mac_cred.c revision 106412
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 * 10106392Srwatson * This software was developed for the FreeBSD Project in part by Network 11106392Srwatson * Associates Laboratories, the Security Research Division of Network 12106392Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 13106392Srwatson * as part of the DARPA 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 * 24100894Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25100894Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26100894Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27100894Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28100894Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29100894Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30100894Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31100894Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32100894Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33100894Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34100894Srwatson * SUCH DAMAGE. 35100894Srwatson * 36100894Srwatson * $FreeBSD: head/sys/security/mac/mac_process.c 106412 2002-11-04 15:13:36Z rwatson $ 37100894Srwatson */ 38100894Srwatson/* 39100894Srwatson * Developed by the TrustedBSD Project. 40100894Srwatson * 41100894Srwatson * Framework for extensible kernel access control. Kernel and userland 42100894Srwatson * interface to the framework, policy registration and composition. 43100894Srwatson */ 44100894Srwatson 45100894Srwatson#include "opt_mac.h" 46104300Sphk#include "opt_devfs.h" 47101173Srwatson 48100894Srwatson#include <sys/param.h> 49100979Srwatson#include <sys/extattr.h> 50100979Srwatson#include <sys/kernel.h> 51100979Srwatson#include <sys/lock.h> 52102949Sbde#include <sys/malloc.h> 53100979Srwatson#include <sys/mutex.h> 54100979Srwatson#include <sys/mac.h> 55101712Srwatson#include <sys/module.h> 56100979Srwatson#include <sys/proc.h> 57100979Srwatson#include <sys/systm.h> 58100894Srwatson#include <sys/sysproto.h> 59100894Srwatson#include <sys/sysent.h> 60100979Srwatson#include <sys/vnode.h> 61100979Srwatson#include <sys/mount.h> 62100979Srwatson#include <sys/file.h> 63100979Srwatson#include <sys/namei.h> 64100979Srwatson#include <sys/socket.h> 65100979Srwatson#include <sys/pipe.h> 66100979Srwatson#include <sys/socketvar.h> 67100979Srwatson#include <sys/sysctl.h> 68100894Srwatson 69100979Srwatson#include <vm/vm.h> 70100979Srwatson#include <vm/pmap.h> 71100979Srwatson#include <vm/vm_map.h> 72100979Srwatson#include <vm/vm_object.h> 73100979Srwatson 74100979Srwatson#include <sys/mac_policy.h> 75100979Srwatson 76100979Srwatson#include <fs/devfs/devfs.h> 77100979Srwatson 78100979Srwatson#include <net/bpfdesc.h> 79100979Srwatson#include <net/if.h> 80100979Srwatson#include <net/if_var.h> 81100979Srwatson 82100979Srwatson#include <netinet/in.h> 83100979Srwatson#include <netinet/ip_var.h> 84100979Srwatson 85100979Srwatson#ifdef MAC 86100979Srwatson 87101712Srwatson/* 88101712Srwatson * Declare that the kernel provides MAC support, version 1. This permits 89101712Srwatson * modules to refuse to be loaded if the necessary support isn't present, 90101712Srwatson * even if it's pre-boot. 91101712Srwatson */ 92101712SrwatsonMODULE_VERSION(kernel_mac_support, 1); 93101712Srwatson 94100979SrwatsonSYSCTL_DECL(_security); 95100979Srwatson 96100979SrwatsonSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 97100979Srwatson "TrustedBSD MAC policy controls"); 98104517Srwatson 99100979Srwatson#if MAC_MAX_POLICIES > 32 100100979Srwatson#error "MAC_MAX_POLICIES too large" 101100979Srwatson#endif 102105497Srwatson 103100979Srwatsonstatic unsigned int mac_max_policies = MAC_MAX_POLICIES; 104100979Srwatsonstatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 105100979SrwatsonSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 106100979Srwatson &mac_max_policies, 0, ""); 107100979Srwatson 108105959Srwatson/* 109105959Srwatson * Has the kernel started generating labeled objects yet? All read/write 110105959Srwatson * access to this variable is serialized during the boot process. Following 111105959Srwatson * the end of serialization, we don't update this flag; no locking. 112105959Srwatson */ 113100979Srwatsonstatic int mac_late = 0; 114100979Srwatson 115105988Srwatson/* 116105988Srwatson * Warn about EA transactions only the first time they happen. 117105988Srwatson * Weak coherency, no locking. 118105988Srwatson */ 119105988Srwatsonstatic int ea_warn_once = 0; 120105988Srwatson 121100979Srwatsonstatic int mac_enforce_fs = 1; 122100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 123100979Srwatson &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 124100979SrwatsonTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 125100979Srwatson 126100979Srwatsonstatic int mac_enforce_network = 1; 127100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 128100979Srwatson &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 129100979SrwatsonTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 130100979Srwatson 131103513Srwatsonstatic int mac_enforce_pipe = 1; 132103513SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 133103513Srwatson &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 134104236SrwatsonTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 135103513Srwatson 136100979Srwatsonstatic int mac_enforce_process = 1; 137100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 138100979Srwatson &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 139100979SrwatsonTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 140100979Srwatson 141100979Srwatsonstatic int mac_enforce_socket = 1; 142100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 143100979Srwatson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 144100979SrwatsonTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 145100979Srwatson 146106045Srwatsonstatic int mac_enforce_system = 1; 147106045SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 148106045Srwatson &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 149106045SrwatsonTUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 150106025Srwatson 151106045Srwatsonstatic int mac_enforce_vm = 1; 152103514SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 153103514Srwatson &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 154104236SrwatsonTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 155103514Srwatson 156103136Srwatsonstatic int mac_mmap_revocation = 1; 157103136SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 158103136Srwatson &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 159103136Srwatson "relabel"); 160101892Srwatsonstatic int mac_mmap_revocation_via_cow = 0; 161100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 162100979Srwatson &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 163100979Srwatson "copy-on-write semantics, or by removing all write access"); 164100979Srwatson 165101988Srwatson#ifdef MAC_DEBUG 166104268SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 167104268Srwatson "TrustedBSD MAC debug info"); 168104268Srwatson 169104268Srwatsonstatic int mac_debug_label_fallback = 0; 170104268SrwatsonSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 171104268Srwatson &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 172104268Srwatson "when label is corrupted."); 173104268SrwatsonTUNABLE_INT("security.mac.debug_label_fallback", 174104268Srwatson &mac_debug_label_fallback); 175104268Srwatson 176104517SrwatsonSYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 177104517Srwatson "TrustedBSD MAC object counters"); 178104517Srwatson 179100979Srwatsonstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 180100979Srwatson nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 181100979Srwatson nmacipqs, nmacpipes; 182104517Srwatson 183104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 184100979Srwatson &nmacmbufs, 0, "number of mbufs in use"); 185104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 186100979Srwatson &nmaccreds, 0, "number of ucreds in use"); 187104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 188100979Srwatson &nmacifnets, 0, "number of ifnets in use"); 189104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 190100979Srwatson &nmacipqs, 0, "number of ipqs in use"); 191104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 192100979Srwatson &nmacbpfdescs, 0, "number of bpfdescs in use"); 193104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 194100979Srwatson &nmacsockets, 0, "number of sockets in use"); 195104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 196100979Srwatson &nmacpipes, 0, "number of pipes in use"); 197104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 198100979Srwatson &nmacmounts, 0, "number of mounts in use"); 199104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 200100979Srwatson &nmactemp, 0, "number of temporary labels in use"); 201104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 202100979Srwatson &nmacvnodes, 0, "number of vnodes in use"); 203104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 204100979Srwatson &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 205101988Srwatson#endif 206100979Srwatson 207100979Srwatsonstatic int error_select(int error1, int error2); 208100979Srwatsonstatic int mac_policy_register(struct mac_policy_conf *mpc); 209100979Srwatsonstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 210100979Srwatson 211104546Srwatsonstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 212104546Srwatson struct vnode *vp, int *prot); 213100979Srwatsonstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 214100979Srwatson struct ucred *cred, struct vm_map *map); 215100979Srwatson 216104541Srwatsonstatic void mac_destroy_socket_label(struct label *label); 217104541Srwatson 218105988Srwatsonstatic int mac_setlabel_vnode_extattr(struct ucred *cred, 219105988Srwatson struct vnode *vp, struct label *intlabel); 220105988Srwatson 221105988Srwatson 222100979SrwatsonMALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 223100979SrwatsonMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 224105694SrwatsonMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 225100979Srwatson 226100979Srwatson/* 227100979Srwatson * mac_policy_list_lock protects the consistency of 'mac_policy_list', 228100979Srwatson * the linked list of attached policy modules. Read-only consumers of 229100979Srwatson * the list must acquire a shared lock for the duration of their use; 230100979Srwatson * writers must acquire an exclusive lock. Note that for compound 231100979Srwatson * operations, locks should be held for the entire compound operation, 232100979Srwatson * and that this is not yet done for relabel requests. 233100979Srwatson */ 234100979Srwatsonstatic struct mtx mac_policy_list_lock; 235100979Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 236100979Srwatsonstatic int mac_policy_list_busy; 237100979Srwatson#define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 238100979Srwatson "mac_policy_list_lock", NULL, MTX_DEF); 239100979Srwatson#define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 240100979Srwatson#define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 241100979Srwatson 242100979Srwatson#define MAC_POLICY_LIST_BUSY() do { \ 243100979Srwatson MAC_POLICY_LIST_LOCK(); \ 244100979Srwatson mac_policy_list_busy++; \ 245100979Srwatson MAC_POLICY_LIST_UNLOCK(); \ 246100979Srwatson} while (0) 247100979Srwatson 248100979Srwatson#define MAC_POLICY_LIST_UNBUSY() do { \ 249100979Srwatson MAC_POLICY_LIST_LOCK(); \ 250100979Srwatson mac_policy_list_busy--; \ 251100979Srwatson if (mac_policy_list_busy < 0) \ 252100979Srwatson panic("Extra mac_policy_list_busy--"); \ 253100979Srwatson MAC_POLICY_LIST_UNLOCK(); \ 254100979Srwatson} while (0) 255100979Srwatson 256100979Srwatson/* 257100979Srwatson * MAC_CHECK performs the designated check by walking the policy 258100979Srwatson * module list and checking with each as to how it feels about the 259100979Srwatson * request. Note that it returns its value via 'error' in the scope 260100979Srwatson * of the caller. 261100979Srwatson */ 262100979Srwatson#define MAC_CHECK(check, args...) do { \ 263100979Srwatson struct mac_policy_conf *mpc; \ 264100979Srwatson \ 265100979Srwatson error = 0; \ 266100979Srwatson MAC_POLICY_LIST_BUSY(); \ 267100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 268100979Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 269100979Srwatson error = error_select( \ 270100979Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 271100979Srwatson error); \ 272100979Srwatson } \ 273100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 274100979Srwatson} while (0) 275100979Srwatson 276100979Srwatson/* 277100979Srwatson * MAC_BOOLEAN performs the designated boolean composition by walking 278100979Srwatson * the module list, invoking each instance of the operation, and 279100979Srwatson * combining the results using the passed C operator. Note that it 280100979Srwatson * returns its value via 'result' in the scope of the caller, which 281100979Srwatson * should be initialized by the caller in a meaningful way to get 282100979Srwatson * a meaningful result. 283100979Srwatson */ 284100979Srwatson#define MAC_BOOLEAN(operation, composition, args...) do { \ 285100979Srwatson struct mac_policy_conf *mpc; \ 286100979Srwatson \ 287100979Srwatson MAC_POLICY_LIST_BUSY(); \ 288100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 289100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 290100979Srwatson result = result composition \ 291100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 292100979Srwatson } \ 293100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 294100979Srwatson} while (0) 295100979Srwatson 296105694Srwatson#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 297105694Srwatson outbuflen) do { \ 298105694Srwatson char *curptr, *curptr_start, *element_name, *element_temp; \ 299105694Srwatson size_t left, left_start, len; \ 300105694Srwatson int claimed, first, first_start, ignorenotfound; \ 301105694Srwatson \ 302105694Srwatson error = 0; \ 303105694Srwatson element_temp = elementlist; \ 304105694Srwatson curptr = outbuf; \ 305105694Srwatson curptr[0] = '\0'; \ 306105694Srwatson left = outbuflen; \ 307105694Srwatson first = 1; \ 308105694Srwatson while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 309105694Srwatson curptr_start = curptr; \ 310105694Srwatson left_start = left; \ 311105694Srwatson first_start = first; \ 312105694Srwatson if (element_name[0] == '?') { \ 313105694Srwatson element_name++; \ 314105694Srwatson ignorenotfound = 1; \ 315105694Srwatson } else \ 316105694Srwatson ignorenotfound = 0; \ 317105694Srwatson claimed = 0; \ 318105694Srwatson if (first) { \ 319105694Srwatson len = snprintf(curptr, left, "%s/", \ 320105694Srwatson element_name); \ 321105694Srwatson first = 0; \ 322105694Srwatson } else \ 323105694Srwatson len = snprintf(curptr, left, ",%s/", \ 324105694Srwatson element_name); \ 325105694Srwatson if (len >= left) { \ 326105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 327105694Srwatson break; \ 328105694Srwatson } \ 329105694Srwatson curptr += len; \ 330105694Srwatson left -= len; \ 331105694Srwatson \ 332105694Srwatson MAC_CHECK(externalize_ ## type, label, element_name, \ 333105694Srwatson curptr, left, &len, &claimed); \ 334105694Srwatson if (error) \ 335105694Srwatson break; \ 336105694Srwatson if (claimed == 1) { \ 337105694Srwatson if (len >= outbuflen) { \ 338105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 339105694Srwatson break; \ 340105694Srwatson } \ 341105694Srwatson curptr += len; \ 342105694Srwatson left -= len; \ 343105694Srwatson } else if (claimed == 0 && ignorenotfound) { \ 344105694Srwatson /* \ 345105694Srwatson * Revert addition of the label element \ 346105694Srwatson * name. \ 347105694Srwatson */ \ 348105694Srwatson curptr = curptr_start; \ 349105694Srwatson *curptr = '\0'; \ 350105694Srwatson left = left_start; \ 351105694Srwatson first = first_start; \ 352105694Srwatson } else { \ 353105694Srwatson error = EINVAL; /* XXXMAC: ENOLABEL */ \ 354105694Srwatson break; \ 355105694Srwatson } \ 356105694Srwatson } \ 357105694Srwatson} while (0) 358105694Srwatson 359105694Srwatson#define MAC_INTERNALIZE(type, label, instring) do { \ 360105694Srwatson char *element, *element_name, *element_data; \ 361105694Srwatson int claimed; \ 362105694Srwatson \ 363105694Srwatson error = 0; \ 364105694Srwatson element = instring; \ 365105694Srwatson while ((element_name = strsep(&element, ",")) != NULL) { \ 366105694Srwatson element_data = element_name; \ 367105694Srwatson element_name = strsep(&element_data, "/"); \ 368105694Srwatson if (element_data == NULL) { \ 369105694Srwatson error = EINVAL; \ 370105694Srwatson break; \ 371105694Srwatson } \ 372105694Srwatson claimed = 0; \ 373105694Srwatson MAC_CHECK(internalize_ ## type, label, element_name, \ 374105694Srwatson element_data, &claimed); \ 375105694Srwatson if (error) \ 376105694Srwatson break; \ 377105694Srwatson if (claimed != 1) { \ 378105694Srwatson /* XXXMAC: Another error here? */ \ 379105694Srwatson error = EINVAL; \ 380105694Srwatson break; \ 381105694Srwatson } \ 382105694Srwatson } \ 383105694Srwatson} while (0) 384105694Srwatson 385100979Srwatson/* 386100979Srwatson * MAC_PERFORM performs the designated operation by walking the policy 387100979Srwatson * module list and invoking that operation for each policy. 388100979Srwatson */ 389100979Srwatson#define MAC_PERFORM(operation, args...) do { \ 390100979Srwatson struct mac_policy_conf *mpc; \ 391100979Srwatson \ 392100979Srwatson MAC_POLICY_LIST_BUSY(); \ 393100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 394100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 395100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 396100979Srwatson } \ 397100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 398100979Srwatson} while (0) 399100979Srwatson 400100979Srwatson/* 401100979Srwatson * Initialize the MAC subsystem, including appropriate SMP locks. 402100979Srwatson */ 403100979Srwatsonstatic void 404100979Srwatsonmac_init(void) 405100979Srwatson{ 406100979Srwatson 407100979Srwatson LIST_INIT(&mac_policy_list); 408100979Srwatson MAC_POLICY_LIST_LOCKINIT(); 409100979Srwatson} 410100979Srwatson 411100979Srwatson/* 412100979Srwatson * For the purposes of modules that want to know if they were loaded 413100979Srwatson * "early", set the mac_late flag once we've processed modules either 414100979Srwatson * linked into the kernel, or loaded before the kernel startup. 415100979Srwatson */ 416100979Srwatsonstatic void 417100979Srwatsonmac_late_init(void) 418100979Srwatson{ 419100979Srwatson 420100979Srwatson mac_late = 1; 421100979Srwatson} 422100979Srwatson 423100979Srwatson/* 424100979Srwatson * Allow MAC policy modules to register during boot, etc. 425100979Srwatson */ 426100894Srwatsonint 427100979Srwatsonmac_policy_modevent(module_t mod, int type, void *data) 428100979Srwatson{ 429100979Srwatson struct mac_policy_conf *mpc; 430100979Srwatson int error; 431100979Srwatson 432100979Srwatson error = 0; 433100979Srwatson mpc = (struct mac_policy_conf *) data; 434100979Srwatson 435100979Srwatson switch (type) { 436100979Srwatson case MOD_LOAD: 437100979Srwatson if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 438100979Srwatson mac_late) { 439100979Srwatson printf("mac_policy_modevent: can't load %s policy " 440100979Srwatson "after booting\n", mpc->mpc_name); 441100979Srwatson error = EBUSY; 442100979Srwatson break; 443100979Srwatson } 444100979Srwatson error = mac_policy_register(mpc); 445100979Srwatson break; 446100979Srwatson case MOD_UNLOAD: 447100979Srwatson /* Don't unregister the module if it was never registered. */ 448100979Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 449100979Srwatson != 0) 450100979Srwatson error = mac_policy_unregister(mpc); 451100979Srwatson else 452100979Srwatson error = 0; 453100979Srwatson break; 454100979Srwatson default: 455100979Srwatson break; 456100979Srwatson } 457100979Srwatson 458100979Srwatson return (error); 459100979Srwatson} 460100979Srwatson 461100979Srwatsonstatic int 462100979Srwatsonmac_policy_register(struct mac_policy_conf *mpc) 463100979Srwatson{ 464100979Srwatson struct mac_policy_conf *tmpc; 465100979Srwatson int slot; 466100979Srwatson 467100979Srwatson MAC_POLICY_LIST_LOCK(); 468100979Srwatson if (mac_policy_list_busy > 0) { 469100979Srwatson MAC_POLICY_LIST_UNLOCK(); 470100979Srwatson return (EBUSY); 471100979Srwatson } 472100979Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 473100979Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 474100979Srwatson MAC_POLICY_LIST_UNLOCK(); 475100979Srwatson return (EEXIST); 476100979Srwatson } 477100979Srwatson } 478100979Srwatson if (mpc->mpc_field_off != NULL) { 479100979Srwatson slot = ffs(mac_policy_offsets_free); 480100979Srwatson if (slot == 0) { 481100979Srwatson MAC_POLICY_LIST_UNLOCK(); 482100979Srwatson return (ENOMEM); 483100979Srwatson } 484100979Srwatson slot--; 485100979Srwatson mac_policy_offsets_free &= ~(1 << slot); 486100979Srwatson *mpc->mpc_field_off = slot; 487100979Srwatson } 488100979Srwatson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 489100979Srwatson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 490100979Srwatson 491100979Srwatson /* Per-policy initialization. */ 492100979Srwatson if (mpc->mpc_ops->mpo_init != NULL) 493100979Srwatson (*(mpc->mpc_ops->mpo_init))(mpc); 494100979Srwatson MAC_POLICY_LIST_UNLOCK(); 495100979Srwatson 496100979Srwatson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 497100979Srwatson mpc->mpc_name); 498100979Srwatson 499100979Srwatson return (0); 500100979Srwatson} 501100979Srwatson 502100979Srwatsonstatic int 503100979Srwatsonmac_policy_unregister(struct mac_policy_conf *mpc) 504100979Srwatson{ 505100979Srwatson 506104520Srwatson /* 507104520Srwatson * If we fail the load, we may get a request to unload. Check 508104520Srwatson * to see if we did the run-time registration, and if not, 509104520Srwatson * silently succeed. 510104520Srwatson */ 511104520Srwatson MAC_POLICY_LIST_LOCK(); 512104520Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 513104520Srwatson MAC_POLICY_LIST_UNLOCK(); 514104520Srwatson return (0); 515104520Srwatson } 516100979Srwatson#if 0 517100979Srwatson /* 518100979Srwatson * Don't allow unloading modules with private data. 519100979Srwatson */ 520104520Srwatson if (mpc->mpc_field_off != NULL) { 521104520Srwatson MAC_POLICY_LIST_UNLOCK(); 522100979Srwatson return (EBUSY); 523104520Srwatson } 524100979Srwatson#endif 525104520Srwatson /* 526104520Srwatson * Only allow the unload to proceed if the module is unloadable 527104520Srwatson * by its own definition. 528104520Srwatson */ 529104520Srwatson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 530104520Srwatson MAC_POLICY_LIST_UNLOCK(); 531100979Srwatson return (EBUSY); 532104520Srwatson } 533104520Srwatson /* 534104520Srwatson * Right now, we EBUSY if the list is in use. In the future, 535104520Srwatson * for reliability reasons, we might want to sleep and wakeup 536104520Srwatson * later to try again. 537104520Srwatson */ 538100979Srwatson if (mac_policy_list_busy > 0) { 539100979Srwatson MAC_POLICY_LIST_UNLOCK(); 540100979Srwatson return (EBUSY); 541100979Srwatson } 542100979Srwatson if (mpc->mpc_ops->mpo_destroy != NULL) 543100979Srwatson (*(mpc->mpc_ops->mpo_destroy))(mpc); 544100979Srwatson 545100979Srwatson LIST_REMOVE(mpc, mpc_list); 546100979Srwatson MAC_POLICY_LIST_UNLOCK(); 547100979Srwatson 548105474Srwatson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 549100979Srwatson 550100979Srwatson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 551100979Srwatson mpc->mpc_name); 552100979Srwatson 553100979Srwatson return (0); 554100979Srwatson} 555100979Srwatson 556100979Srwatson/* 557100979Srwatson * Define an error value precedence, and given two arguments, selects the 558100979Srwatson * value with the higher precedence. 559100979Srwatson */ 560100979Srwatsonstatic int 561100979Srwatsonerror_select(int error1, int error2) 562100979Srwatson{ 563100979Srwatson 564100979Srwatson /* Certain decision-making errors take top priority. */ 565100979Srwatson if (error1 == EDEADLK || error2 == EDEADLK) 566100979Srwatson return (EDEADLK); 567100979Srwatson 568100979Srwatson /* Invalid arguments should be reported where possible. */ 569100979Srwatson if (error1 == EINVAL || error2 == EINVAL) 570100979Srwatson return (EINVAL); 571100979Srwatson 572100979Srwatson /* Precedence goes to "visibility", with both process and file. */ 573100979Srwatson if (error1 == ESRCH || error2 == ESRCH) 574100979Srwatson return (ESRCH); 575100979Srwatson 576100979Srwatson if (error1 == ENOENT || error2 == ENOENT) 577100979Srwatson return (ENOENT); 578100979Srwatson 579100979Srwatson /* Precedence goes to DAC/MAC protections. */ 580100979Srwatson if (error1 == EACCES || error2 == EACCES) 581100979Srwatson return (EACCES); 582100979Srwatson 583100979Srwatson /* Precedence goes to privilege. */ 584100979Srwatson if (error1 == EPERM || error2 == EPERM) 585100979Srwatson return (EPERM); 586100979Srwatson 587100979Srwatson /* Precedence goes to error over success; otherwise, arbitrary. */ 588100979Srwatson if (error1 != 0) 589100979Srwatson return (error1); 590100979Srwatson return (error2); 591100979Srwatson} 592100979Srwatson 593104521Srwatsonstatic void 594104521Srwatsonmac_init_label(struct label *label) 595104521Srwatson{ 596104521Srwatson 597104521Srwatson bzero(label, sizeof(*label)); 598104521Srwatson label->l_flags = MAC_FLAG_INITIALIZED; 599104521Srwatson} 600104521Srwatson 601104521Srwatsonstatic void 602104521Srwatsonmac_destroy_label(struct label *label) 603104521Srwatson{ 604104521Srwatson 605104521Srwatson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 606104521Srwatson ("destroying uninitialized label")); 607104521Srwatson 608104521Srwatson bzero(label, sizeof(*label)); 609104521Srwatson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 610104521Srwatson} 611104521Srwatson 612100979Srwatsonvoid 613104527Srwatsonmac_init_bpfdesc(struct bpf_d *bpf_d) 614104521Srwatson{ 615104521Srwatson 616104527Srwatson mac_init_label(&bpf_d->bd_label); 617104527Srwatson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 618104521Srwatson#ifdef MAC_DEBUG 619104527Srwatson atomic_add_int(&nmacbpfdescs, 1); 620104521Srwatson#endif 621104521Srwatson} 622104521Srwatson 623105694Srwatsonstatic void 624105694Srwatsonmac_init_cred_label(struct label *label) 625104521Srwatson{ 626104521Srwatson 627105694Srwatson mac_init_label(label); 628105694Srwatson MAC_PERFORM(init_cred_label, label); 629104521Srwatson#ifdef MAC_DEBUG 630104521Srwatson atomic_add_int(&nmaccreds, 1); 631104521Srwatson#endif 632104521Srwatson} 633104521Srwatson 634104521Srwatsonvoid 635105694Srwatsonmac_init_cred(struct ucred *cred) 636105694Srwatson{ 637105694Srwatson 638105694Srwatson mac_init_cred_label(&cred->cr_label); 639105694Srwatson} 640105694Srwatson 641105694Srwatsonvoid 642104527Srwatsonmac_init_devfsdirent(struct devfs_dirent *de) 643104521Srwatson{ 644104521Srwatson 645104527Srwatson mac_init_label(&de->de_label); 646104527Srwatson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 647104521Srwatson#ifdef MAC_DEBUG 648104527Srwatson atomic_add_int(&nmacdevfsdirents, 1); 649104521Srwatson#endif 650104521Srwatson} 651104521Srwatson 652105694Srwatsonstatic void 653105694Srwatsonmac_init_ifnet_label(struct label *label) 654104521Srwatson{ 655104521Srwatson 656105694Srwatson mac_init_label(label); 657105694Srwatson MAC_PERFORM(init_ifnet_label, label); 658104521Srwatson#ifdef MAC_DEBUG 659104521Srwatson atomic_add_int(&nmacifnets, 1); 660104521Srwatson#endif 661104521Srwatson} 662104521Srwatson 663104521Srwatsonvoid 664105694Srwatsonmac_init_ifnet(struct ifnet *ifp) 665105694Srwatson{ 666105694Srwatson 667105694Srwatson mac_init_ifnet_label(&ifp->if_label); 668105694Srwatson} 669105694Srwatson 670105694Srwatsonvoid 671104527Srwatsonmac_init_ipq(struct ipq *ipq) 672104521Srwatson{ 673104521Srwatson 674104527Srwatson mac_init_label(&ipq->ipq_label); 675104527Srwatson MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 676104521Srwatson#ifdef MAC_DEBUG 677104527Srwatson atomic_add_int(&nmacipqs, 1); 678104521Srwatson#endif 679104521Srwatson} 680104521Srwatson 681104527Srwatsonint 682104527Srwatsonmac_init_mbuf(struct mbuf *m, int flag) 683104527Srwatson{ 684104528Srwatson int error; 685104528Srwatson 686104527Srwatson KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 687104527Srwatson 688104527Srwatson mac_init_label(&m->m_pkthdr.label); 689104527Srwatson 690104528Srwatson MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 691104528Srwatson if (error) { 692104528Srwatson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 693104528Srwatson mac_destroy_label(&m->m_pkthdr.label); 694104528Srwatson } 695104528Srwatson 696104527Srwatson#ifdef MAC_DEBUG 697104528Srwatson if (error == 0) 698104528Srwatson atomic_add_int(&nmacmbufs, 1); 699104527Srwatson#endif 700104528Srwatson return (error); 701104527Srwatson} 702104527Srwatson 703104521Srwatsonvoid 704104527Srwatsonmac_init_mount(struct mount *mp) 705104521Srwatson{ 706104521Srwatson 707104527Srwatson mac_init_label(&mp->mnt_mntlabel); 708104527Srwatson mac_init_label(&mp->mnt_fslabel); 709104527Srwatson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 710104527Srwatson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 711104521Srwatson#ifdef MAC_DEBUG 712104527Srwatson atomic_add_int(&nmacmounts, 1); 713104521Srwatson#endif 714104521Srwatson} 715104521Srwatson 716105694Srwatsonstatic void 717105694Srwatsonmac_init_pipe_label(struct label *label) 718105694Srwatson{ 719105694Srwatson 720105694Srwatson mac_init_label(label); 721105694Srwatson MAC_PERFORM(init_pipe_label, label); 722105694Srwatson#ifdef MAC_DEBUG 723105694Srwatson atomic_add_int(&nmacpipes, 1); 724105694Srwatson#endif 725105694Srwatson} 726105694Srwatson 727104521Srwatsonvoid 728104527Srwatsonmac_init_pipe(struct pipe *pipe) 729104521Srwatson{ 730104527Srwatson struct label *label; 731104521Srwatson 732104527Srwatson label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 733104527Srwatson pipe->pipe_label = label; 734104527Srwatson pipe->pipe_peer->pipe_label = label; 735105694Srwatson mac_init_pipe_label(label); 736104521Srwatson} 737104521Srwatson 738104541Srwatsonstatic int 739104541Srwatsonmac_init_socket_label(struct label *label, int flag) 740104521Srwatson{ 741104541Srwatson int error; 742104521Srwatson 743104541Srwatson mac_init_label(label); 744104541Srwatson 745104541Srwatson MAC_CHECK(init_socket_label, label, flag); 746104541Srwatson if (error) { 747104541Srwatson MAC_PERFORM(destroy_socket_label, label); 748104541Srwatson mac_destroy_label(label); 749104541Srwatson } 750104541Srwatson 751104521Srwatson#ifdef MAC_DEBUG 752104541Srwatson if (error == 0) 753104541Srwatson atomic_add_int(&nmacsockets, 1); 754104521Srwatson#endif 755104541Srwatson 756104541Srwatson return (error); 757104521Srwatson} 758104521Srwatson 759104541Srwatsonstatic int 760104541Srwatsonmac_init_socket_peer_label(struct label *label, int flag) 761104541Srwatson{ 762104541Srwatson int error; 763104541Srwatson 764104541Srwatson mac_init_label(label); 765104541Srwatson 766104541Srwatson MAC_CHECK(init_socket_peer_label, label, flag); 767104541Srwatson if (error) { 768104541Srwatson MAC_PERFORM(destroy_socket_label, label); 769104541Srwatson mac_destroy_label(label); 770104541Srwatson } 771104541Srwatson 772104541Srwatson return (error); 773104541Srwatson} 774104541Srwatson 775104541Srwatsonint 776104541Srwatsonmac_init_socket(struct socket *socket, int flag) 777104541Srwatson{ 778104541Srwatson int error; 779104541Srwatson 780104541Srwatson error = mac_init_socket_label(&socket->so_label, flag); 781104541Srwatson if (error) 782104541Srwatson return (error); 783104541Srwatson 784104541Srwatson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 785104541Srwatson if (error) 786104541Srwatson mac_destroy_socket_label(&socket->so_label); 787104541Srwatson 788104541Srwatson return (error); 789104541Srwatson} 790104541Srwatson 791105988Srwatsonvoid 792105694Srwatsonmac_init_vnode_label(struct label *label) 793104521Srwatson{ 794104521Srwatson 795104527Srwatson mac_init_label(label); 796105694Srwatson MAC_PERFORM(init_vnode_label, label); 797104521Srwatson#ifdef MAC_DEBUG 798105694Srwatson atomic_add_int(&nmacvnodes, 1); 799104521Srwatson#endif 800104521Srwatson} 801104521Srwatson 802104521Srwatsonvoid 803104527Srwatsonmac_init_vnode(struct vnode *vp) 804104521Srwatson{ 805104521Srwatson 806105694Srwatson mac_init_vnode_label(&vp->v_label); 807104521Srwatson} 808104521Srwatson 809104521Srwatsonvoid 810104527Srwatsonmac_destroy_bpfdesc(struct bpf_d *bpf_d) 811104521Srwatson{ 812104521Srwatson 813104527Srwatson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 814104527Srwatson mac_destroy_label(&bpf_d->bd_label); 815104521Srwatson#ifdef MAC_DEBUG 816104527Srwatson atomic_subtract_int(&nmacbpfdescs, 1); 817104521Srwatson#endif 818104521Srwatson} 819104521Srwatson 820105694Srwatsonstatic void 821105694Srwatsonmac_destroy_cred_label(struct label *label) 822104521Srwatson{ 823104521Srwatson 824105694Srwatson MAC_PERFORM(destroy_cred_label, label); 825105694Srwatson mac_destroy_label(label); 826104521Srwatson#ifdef MAC_DEBUG 827104527Srwatson atomic_subtract_int(&nmaccreds, 1); 828104521Srwatson#endif 829104521Srwatson} 830104521Srwatson 831104521Srwatsonvoid 832105694Srwatsonmac_destroy_cred(struct ucred *cred) 833105694Srwatson{ 834105694Srwatson 835105694Srwatson mac_destroy_cred_label(&cred->cr_label); 836105694Srwatson} 837105694Srwatson 838105694Srwatsonvoid 839104527Srwatsonmac_destroy_devfsdirent(struct devfs_dirent *de) 840104521Srwatson{ 841104521Srwatson 842104527Srwatson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 843104527Srwatson mac_destroy_label(&de->de_label); 844104521Srwatson#ifdef MAC_DEBUG 845104527Srwatson atomic_subtract_int(&nmacdevfsdirents, 1); 846104521Srwatson#endif 847104521Srwatson} 848104521Srwatson 849105694Srwatsonstatic void 850105694Srwatsonmac_destroy_ifnet_label(struct label *label) 851104521Srwatson{ 852104521Srwatson 853105694Srwatson MAC_PERFORM(destroy_ifnet_label, label); 854105694Srwatson mac_destroy_label(label); 855104521Srwatson#ifdef MAC_DEBUG 856104527Srwatson atomic_subtract_int(&nmacifnets, 1); 857104521Srwatson#endif 858104521Srwatson} 859104521Srwatson 860104521Srwatsonvoid 861105694Srwatsonmac_destroy_ifnet(struct ifnet *ifp) 862105694Srwatson{ 863105694Srwatson 864105694Srwatson mac_destroy_ifnet_label(&ifp->if_label); 865105694Srwatson} 866105694Srwatson 867105694Srwatsonvoid 868104527Srwatsonmac_destroy_ipq(struct ipq *ipq) 869104521Srwatson{ 870104521Srwatson 871104527Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 872104527Srwatson mac_destroy_label(&ipq->ipq_label); 873104521Srwatson#ifdef MAC_DEBUG 874104527Srwatson atomic_subtract_int(&nmacipqs, 1); 875104521Srwatson#endif 876104521Srwatson} 877104521Srwatson 878104527Srwatsonvoid 879104527Srwatsonmac_destroy_mbuf(struct mbuf *m) 880104521Srwatson{ 881104521Srwatson 882104527Srwatson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 883104527Srwatson mac_destroy_label(&m->m_pkthdr.label); 884104521Srwatson#ifdef MAC_DEBUG 885104527Srwatson atomic_subtract_int(&nmacmbufs, 1); 886104521Srwatson#endif 887104521Srwatson} 888104521Srwatson 889104527Srwatsonvoid 890104527Srwatsonmac_destroy_mount(struct mount *mp) 891104521Srwatson{ 892104521Srwatson 893104527Srwatson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 894104527Srwatson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 895104527Srwatson mac_destroy_label(&mp->mnt_fslabel); 896104527Srwatson mac_destroy_label(&mp->mnt_mntlabel); 897104521Srwatson#ifdef MAC_DEBUG 898104527Srwatson atomic_subtract_int(&nmacmounts, 1); 899104521Srwatson#endif 900104521Srwatson} 901104521Srwatson 902105694Srwatsonstatic void 903105694Srwatsonmac_destroy_pipe_label(struct label *label) 904104521Srwatson{ 905104521Srwatson 906105694Srwatson MAC_PERFORM(destroy_pipe_label, label); 907105694Srwatson mac_destroy_label(label); 908104521Srwatson#ifdef MAC_DEBUG 909104527Srwatson atomic_subtract_int(&nmacpipes, 1); 910104521Srwatson#endif 911104521Srwatson} 912104521Srwatson 913105694Srwatsonvoid 914105694Srwatsonmac_destroy_pipe(struct pipe *pipe) 915105694Srwatson{ 916105694Srwatson 917105694Srwatson mac_destroy_pipe_label(pipe->pipe_label); 918105694Srwatson free(pipe->pipe_label, M_MACPIPELABEL); 919105694Srwatson} 920105694Srwatson 921104541Srwatsonstatic void 922104541Srwatsonmac_destroy_socket_label(struct label *label) 923104521Srwatson{ 924104521Srwatson 925104541Srwatson MAC_PERFORM(destroy_socket_label, label); 926104541Srwatson mac_destroy_label(label); 927104521Srwatson#ifdef MAC_DEBUG 928104527Srwatson atomic_subtract_int(&nmacsockets, 1); 929104521Srwatson#endif 930104521Srwatson} 931104521Srwatson 932104527Srwatsonstatic void 933104541Srwatsonmac_destroy_socket_peer_label(struct label *label) 934104541Srwatson{ 935104541Srwatson 936104541Srwatson MAC_PERFORM(destroy_socket_peer_label, label); 937104541Srwatson mac_destroy_label(label); 938104541Srwatson} 939104541Srwatson 940104541Srwatsonvoid 941104541Srwatsonmac_destroy_socket(struct socket *socket) 942104541Srwatson{ 943104541Srwatson 944104541Srwatson mac_destroy_socket_label(&socket->so_label); 945104541Srwatson mac_destroy_socket_peer_label(&socket->so_peerlabel); 946104541Srwatson} 947104541Srwatson 948105988Srwatsonvoid 949105694Srwatsonmac_destroy_vnode_label(struct label *label) 950104521Srwatson{ 951104521Srwatson 952105694Srwatson MAC_PERFORM(destroy_vnode_label, label); 953104527Srwatson mac_destroy_label(label); 954104521Srwatson#ifdef MAC_DEBUG 955105694Srwatson atomic_subtract_int(&nmacvnodes, 1); 956104521Srwatson#endif 957104521Srwatson} 958104521Srwatson 959104521Srwatsonvoid 960104527Srwatsonmac_destroy_vnode(struct vnode *vp) 961104521Srwatson{ 962104521Srwatson 963105694Srwatson mac_destroy_vnode_label(&vp->v_label); 964104521Srwatson} 965104521Srwatson 966105694Srwatsonstatic void 967105694Srwatsonmac_copy_pipe_label(struct label *src, struct label *dest) 968105694Srwatson{ 969105694Srwatson 970105694Srwatson MAC_PERFORM(copy_pipe_label, src, dest); 971105694Srwatson} 972105694Srwatson 973105988Srwatsonvoid 974105694Srwatsonmac_copy_vnode_label(struct label *src, struct label *dest) 975105694Srwatson{ 976105694Srwatson 977105694Srwatson MAC_PERFORM(copy_vnode_label, src, dest); 978105694Srwatson} 979105694Srwatson 980104522Srwatsonstatic int 981105694Srwatsonmac_check_structmac_consistent(struct mac *mac) 982104522Srwatson{ 983105694Srwatson 984105694Srwatson if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 985105694Srwatson return (EINVAL); 986105694Srwatson 987105694Srwatson return (0); 988105694Srwatson} 989105694Srwatson 990105694Srwatsonstatic int 991105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements, 992105694Srwatson char *outbuf, size_t outbuflen, int flags) 993105694Srwatson{ 994104522Srwatson int error; 995104522Srwatson 996105694Srwatson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 997104522Srwatson 998104522Srwatson return (error); 999104522Srwatson} 1000104522Srwatson 1001104522Srwatsonstatic int 1002105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements, 1003105694Srwatson char *outbuf, size_t outbuflen, int flags) 1004104522Srwatson{ 1005104522Srwatson int error; 1006104522Srwatson 1007105694Srwatson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1008104522Srwatson 1009104522Srwatson return (error); 1010104522Srwatson} 1011104522Srwatson 1012105694Srwatsonstatic int 1013105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements, 1014105694Srwatson char *outbuf, size_t outbuflen, int flags) 1015105694Srwatson{ 1016105694Srwatson int error; 1017105694Srwatson 1018105694Srwatson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1019105694Srwatson 1020105694Srwatson return (error); 1021105694Srwatson} 1022105694Srwatson 1023105694Srwatsonstatic int 1024105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements, 1025105694Srwatson char *outbuf, size_t outbuflen, int flags) 1026105694Srwatson{ 1027105694Srwatson int error; 1028105694Srwatson 1029105694Srwatson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1030105694Srwatson 1031105694Srwatson return (error); 1032105694Srwatson} 1033105694Srwatson 1034105694Srwatsonstatic int 1035105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements, 1036105694Srwatson char *outbuf, size_t outbuflen, int flags) 1037105694Srwatson{ 1038105694Srwatson int error; 1039105694Srwatson 1040105694Srwatson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1041105694Srwatson 1042105694Srwatson return (error); 1043105694Srwatson} 1044105694Srwatson 1045105694Srwatsonstatic int 1046105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements, 1047105694Srwatson char *outbuf, size_t outbuflen, int flags) 1048105694Srwatson{ 1049105694Srwatson int error; 1050105694Srwatson 1051105694Srwatson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1052105694Srwatson 1053105694Srwatson return (error); 1054105694Srwatson} 1055105694Srwatson 1056105694Srwatsonstatic int 1057105694Srwatsonmac_internalize_cred_label(struct label *label, char *string) 1058105694Srwatson{ 1059105694Srwatson int error; 1060105694Srwatson 1061105694Srwatson MAC_INTERNALIZE(cred_label, label, string); 1062105694Srwatson 1063105694Srwatson return (error); 1064105694Srwatson} 1065105694Srwatson 1066105694Srwatsonstatic int 1067105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string) 1068105694Srwatson{ 1069105694Srwatson int error; 1070105694Srwatson 1071105694Srwatson MAC_INTERNALIZE(ifnet_label, label, string); 1072105694Srwatson 1073105694Srwatson return (error); 1074105694Srwatson} 1075105694Srwatson 1076105694Srwatsonstatic int 1077105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string) 1078105694Srwatson{ 1079105694Srwatson int error; 1080105694Srwatson 1081105694Srwatson MAC_INTERNALIZE(pipe_label, label, string); 1082105694Srwatson 1083105694Srwatson return (error); 1084105694Srwatson} 1085105694Srwatson 1086105694Srwatsonstatic int 1087105694Srwatsonmac_internalize_socket_label(struct label *label, char *string) 1088105694Srwatson{ 1089105694Srwatson int error; 1090105694Srwatson 1091105694Srwatson MAC_INTERNALIZE(socket_label, label, string); 1092105694Srwatson 1093105694Srwatson return (error); 1094105694Srwatson} 1095105694Srwatson 1096105694Srwatsonstatic int 1097105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string) 1098105694Srwatson{ 1099105694Srwatson int error; 1100105694Srwatson 1101105694Srwatson MAC_INTERNALIZE(vnode_label, label, string); 1102105694Srwatson 1103105694Srwatson return (error); 1104105694Srwatson} 1105105694Srwatson 1106104522Srwatson/* 1107104522Srwatson * Initialize MAC label for the first kernel process, from which other 1108104522Srwatson * kernel processes and threads are spawned. 1109104522Srwatson */ 1110104521Srwatsonvoid 1111104522Srwatsonmac_create_proc0(struct ucred *cred) 1112104522Srwatson{ 1113104522Srwatson 1114104522Srwatson MAC_PERFORM(create_proc0, cred); 1115104522Srwatson} 1116104522Srwatson 1117104522Srwatson/* 1118104522Srwatson * Initialize MAC label for the first userland process, from which other 1119104522Srwatson * userland processes and threads are spawned. 1120104522Srwatson */ 1121104522Srwatsonvoid 1122104522Srwatsonmac_create_proc1(struct ucred *cred) 1123104522Srwatson{ 1124104522Srwatson 1125104522Srwatson MAC_PERFORM(create_proc1, cred); 1126104522Srwatson} 1127104522Srwatson 1128104522Srwatsonvoid 1129104522Srwatsonmac_thread_userret(struct thread *td) 1130104522Srwatson{ 1131104522Srwatson 1132104522Srwatson MAC_PERFORM(thread_userret, td); 1133104522Srwatson} 1134104522Srwatson 1135104522Srwatson/* 1136104522Srwatson * When a new process is created, its label must be initialized. Generally, 1137104522Srwatson * this involves inheritence from the parent process, modulo possible 1138104522Srwatson * deltas. This function allows that processing to take place. 1139104522Srwatson */ 1140104522Srwatsonvoid 1141104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1142104522Srwatson{ 1143104522Srwatson 1144104522Srwatson MAC_PERFORM(create_cred, parent_cred, child_cred); 1145104522Srwatson} 1146104522Srwatson 1147104522Srwatsonvoid 1148100979Srwatsonmac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 1149100979Srwatson{ 1150100979Srwatson 1151100979Srwatson MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 1152100979Srwatson} 1153100979Srwatson 1154100979Srwatsonvoid 1155105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1156105988Srwatson struct vnode *vp) 1157100979Srwatson{ 1158100979Srwatson 1159105988Srwatson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1160105988Srwatson &de->de_label, vp, &vp->v_label); 1161100979Srwatson} 1162100979Srwatson 1163105988Srwatsonint 1164105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1165100979Srwatson{ 1166100979Srwatson int error; 1167100979Srwatson 1168105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1169100979Srwatson 1170105988Srwatson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1171105988Srwatson &vp->v_label); 1172100979Srwatson 1173100979Srwatson return (error); 1174100979Srwatson} 1175100979Srwatson 1176100979Srwatsonvoid 1177105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1178100979Srwatson{ 1179100979Srwatson 1180105988Srwatson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1181105988Srwatson &vp->v_label); 1182100979Srwatson} 1183100979Srwatson 1184100979Srwatsonint 1185105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1186105988Srwatson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1187100979Srwatson{ 1188105988Srwatson int error; 1189100979Srwatson 1190105988Srwatson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1191105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1192100979Srwatson 1193105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1194105988Srwatson if (error == EOPNOTSUPP) { 1195105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1196105988Srwatson if (ea_warn_once == 0) { 1197105988Srwatson printf("Warning: transactions not supported " 1198105988Srwatson "in EA write.\n"); 1199105988Srwatson ea_warn_once = 1; 1200105988Srwatson } 1201105988Srwatson } else if (error) 1202100979Srwatson return (error); 1203100979Srwatson 1204105988Srwatson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1205105988Srwatson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1206100979Srwatson 1207105988Srwatson if (error) { 1208105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1209100979Srwatson return (error); 1210100979Srwatson } 1211100979Srwatson 1212105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1213100979Srwatson 1214105988Srwatson if (error == EOPNOTSUPP) 1215105988Srwatson error = 0; /* XXX */ 1216100979Srwatson 1217100979Srwatson return (error); 1218100979Srwatson} 1219100979Srwatson 1220100979Srwatsonstatic int 1221105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1222105988Srwatson struct label *intlabel) 1223100979Srwatson{ 1224100979Srwatson int error; 1225100979Srwatson 1226105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1227100979Srwatson 1228105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1229105988Srwatson if (error == EOPNOTSUPP) { 1230105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1231105988Srwatson if (ea_warn_once == 0) { 1232105988Srwatson printf("Warning: transactions not supported " 1233105988Srwatson "in EA write.\n"); 1234105988Srwatson ea_warn_once = 1; 1235105988Srwatson } 1236105988Srwatson } else if (error) 1237105988Srwatson return (error); 1238100979Srwatson 1239105988Srwatson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1240100979Srwatson 1241105988Srwatson if (error) { 1242105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1243100979Srwatson return (error); 1244100979Srwatson } 1245100979Srwatson 1246105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1247100979Srwatson 1248105988Srwatson if (error == EOPNOTSUPP) 1249105988Srwatson error = 0; /* XXX */ 1250100979Srwatson 1251105988Srwatson return (error); 1252100979Srwatson} 1253100979Srwatson 1254100979Srwatsonvoid 1255100979Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 1256100979Srwatson{ 1257100979Srwatson 1258100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1259100979Srwatson 1260100979Srwatson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 1261100979Srwatson} 1262100979Srwatson 1263100979Srwatsonint 1264100979Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp) 1265100979Srwatson{ 1266105988Srwatson int result; 1267100979Srwatson 1268100979Srwatson result = 0; 1269100979Srwatson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 1270100979Srwatson 1271100979Srwatson return (result); 1272100979Srwatson} 1273100979Srwatson 1274100979Srwatsonint 1275106212Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1276100979Srwatson{ 1277100979Srwatson int error; 1278100979Srwatson 1279100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1280100979Srwatson 1281100979Srwatson if (!mac_enforce_fs) 1282100979Srwatson return (0); 1283100979Srwatson 1284106212Srwatson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1285100979Srwatson return (error); 1286100979Srwatson} 1287100979Srwatson 1288100979Srwatsonint 1289100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1290100979Srwatson{ 1291100979Srwatson int error; 1292100979Srwatson 1293100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1294100979Srwatson 1295100979Srwatson if (!mac_enforce_fs) 1296100979Srwatson return (0); 1297100979Srwatson 1298100979Srwatson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1299100979Srwatson return (error); 1300100979Srwatson} 1301100979Srwatson 1302100979Srwatsonint 1303100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1304100979Srwatson{ 1305100979Srwatson int error; 1306100979Srwatson 1307100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1308100979Srwatson 1309100979Srwatson if (!mac_enforce_fs) 1310100979Srwatson return (0); 1311100979Srwatson 1312100979Srwatson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1313100979Srwatson return (error); 1314100979Srwatson} 1315100979Srwatson 1316100979Srwatsonint 1317100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1318100979Srwatson struct componentname *cnp, struct vattr *vap) 1319100979Srwatson{ 1320100979Srwatson int error; 1321100979Srwatson 1322100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1323100979Srwatson 1324100979Srwatson if (!mac_enforce_fs) 1325100979Srwatson return (0); 1326100979Srwatson 1327100979Srwatson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1328100979Srwatson return (error); 1329100979Srwatson} 1330100979Srwatson 1331100979Srwatsonint 1332100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1333100979Srwatson struct componentname *cnp) 1334100979Srwatson{ 1335100979Srwatson int error; 1336100979Srwatson 1337100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1338100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1339100979Srwatson 1340100979Srwatson if (!mac_enforce_fs) 1341100979Srwatson return (0); 1342100979Srwatson 1343100979Srwatson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1344100979Srwatson &vp->v_label, cnp); 1345100979Srwatson return (error); 1346100979Srwatson} 1347100979Srwatson 1348100979Srwatsonint 1349100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1350100979Srwatson acl_type_t type) 1351100979Srwatson{ 1352100979Srwatson int error; 1353100979Srwatson 1354100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1355100979Srwatson 1356100979Srwatson if (!mac_enforce_fs) 1357100979Srwatson return (0); 1358100979Srwatson 1359100979Srwatson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1360100979Srwatson return (error); 1361100979Srwatson} 1362100979Srwatson 1363100979Srwatsonint 1364100979Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 1365100979Srwatson{ 1366100979Srwatson int error; 1367100979Srwatson 1368102102Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1369102102Srwatson 1370100979Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1371100979Srwatson return (0); 1372100979Srwatson 1373100979Srwatson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 1374100979Srwatson 1375100979Srwatson return (error); 1376100979Srwatson} 1377100979Srwatson 1378100979Srwatsonint 1379100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1380100979Srwatson{ 1381100979Srwatson int error; 1382100979Srwatson 1383100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1384100979Srwatson 1385100979Srwatson if (!mac_enforce_fs) 1386100979Srwatson return (0); 1387100979Srwatson 1388100979Srwatson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1389100979Srwatson return (error); 1390100979Srwatson} 1391100979Srwatson 1392100979Srwatsonint 1393100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1394100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1395100979Srwatson{ 1396100979Srwatson int error; 1397100979Srwatson 1398100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1399100979Srwatson 1400100979Srwatson if (!mac_enforce_fs) 1401100979Srwatson return (0); 1402100979Srwatson 1403100979Srwatson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1404100979Srwatson attrnamespace, name, uio); 1405100979Srwatson return (error); 1406100979Srwatson} 1407100979Srwatson 1408100979Srwatsonint 1409104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1410104529Srwatson struct vnode *vp, struct componentname *cnp) 1411104529Srwatson{ 1412104529Srwatson int error; 1413104529Srwatson 1414104529Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1415104529Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1416104529Srwatson 1417104529Srwatson if (!mac_enforce_fs) 1418104529Srwatson return (0); 1419104529Srwatson 1420104529Srwatson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1421104529Srwatson &vp->v_label, cnp); 1422104529Srwatson return (error); 1423104529Srwatson} 1424104529Srwatson 1425104529Srwatsonint 1426100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1427100979Srwatson struct componentname *cnp) 1428100979Srwatson{ 1429100979Srwatson int error; 1430100979Srwatson 1431100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1432100979Srwatson 1433100979Srwatson if (!mac_enforce_fs) 1434100979Srwatson return (0); 1435100979Srwatson 1436100979Srwatson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1437100979Srwatson return (error); 1438100979Srwatson} 1439100979Srwatson 1440104546Srwatsonint 1441104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1442100979Srwatson{ 1443104546Srwatson int error; 1444100979Srwatson 1445104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1446103514Srwatson 1447104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1448104546Srwatson return (0); 1449104546Srwatson 1450104546Srwatson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1451104546Srwatson return (error); 1452100979Srwatson} 1453100979Srwatson 1454104546Srwatsonvoid 1455104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1456104546Srwatson{ 1457104546Srwatson int result = *prot; 1458104546Srwatson 1459104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1460104546Srwatson 1461104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1462104546Srwatson return; 1463104546Srwatson 1464104546Srwatson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1465104546Srwatson &result); 1466104546Srwatson 1467104546Srwatson *prot = result; 1468104546Srwatson} 1469104546Srwatson 1470100979Srwatsonint 1471104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1472104546Srwatson{ 1473104546Srwatson int error; 1474104546Srwatson 1475104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1476104546Srwatson 1477104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1478104546Srwatson return (0); 1479104546Srwatson 1480104546Srwatson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1481104546Srwatson return (error); 1482104546Srwatson} 1483104546Srwatson 1484104546Srwatsonint 1485106212Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1486100979Srwatson{ 1487100979Srwatson int error; 1488100979Srwatson 1489102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1490102112Srwatson 1491100979Srwatson if (!mac_enforce_fs) 1492100979Srwatson return (0); 1493100979Srwatson 1494102112Srwatson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1495102112Srwatson return (error); 1496102112Srwatson} 1497102112Srwatson 1498102112Srwatsonint 1499102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1500102129Srwatson struct vnode *vp) 1501102112Srwatson{ 1502102112Srwatson int error; 1503102112Srwatson 1504102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1505102112Srwatson 1506102112Srwatson if (!mac_enforce_fs) 1507102112Srwatson return (0); 1508102112Srwatson 1509102129Srwatson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1510102129Srwatson &vp->v_label); 1511100979Srwatson 1512100979Srwatson return (error); 1513100979Srwatson} 1514100979Srwatson 1515100979Srwatsonint 1516102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1517102129Srwatson struct vnode *vp) 1518100979Srwatson{ 1519100979Srwatson int error; 1520100979Srwatson 1521102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1522100979Srwatson 1523100979Srwatson if (!mac_enforce_fs) 1524100979Srwatson return (0); 1525100979Srwatson 1526102129Srwatson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1527102129Srwatson &vp->v_label); 1528102112Srwatson 1529100979Srwatson return (error); 1530100979Srwatson} 1531100979Srwatson 1532100979Srwatsonint 1533100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1534100979Srwatson{ 1535100979Srwatson int error; 1536100979Srwatson 1537100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1538100979Srwatson 1539100979Srwatson if (!mac_enforce_fs) 1540100979Srwatson return (0); 1541100979Srwatson 1542100979Srwatson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1543100979Srwatson return (error); 1544100979Srwatson} 1545100979Srwatson 1546100979Srwatsonint 1547100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1548100979Srwatson{ 1549100979Srwatson int error; 1550100979Srwatson 1551100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1552100979Srwatson 1553100979Srwatson if (!mac_enforce_fs) 1554100979Srwatson return (0); 1555100979Srwatson 1556100979Srwatson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1557100979Srwatson return (error); 1558100979Srwatson} 1559100979Srwatson 1560100979Srwatsonstatic int 1561100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1562100979Srwatson struct label *newlabel) 1563100979Srwatson{ 1564100979Srwatson int error; 1565100979Srwatson 1566100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1567100979Srwatson 1568100979Srwatson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1569100979Srwatson 1570100979Srwatson return (error); 1571100979Srwatson} 1572100979Srwatson 1573100979Srwatsonint 1574100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1575100979Srwatson struct vnode *vp, struct componentname *cnp) 1576100979Srwatson{ 1577100979Srwatson int error; 1578100979Srwatson 1579100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1580100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1581100979Srwatson 1582100979Srwatson if (!mac_enforce_fs) 1583100979Srwatson return (0); 1584100979Srwatson 1585100979Srwatson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1586100979Srwatson &vp->v_label, cnp); 1587100979Srwatson return (error); 1588100979Srwatson} 1589100979Srwatson 1590100979Srwatsonint 1591100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1592100979Srwatson struct vnode *vp, int samedir, struct componentname *cnp) 1593100979Srwatson{ 1594100979Srwatson int error; 1595100979Srwatson 1596100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1597100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1598100979Srwatson 1599100979Srwatson if (!mac_enforce_fs) 1600100979Srwatson return (0); 1601100979Srwatson 1602100979Srwatson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1603100979Srwatson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1604100979Srwatson return (error); 1605100979Srwatson} 1606100979Srwatson 1607100979Srwatsonint 1608100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1609100979Srwatson{ 1610100979Srwatson int error; 1611100979Srwatson 1612100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1613100979Srwatson 1614100979Srwatson if (!mac_enforce_fs) 1615100979Srwatson return (0); 1616100979Srwatson 1617100979Srwatson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1618100979Srwatson return (error); 1619100979Srwatson} 1620100979Srwatson 1621100979Srwatsonint 1622100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1623100979Srwatson struct acl *acl) 1624100979Srwatson{ 1625100979Srwatson int error; 1626100979Srwatson 1627100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1628100979Srwatson 1629100979Srwatson if (!mac_enforce_fs) 1630100979Srwatson return (0); 1631100979Srwatson 1632100979Srwatson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1633100979Srwatson return (error); 1634100979Srwatson} 1635100979Srwatson 1636100979Srwatsonint 1637100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1638100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1639100979Srwatson{ 1640100979Srwatson int error; 1641100979Srwatson 1642100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1643100979Srwatson 1644100979Srwatson if (!mac_enforce_fs) 1645100979Srwatson return (0); 1646100979Srwatson 1647100979Srwatson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1648100979Srwatson attrnamespace, name, uio); 1649100979Srwatson return (error); 1650100979Srwatson} 1651100979Srwatson 1652100979Srwatsonint 1653100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1654100979Srwatson{ 1655100979Srwatson int error; 1656100979Srwatson 1657100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1658100979Srwatson 1659100979Srwatson if (!mac_enforce_fs) 1660100979Srwatson return (0); 1661100979Srwatson 1662100979Srwatson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1663100979Srwatson return (error); 1664100979Srwatson} 1665100979Srwatson 1666100979Srwatsonint 1667100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1668100979Srwatson{ 1669100979Srwatson int error; 1670100979Srwatson 1671100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1672100979Srwatson 1673100979Srwatson if (!mac_enforce_fs) 1674100979Srwatson return (0); 1675100979Srwatson 1676100979Srwatson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1677100979Srwatson return (error); 1678100979Srwatson} 1679100979Srwatson 1680100979Srwatsonint 1681100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1682100979Srwatson gid_t gid) 1683100979Srwatson{ 1684100979Srwatson int error; 1685100979Srwatson 1686100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1687100979Srwatson 1688100979Srwatson if (!mac_enforce_fs) 1689100979Srwatson return (0); 1690100979Srwatson 1691100979Srwatson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1692100979Srwatson return (error); 1693100979Srwatson} 1694100979Srwatson 1695100979Srwatsonint 1696100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1697100979Srwatson struct timespec atime, struct timespec mtime) 1698100979Srwatson{ 1699100979Srwatson int error; 1700100979Srwatson 1701100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1702100979Srwatson 1703100979Srwatson if (!mac_enforce_fs) 1704100979Srwatson return (0); 1705100979Srwatson 1706100979Srwatson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1707100979Srwatson mtime); 1708100979Srwatson return (error); 1709100979Srwatson} 1710100979Srwatson 1711100979Srwatsonint 1712102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1713102129Srwatson struct vnode *vp) 1714100979Srwatson{ 1715100979Srwatson int error; 1716100979Srwatson 1717100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 1718100979Srwatson 1719100979Srwatson if (!mac_enforce_fs) 1720100979Srwatson return (0); 1721100979Srwatson 1722102129Srwatson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 1723102129Srwatson &vp->v_label); 1724100979Srwatson return (error); 1725100979Srwatson} 1726100979Srwatson 1727102112Srwatsonint 1728102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1729102129Srwatson struct vnode *vp) 1730102112Srwatson{ 1731102112Srwatson int error; 1732102112Srwatson 1733102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 1734102112Srwatson 1735102112Srwatson if (!mac_enforce_fs) 1736102112Srwatson return (0); 1737102112Srwatson 1738102129Srwatson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 1739102129Srwatson &vp->v_label); 1740102112Srwatson 1741102112Srwatson return (error); 1742102112Srwatson} 1743102112Srwatson 1744100979Srwatson/* 1745100979Srwatson * When relabeling a process, call out to the policies for the maximum 1746100979Srwatson * permission allowed for each object type we know about in its 1747100979Srwatson * memory space, and revoke access (in the least surprising ways we 1748100979Srwatson * know) when necessary. The process lock is not held here. 1749100979Srwatson */ 1750100979Srwatsonstatic void 1751100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 1752100979Srwatson{ 1753100979Srwatson 1754100979Srwatson /* XXX freeze all other threads */ 1755100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 1756100979Srwatson &td->td_proc->p_vmspace->vm_map); 1757100979Srwatson /* XXX allow other threads to continue */ 1758100979Srwatson} 1759100979Srwatson 1760100979Srwatsonstatic __inline const char * 1761100979Srwatsonprot2str(vm_prot_t prot) 1762100979Srwatson{ 1763100979Srwatson 1764100979Srwatson switch (prot & VM_PROT_ALL) { 1765100979Srwatson case VM_PROT_READ: 1766100979Srwatson return ("r--"); 1767100979Srwatson case VM_PROT_READ | VM_PROT_WRITE: 1768100979Srwatson return ("rw-"); 1769100979Srwatson case VM_PROT_READ | VM_PROT_EXECUTE: 1770100979Srwatson return ("r-x"); 1771100979Srwatson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 1772100979Srwatson return ("rwx"); 1773100979Srwatson case VM_PROT_WRITE: 1774100979Srwatson return ("-w-"); 1775100979Srwatson case VM_PROT_EXECUTE: 1776100979Srwatson return ("--x"); 1777100979Srwatson case VM_PROT_WRITE | VM_PROT_EXECUTE: 1778100979Srwatson return ("-wx"); 1779100979Srwatson default: 1780100979Srwatson return ("---"); 1781100979Srwatson } 1782100979Srwatson} 1783100979Srwatson 1784100979Srwatsonstatic void 1785100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 1786100979Srwatson struct vm_map *map) 1787100979Srwatson{ 1788100979Srwatson struct vm_map_entry *vme; 1789104546Srwatson int result; 1790104546Srwatson vm_prot_t revokeperms; 1791100979Srwatson vm_object_t object; 1792100979Srwatson vm_ooffset_t offset; 1793100979Srwatson struct vnode *vp; 1794100979Srwatson 1795103136Srwatson if (!mac_mmap_revocation) 1796103136Srwatson return; 1797103136Srwatson 1798100979Srwatson vm_map_lock_read(map); 1799100979Srwatson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 1800100979Srwatson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 1801100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 1802100979Srwatson vme->object.sub_map); 1803100979Srwatson continue; 1804100979Srwatson } 1805100979Srwatson /* 1806100979Srwatson * Skip over entries that obviously are not shared. 1807100979Srwatson */ 1808100979Srwatson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 1809100979Srwatson !vme->max_protection) 1810100979Srwatson continue; 1811100979Srwatson /* 1812100979Srwatson * Drill down to the deepest backing object. 1813100979Srwatson */ 1814100979Srwatson offset = vme->offset; 1815100979Srwatson object = vme->object.vm_object; 1816100979Srwatson if (object == NULL) 1817100979Srwatson continue; 1818100979Srwatson while (object->backing_object != NULL) { 1819100979Srwatson object = object->backing_object; 1820100979Srwatson offset += object->backing_object_offset; 1821100979Srwatson } 1822100979Srwatson /* 1823100979Srwatson * At the moment, vm_maps and objects aren't considered 1824100979Srwatson * by the MAC system, so only things with backing by a 1825100979Srwatson * normal object (read: vnodes) are checked. 1826100979Srwatson */ 1827100979Srwatson if (object->type != OBJT_VNODE) 1828100979Srwatson continue; 1829100979Srwatson vp = (struct vnode *)object->handle; 1830100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1831104546Srwatson result = vme->max_protection; 1832104546Srwatson mac_check_vnode_mmap_downgrade(cred, vp, &result); 1833100979Srwatson VOP_UNLOCK(vp, 0, td); 1834100979Srwatson /* 1835100979Srwatson * Find out what maximum protection we may be allowing 1836100979Srwatson * now but a policy needs to get removed. 1837100979Srwatson */ 1838100979Srwatson revokeperms = vme->max_protection & ~result; 1839100979Srwatson if (!revokeperms) 1840100979Srwatson continue; 1841102949Sbde printf("pid %ld: revoking %s perms from %#lx:%ld " 1842102949Sbde "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 1843102949Sbde prot2str(revokeperms), (u_long)vme->start, 1844102949Sbde (long)(vme->end - vme->start), 1845100979Srwatson prot2str(vme->max_protection), prot2str(vme->protection)); 1846100979Srwatson vm_map_lock_upgrade(map); 1847100979Srwatson /* 1848100979Srwatson * This is the really simple case: if a map has more 1849100979Srwatson * max_protection than is allowed, but it's not being 1850100979Srwatson * actually used (that is, the current protection is 1851100979Srwatson * still allowed), we can just wipe it out and do 1852100979Srwatson * nothing more. 1853100979Srwatson */ 1854100979Srwatson if ((vme->protection & revokeperms) == 0) { 1855100979Srwatson vme->max_protection -= revokeperms; 1856100979Srwatson } else { 1857100979Srwatson if (revokeperms & VM_PROT_WRITE) { 1858100979Srwatson /* 1859100979Srwatson * In the more complicated case, flush out all 1860100979Srwatson * pending changes to the object then turn it 1861100979Srwatson * copy-on-write. 1862100979Srwatson */ 1863100979Srwatson vm_object_reference(object); 1864100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1865100979Srwatson vm_object_page_clean(object, 1866100979Srwatson OFF_TO_IDX(offset), 1867100979Srwatson OFF_TO_IDX(offset + vme->end - vme->start + 1868100979Srwatson PAGE_MASK), 1869100979Srwatson OBJPC_SYNC); 1870100979Srwatson VOP_UNLOCK(vp, 0, td); 1871100979Srwatson vm_object_deallocate(object); 1872100979Srwatson /* 1873100979Srwatson * Why bother if there's no read permissions 1874100979Srwatson * anymore? For the rest, we need to leave 1875100979Srwatson * the write permissions on for COW, or 1876100979Srwatson * remove them entirely if configured to. 1877100979Srwatson */ 1878100979Srwatson if (!mac_mmap_revocation_via_cow) { 1879100979Srwatson vme->max_protection &= ~VM_PROT_WRITE; 1880100979Srwatson vme->protection &= ~VM_PROT_WRITE; 1881100979Srwatson } if ((revokeperms & VM_PROT_READ) == 0) 1882100979Srwatson vme->eflags |= MAP_ENTRY_COW | 1883100979Srwatson MAP_ENTRY_NEEDS_COPY; 1884100979Srwatson } 1885100979Srwatson if (revokeperms & VM_PROT_EXECUTE) { 1886100979Srwatson vme->max_protection &= ~VM_PROT_EXECUTE; 1887100979Srwatson vme->protection &= ~VM_PROT_EXECUTE; 1888100979Srwatson } 1889100979Srwatson if (revokeperms & VM_PROT_READ) { 1890100979Srwatson vme->max_protection = 0; 1891100979Srwatson vme->protection = 0; 1892100979Srwatson } 1893100979Srwatson pmap_protect(map->pmap, vme->start, vme->end, 1894100979Srwatson vme->protection & ~revokeperms); 1895100979Srwatson vm_map_simplify_entry(map, vme); 1896100979Srwatson } 1897100979Srwatson vm_map_lock_downgrade(map); 1898100979Srwatson } 1899100979Srwatson vm_map_unlock_read(map); 1900100979Srwatson} 1901100979Srwatson 1902100979Srwatson/* 1903100979Srwatson * When the subject's label changes, it may require revocation of privilege 1904100979Srwatson * to mapped objects. This can't be done on-the-fly later with a unified 1905100979Srwatson * buffer cache. 1906100979Srwatson */ 1907100979Srwatsonstatic void 1908100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel) 1909100979Srwatson{ 1910100979Srwatson 1911100979Srwatson MAC_PERFORM(relabel_cred, cred, newlabel); 1912100979Srwatson} 1913100979Srwatson 1914100979Srwatsonvoid 1915100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 1916100979Srwatson{ 1917100979Srwatson 1918100979Srwatson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 1919100979Srwatson} 1920100979Srwatson 1921100979Srwatsonvoid 1922100979Srwatsonmac_create_ifnet(struct ifnet *ifnet) 1923100979Srwatson{ 1924100979Srwatson 1925100979Srwatson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 1926100979Srwatson} 1927100979Srwatson 1928100979Srwatsonvoid 1929100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 1930100979Srwatson{ 1931100979Srwatson 1932100979Srwatson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 1933100979Srwatson} 1934100979Srwatson 1935100979Srwatsonvoid 1936100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket) 1937100979Srwatson{ 1938100979Srwatson 1939100979Srwatson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 1940100979Srwatson} 1941100979Srwatson 1942100979Srwatsonvoid 1943100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe) 1944100979Srwatson{ 1945100979Srwatson 1946100979Srwatson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 1947100979Srwatson} 1948100979Srwatson 1949100979Srwatsonvoid 1950100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket, 1951100979Srwatson struct socket *newsocket) 1952100979Srwatson{ 1953100979Srwatson 1954100979Srwatson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 1955100979Srwatson newsocket, &newsocket->so_label); 1956100979Srwatson} 1957100979Srwatson 1958100979Srwatsonstatic void 1959100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket, 1960100979Srwatson struct label *newlabel) 1961100979Srwatson{ 1962100979Srwatson 1963100979Srwatson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 1964100979Srwatson} 1965100979Srwatson 1966100979Srwatsonstatic void 1967100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 1968100979Srwatson{ 1969100979Srwatson 1970100979Srwatson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 1971100979Srwatson} 1972100979Srwatson 1973100979Srwatsonvoid 1974100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 1975100979Srwatson{ 1976100979Srwatson 1977100979Srwatson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 1978100979Srwatson socket, &socket->so_peerlabel); 1979100979Srwatson} 1980100979Srwatson 1981100979Srwatsonvoid 1982100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket, 1983100979Srwatson struct socket *newsocket) 1984100979Srwatson{ 1985100979Srwatson 1986100979Srwatson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 1987100979Srwatson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 1988100979Srwatson} 1989100979Srwatson 1990100979Srwatsonvoid 1991100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 1992100979Srwatson{ 1993100979Srwatson 1994100979Srwatson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 1995100979Srwatson datagram, &datagram->m_pkthdr.label); 1996100979Srwatson} 1997100979Srwatson 1998100979Srwatsonvoid 1999100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2000100979Srwatson{ 2001100979Srwatson 2002100979Srwatson MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2003100979Srwatson fragment, &fragment->m_pkthdr.label); 2004100979Srwatson} 2005100979Srwatson 2006100979Srwatsonvoid 2007100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2008100979Srwatson{ 2009100979Srwatson 2010100979Srwatson MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2011100979Srwatson &ipq->ipq_label); 2012100979Srwatson} 2013100979Srwatson 2014100979Srwatsonvoid 2015100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2016100979Srwatson{ 2017100979Srwatson 2018100979Srwatson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2019100979Srwatson newmbuf, &newmbuf->m_pkthdr.label); 2020100979Srwatson} 2021100979Srwatson 2022100979Srwatsonvoid 2023100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2024100979Srwatson{ 2025100979Srwatson 2026100979Srwatson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2027100979Srwatson &mbuf->m_pkthdr.label); 2028100979Srwatson} 2029100979Srwatson 2030100979Srwatsonvoid 2031100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2032100979Srwatson{ 2033100979Srwatson 2034100979Srwatson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2035100979Srwatson &mbuf->m_pkthdr.label); 2036100979Srwatson} 2037100979Srwatson 2038100979Srwatsonvoid 2039100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2040100979Srwatson{ 2041100979Srwatson 2042100979Srwatson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2043100979Srwatson &mbuf->m_pkthdr.label); 2044100979Srwatson} 2045100979Srwatson 2046100979Srwatsonvoid 2047100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2048100979Srwatson struct mbuf *newmbuf) 2049100979Srwatson{ 2050100979Srwatson 2051100979Srwatson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2052100979Srwatson &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2053100979Srwatson &newmbuf->m_pkthdr.label); 2054100979Srwatson} 2055100979Srwatson 2056100979Srwatsonvoid 2057100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2058100979Srwatson{ 2059100979Srwatson 2060100979Srwatson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2061100979Srwatson newmbuf, &newmbuf->m_pkthdr.label); 2062100979Srwatson} 2063100979Srwatson 2064100979Srwatsonint 2065100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2066100979Srwatson{ 2067100979Srwatson int result; 2068100979Srwatson 2069100979Srwatson result = 1; 2070100979Srwatson MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2071100979Srwatson ipq, &ipq->ipq_label); 2072100979Srwatson 2073100979Srwatson return (result); 2074100979Srwatson} 2075100979Srwatson 2076100979Srwatsonvoid 2077100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2078100979Srwatson{ 2079100979Srwatson 2080100979Srwatson MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2081100979Srwatson &ipq->ipq_label); 2082100979Srwatson} 2083100979Srwatson 2084100979Srwatsonvoid 2085100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2086100979Srwatson{ 2087100979Srwatson 2088100979Srwatson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2089100979Srwatson &mbuf->m_pkthdr.label); 2090100979Srwatson} 2091100979Srwatson 2092100979Srwatsonvoid 2093100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp) 2094100979Srwatson{ 2095100979Srwatson 2096100979Srwatson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2097100979Srwatson &mp->mnt_fslabel); 2098100979Srwatson} 2099100979Srwatson 2100100979Srwatsonvoid 2101100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp) 2102100979Srwatson{ 2103100979Srwatson 2104100979Srwatson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2105100979Srwatson &mp->mnt_fslabel); 2106100979Srwatson} 2107100979Srwatson 2108100979Srwatsonint 2109100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2110100979Srwatson{ 2111100979Srwatson int error; 2112100979Srwatson 2113100979Srwatson if (!mac_enforce_network) 2114100979Srwatson return (0); 2115100979Srwatson 2116100979Srwatson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2117100979Srwatson &ifnet->if_label); 2118100979Srwatson 2119100979Srwatson return (error); 2120100979Srwatson} 2121100979Srwatson 2122100979Srwatsonstatic int 2123100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2124100979Srwatson{ 2125100979Srwatson int error; 2126100979Srwatson 2127100979Srwatson MAC_CHECK(check_cred_relabel, cred, newlabel); 2128100979Srwatson 2129100979Srwatson return (error); 2130100979Srwatson} 2131100979Srwatson 2132100979Srwatsonint 2133100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2134100979Srwatson{ 2135100979Srwatson int error; 2136100979Srwatson 2137100979Srwatson if (!mac_enforce_process) 2138100979Srwatson return (0); 2139100979Srwatson 2140100979Srwatson MAC_CHECK(check_cred_visible, u1, u2); 2141100979Srwatson 2142100979Srwatson return (error); 2143100979Srwatson} 2144100979Srwatson 2145100979Srwatsonint 2146100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2147100979Srwatson{ 2148100979Srwatson int error; 2149100979Srwatson 2150100979Srwatson if (!mac_enforce_network) 2151100979Srwatson return (0); 2152100979Srwatson 2153100979Srwatson KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2154100979Srwatson if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2155105598Sbrooks if_printf(ifnet, "not initialized\n"); 2156100979Srwatson 2157100979Srwatson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2158100979Srwatson &mbuf->m_pkthdr.label); 2159100979Srwatson 2160100979Srwatson return (error); 2161100979Srwatson} 2162100979Srwatson 2163100979Srwatsonint 2164106308Srwatsonmac_check_kenv_dump(struct ucred *cred) 2165106308Srwatson{ 2166106308Srwatson int error; 2167106308Srwatson 2168106308Srwatson if (!mac_enforce_system) 2169106308Srwatson return (0); 2170106308Srwatson 2171106308Srwatson MAC_CHECK(check_kenv_dump, cred); 2172106308Srwatson 2173106308Srwatson return (error); 2174106308Srwatson} 2175106308Srwatson 2176106308Srwatsonint 2177106308Srwatsonmac_check_kenv_get(struct ucred *cred, char *name) 2178106308Srwatson{ 2179106308Srwatson int error; 2180106308Srwatson 2181106308Srwatson if (!mac_enforce_system) 2182106308Srwatson return (0); 2183106308Srwatson 2184106308Srwatson MAC_CHECK(check_kenv_get, cred, name); 2185106308Srwatson 2186106308Srwatson return (error); 2187106308Srwatson} 2188106308Srwatson 2189106308Srwatsonint 2190106308Srwatsonmac_check_kenv_set(struct ucred *cred, char *name, char *value) 2191106308Srwatson{ 2192106308Srwatson int error; 2193106308Srwatson 2194106308Srwatson if (!mac_enforce_system) 2195106308Srwatson return (0); 2196106308Srwatson 2197106308Srwatson MAC_CHECK(check_kenv_set, cred, name, value); 2198106308Srwatson 2199106308Srwatson return (error); 2200106308Srwatson} 2201106308Srwatson 2202106308Srwatsonint 2203106308Srwatsonmac_check_kenv_unset(struct ucred *cred, char *name) 2204106308Srwatson{ 2205106308Srwatson int error; 2206106308Srwatson 2207106308Srwatson if (!mac_enforce_system) 2208106308Srwatson return (0); 2209106308Srwatson 2210106308Srwatson MAC_CHECK(check_kenv_unset, cred, name); 2211106308Srwatson 2212106308Srwatson return (error); 2213106308Srwatson} 2214106308Srwatson 2215106308Srwatsonint 2216100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount) 2217100979Srwatson{ 2218100979Srwatson int error; 2219100979Srwatson 2220100979Srwatson if (!mac_enforce_fs) 2221100979Srwatson return (0); 2222100979Srwatson 2223100979Srwatson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2224100979Srwatson 2225100979Srwatson return (error); 2226100979Srwatson} 2227100979Srwatson 2228100979Srwatsonint 2229100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2230100979Srwatson void *data) 2231100979Srwatson{ 2232100979Srwatson int error; 2233100979Srwatson 2234104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2235104269Srwatson 2236104269Srwatson if (!mac_enforce_pipe) 2237104269Srwatson return (0); 2238104269Srwatson 2239100979Srwatson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2240100979Srwatson 2241100979Srwatson return (error); 2242100979Srwatson} 2243100979Srwatson 2244100979Srwatsonint 2245102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2246100979Srwatson{ 2247100979Srwatson int error; 2248100979Srwatson 2249104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2250104269Srwatson 2251104269Srwatson if (!mac_enforce_pipe) 2252104269Srwatson return (0); 2253104269Srwatson 2254102115Srwatson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2255100979Srwatson 2256100979Srwatson return (error); 2257100979Srwatson} 2258100979Srwatson 2259102115Srwatsonint 2260102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2261102115Srwatson{ 2262102115Srwatson int error; 2263102115Srwatson 2264104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2265104269Srwatson 2266104269Srwatson if (!mac_enforce_pipe) 2267104269Srwatson return (0); 2268104269Srwatson 2269102115Srwatson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2270102115Srwatson 2271102115Srwatson return (error); 2272102115Srwatson} 2273102115Srwatson 2274100979Srwatsonstatic int 2275100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2276100979Srwatson struct label *newlabel) 2277100979Srwatson{ 2278100979Srwatson int error; 2279100979Srwatson 2280104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2281104269Srwatson 2282104269Srwatson if (!mac_enforce_pipe) 2283104269Srwatson return (0); 2284104269Srwatson 2285100979Srwatson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2286100979Srwatson 2287100979Srwatson return (error); 2288100979Srwatson} 2289100979Srwatson 2290100979Srwatsonint 2291102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2292102115Srwatson{ 2293102115Srwatson int error; 2294102115Srwatson 2295104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2296104269Srwatson 2297104269Srwatson if (!mac_enforce_pipe) 2298104269Srwatson return (0); 2299104269Srwatson 2300102115Srwatson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2301102115Srwatson 2302102115Srwatson return (error); 2303102115Srwatson} 2304102115Srwatson 2305102115Srwatsonint 2306102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2307102115Srwatson{ 2308102115Srwatson int error; 2309102115Srwatson 2310104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2311104269Srwatson 2312104269Srwatson if (!mac_enforce_pipe) 2313104269Srwatson return (0); 2314104269Srwatson 2315102115Srwatson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2316102115Srwatson 2317102115Srwatson return (error); 2318102115Srwatson} 2319102115Srwatson 2320102115Srwatsonint 2321100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc) 2322100979Srwatson{ 2323100979Srwatson int error; 2324100979Srwatson 2325102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2326102103Srwatson 2327100979Srwatson if (!mac_enforce_process) 2328100979Srwatson return (0); 2329100979Srwatson 2330100979Srwatson MAC_CHECK(check_proc_debug, cred, proc); 2331100979Srwatson 2332100979Srwatson return (error); 2333100979Srwatson} 2334100979Srwatson 2335100979Srwatsonint 2336100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc) 2337100979Srwatson{ 2338100979Srwatson int error; 2339100979Srwatson 2340102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2341102103Srwatson 2342100979Srwatson if (!mac_enforce_process) 2343100979Srwatson return (0); 2344100979Srwatson 2345100979Srwatson MAC_CHECK(check_proc_sched, cred, proc); 2346100979Srwatson 2347100979Srwatson return (error); 2348100979Srwatson} 2349100979Srwatson 2350100979Srwatsonint 2351100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2352100979Srwatson{ 2353100979Srwatson int error; 2354100979Srwatson 2355102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2356102103Srwatson 2357100979Srwatson if (!mac_enforce_process) 2358100979Srwatson return (0); 2359100979Srwatson 2360100979Srwatson MAC_CHECK(check_proc_signal, cred, proc, signum); 2361100979Srwatson 2362100979Srwatson return (error); 2363100979Srwatson} 2364100979Srwatson 2365100979Srwatsonint 2366100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2367100979Srwatson struct sockaddr *sockaddr) 2368100979Srwatson{ 2369100979Srwatson int error; 2370100979Srwatson 2371100979Srwatson if (!mac_enforce_socket) 2372100979Srwatson return (0); 2373100979Srwatson 2374100979Srwatson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2375100979Srwatson sockaddr); 2376100979Srwatson 2377100979Srwatson return (error); 2378100979Srwatson} 2379100979Srwatson 2380100979Srwatsonint 2381100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket, 2382100979Srwatson struct sockaddr *sockaddr) 2383100979Srwatson{ 2384100979Srwatson int error; 2385100979Srwatson 2386100979Srwatson if (!mac_enforce_socket) 2387100979Srwatson return (0); 2388100979Srwatson 2389100979Srwatson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2390100979Srwatson sockaddr); 2391100979Srwatson 2392100979Srwatson return (error); 2393100979Srwatson} 2394100979Srwatson 2395100979Srwatsonint 2396101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2397100979Srwatson{ 2398100979Srwatson int error; 2399100979Srwatson 2400100979Srwatson if (!mac_enforce_socket) 2401100979Srwatson return (0); 2402100979Srwatson 2403101933Srwatson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2404101933Srwatson &mbuf->m_pkthdr.label); 2405101933Srwatson 2406100979Srwatson return (error); 2407100979Srwatson} 2408100979Srwatson 2409100979Srwatsonint 2410101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket) 2411100979Srwatson{ 2412100979Srwatson int error; 2413100979Srwatson 2414100979Srwatson if (!mac_enforce_socket) 2415100979Srwatson return (0); 2416100979Srwatson 2417101933Srwatson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2418100979Srwatson return (error); 2419100979Srwatson} 2420100979Srwatson 2421104571Srwatsonint 2422104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so) 2423104571Srwatson{ 2424104571Srwatson int error; 2425104571Srwatson 2426104571Srwatson if (!mac_enforce_socket) 2427104571Srwatson return (0); 2428104571Srwatson 2429104571Srwatson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2430104571Srwatson 2431104571Srwatson return (error); 2432104571Srwatson} 2433104571Srwatson 2434100979Srwatsonstatic int 2435100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2436100979Srwatson struct label *newlabel) 2437100979Srwatson{ 2438100979Srwatson int error; 2439100979Srwatson 2440100979Srwatson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2441100979Srwatson newlabel); 2442100979Srwatson 2443100979Srwatson return (error); 2444100979Srwatson} 2445100979Srwatson 2446100979Srwatsonint 2447104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so) 2448104571Srwatson{ 2449104571Srwatson int error; 2450104571Srwatson 2451104571Srwatson if (!mac_enforce_socket) 2452104571Srwatson return (0); 2453104571Srwatson 2454104571Srwatson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2455104571Srwatson 2456104571Srwatson return (error); 2457104571Srwatson} 2458104571Srwatson 2459104571Srwatsonint 2460100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket) 2461100979Srwatson{ 2462100979Srwatson int error; 2463100979Srwatson 2464100979Srwatson if (!mac_enforce_socket) 2465100979Srwatson return (0); 2466105694Srwatson 2467100979Srwatson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2468105694Srwatson 2469100979Srwatson return (error); 2470100979Srwatson} 2471100979Srwatson 2472100979Srwatsonint 2473106412Srwatsonmac_check_system_acct(struct ucred *cred, struct vnode *vp) 2474106412Srwatson{ 2475106412Srwatson int error; 2476106412Srwatson 2477106412Srwatson if (vp != NULL) { 2478106412Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2479106412Srwatson } 2480106412Srwatson 2481106412Srwatson if (!mac_enforce_system) 2482106412Srwatson return (0); 2483106412Srwatson 2484106412Srwatson MAC_CHECK(check_system_acct, cred, vp, 2485106412Srwatson vp != NULL ? &vp->v_label : NULL); 2486106412Srwatson 2487106412Srwatson return (error); 2488106412Srwatson} 2489106412Srwatson 2490106412Srwatsonint 2491106412Srwatsonmac_check_system_nfsd(struct ucred *cred) 2492106412Srwatson{ 2493106412Srwatson int error; 2494106412Srwatson 2495106412Srwatson if (!mac_enforce_system) 2496106412Srwatson return (0); 2497106412Srwatson 2498106412Srwatson MAC_CHECK(check_system_nfsd, cred); 2499106412Srwatson 2500106412Srwatson return (error); 2501106412Srwatson} 2502106412Srwatson 2503106412Srwatsonint 2504106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto) 2505106024Srwatson{ 2506106024Srwatson int error; 2507106024Srwatson 2508106045Srwatson if (!mac_enforce_system) 2509106024Srwatson return (0); 2510106024Srwatson 2511106024Srwatson MAC_CHECK(check_system_reboot, cred, howto); 2512106045Srwatson 2513106024Srwatson return (error); 2514106024Srwatson} 2515106024Srwatson 2516106024Srwatsonint 2517106369Srwatsonmac_check_system_settime(struct ucred *cred) 2518106369Srwatson{ 2519106369Srwatson int error; 2520106369Srwatson 2521106369Srwatson if (!mac_enforce_system) 2522106369Srwatson return (0); 2523106369Srwatson 2524106369Srwatson MAC_CHECK(check_system_settime, cred); 2525106369Srwatson 2526106369Srwatson return (error); 2527106369Srwatson} 2528106369Srwatson 2529106369Srwatsonint 2530106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2531106023Srwatson{ 2532106023Srwatson int error; 2533106023Srwatson 2534106023Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2535106023Srwatson 2536106045Srwatson if (!mac_enforce_system) 2537106023Srwatson return (0); 2538106023Srwatson 2539106023Srwatson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2540106023Srwatson return (error); 2541106023Srwatson} 2542106023Srwatson 2543106023Srwatsonint 2544106025Srwatsonmac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2545106025Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2546106025Srwatson{ 2547106025Srwatson int error; 2548106025Srwatson 2549106025Srwatson /* 2550106025Srwatson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2551106025Srwatson * but since it's not exported from kern_sysctl.c, we can't. 2552106025Srwatson */ 2553106045Srwatson if (!mac_enforce_system) 2554106025Srwatson return (0); 2555106025Srwatson 2556106025Srwatson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2557106025Srwatson inkernel, new, newlen); 2558106025Srwatson 2559106025Srwatson return (error); 2560106025Srwatson} 2561106025Srwatson 2562106025Srwatsonint 2563100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2564100979Srwatson struct ifnet *ifnet) 2565100979Srwatson{ 2566105694Srwatson char *elements, *buffer; 2567105694Srwatson struct mac mac; 2568100979Srwatson int error; 2569100979Srwatson 2570105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2571100979Srwatson if (error) 2572100979Srwatson return (error); 2573100979Srwatson 2574105694Srwatson error = mac_check_structmac_consistent(&mac); 2575105694Srwatson if (error) 2576105694Srwatson return (error); 2577105694Srwatson 2578105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2579105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2580105694Srwatson if (error) { 2581105694Srwatson free(elements, M_MACTEMP); 2582105694Srwatson return (error); 2583105694Srwatson } 2584105694Srwatson 2585105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2586105694Srwatson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 2587105694Srwatson buffer, mac.m_buflen, M_WAITOK); 2588105694Srwatson if (error == 0) 2589105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2590105694Srwatson 2591105694Srwatson free(buffer, M_MACTEMP); 2592105694Srwatson free(elements, M_MACTEMP); 2593105694Srwatson 2594105694Srwatson return (error); 2595100979Srwatson} 2596100979Srwatson 2597100979Srwatsonint 2598100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2599100979Srwatson struct ifnet *ifnet) 2600100979Srwatson{ 2601100979Srwatson struct label intlabel; 2602105694Srwatson struct mac mac; 2603105694Srwatson char *buffer; 2604100979Srwatson int error; 2605100979Srwatson 2606105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2607100979Srwatson if (error) 2608100979Srwatson return (error); 2609100979Srwatson 2610105694Srwatson error = mac_check_structmac_consistent(&mac); 2611100979Srwatson if (error) 2612100979Srwatson return (error); 2613100979Srwatson 2614105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2615105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2616105694Srwatson if (error) { 2617105694Srwatson free(buffer, M_MACTEMP); 2618105694Srwatson return (error); 2619105694Srwatson } 2620105694Srwatson 2621105694Srwatson mac_init_ifnet_label(&intlabel); 2622105694Srwatson error = mac_internalize_ifnet_label(&intlabel, buffer); 2623105694Srwatson free(buffer, M_MACTEMP); 2624105694Srwatson if (error) { 2625105694Srwatson mac_destroy_ifnet_label(&intlabel); 2626105694Srwatson return (error); 2627105694Srwatson } 2628105694Srwatson 2629100979Srwatson /* 2630100979Srwatson * XXX: Note that this is a redundant privilege check, since 2631100979Srwatson * policies impose this check themselves if required by the 2632100979Srwatson * policy. Eventually, this should go away. 2633100979Srwatson */ 2634100979Srwatson error = suser_cred(cred, 0); 2635105694Srwatson if (error) { 2636105694Srwatson mac_destroy_ifnet_label(&intlabel); 2637105694Srwatson return (error); 2638105694Srwatson } 2639100979Srwatson 2640100979Srwatson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2641100979Srwatson &intlabel); 2642105694Srwatson if (error) { 2643105694Srwatson mac_destroy_ifnet_label(&intlabel); 2644105694Srwatson return (error); 2645105694Srwatson } 2646100979Srwatson 2647100979Srwatson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2648100979Srwatson 2649105694Srwatson mac_destroy_ifnet_label(&intlabel); 2650105694Srwatson return (0); 2651100979Srwatson} 2652100979Srwatson 2653100979Srwatsonvoid 2654100979Srwatsonmac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 2655100979Srwatson{ 2656100979Srwatson 2657100979Srwatson MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 2658100979Srwatson} 2659100979Srwatson 2660100979Srwatsonvoid 2661100979Srwatsonmac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 2662100979Srwatson{ 2663100979Srwatson 2664100979Srwatson MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 2665100979Srwatson} 2666100979Srwatson 2667104533Srwatsonvoid 2668104533Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 2669104533Srwatson struct devfs_dirent *de) 2670104533Srwatson{ 2671104533Srwatson 2672104533Srwatson MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de, 2673104533Srwatson &de->de_label); 2674104533Srwatson} 2675104533Srwatson 2676100979Srwatsonvoid 2677100979Srwatsonmac_create_devfs_directory(char *dirname, int dirnamelen, 2678100979Srwatson struct devfs_dirent *de) 2679100979Srwatson{ 2680100979Srwatson 2681100979Srwatson MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 2682100979Srwatson &de->de_label); 2683100979Srwatson} 2684100979Srwatson 2685100979Srwatsonint 2686100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2687105694Srwatson struct mac *mac) 2688100979Srwatson{ 2689100979Srwatson struct label intlabel; 2690105694Srwatson char *buffer; 2691100979Srwatson int error; 2692100979Srwatson 2693105694Srwatson error = mac_check_structmac_consistent(mac); 2694100979Srwatson if (error) 2695100979Srwatson return (error); 2696100979Srwatson 2697105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2698105694Srwatson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 2699105694Srwatson if (error) { 2700105694Srwatson free(buffer, M_MACTEMP); 2701105694Srwatson return (error); 2702105694Srwatson } 2703105694Srwatson 2704105694Srwatson mac_init_socket_label(&intlabel, M_WAITOK); 2705105694Srwatson error = mac_internalize_socket_label(&intlabel, buffer); 2706105694Srwatson free(buffer, M_MACTEMP); 2707105694Srwatson if (error) { 2708105694Srwatson mac_destroy_socket_label(&intlabel); 2709105694Srwatson return (error); 2710105694Srwatson } 2711105694Srwatson 2712100979Srwatson mac_check_socket_relabel(cred, so, &intlabel); 2713100979Srwatson if (error) { 2714105694Srwatson mac_destroy_socket_label(&intlabel); 2715100979Srwatson return (error); 2716100979Srwatson } 2717100979Srwatson 2718100979Srwatson mac_relabel_socket(cred, so, &intlabel); 2719100979Srwatson 2720105694Srwatson mac_destroy_socket_label(&intlabel); 2721100979Srwatson return (0); 2722100979Srwatson} 2723100979Srwatson 2724100979Srwatsonint 2725100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 2726100979Srwatson{ 2727100979Srwatson int error; 2728100979Srwatson 2729104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2730104269Srwatson 2731100979Srwatson error = mac_check_pipe_relabel(cred, pipe, label); 2732100979Srwatson if (error) 2733100979Srwatson return (error); 2734100979Srwatson 2735100979Srwatson mac_relabel_pipe(cred, pipe, label); 2736100979Srwatson 2737100979Srwatson return (0); 2738100979Srwatson} 2739100979Srwatson 2740100979Srwatsonint 2741100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2742105694Srwatson struct mac *mac) 2743100979Srwatson{ 2744105694Srwatson char *buffer, *elements; 2745105694Srwatson int error; 2746100979Srwatson 2747105694Srwatson error = mac_check_structmac_consistent(mac); 2748105694Srwatson if (error) 2749105694Srwatson return (error); 2750105694Srwatson 2751105694Srwatson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2752105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2753105694Srwatson if (error) { 2754105694Srwatson free(elements, M_MACTEMP); 2755105694Srwatson return (error); 2756105694Srwatson } 2757105694Srwatson 2758105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2759105694Srwatson error = mac_externalize_socket_label(&so->so_label, elements, 2760105694Srwatson buffer, mac->m_buflen, M_WAITOK); 2761105694Srwatson if (error == 0) 2762105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2763105694Srwatson 2764105694Srwatson free(buffer, M_MACTEMP); 2765105694Srwatson free(elements, M_MACTEMP); 2766105694Srwatson 2767105694Srwatson return (error); 2768100979Srwatson} 2769100979Srwatson 2770100979Srwatsonint 2771100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2772105694Srwatson struct mac *mac) 2773100979Srwatson{ 2774105694Srwatson char *elements, *buffer; 2775105694Srwatson int error; 2776100979Srwatson 2777105694Srwatson error = mac_check_structmac_consistent(mac); 2778105694Srwatson if (error) 2779105694Srwatson return (error); 2780105694Srwatson 2781105694Srwatson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2782105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2783105694Srwatson if (error) { 2784105694Srwatson free(elements, M_MACTEMP); 2785105694Srwatson return (error); 2786105694Srwatson } 2787105694Srwatson 2788105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2789105694Srwatson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 2790105694Srwatson elements, buffer, mac->m_buflen, M_WAITOK); 2791105694Srwatson if (error == 0) 2792105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2793105694Srwatson 2794105694Srwatson free(buffer, M_MACTEMP); 2795105694Srwatson free(elements, M_MACTEMP); 2796105694Srwatson 2797105694Srwatson return (error); 2798100979Srwatson} 2799100979Srwatson 2800100979Srwatson/* 2801100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes 2802100979Srwatson * to store label data. Can be referenced by filesystems supporting 2803100979Srwatson * extended attributes. 2804100979Srwatson */ 2805100979Srwatsonint 2806100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap) 2807100979Srwatson{ 2808100979Srwatson struct vnode *vp = ap->a_vp; 2809100979Srwatson struct label *intlabel = ap->a_label; 2810100979Srwatson int error; 2811100979Srwatson 2812100979Srwatson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 2813100979Srwatson 2814105988Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2815105988Srwatson return (EOPNOTSUPP); 2816100979Srwatson 2817105988Srwatson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 2818100979Srwatson if (error) 2819100979Srwatson return (error); 2820100979Srwatson 2821100979Srwatson mac_relabel_vnode(ap->a_cred, vp, intlabel); 2822100979Srwatson 2823100979Srwatson return (0); 2824100979Srwatson} 2825100979Srwatson 2826100979Srwatsonstatic int 2827100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 2828100979Srwatson{ 2829100979Srwatson int error; 2830100979Srwatson 2831100979Srwatson if (vp->v_mount == NULL) { 2832100979Srwatson /* printf("vn_setlabel: null v_mount\n"); */ 2833103314Snjl if (vp->v_type != VNON) 2834103314Snjl printf("vn_setlabel: null v_mount with non-VNON\n"); 2835100979Srwatson return (EBADF); 2836100979Srwatson } 2837100979Srwatson 2838100979Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2839100979Srwatson return (EOPNOTSUPP); 2840100979Srwatson 2841100979Srwatson /* 2842100979Srwatson * Multi-phase commit. First check the policies to confirm the 2843100979Srwatson * change is OK. Then commit via the filesystem. Finally, 2844100979Srwatson * update the actual vnode label. Question: maybe the filesystem 2845100979Srwatson * should update the vnode at the end as part of VOP_SETLABEL()? 2846100979Srwatson */ 2847100979Srwatson error = mac_check_vnode_relabel(cred, vp, intlabel); 2848100979Srwatson if (error) 2849100979Srwatson return (error); 2850100979Srwatson 2851100979Srwatson /* 2852100979Srwatson * VADMIN provides the opportunity for the filesystem to make 2853100979Srwatson * decisions about who is and is not able to modify labels 2854100979Srwatson * and protections on files. This might not be right. We can't 2855100979Srwatson * assume VOP_SETLABEL() will do it, because we might implement 2856100979Srwatson * that as part of vop_stdsetlabel_ea(). 2857100979Srwatson */ 2858100979Srwatson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 2859100979Srwatson if (error) 2860100979Srwatson return (error); 2861100979Srwatson 2862100979Srwatson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 2863100979Srwatson if (error) 2864100979Srwatson return (error); 2865100979Srwatson 2866100979Srwatson return (0); 2867100979Srwatson} 2868100979Srwatson 2869105694Srwatsonint 2870105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 2871105694Srwatson{ 2872105694Srwatson char *elements, *buffer; 2873105694Srwatson struct mac mac; 2874105694Srwatson struct proc *tproc; 2875105694Srwatson struct ucred *tcred; 2876105694Srwatson int error; 2877105694Srwatson 2878105694Srwatson error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac)); 2879105694Srwatson if (error) 2880105694Srwatson return (error); 2881105694Srwatson 2882105694Srwatson error = mac_check_structmac_consistent(&mac); 2883105694Srwatson if (error) 2884105694Srwatson return (error); 2885105694Srwatson 2886105694Srwatson tproc = pfind(uap->pid); 2887105694Srwatson if (tproc == NULL) 2888105694Srwatson return (ESRCH); 2889105694Srwatson 2890105694Srwatson tcred = NULL; /* Satisfy gcc. */ 2891105694Srwatson error = p_cansee(td, tproc); 2892105694Srwatson if (error == 0) 2893105694Srwatson tcred = crhold(tproc->p_ucred); 2894105694Srwatson PROC_UNLOCK(tproc); 2895105694Srwatson if (error) 2896105694Srwatson return (error); 2897105694Srwatson 2898105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2899105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2900105694Srwatson if (error) { 2901105694Srwatson free(elements, M_MACTEMP); 2902105694Srwatson crfree(tcred); 2903105694Srwatson return (error); 2904105694Srwatson } 2905105694Srwatson 2906105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2907105694Srwatson error = mac_externalize_cred_label(&tcred->cr_label, elements, 2908105694Srwatson buffer, mac.m_buflen, M_WAITOK); 2909105694Srwatson if (error == 0) 2910105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2911105694Srwatson 2912105694Srwatson free(buffer, M_MACTEMP); 2913105694Srwatson free(elements, M_MACTEMP); 2914105694Srwatson crfree(tcred); 2915105694Srwatson return (error); 2916105694Srwatson} 2917105694Srwatson 2918100979Srwatson/* 2919100979Srwatson * MPSAFE 2920100979Srwatson */ 2921100979Srwatsonint 2922100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 2923100894Srwatson{ 2924105694Srwatson char *elements, *buffer; 2925105694Srwatson struct mac mac; 2926100979Srwatson int error; 2927100894Srwatson 2928105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 2929105694Srwatson if (error) 2930105694Srwatson return (error); 2931105694Srwatson 2932105694Srwatson error = mac_check_structmac_consistent(&mac); 2933105694Srwatson if (error) 2934105694Srwatson return (error); 2935105694Srwatson 2936105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2937105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2938105694Srwatson if (error) { 2939105694Srwatson free(elements, M_MACTEMP); 2940105694Srwatson return (error); 2941105694Srwatson } 2942105694Srwatson 2943105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2944105694Srwatson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 2945105694Srwatson elements, buffer, mac.m_buflen, M_WAITOK); 2946100979Srwatson if (error == 0) 2947105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2948100979Srwatson 2949105694Srwatson free(buffer, M_MACTEMP); 2950105694Srwatson free(elements, M_MACTEMP); 2951100979Srwatson return (error); 2952100979Srwatson} 2953100979Srwatson 2954100979Srwatson/* 2955100979Srwatson * MPSAFE 2956100979Srwatson */ 2957100979Srwatsonint 2958100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 2959100979Srwatson{ 2960100979Srwatson struct ucred *newcred, *oldcred; 2961105694Srwatson struct label intlabel; 2962100979Srwatson struct proc *p; 2963105694Srwatson struct mac mac; 2964105694Srwatson char *buffer; 2965100979Srwatson int error; 2966100979Srwatson 2967105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 2968100979Srwatson if (error) 2969100979Srwatson return (error); 2970100979Srwatson 2971105694Srwatson error = mac_check_structmac_consistent(&mac); 2972100979Srwatson if (error) 2973100979Srwatson return (error); 2974100979Srwatson 2975105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2976105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2977105694Srwatson if (error) { 2978105694Srwatson free(buffer, M_MACTEMP); 2979105694Srwatson return (error); 2980105694Srwatson } 2981105694Srwatson 2982105694Srwatson mac_init_cred_label(&intlabel); 2983105694Srwatson error = mac_internalize_cred_label(&intlabel, buffer); 2984105694Srwatson free(buffer, M_MACTEMP); 2985105694Srwatson if (error) { 2986105694Srwatson mac_destroy_cred_label(&intlabel); 2987105694Srwatson return (error); 2988105694Srwatson } 2989105694Srwatson 2990100979Srwatson newcred = crget(); 2991100979Srwatson 2992100979Srwatson p = td->td_proc; 2993100979Srwatson PROC_LOCK(p); 2994100979Srwatson oldcred = p->p_ucred; 2995100979Srwatson 2996100979Srwatson error = mac_check_cred_relabel(oldcred, &intlabel); 2997100979Srwatson if (error) { 2998100979Srwatson PROC_UNLOCK(p); 2999100979Srwatson crfree(newcred); 3000105694Srwatson goto out; 3001100979Srwatson } 3002100979Srwatson 3003100979Srwatson setsugid(p); 3004100979Srwatson crcopy(newcred, oldcred); 3005100979Srwatson mac_relabel_cred(newcred, &intlabel); 3006102136Srwatson p->p_ucred = newcred; 3007100979Srwatson 3008102136Srwatson /* 3009102136Srwatson * Grab additional reference for use while revoking mmaps, prior 3010102136Srwatson * to releasing the proc lock and sharing the cred. 3011102136Srwatson */ 3012102136Srwatson crhold(newcred); 3013100979Srwatson PROC_UNLOCK(p); 3014102136Srwatson 3015105694Srwatson if (mac_enforce_vm) { 3016105694Srwatson mtx_lock(&Giant); 3017105694Srwatson mac_cred_mmapped_drop_perms(td, newcred); 3018105694Srwatson mtx_unlock(&Giant); 3019105694Srwatson } 3020102136Srwatson 3021102136Srwatson crfree(newcred); /* Free revocation reference. */ 3022100979Srwatson crfree(oldcred); 3023105694Srwatson 3024105694Srwatsonout: 3025105694Srwatson mac_destroy_cred_label(&intlabel); 3026105694Srwatson return (error); 3027100979Srwatson} 3028100979Srwatson 3029100979Srwatson/* 3030100979Srwatson * MPSAFE 3031100979Srwatson */ 3032100979Srwatsonint 3033100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3034100979Srwatson{ 3035105694Srwatson char *elements, *buffer; 3036105694Srwatson struct label intlabel; 3037100979Srwatson struct file *fp; 3038105694Srwatson struct mac mac; 3039100979Srwatson struct vnode *vp; 3040100979Srwatson struct pipe *pipe; 3041105694Srwatson short label_type; 3042100979Srwatson int error; 3043100979Srwatson 3044105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3045105694Srwatson if (error) 3046105694Srwatson return (error); 3047100979Srwatson 3048105694Srwatson error = mac_check_structmac_consistent(&mac); 3049105694Srwatson if (error) 3050105694Srwatson return (error); 3051105694Srwatson 3052105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3053105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3054105694Srwatson if (error) { 3055105694Srwatson free(elements, M_MACTEMP); 3056105694Srwatson return (error); 3057105694Srwatson } 3058105694Srwatson 3059105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3060105694Srwatson mtx_lock(&Giant); /* VFS */ 3061100979Srwatson error = fget(td, SCARG(uap, fd), &fp); 3062100979Srwatson if (error) 3063100979Srwatson goto out; 3064100979Srwatson 3065105694Srwatson label_type = fp->f_type; 3066100979Srwatson switch (fp->f_type) { 3067100979Srwatson case DTYPE_FIFO: 3068100979Srwatson case DTYPE_VNODE: 3069100979Srwatson vp = (struct vnode *)fp->f_data; 3070100979Srwatson 3071105694Srwatson mac_init_vnode_label(&intlabel); 3072105694Srwatson 3073100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3074105988Srwatson mac_copy_vnode_label(&vp->v_label, &intlabel); 3075100979Srwatson VOP_UNLOCK(vp, 0, td); 3076105694Srwatson 3077100979Srwatson break; 3078100979Srwatson case DTYPE_PIPE: 3079100979Srwatson pipe = (struct pipe *)fp->f_data; 3080105694Srwatson 3081105694Srwatson mac_init_pipe_label(&intlabel); 3082105694Srwatson 3083105694Srwatson PIPE_LOCK(pipe); 3084105694Srwatson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3085105694Srwatson PIPE_UNLOCK(pipe); 3086100979Srwatson break; 3087100979Srwatson default: 3088100979Srwatson error = EINVAL; 3089105694Srwatson fdrop(fp, td); 3090105694Srwatson goto out; 3091100979Srwatson } 3092105694Srwatson fdrop(fp, td); 3093100979Srwatson 3094105694Srwatson switch (label_type) { 3095105694Srwatson case DTYPE_FIFO: 3096105694Srwatson case DTYPE_VNODE: 3097105694Srwatson if (error == 0) 3098105694Srwatson error = mac_externalize_vnode_label(&intlabel, 3099105694Srwatson elements, buffer, mac.m_buflen, M_WAITOK); 3100105694Srwatson mac_destroy_vnode_label(&intlabel); 3101105694Srwatson break; 3102105694Srwatson case DTYPE_PIPE: 3103105694Srwatson error = mac_externalize_pipe_label(&intlabel, elements, 3104105694Srwatson buffer, mac.m_buflen, M_WAITOK); 3105105694Srwatson mac_destroy_pipe_label(&intlabel); 3106105694Srwatson break; 3107105694Srwatson default: 3108105694Srwatson panic("__mac_get_fd: corrupted label_type"); 3109105694Srwatson } 3110105694Srwatson 3111100979Srwatson if (error == 0) 3112105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3113100979Srwatson 3114105694Srwatsonout: 3115105694Srwatson mtx_unlock(&Giant); /* VFS */ 3116105694Srwatson free(buffer, M_MACTEMP); 3117105694Srwatson free(elements, M_MACTEMP); 3118100979Srwatson 3119100979Srwatson return (error); 3120100979Srwatson} 3121100979Srwatson 3122100979Srwatson/* 3123100979Srwatson * MPSAFE 3124100979Srwatson */ 3125100979Srwatsonint 3126100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3127100979Srwatson{ 3128105694Srwatson char *elements, *buffer; 3129100979Srwatson struct nameidata nd; 3130105694Srwatson struct label intlabel; 3131105694Srwatson struct mac mac; 3132100979Srwatson int error; 3133100979Srwatson 3134105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3135105694Srwatson if (error) 3136105694Srwatson return (error); 3137105694Srwatson 3138105694Srwatson error = mac_check_structmac_consistent(&mac); 3139105694Srwatson if (error) 3140105694Srwatson return (error); 3141105694Srwatson 3142105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3143105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3144105694Srwatson if (error) { 3145105694Srwatson free(elements, M_MACTEMP); 3146105694Srwatson return (error); 3147105694Srwatson } 3148105694Srwatson 3149105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3150105694Srwatson mtx_lock(&Giant); /* VFS */ 3151105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3152105694Srwatson td); 3153100979Srwatson error = namei(&nd); 3154100979Srwatson if (error) 3155100979Srwatson goto out; 3156100979Srwatson 3157105694Srwatson mac_init_vnode_label(&intlabel); 3158105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3159105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3160105988Srwatson mac.m_buflen, M_WAITOK); 3161105694Srwatson 3162100979Srwatson NDFREE(&nd, 0); 3163105694Srwatson mac_destroy_vnode_label(&intlabel); 3164105694Srwatson 3165105694Srwatson if (error == 0) 3166105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3167105694Srwatson 3168105694Srwatsonout: 3169105694Srwatson mtx_unlock(&Giant); /* VFS */ 3170105694Srwatson 3171105694Srwatson free(buffer, M_MACTEMP); 3172105694Srwatson free(elements, M_MACTEMP); 3173105694Srwatson 3174105694Srwatson return (error); 3175105694Srwatson} 3176105694Srwatson 3177105694Srwatson/* 3178105694Srwatson * MPSAFE 3179105694Srwatson */ 3180105694Srwatsonint 3181105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3182105694Srwatson{ 3183105694Srwatson char *elements, *buffer; 3184105694Srwatson struct nameidata nd; 3185105694Srwatson struct label intlabel; 3186105694Srwatson struct mac mac; 3187105694Srwatson int error; 3188105694Srwatson 3189105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3190100979Srwatson if (error) 3191105694Srwatson return (error); 3192105694Srwatson 3193105694Srwatson error = mac_check_structmac_consistent(&mac); 3194105694Srwatson if (error) 3195105694Srwatson return (error); 3196105694Srwatson 3197105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3198105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3199105694Srwatson if (error) { 3200105694Srwatson free(elements, M_MACTEMP); 3201105694Srwatson return (error); 3202105694Srwatson } 3203105694Srwatson 3204105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3205105694Srwatson mtx_lock(&Giant); /* VFS */ 3206105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3207105694Srwatson td); 3208105694Srwatson error = namei(&nd); 3209105694Srwatson if (error) 3210100979Srwatson goto out; 3211100979Srwatson 3212105694Srwatson mac_init_vnode_label(&intlabel); 3213105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3214105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3215105988Srwatson mac.m_buflen, M_WAITOK); 3216105694Srwatson NDFREE(&nd, 0); 3217105694Srwatson mac_destroy_vnode_label(&intlabel); 3218100979Srwatson 3219105694Srwatson if (error == 0) 3220105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3221105694Srwatson 3222100979Srwatsonout: 3223105694Srwatson mtx_unlock(&Giant); /* VFS */ 3224105694Srwatson 3225105694Srwatson free(buffer, M_MACTEMP); 3226105694Srwatson free(elements, M_MACTEMP); 3227105694Srwatson 3228100979Srwatson return (error); 3229100979Srwatson} 3230100979Srwatson 3231100979Srwatson/* 3232100979Srwatson * MPSAFE 3233100979Srwatson */ 3234100979Srwatsonint 3235100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3236100979Srwatson{ 3237105694Srwatson struct label intlabel; 3238105694Srwatson struct pipe *pipe; 3239100979Srwatson struct file *fp; 3240100979Srwatson struct mount *mp; 3241100979Srwatson struct vnode *vp; 3242105694Srwatson struct mac mac; 3243105694Srwatson char *buffer; 3244100979Srwatson int error; 3245100979Srwatson 3246105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3247100979Srwatson if (error) 3248105694Srwatson return (error); 3249100979Srwatson 3250105694Srwatson error = mac_check_structmac_consistent(&mac); 3251100979Srwatson if (error) 3252105694Srwatson return (error); 3253100979Srwatson 3254105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3255105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3256105694Srwatson if (error) { 3257105694Srwatson free(buffer, M_MACTEMP); 3258105694Srwatson return (error); 3259105694Srwatson } 3260105694Srwatson 3261105694Srwatson mtx_lock(&Giant); /* VFS */ 3262105694Srwatson 3263105694Srwatson error = fget(td, SCARG(uap, fd), &fp); 3264100979Srwatson if (error) 3265105694Srwatson goto out; 3266100979Srwatson 3267100979Srwatson switch (fp->f_type) { 3268100979Srwatson case DTYPE_FIFO: 3269100979Srwatson case DTYPE_VNODE: 3270105694Srwatson mac_init_vnode_label(&intlabel); 3271105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3272105694Srwatson if (error) { 3273105694Srwatson mac_destroy_vnode_label(&intlabel); 3274105694Srwatson break; 3275105694Srwatson } 3276105694Srwatson 3277100979Srwatson vp = (struct vnode *)fp->f_data; 3278100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3279105694Srwatson if (error != 0) { 3280105694Srwatson mac_destroy_vnode_label(&intlabel); 3281100979Srwatson break; 3282105694Srwatson } 3283100979Srwatson 3284100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3285100979Srwatson error = vn_setlabel(vp, &intlabel, td->td_ucred); 3286100979Srwatson VOP_UNLOCK(vp, 0, td); 3287100979Srwatson vn_finished_write(mp); 3288105694Srwatson 3289105694Srwatson mac_destroy_vnode_label(&intlabel); 3290100979Srwatson break; 3291105694Srwatson 3292100979Srwatson case DTYPE_PIPE: 3293105694Srwatson mac_init_pipe_label(&intlabel); 3294105694Srwatson error = mac_internalize_pipe_label(&intlabel, buffer); 3295105694Srwatson if (error == 0) { 3296105694Srwatson pipe = (struct pipe *)fp->f_data; 3297105694Srwatson PIPE_LOCK(pipe); 3298105694Srwatson error = mac_pipe_label_set(td->td_ucred, pipe, 3299105694Srwatson &intlabel); 3300105694Srwatson PIPE_UNLOCK(pipe); 3301105694Srwatson } 3302105694Srwatson 3303105694Srwatson mac_destroy_pipe_label(&intlabel); 3304100979Srwatson break; 3305105694Srwatson 3306100979Srwatson default: 3307100979Srwatson error = EINVAL; 3308100979Srwatson } 3309100979Srwatson 3310100979Srwatson fdrop(fp, td); 3311105694Srwatsonout: 3312105694Srwatson mtx_unlock(&Giant); /* VFS */ 3313105694Srwatson 3314105694Srwatson free(buffer, M_MACTEMP); 3315105694Srwatson 3316100979Srwatson return (error); 3317100979Srwatson} 3318100979Srwatson 3319100979Srwatson/* 3320100979Srwatson * MPSAFE 3321100979Srwatson */ 3322100979Srwatsonint 3323100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3324100979Srwatson{ 3325105694Srwatson struct label intlabel; 3326100979Srwatson struct nameidata nd; 3327100979Srwatson struct mount *mp; 3328105694Srwatson struct mac mac; 3329105694Srwatson char *buffer; 3330100979Srwatson int error; 3331100979Srwatson 3332105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3333100979Srwatson if (error) 3334105694Srwatson return (error); 3335100979Srwatson 3336105694Srwatson error = mac_check_structmac_consistent(&mac); 3337100979Srwatson if (error) 3338105694Srwatson return (error); 3339100979Srwatson 3340105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3341105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3342105694Srwatson if (error) { 3343105694Srwatson free(buffer, M_MACTEMP); 3344105694Srwatson return (error); 3345105694Srwatson } 3346105694Srwatson 3347105694Srwatson mac_init_vnode_label(&intlabel); 3348105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3349105694Srwatson free(buffer, M_MACTEMP); 3350105694Srwatson if (error) { 3351105694Srwatson mac_destroy_vnode_label(&intlabel); 3352105694Srwatson return (error); 3353105694Srwatson } 3354105694Srwatson 3355105694Srwatson mtx_lock(&Giant); /* VFS */ 3356105694Srwatson 3357105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3358105694Srwatson td); 3359100979Srwatson error = namei(&nd); 3360105694Srwatson if (error == 0) { 3361105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3362105694Srwatson if (error == 0) 3363105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3364105694Srwatson td->td_ucred); 3365105694Srwatson vn_finished_write(mp); 3366105694Srwatson } 3367105694Srwatson 3368105694Srwatson NDFREE(&nd, 0); 3369105694Srwatson mtx_unlock(&Giant); /* VFS */ 3370105694Srwatson mac_destroy_vnode_label(&intlabel); 3371105694Srwatson 3372105694Srwatson return (error); 3373105694Srwatson} 3374105694Srwatson 3375105694Srwatson/* 3376105694Srwatson * MPSAFE 3377105694Srwatson */ 3378105694Srwatsonint 3379105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3380105694Srwatson{ 3381105694Srwatson struct label intlabel; 3382105694Srwatson struct nameidata nd; 3383105694Srwatson struct mount *mp; 3384105694Srwatson struct mac mac; 3385105694Srwatson char *buffer; 3386105694Srwatson int error; 3387105694Srwatson 3388105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3389100979Srwatson if (error) 3390105694Srwatson return (error); 3391105694Srwatson 3392105694Srwatson error = mac_check_structmac_consistent(&mac); 3393100979Srwatson if (error) 3394105694Srwatson return (error); 3395100979Srwatson 3396105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3397105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3398105694Srwatson if (error) { 3399105694Srwatson free(buffer, M_MACTEMP); 3400105694Srwatson return (error); 3401105694Srwatson } 3402105694Srwatson 3403105694Srwatson mac_init_vnode_label(&intlabel); 3404105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3405105694Srwatson free(buffer, M_MACTEMP); 3406105694Srwatson if (error) { 3407105694Srwatson mac_destroy_vnode_label(&intlabel); 3408105694Srwatson return (error); 3409105694Srwatson } 3410105694Srwatson 3411105694Srwatson mtx_lock(&Giant); /* VFS */ 3412105694Srwatson 3413105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3414105694Srwatson td); 3415105694Srwatson error = namei(&nd); 3416105694Srwatson if (error == 0) { 3417105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3418105694Srwatson if (error == 0) 3419105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3420105694Srwatson td->td_ucred); 3421105694Srwatson vn_finished_write(mp); 3422105694Srwatson } 3423105694Srwatson 3424100979Srwatson NDFREE(&nd, 0); 3425105694Srwatson mtx_unlock(&Giant); /* VFS */ 3426105694Srwatson mac_destroy_vnode_label(&intlabel); 3427105694Srwatson 3428100979Srwatson return (error); 3429100979Srwatson} 3430100979Srwatson 3431105694Srwatson/* 3432105694Srwatson * MPSAFE 3433105694Srwatson */ 3434102123Srwatsonint 3435102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3436102123Srwatson{ 3437102123Srwatson struct mac_policy_conf *mpc; 3438102123Srwatson char target[MAC_MAX_POLICY_NAME]; 3439102123Srwatson int error; 3440102123Srwatson 3441102123Srwatson error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3442102123Srwatson if (error) 3443102123Srwatson return (error); 3444102123Srwatson 3445102123Srwatson error = ENOSYS; 3446102123Srwatson MAC_POLICY_LIST_BUSY(); 3447102123Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3448102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3449102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3450102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3451102123Srwatson SCARG(uap, call), SCARG(uap, arg)); 3452102123Srwatson goto out; 3453102123Srwatson } 3454102123Srwatson } 3455102123Srwatson 3456102123Srwatsonout: 3457102123Srwatson MAC_POLICY_LIST_UNBUSY(); 3458102123Srwatson return (error); 3459102123Srwatson} 3460102123Srwatson 3461100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3462100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3463100979Srwatson 3464100979Srwatson#else /* !MAC */ 3465100979Srwatson 3466100979Srwatsonint 3467105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3468105694Srwatson{ 3469105694Srwatson 3470105694Srwatson return (ENOSYS); 3471105694Srwatson} 3472105694Srwatson 3473105694Srwatsonint 3474100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3475100979Srwatson{ 3476100979Srwatson 3477100894Srwatson return (ENOSYS); 3478100894Srwatson} 3479100894Srwatson 3480100894Srwatsonint 3481100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3482100894Srwatson{ 3483100894Srwatson 3484100894Srwatson return (ENOSYS); 3485100894Srwatson} 3486100894Srwatson 3487100894Srwatsonint 3488100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3489100894Srwatson{ 3490100894Srwatson 3491100894Srwatson return (ENOSYS); 3492100894Srwatson} 3493100894Srwatson 3494100894Srwatsonint 3495100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3496100894Srwatson{ 3497100894Srwatson 3498100894Srwatson return (ENOSYS); 3499100894Srwatson} 3500100894Srwatson 3501100894Srwatsonint 3502105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3503105694Srwatson{ 3504105694Srwatson 3505105694Srwatson return (ENOSYS); 3506105694Srwatson} 3507105694Srwatson 3508105694Srwatsonint 3509100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3510100894Srwatson{ 3511100894Srwatson 3512100894Srwatson return (ENOSYS); 3513100894Srwatson} 3514100894Srwatson 3515100894Srwatsonint 3516100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3517100894Srwatson{ 3518100894Srwatson 3519100894Srwatson return (ENOSYS); 3520100894Srwatson} 3521100979Srwatson 3522102123Srwatsonint 3523105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3524105694Srwatson{ 3525105694Srwatson 3526105694Srwatson return (ENOSYS); 3527105694Srwatson} 3528105694Srwatson 3529105694Srwatsonint 3530102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3531102123Srwatson{ 3532102123Srwatson 3533102123Srwatson return (ENOSYS); 3534102123Srwatson} 3535102123Srwatson 3536105694Srwatson#endif 3537