mac_framework.c revision 116182
1100894Srwatson/*- 2100894Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3100894Srwatson * Copyright (c) 2001 Ilmar S. Habibulin 4113681Srwatson * Copyright (c) 2001, 2002, 2003 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 */ 36116182Sobrien 37100894Srwatson/* 38100894Srwatson * Framework for extensible kernel access control. Kernel and userland 39100894Srwatson * interface to the framework, policy registration and composition. 40100894Srwatson */ 41100894Srwatson 42116182Sobrien#include <sys/cdefs.h> 43116182Sobrien__FBSDID("$FreeBSD: head/sys/security/mac/mac_framework.c 116182 2003-06-11 00:56:59Z obrien $"); 44116182Sobrien 45100894Srwatson#include "opt_mac.h" 46104300Sphk#include "opt_devfs.h" 47101173Srwatson 48100894Srwatson#include <sys/param.h> 49106856Srwatson#include <sys/condvar.h> 50100979Srwatson#include <sys/extattr.h> 51106468Srwatson#include <sys/imgact.h> 52100979Srwatson#include <sys/kernel.h> 53100979Srwatson#include <sys/lock.h> 54102949Sbde#include <sys/malloc.h> 55100979Srwatson#include <sys/mutex.h> 56100979Srwatson#include <sys/mac.h> 57101712Srwatson#include <sys/module.h> 58100979Srwatson#include <sys/proc.h> 59100979Srwatson#include <sys/systm.h> 60100894Srwatson#include <sys/sysproto.h> 61100894Srwatson#include <sys/sysent.h> 62100979Srwatson#include <sys/vnode.h> 63100979Srwatson#include <sys/mount.h> 64100979Srwatson#include <sys/file.h> 65100979Srwatson#include <sys/namei.h> 66100979Srwatson#include <sys/socket.h> 67100979Srwatson#include <sys/pipe.h> 68100979Srwatson#include <sys/socketvar.h> 69100979Srwatson#include <sys/sysctl.h> 70100894Srwatson 71100979Srwatson#include <vm/vm.h> 72100979Srwatson#include <vm/pmap.h> 73100979Srwatson#include <vm/vm_map.h> 74100979Srwatson#include <vm/vm_object.h> 75100979Srwatson 76100979Srwatson#include <sys/mac_policy.h> 77100979Srwatson 78100979Srwatson#include <fs/devfs/devfs.h> 79100979Srwatson 80100979Srwatson#include <net/bpfdesc.h> 81100979Srwatson#include <net/if.h> 82100979Srwatson#include <net/if_var.h> 83100979Srwatson 84100979Srwatson#include <netinet/in.h> 85100979Srwatson#include <netinet/ip_var.h> 86100979Srwatson 87100979Srwatson#ifdef MAC 88100979Srwatson 89101712Srwatson/* 90101712Srwatson * Declare that the kernel provides MAC support, version 1. This permits 91101712Srwatson * modules to refuse to be loaded if the necessary support isn't present, 92101712Srwatson * even if it's pre-boot. 93101712Srwatson */ 94101712SrwatsonMODULE_VERSION(kernel_mac_support, 1); 95101712Srwatson 96100979SrwatsonSYSCTL_DECL(_security); 97100979Srwatson 98100979SrwatsonSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 99100979Srwatson "TrustedBSD MAC policy controls"); 100104517Srwatson 101114846Srwatson#if MAC_MAX_SLOTS > 32 102114846Srwatson#error "MAC_MAX_SLOTS too large" 103100979Srwatson#endif 104105497Srwatson 105114846Srwatsonstatic unsigned int mac_max_slots = MAC_MAX_SLOTS; 106114846Srwatsonstatic unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1; 107114846SrwatsonSYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD, 108114846Srwatson &mac_max_slots, 0, ""); 109100979Srwatson 110105959Srwatson/* 111105959Srwatson * Has the kernel started generating labeled objects yet? All read/write 112105959Srwatson * access to this variable is serialized during the boot process. Following 113105959Srwatson * the end of serialization, we don't update this flag; no locking. 114105959Srwatson */ 115100979Srwatsonstatic int mac_late = 0; 116100979Srwatson 117105988Srwatson/* 118105988Srwatson * Warn about EA transactions only the first time they happen. 119105988Srwatson * Weak coherency, no locking. 120105988Srwatson */ 121105988Srwatsonstatic int ea_warn_once = 0; 122105988Srwatson 123113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 124113487Srwatson/* 125113487Srwatson * Flag to indicate whether or not we should allocate label storage for 126113487Srwatson * new mbufs. Since most dynamic policies we currently work with don't 127113487Srwatson * rely on mbuf labeling, try to avoid paying the cost of mtag allocation 128113487Srwatson * unless specifically notified of interest. One result of this is 129113487Srwatson * that if a dynamically loaded policy requests mbuf labels, it must 130113487Srwatson * be able to deal with a NULL label being returned on any mbufs that 131113487Srwatson * were already in flight when the policy was loaded. Since the policy 132113487Srwatson * already has to deal with uninitialized labels, this probably won't 133113487Srwatson * be a problem. Note: currently no locking. Will this be a problem? 134113487Srwatson */ 135113487Srwatsonstatic int mac_labelmbufs = 0; 136113487Srwatson#endif 137113487Srwatson 138100979Srwatsonstatic int mac_enforce_fs = 1; 139100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 140100979Srwatson &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 141100979SrwatsonTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 142100979Srwatson 143107089Srwatsonstatic int mac_enforce_kld = 1; 144107089SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW, 145107089Srwatson &mac_enforce_kld, 0, "Enforce MAC policy on kld operations"); 146107089SrwatsonTUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld); 147107089Srwatson 148100979Srwatsonstatic int mac_enforce_network = 1; 149100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 150100979Srwatson &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 151100979SrwatsonTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 152100979Srwatson 153103513Srwatsonstatic int mac_enforce_pipe = 1; 154103513SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 155103513Srwatson &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 156104236SrwatsonTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 157103513Srwatson 158100979Srwatsonstatic int mac_enforce_process = 1; 159100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 160100979Srwatson &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 161100979SrwatsonTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 162100979Srwatson 163100979Srwatsonstatic int mac_enforce_socket = 1; 164100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 165100979Srwatson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 166100979SrwatsonTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 167100979Srwatson 168106045Srwatsonstatic int mac_enforce_system = 1; 169106045SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 170106045Srwatson &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 171106045SrwatsonTUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 172106025Srwatson 173106045Srwatsonstatic int mac_enforce_vm = 1; 174103514SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 175103514Srwatson &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 176104236SrwatsonTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 177103514Srwatson 178103136Srwatsonstatic int mac_mmap_revocation = 1; 179103136SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 180103136Srwatson &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 181103136Srwatson "relabel"); 182101892Srwatsonstatic int mac_mmap_revocation_via_cow = 0; 183100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 184100979Srwatson &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 185100979Srwatson "copy-on-write semantics, or by removing all write access"); 186100979Srwatson 187101988Srwatson#ifdef MAC_DEBUG 188104268SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 189104268Srwatson "TrustedBSD MAC debug info"); 190104268Srwatson 191104268Srwatsonstatic int mac_debug_label_fallback = 0; 192104268SrwatsonSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 193104268Srwatson &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 194104268Srwatson "when label is corrupted."); 195104268SrwatsonTUNABLE_INT("security.mac.debug_label_fallback", 196104268Srwatson &mac_debug_label_fallback); 197104268Srwatson 198104517SrwatsonSYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 199104517Srwatson "TrustedBSD MAC object counters"); 200104517Srwatson 201100979Srwatsonstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 202100979Srwatson nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 203107105Srwatson nmacipqs, nmacpipes, nmacprocs; 204104517Srwatson 205104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 206100979Srwatson &nmacmbufs, 0, "number of mbufs in use"); 207104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 208100979Srwatson &nmaccreds, 0, "number of ucreds in use"); 209104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 210100979Srwatson &nmacifnets, 0, "number of ifnets in use"); 211104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 212100979Srwatson &nmacipqs, 0, "number of ipqs in use"); 213104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 214100979Srwatson &nmacbpfdescs, 0, "number of bpfdescs in use"); 215104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 216100979Srwatson &nmacsockets, 0, "number of sockets in use"); 217104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 218100979Srwatson &nmacpipes, 0, "number of pipes in use"); 219107105SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, procs, CTLFLAG_RD, 220107105Srwatson &nmacprocs, 0, "number of procs in use"); 221104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 222100979Srwatson &nmacmounts, 0, "number of mounts in use"); 223104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 224100979Srwatson &nmactemp, 0, "number of temporary labels in use"); 225104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 226100979Srwatson &nmacvnodes, 0, "number of vnodes in use"); 227104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 228100979Srwatson &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 229101988Srwatson#endif 230100979Srwatson 231100979Srwatsonstatic int error_select(int error1, int error2); 232100979Srwatsonstatic int mac_policy_register(struct mac_policy_conf *mpc); 233100979Srwatsonstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 234100979Srwatson 235104546Srwatsonstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 236104546Srwatson struct vnode *vp, int *prot); 237100979Srwatsonstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 238100979Srwatson struct ucred *cred, struct vm_map *map); 239100979Srwatson 240104541Srwatsonstatic void mac_destroy_socket_label(struct label *label); 241104541Srwatson 242105988Srwatsonstatic int mac_setlabel_vnode_extattr(struct ucred *cred, 243105988Srwatson struct vnode *vp, struct label *intlabel); 244105988Srwatson 245100979SrwatsonMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 246105694SrwatsonMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 247100979Srwatson 248100979Srwatson/* 249114806Srwatson * mac_static_policy_list holds a list of policy modules that are not 250114806Srwatson * loaded while the system is "live", and cannot be unloaded. These 251114806Srwatson * policies can be invoked without holding the busy count. 252114806Srwatson * 253114806Srwatson * mac_policy_list stores the list of dynamic policies. A busy count is 254106856Srwatson * maintained for the list, stored in mac_policy_busy. The busy count 255114806Srwatson * is protected by mac_policy_mtx; the list may be modified only 256106856Srwatson * while the busy count is 0, requiring that the lock be held to 257106856Srwatson * prevent new references to the list from being acquired. For almost 258106856Srwatson * all operations, incrementing the busy count is sufficient to 259106856Srwatson * guarantee consistency, as the list cannot be modified while the 260106856Srwatson * busy count is elevated. For a few special operations involving a 261114806Srwatson * change to the list of active policies, the mtx itself must be held. 262114806Srwatson * A condition variable, mac_policy_cv, is used to signal potential 263114806Srwatson * exclusive consumers that they should try to acquire the lock if a 264114806Srwatson * first attempt at exclusive access fails. 265100979Srwatson */ 266114806Srwatsonstatic struct mtx mac_policy_mtx; 267114806Srwatsonstatic struct cv mac_policy_cv; 268114806Srwatsonstatic int mac_policy_count; 269100979Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 270114806Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_static_policy_list; 271100979Srwatson 272106856Srwatson/* 273111883Sjhb * We manually invoke WITNESS_WARN() to allow Witness to generate 274106856Srwatson * warnings even if we don't end up ever triggering the wait at 275106856Srwatson * run-time. The consumer of the exclusive interface must not hold 276106856Srwatson * any locks (other than potentially Giant) since we may sleep for 277106856Srwatson * long (potentially indefinite) periods of time waiting for the 278106856Srwatson * framework to become quiescent so that a policy list change may 279106856Srwatson * be made. 280106856Srwatson */ 281114806Srwatsonstatic __inline void 282114806Srwatsonmac_policy_grab_exclusive(void) 283114806Srwatson{ 284114806Srwatson WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 285114806Srwatson "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__); 286114806Srwatson mtx_lock(&mac_policy_mtx); 287114806Srwatson while (mac_policy_count != 0) 288114806Srwatson cv_wait(&mac_policy_cv, &mac_policy_mtx); 289114806Srwatson} 290106856Srwatson 291114806Srwatsonstatic __inline void 292114806Srwatsonmac_policy_assert_exclusive(void) 293114806Srwatson{ 294114806Srwatson mtx_assert(&mac_policy_mtx, MA_OWNED); 295114806Srwatson KASSERT(mac_policy_count == 0, 296114806Srwatson ("mac_policy_assert_exclusive(): not exclusive")); 297114806Srwatson} 298113487Srwatson 299114806Srwatsonstatic __inline void 300114806Srwatsonmac_policy_release_exclusive(void) 301114806Srwatson{ 302100979Srwatson 303114806Srwatson KASSERT(mac_policy_count == 0, 304114806Srwatson ("mac_policy_release_exclusive(): not exclusive")); 305114806Srwatson mtx_unlock(&mac_policy_mtx); 306114806Srwatson cv_signal(&mac_policy_cv); 307114806Srwatson} 308100979Srwatson 309114806Srwatsonstatic __inline void 310114806Srwatsonmac_policy_list_busy(void) 311114806Srwatson{ 312114806Srwatson mtx_lock(&mac_policy_mtx); 313114806Srwatson mac_policy_count++; 314114806Srwatson mtx_unlock(&mac_policy_mtx); 315114806Srwatson} 316114806Srwatson 317114806Srwatsonstatic __inline int 318114806Srwatsonmac_policy_list_conditional_busy(void) 319114806Srwatson{ 320114806Srwatson int ret; 321114806Srwatson 322114806Srwatson mtx_lock(&mac_policy_mtx); 323114806Srwatson if (!LIST_EMPTY(&mac_policy_list)) { 324114806Srwatson mac_policy_count++; 325114806Srwatson ret = 1; 326114806Srwatson } else 327114806Srwatson ret = 0; 328114806Srwatson mtx_unlock(&mac_policy_mtx); 329114806Srwatson return (ret); 330114806Srwatson} 331114806Srwatson 332114806Srwatsonstatic __inline void 333114806Srwatsonmac_policy_list_unbusy(void) 334114806Srwatson{ 335114806Srwatson mtx_lock(&mac_policy_mtx); 336114806Srwatson mac_policy_count--; 337114806Srwatson KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK")); 338114806Srwatson if (mac_policy_count == 0) 339114806Srwatson cv_signal(&mac_policy_cv); 340114806Srwatson mtx_unlock(&mac_policy_mtx); 341114806Srwatson} 342114806Srwatson 343100979Srwatson/* 344100979Srwatson * MAC_CHECK performs the designated check by walking the policy 345100979Srwatson * module list and checking with each as to how it feels about the 346100979Srwatson * request. Note that it returns its value via 'error' in the scope 347100979Srwatson * of the caller. 348100979Srwatson */ 349100979Srwatson#define MAC_CHECK(check, args...) do { \ 350100979Srwatson struct mac_policy_conf *mpc; \ 351114806Srwatson int entrycount; \ 352100979Srwatson \ 353100979Srwatson error = 0; \ 354114806Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ 355100979Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 356100979Srwatson error = error_select( \ 357100979Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 358100979Srwatson error); \ 359100979Srwatson } \ 360114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ 361114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 362114806Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 363114806Srwatson error = error_select( \ 364114806Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 365114806Srwatson error); \ 366114806Srwatson } \ 367114806Srwatson mac_policy_list_unbusy(); \ 368114806Srwatson } \ 369100979Srwatson} while (0) 370100979Srwatson 371100979Srwatson/* 372100979Srwatson * MAC_BOOLEAN performs the designated boolean composition by walking 373100979Srwatson * the module list, invoking each instance of the operation, and 374100979Srwatson * combining the results using the passed C operator. Note that it 375100979Srwatson * returns its value via 'result' in the scope of the caller, which 376100979Srwatson * should be initialized by the caller in a meaningful way to get 377100979Srwatson * a meaningful result. 378100979Srwatson */ 379100979Srwatson#define MAC_BOOLEAN(operation, composition, args...) do { \ 380100979Srwatson struct mac_policy_conf *mpc; \ 381114806Srwatson int entrycount; \ 382100979Srwatson \ 383114806Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ 384100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 385100979Srwatson result = result composition \ 386100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 387100979Srwatson } \ 388114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ 389114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 390114806Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 391114806Srwatson result = result composition \ 392114806Srwatson mpc->mpc_ops->mpo_ ## operation \ 393114806Srwatson (args); \ 394114806Srwatson } \ 395114806Srwatson mac_policy_list_unbusy(); \ 396114806Srwatson } \ 397100979Srwatson} while (0) 398100979Srwatson 399105694Srwatson#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 400105694Srwatson outbuflen) do { \ 401105694Srwatson char *curptr, *curptr_start, *element_name, *element_temp; \ 402105694Srwatson size_t left, left_start, len; \ 403105694Srwatson int claimed, first, first_start, ignorenotfound; \ 404105694Srwatson \ 405105694Srwatson error = 0; \ 406105694Srwatson element_temp = elementlist; \ 407105694Srwatson curptr = outbuf; \ 408105694Srwatson curptr[0] = '\0'; \ 409105694Srwatson left = outbuflen; \ 410105694Srwatson first = 1; \ 411105694Srwatson while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 412105694Srwatson curptr_start = curptr; \ 413105694Srwatson left_start = left; \ 414105694Srwatson first_start = first; \ 415105694Srwatson if (element_name[0] == '?') { \ 416105694Srwatson element_name++; \ 417105694Srwatson ignorenotfound = 1; \ 418105694Srwatson } else \ 419105694Srwatson ignorenotfound = 0; \ 420105694Srwatson claimed = 0; \ 421105694Srwatson if (first) { \ 422105694Srwatson len = snprintf(curptr, left, "%s/", \ 423105694Srwatson element_name); \ 424105694Srwatson first = 0; \ 425105694Srwatson } else \ 426105694Srwatson len = snprintf(curptr, left, ",%s/", \ 427105694Srwatson element_name); \ 428105694Srwatson if (len >= left) { \ 429105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 430105694Srwatson break; \ 431105694Srwatson } \ 432105694Srwatson curptr += len; \ 433105694Srwatson left -= len; \ 434105694Srwatson \ 435105694Srwatson MAC_CHECK(externalize_ ## type, label, element_name, \ 436105694Srwatson curptr, left, &len, &claimed); \ 437105694Srwatson if (error) \ 438105694Srwatson break; \ 439105694Srwatson if (claimed == 1) { \ 440105694Srwatson if (len >= outbuflen) { \ 441105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 442105694Srwatson break; \ 443105694Srwatson } \ 444105694Srwatson curptr += len; \ 445105694Srwatson left -= len; \ 446105694Srwatson } else if (claimed == 0 && ignorenotfound) { \ 447105694Srwatson /* \ 448105694Srwatson * Revert addition of the label element \ 449105694Srwatson * name. \ 450105694Srwatson */ \ 451105694Srwatson curptr = curptr_start; \ 452105694Srwatson *curptr = '\0'; \ 453105694Srwatson left = left_start; \ 454105694Srwatson first = first_start; \ 455105694Srwatson } else { \ 456105694Srwatson error = EINVAL; /* XXXMAC: ENOLABEL */ \ 457105694Srwatson break; \ 458105694Srwatson } \ 459105694Srwatson } \ 460105694Srwatson} while (0) 461105694Srwatson 462105694Srwatson#define MAC_INTERNALIZE(type, label, instring) do { \ 463105694Srwatson char *element, *element_name, *element_data; \ 464105694Srwatson int claimed; \ 465105694Srwatson \ 466105694Srwatson error = 0; \ 467105694Srwatson element = instring; \ 468105694Srwatson while ((element_name = strsep(&element, ",")) != NULL) { \ 469105694Srwatson element_data = element_name; \ 470105694Srwatson element_name = strsep(&element_data, "/"); \ 471105694Srwatson if (element_data == NULL) { \ 472105694Srwatson error = EINVAL; \ 473105694Srwatson break; \ 474105694Srwatson } \ 475105694Srwatson claimed = 0; \ 476105694Srwatson MAC_CHECK(internalize_ ## type, label, element_name, \ 477105694Srwatson element_data, &claimed); \ 478105694Srwatson if (error) \ 479105694Srwatson break; \ 480105694Srwatson if (claimed != 1) { \ 481105694Srwatson /* XXXMAC: Another error here? */ \ 482105694Srwatson error = EINVAL; \ 483105694Srwatson break; \ 484105694Srwatson } \ 485105694Srwatson } \ 486105694Srwatson} while (0) 487105694Srwatson 488100979Srwatson/* 489100979Srwatson * MAC_PERFORM performs the designated operation by walking the policy 490100979Srwatson * module list and invoking that operation for each policy. 491100979Srwatson */ 492100979Srwatson#define MAC_PERFORM(operation, args...) do { \ 493100979Srwatson struct mac_policy_conf *mpc; \ 494114806Srwatson int entrycount; \ 495100979Srwatson \ 496114806Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ 497100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 498100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 499100979Srwatson } \ 500114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ 501114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 502114806Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 503114806Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 504114806Srwatson } \ 505114806Srwatson mac_policy_list_unbusy(); \ 506114806Srwatson } \ 507100979Srwatson} while (0) 508100979Srwatson 509100979Srwatson/* 510100979Srwatson * Initialize the MAC subsystem, including appropriate SMP locks. 511100979Srwatson */ 512100979Srwatsonstatic void 513100979Srwatsonmac_init(void) 514100979Srwatson{ 515100979Srwatson 516114806Srwatson LIST_INIT(&mac_static_policy_list); 517100979Srwatson LIST_INIT(&mac_policy_list); 518114806Srwatson 519114806Srwatson mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF); 520114806Srwatson cv_init(&mac_policy_cv, "mac_policy_cv"); 521100979Srwatson} 522100979Srwatson 523100979Srwatson/* 524100979Srwatson * For the purposes of modules that want to know if they were loaded 525100979Srwatson * "early", set the mac_late flag once we've processed modules either 526100979Srwatson * linked into the kernel, or loaded before the kernel startup. 527100979Srwatson */ 528100979Srwatsonstatic void 529100979Srwatsonmac_late_init(void) 530100979Srwatson{ 531100979Srwatson 532100979Srwatson mac_late = 1; 533100979Srwatson} 534100979Srwatson 535100979Srwatson/* 536113487Srwatson * After the policy list has changed, walk the list to update any global 537113487Srwatson * flags. 538113487Srwatson */ 539113487Srwatsonstatic void 540113487Srwatsonmac_policy_updateflags(void) 541113487Srwatson{ 542113487Srwatson struct mac_policy_conf *tmpc; 543113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 544113487Srwatson int labelmbufs; 545113487Srwatson#endif 546113487Srwatson 547114806Srwatson mac_policy_assert_exclusive(); 548113487Srwatson 549113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 550113487Srwatson labelmbufs = 0; 551113487Srwatson#endif 552114806Srwatson 553114806Srwatson LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { 554114806Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 555114806Srwatson if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) 556114806Srwatson labelmbufs++; 557114806Srwatson#endif 558114806Srwatson } 559113487Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 560113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 561113487Srwatson if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) 562113487Srwatson labelmbufs++; 563113487Srwatson#endif 564113487Srwatson } 565113487Srwatson 566113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 567113487Srwatson mac_labelmbufs = (labelmbufs != 0); 568113487Srwatson#endif 569113487Srwatson} 570113487Srwatson 571113487Srwatson/* 572100979Srwatson * Allow MAC policy modules to register during boot, etc. 573100979Srwatson */ 574100894Srwatsonint 575100979Srwatsonmac_policy_modevent(module_t mod, int type, void *data) 576100979Srwatson{ 577100979Srwatson struct mac_policy_conf *mpc; 578100979Srwatson int error; 579100979Srwatson 580100979Srwatson error = 0; 581100979Srwatson mpc = (struct mac_policy_conf *) data; 582100979Srwatson 583100979Srwatson switch (type) { 584100979Srwatson case MOD_LOAD: 585100979Srwatson if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 586100979Srwatson mac_late) { 587100979Srwatson printf("mac_policy_modevent: can't load %s policy " 588100979Srwatson "after booting\n", mpc->mpc_name); 589100979Srwatson error = EBUSY; 590100979Srwatson break; 591100979Srwatson } 592100979Srwatson error = mac_policy_register(mpc); 593100979Srwatson break; 594100979Srwatson case MOD_UNLOAD: 595100979Srwatson /* Don't unregister the module if it was never registered. */ 596100979Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 597100979Srwatson != 0) 598100979Srwatson error = mac_policy_unregister(mpc); 599100979Srwatson else 600100979Srwatson error = 0; 601100979Srwatson break; 602100979Srwatson default: 603100979Srwatson break; 604100979Srwatson } 605100979Srwatson 606100979Srwatson return (error); 607100979Srwatson} 608100979Srwatson 609100979Srwatsonstatic int 610100979Srwatsonmac_policy_register(struct mac_policy_conf *mpc) 611100979Srwatson{ 612100979Srwatson struct mac_policy_conf *tmpc; 613114806Srwatson int error, slot, static_entry; 614100979Srwatson 615114806Srwatson error = 0; 616114806Srwatson 617114806Srwatson /* 618114806Srwatson * We don't technically need exclusive access while !mac_late, 619114806Srwatson * but hold it for assertion consistency. 620114806Srwatson */ 621114806Srwatson mac_policy_grab_exclusive(); 622114806Srwatson 623114806Srwatson /* 624114806Srwatson * If the module can potentially be unloaded, or we're loading 625114806Srwatson * late, we have to stick it in the non-static list and pay 626114806Srwatson * an extra performance overhead. Otherwise, we can pay a 627114806Srwatson * light locking cost and stick it in the static list. 628114806Srwatson */ 629114806Srwatson static_entry = (!mac_late && 630114806Srwatson !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK)); 631114806Srwatson 632114806Srwatson if (static_entry) { 633114806Srwatson LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { 634114806Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 635114806Srwatson error = EEXIST; 636114806Srwatson goto out; 637114806Srwatson } 638100979Srwatson } 639114806Srwatson } else { 640114806Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 641114806Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 642114806Srwatson error = EEXIST; 643114806Srwatson goto out; 644114806Srwatson } 645114806Srwatson } 646100979Srwatson } 647100979Srwatson if (mpc->mpc_field_off != NULL) { 648114846Srwatson slot = ffs(mac_slot_offsets_free); 649100979Srwatson if (slot == 0) { 650114806Srwatson error = ENOMEM; 651114806Srwatson goto out; 652100979Srwatson } 653100979Srwatson slot--; 654114846Srwatson mac_slot_offsets_free &= ~(1 << slot); 655100979Srwatson *mpc->mpc_field_off = slot; 656100979Srwatson } 657100979Srwatson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 658100979Srwatson 659114806Srwatson /* 660114806Srwatson * If we're loading a MAC module after the framework has 661114806Srwatson * initialized, it has to go into the dynamic list. If 662114806Srwatson * we're loading it before we've finished initializing, 663114806Srwatson * it can go into the static list with weaker locker 664114806Srwatson * requirements. 665114806Srwatson */ 666114806Srwatson if (static_entry) 667114806Srwatson LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list); 668114806Srwatson else 669114806Srwatson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 670114806Srwatson 671100979Srwatson /* Per-policy initialization. */ 672100979Srwatson if (mpc->mpc_ops->mpo_init != NULL) 673100979Srwatson (*(mpc->mpc_ops->mpo_init))(mpc); 674113487Srwatson mac_policy_updateflags(); 675100979Srwatson 676100979Srwatson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 677100979Srwatson mpc->mpc_name); 678100979Srwatson 679114806Srwatsonout: 680114806Srwatson mac_policy_release_exclusive(); 681114806Srwatson return (error); 682100979Srwatson} 683100979Srwatson 684100979Srwatsonstatic int 685100979Srwatsonmac_policy_unregister(struct mac_policy_conf *mpc) 686100979Srwatson{ 687100979Srwatson 688104520Srwatson /* 689104520Srwatson * If we fail the load, we may get a request to unload. Check 690104520Srwatson * to see if we did the run-time registration, and if not, 691104520Srwatson * silently succeed. 692104520Srwatson */ 693114806Srwatson mac_policy_grab_exclusive(); 694104520Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 695114806Srwatson mac_policy_release_exclusive(); 696104520Srwatson return (0); 697104520Srwatson } 698100979Srwatson#if 0 699100979Srwatson /* 700100979Srwatson * Don't allow unloading modules with private data. 701100979Srwatson */ 702104520Srwatson if (mpc->mpc_field_off != NULL) { 703104520Srwatson MAC_POLICY_LIST_UNLOCK(); 704100979Srwatson return (EBUSY); 705104520Srwatson } 706100979Srwatson#endif 707104520Srwatson /* 708104520Srwatson * Only allow the unload to proceed if the module is unloadable 709104520Srwatson * by its own definition. 710104520Srwatson */ 711104520Srwatson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 712114806Srwatson mac_policy_release_exclusive(); 713100979Srwatson return (EBUSY); 714104520Srwatson } 715100979Srwatson if (mpc->mpc_ops->mpo_destroy != NULL) 716100979Srwatson (*(mpc->mpc_ops->mpo_destroy))(mpc); 717100979Srwatson 718100979Srwatson LIST_REMOVE(mpc, mpc_list); 719106856Srwatson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 720113487Srwatson mac_policy_updateflags(); 721100979Srwatson 722114806Srwatson mac_policy_release_exclusive(); 723114806Srwatson 724100979Srwatson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 725100979Srwatson mpc->mpc_name); 726100979Srwatson 727100979Srwatson return (0); 728100979Srwatson} 729100979Srwatson 730100979Srwatson/* 731100979Srwatson * Define an error value precedence, and given two arguments, selects the 732100979Srwatson * value with the higher precedence. 733100979Srwatson */ 734100979Srwatsonstatic int 735100979Srwatsonerror_select(int error1, int error2) 736100979Srwatson{ 737100979Srwatson 738100979Srwatson /* Certain decision-making errors take top priority. */ 739100979Srwatson if (error1 == EDEADLK || error2 == EDEADLK) 740100979Srwatson return (EDEADLK); 741100979Srwatson 742100979Srwatson /* Invalid arguments should be reported where possible. */ 743100979Srwatson if (error1 == EINVAL || error2 == EINVAL) 744100979Srwatson return (EINVAL); 745100979Srwatson 746100979Srwatson /* Precedence goes to "visibility", with both process and file. */ 747100979Srwatson if (error1 == ESRCH || error2 == ESRCH) 748100979Srwatson return (ESRCH); 749100979Srwatson 750100979Srwatson if (error1 == ENOENT || error2 == ENOENT) 751100979Srwatson return (ENOENT); 752100979Srwatson 753100979Srwatson /* Precedence goes to DAC/MAC protections. */ 754100979Srwatson if (error1 == EACCES || error2 == EACCES) 755100979Srwatson return (EACCES); 756100979Srwatson 757100979Srwatson /* Precedence goes to privilege. */ 758100979Srwatson if (error1 == EPERM || error2 == EPERM) 759100979Srwatson return (EPERM); 760100979Srwatson 761100979Srwatson /* Precedence goes to error over success; otherwise, arbitrary. */ 762100979Srwatson if (error1 != 0) 763100979Srwatson return (error1); 764100979Srwatson return (error2); 765100979Srwatson} 766100979Srwatson 767113482Srwatsonstatic struct label * 768113482Srwatsonmbuf_to_label(struct mbuf *mbuf) 769113482Srwatson{ 770113487Srwatson struct m_tag *tag; 771113482Srwatson struct label *label; 772113482Srwatson 773113487Srwatson tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL); 774113487Srwatson label = (struct label *)(tag+1); 775113482Srwatson 776113482Srwatson return (label); 777113482Srwatson} 778113482Srwatson 779104521Srwatsonstatic void 780104521Srwatsonmac_init_label(struct label *label) 781104521Srwatson{ 782104521Srwatson 783104521Srwatson bzero(label, sizeof(*label)); 784104521Srwatson label->l_flags = MAC_FLAG_INITIALIZED; 785104521Srwatson} 786104521Srwatson 787104521Srwatsonstatic void 788104521Srwatsonmac_destroy_label(struct label *label) 789104521Srwatson{ 790104521Srwatson 791104521Srwatson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 792104521Srwatson ("destroying uninitialized label")); 793104521Srwatson 794104521Srwatson bzero(label, sizeof(*label)); 795104521Srwatson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 796104521Srwatson} 797104521Srwatson 798100979Srwatsonvoid 799104527Srwatsonmac_init_bpfdesc(struct bpf_d *bpf_d) 800104521Srwatson{ 801104521Srwatson 802104527Srwatson mac_init_label(&bpf_d->bd_label); 803104527Srwatson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 804104521Srwatson#ifdef MAC_DEBUG 805104527Srwatson atomic_add_int(&nmacbpfdescs, 1); 806104521Srwatson#endif 807104521Srwatson} 808104521Srwatson 809105694Srwatsonstatic void 810105694Srwatsonmac_init_cred_label(struct label *label) 811104521Srwatson{ 812104521Srwatson 813105694Srwatson mac_init_label(label); 814105694Srwatson MAC_PERFORM(init_cred_label, label); 815104521Srwatson#ifdef MAC_DEBUG 816104521Srwatson atomic_add_int(&nmaccreds, 1); 817104521Srwatson#endif 818104521Srwatson} 819104521Srwatson 820104521Srwatsonvoid 821105694Srwatsonmac_init_cred(struct ucred *cred) 822105694Srwatson{ 823105694Srwatson 824105694Srwatson mac_init_cred_label(&cred->cr_label); 825105694Srwatson} 826105694Srwatson 827105694Srwatsonvoid 828104527Srwatsonmac_init_devfsdirent(struct devfs_dirent *de) 829104521Srwatson{ 830104521Srwatson 831104527Srwatson mac_init_label(&de->de_label); 832104527Srwatson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 833104521Srwatson#ifdef MAC_DEBUG 834104527Srwatson atomic_add_int(&nmacdevfsdirents, 1); 835104521Srwatson#endif 836104521Srwatson} 837104521Srwatson 838105694Srwatsonstatic void 839105694Srwatsonmac_init_ifnet_label(struct label *label) 840104521Srwatson{ 841104521Srwatson 842105694Srwatson mac_init_label(label); 843105694Srwatson MAC_PERFORM(init_ifnet_label, label); 844104521Srwatson#ifdef MAC_DEBUG 845104521Srwatson atomic_add_int(&nmacifnets, 1); 846104521Srwatson#endif 847104521Srwatson} 848104521Srwatson 849104521Srwatsonvoid 850105694Srwatsonmac_init_ifnet(struct ifnet *ifp) 851105694Srwatson{ 852105694Srwatson 853105694Srwatson mac_init_ifnet_label(&ifp->if_label); 854105694Srwatson} 855105694Srwatson 856112675Srwatsonint 857112675Srwatsonmac_init_ipq(struct ipq *ipq, int flag) 858104521Srwatson{ 859112675Srwatson int error; 860104521Srwatson 861104527Srwatson mac_init_label(&ipq->ipq_label); 862112675Srwatson 863112675Srwatson MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag); 864112675Srwatson if (error) { 865112675Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 866112675Srwatson mac_destroy_label(&ipq->ipq_label); 867112675Srwatson } 868104521Srwatson#ifdef MAC_DEBUG 869112675Srwatson if (error == 0) 870112675Srwatson atomic_add_int(&nmacipqs, 1); 871104521Srwatson#endif 872112675Srwatson return (error); 873104521Srwatson} 874104521Srwatson 875104527Srwatsonint 876113487Srwatsonmac_init_mbuf_tag(struct m_tag *tag, int flag) 877104527Srwatson{ 878113487Srwatson struct label *label; 879113526Srwatson int error; 880104528Srwatson 881113487Srwatson label = (struct label *) (tag + 1); 882113487Srwatson mac_init_label(label); 883104527Srwatson 884113526Srwatson MAC_CHECK(init_mbuf_label, label, flag); 885104528Srwatson if (error) { 886113487Srwatson MAC_PERFORM(destroy_mbuf_label, label); 887113487Srwatson mac_destroy_label(label); 888104528Srwatson } 889104527Srwatson#ifdef MAC_DEBUG 890104528Srwatson if (error == 0) 891104528Srwatson atomic_add_int(&nmacmbufs, 1); 892104527Srwatson#endif 893104528Srwatson return (error); 894104527Srwatson} 895104527Srwatson 896113487Srwatsonint 897113487Srwatsonmac_init_mbuf(struct mbuf *m, int flag) 898113487Srwatson{ 899113487Srwatson struct m_tag *tag; 900113487Srwatson int error; 901113487Srwatson 902113487Srwatson M_ASSERTPKTHDR(m); 903113487Srwatson 904113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 905113487Srwatson /* 906113487Srwatson * Don't reserve space for labels on mbufs unless we have a policy 907113487Srwatson * that uses the labels. 908113487Srwatson */ 909113487Srwatson if (mac_labelmbufs) { 910113487Srwatson#endif 911113487Srwatson tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 912113487Srwatson flag); 913113487Srwatson if (tag == NULL) 914113487Srwatson return (ENOMEM); 915113487Srwatson error = mac_init_mbuf_tag(tag, flag); 916113487Srwatson if (error) { 917113487Srwatson m_tag_free(tag); 918113487Srwatson return (error); 919113487Srwatson } 920113487Srwatson m_tag_prepend(m, tag); 921113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 922113487Srwatson } 923113487Srwatson#endif 924113487Srwatson return (0); 925113487Srwatson} 926113487Srwatson 927104521Srwatsonvoid 928104527Srwatsonmac_init_mount(struct mount *mp) 929104521Srwatson{ 930104521Srwatson 931104527Srwatson mac_init_label(&mp->mnt_mntlabel); 932104527Srwatson mac_init_label(&mp->mnt_fslabel); 933104527Srwatson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 934104527Srwatson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 935104521Srwatson#ifdef MAC_DEBUG 936104527Srwatson atomic_add_int(&nmacmounts, 1); 937104521Srwatson#endif 938104521Srwatson} 939104521Srwatson 940105694Srwatsonstatic void 941105694Srwatsonmac_init_pipe_label(struct label *label) 942105694Srwatson{ 943105694Srwatson 944105694Srwatson mac_init_label(label); 945105694Srwatson MAC_PERFORM(init_pipe_label, label); 946105694Srwatson#ifdef MAC_DEBUG 947105694Srwatson atomic_add_int(&nmacpipes, 1); 948105694Srwatson#endif 949105694Srwatson} 950105694Srwatson 951104521Srwatsonvoid 952104527Srwatsonmac_init_pipe(struct pipe *pipe) 953104521Srwatson{ 954104527Srwatson struct label *label; 955104521Srwatson 956111119Simp label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 957104527Srwatson pipe->pipe_label = label; 958104527Srwatson pipe->pipe_peer->pipe_label = label; 959105694Srwatson mac_init_pipe_label(label); 960104521Srwatson} 961104521Srwatson 962107105Srwatsonvoid 963107105Srwatsonmac_init_proc(struct proc *p) 964107105Srwatson{ 965107105Srwatson 966107105Srwatson mac_init_label(&p->p_label); 967107105Srwatson MAC_PERFORM(init_proc_label, &p->p_label); 968107105Srwatson#ifdef MAC_DEBUG 969107105Srwatson atomic_add_int(&nmacprocs, 1); 970107105Srwatson#endif 971107105Srwatson} 972107105Srwatson 973104541Srwatsonstatic int 974104541Srwatsonmac_init_socket_label(struct label *label, int flag) 975104521Srwatson{ 976104541Srwatson int error; 977104521Srwatson 978104541Srwatson mac_init_label(label); 979104541Srwatson 980104541Srwatson MAC_CHECK(init_socket_label, label, flag); 981104541Srwatson if (error) { 982104541Srwatson MAC_PERFORM(destroy_socket_label, label); 983104541Srwatson mac_destroy_label(label); 984104541Srwatson } 985104541Srwatson 986104521Srwatson#ifdef MAC_DEBUG 987104541Srwatson if (error == 0) 988104541Srwatson atomic_add_int(&nmacsockets, 1); 989104521Srwatson#endif 990104541Srwatson 991104541Srwatson return (error); 992104521Srwatson} 993104521Srwatson 994104541Srwatsonstatic int 995104541Srwatsonmac_init_socket_peer_label(struct label *label, int flag) 996104541Srwatson{ 997104541Srwatson int error; 998104541Srwatson 999104541Srwatson mac_init_label(label); 1000104541Srwatson 1001104541Srwatson MAC_CHECK(init_socket_peer_label, label, flag); 1002104541Srwatson if (error) { 1003104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1004104541Srwatson mac_destroy_label(label); 1005104541Srwatson } 1006104541Srwatson 1007104541Srwatson return (error); 1008104541Srwatson} 1009104541Srwatson 1010104541Srwatsonint 1011104541Srwatsonmac_init_socket(struct socket *socket, int flag) 1012104541Srwatson{ 1013104541Srwatson int error; 1014104541Srwatson 1015104541Srwatson error = mac_init_socket_label(&socket->so_label, flag); 1016104541Srwatson if (error) 1017104541Srwatson return (error); 1018104541Srwatson 1019104541Srwatson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 1020104541Srwatson if (error) 1021104541Srwatson mac_destroy_socket_label(&socket->so_label); 1022104541Srwatson 1023104541Srwatson return (error); 1024104541Srwatson} 1025104541Srwatson 1026105988Srwatsonvoid 1027105694Srwatsonmac_init_vnode_label(struct label *label) 1028104521Srwatson{ 1029104521Srwatson 1030104527Srwatson mac_init_label(label); 1031105694Srwatson MAC_PERFORM(init_vnode_label, label); 1032104521Srwatson#ifdef MAC_DEBUG 1033105694Srwatson atomic_add_int(&nmacvnodes, 1); 1034104521Srwatson#endif 1035104521Srwatson} 1036104521Srwatson 1037104521Srwatsonvoid 1038104527Srwatsonmac_init_vnode(struct vnode *vp) 1039104521Srwatson{ 1040104521Srwatson 1041105694Srwatson mac_init_vnode_label(&vp->v_label); 1042104521Srwatson} 1043104521Srwatson 1044104521Srwatsonvoid 1045104527Srwatsonmac_destroy_bpfdesc(struct bpf_d *bpf_d) 1046104521Srwatson{ 1047104521Srwatson 1048104527Srwatson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 1049104527Srwatson mac_destroy_label(&bpf_d->bd_label); 1050104521Srwatson#ifdef MAC_DEBUG 1051104527Srwatson atomic_subtract_int(&nmacbpfdescs, 1); 1052104521Srwatson#endif 1053104521Srwatson} 1054104521Srwatson 1055105694Srwatsonstatic void 1056105694Srwatsonmac_destroy_cred_label(struct label *label) 1057104521Srwatson{ 1058104521Srwatson 1059105694Srwatson MAC_PERFORM(destroy_cred_label, label); 1060105694Srwatson mac_destroy_label(label); 1061104521Srwatson#ifdef MAC_DEBUG 1062104527Srwatson atomic_subtract_int(&nmaccreds, 1); 1063104521Srwatson#endif 1064104521Srwatson} 1065104521Srwatson 1066104521Srwatsonvoid 1067105694Srwatsonmac_destroy_cred(struct ucred *cred) 1068105694Srwatson{ 1069105694Srwatson 1070105694Srwatson mac_destroy_cred_label(&cred->cr_label); 1071105694Srwatson} 1072105694Srwatson 1073105694Srwatsonvoid 1074104527Srwatsonmac_destroy_devfsdirent(struct devfs_dirent *de) 1075104521Srwatson{ 1076104521Srwatson 1077104527Srwatson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 1078104527Srwatson mac_destroy_label(&de->de_label); 1079104521Srwatson#ifdef MAC_DEBUG 1080104527Srwatson atomic_subtract_int(&nmacdevfsdirents, 1); 1081104521Srwatson#endif 1082104521Srwatson} 1083104521Srwatson 1084105694Srwatsonstatic void 1085105694Srwatsonmac_destroy_ifnet_label(struct label *label) 1086104521Srwatson{ 1087104521Srwatson 1088105694Srwatson MAC_PERFORM(destroy_ifnet_label, label); 1089105694Srwatson mac_destroy_label(label); 1090104521Srwatson#ifdef MAC_DEBUG 1091104527Srwatson atomic_subtract_int(&nmacifnets, 1); 1092104521Srwatson#endif 1093104521Srwatson} 1094104521Srwatson 1095104521Srwatsonvoid 1096105694Srwatsonmac_destroy_ifnet(struct ifnet *ifp) 1097105694Srwatson{ 1098105694Srwatson 1099105694Srwatson mac_destroy_ifnet_label(&ifp->if_label); 1100105694Srwatson} 1101105694Srwatson 1102105694Srwatsonvoid 1103104527Srwatsonmac_destroy_ipq(struct ipq *ipq) 1104104521Srwatson{ 1105104521Srwatson 1106104527Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1107104527Srwatson mac_destroy_label(&ipq->ipq_label); 1108104521Srwatson#ifdef MAC_DEBUG 1109104527Srwatson atomic_subtract_int(&nmacipqs, 1); 1110104521Srwatson#endif 1111104521Srwatson} 1112104521Srwatson 1113104527Srwatsonvoid 1114113487Srwatsonmac_destroy_mbuf_tag(struct m_tag *tag) 1115104521Srwatson{ 1116113487Srwatson struct label *label; 1117104521Srwatson 1118113487Srwatson label = (struct label *)(tag+1); 1119113487Srwatson 1120113487Srwatson MAC_PERFORM(destroy_mbuf_label, label); 1121113487Srwatson mac_destroy_label(label); 1122104521Srwatson#ifdef MAC_DEBUG 1123104527Srwatson atomic_subtract_int(&nmacmbufs, 1); 1124104521Srwatson#endif 1125104521Srwatson} 1126104521Srwatson 1127104527Srwatsonvoid 1128104527Srwatsonmac_destroy_mount(struct mount *mp) 1129104521Srwatson{ 1130104521Srwatson 1131104527Srwatson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1132104527Srwatson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1133104527Srwatson mac_destroy_label(&mp->mnt_fslabel); 1134104527Srwatson mac_destroy_label(&mp->mnt_mntlabel); 1135104521Srwatson#ifdef MAC_DEBUG 1136104527Srwatson atomic_subtract_int(&nmacmounts, 1); 1137104521Srwatson#endif 1138104521Srwatson} 1139104521Srwatson 1140105694Srwatsonstatic void 1141105694Srwatsonmac_destroy_pipe_label(struct label *label) 1142104521Srwatson{ 1143104521Srwatson 1144105694Srwatson MAC_PERFORM(destroy_pipe_label, label); 1145105694Srwatson mac_destroy_label(label); 1146104521Srwatson#ifdef MAC_DEBUG 1147104527Srwatson atomic_subtract_int(&nmacpipes, 1); 1148104521Srwatson#endif 1149104521Srwatson} 1150104521Srwatson 1151105694Srwatsonvoid 1152105694Srwatsonmac_destroy_pipe(struct pipe *pipe) 1153105694Srwatson{ 1154105694Srwatson 1155105694Srwatson mac_destroy_pipe_label(pipe->pipe_label); 1156105694Srwatson free(pipe->pipe_label, M_MACPIPELABEL); 1157105694Srwatson} 1158105694Srwatson 1159107105Srwatsonvoid 1160107105Srwatsonmac_destroy_proc(struct proc *p) 1161107105Srwatson{ 1162107105Srwatson 1163107105Srwatson MAC_PERFORM(destroy_proc_label, &p->p_label); 1164107105Srwatson mac_destroy_label(&p->p_label); 1165107105Srwatson#ifdef MAC_DEBUG 1166107105Srwatson atomic_subtract_int(&nmacprocs, 1); 1167107105Srwatson#endif 1168107105Srwatson} 1169107105Srwatson 1170104541Srwatsonstatic void 1171104541Srwatsonmac_destroy_socket_label(struct label *label) 1172104521Srwatson{ 1173104521Srwatson 1174104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1175104541Srwatson mac_destroy_label(label); 1176104521Srwatson#ifdef MAC_DEBUG 1177104527Srwatson atomic_subtract_int(&nmacsockets, 1); 1178104521Srwatson#endif 1179104521Srwatson} 1180104521Srwatson 1181104527Srwatsonstatic void 1182104541Srwatsonmac_destroy_socket_peer_label(struct label *label) 1183104541Srwatson{ 1184104541Srwatson 1185104541Srwatson MAC_PERFORM(destroy_socket_peer_label, label); 1186104541Srwatson mac_destroy_label(label); 1187104541Srwatson} 1188104541Srwatson 1189104541Srwatsonvoid 1190104541Srwatsonmac_destroy_socket(struct socket *socket) 1191104541Srwatson{ 1192104541Srwatson 1193104541Srwatson mac_destroy_socket_label(&socket->so_label); 1194104541Srwatson mac_destroy_socket_peer_label(&socket->so_peerlabel); 1195104541Srwatson} 1196104541Srwatson 1197105988Srwatsonvoid 1198105694Srwatsonmac_destroy_vnode_label(struct label *label) 1199104521Srwatson{ 1200104521Srwatson 1201105694Srwatson MAC_PERFORM(destroy_vnode_label, label); 1202104527Srwatson mac_destroy_label(label); 1203104521Srwatson#ifdef MAC_DEBUG 1204105694Srwatson atomic_subtract_int(&nmacvnodes, 1); 1205104521Srwatson#endif 1206104521Srwatson} 1207104521Srwatson 1208104521Srwatsonvoid 1209104527Srwatsonmac_destroy_vnode(struct vnode *vp) 1210104521Srwatson{ 1211104521Srwatson 1212105694Srwatson mac_destroy_vnode_label(&vp->v_label); 1213104521Srwatson} 1214104521Srwatson 1215113487Srwatsonvoid 1216113487Srwatsonmac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 1217113487Srwatson{ 1218113487Srwatson struct label *src_label, *dest_label; 1219113487Srwatson 1220113487Srwatson src_label = (struct label *)(src+1); 1221113487Srwatson dest_label = (struct label *)(dest+1); 1222113487Srwatson 1223113487Srwatson /* 1224113487Srwatson * mac_init_mbuf_tag() is called on the target tag in 1225113487Srwatson * m_tag_copy(), so we don't need to call it here. 1226113487Srwatson */ 1227113487Srwatson MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 1228113487Srwatson} 1229113487Srwatson 1230105694Srwatsonstatic void 1231105694Srwatsonmac_copy_pipe_label(struct label *src, struct label *dest) 1232105694Srwatson{ 1233105694Srwatson 1234105694Srwatson MAC_PERFORM(copy_pipe_label, src, dest); 1235105694Srwatson} 1236105694Srwatson 1237105988Srwatsonvoid 1238105694Srwatsonmac_copy_vnode_label(struct label *src, struct label *dest) 1239105694Srwatson{ 1240105694Srwatson 1241105694Srwatson MAC_PERFORM(copy_vnode_label, src, dest); 1242105694Srwatson} 1243105694Srwatson 1244104522Srwatsonstatic int 1245105694Srwatsonmac_check_structmac_consistent(struct mac *mac) 1246104522Srwatson{ 1247105694Srwatson 1248105694Srwatson if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1249105694Srwatson return (EINVAL); 1250105694Srwatson 1251105694Srwatson return (0); 1252105694Srwatson} 1253105694Srwatson 1254105694Srwatsonstatic int 1255105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements, 1256105694Srwatson char *outbuf, size_t outbuflen, int flags) 1257105694Srwatson{ 1258104522Srwatson int error; 1259104522Srwatson 1260105694Srwatson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1261104522Srwatson 1262104522Srwatson return (error); 1263104522Srwatson} 1264104522Srwatson 1265104522Srwatsonstatic int 1266105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements, 1267105694Srwatson char *outbuf, size_t outbuflen, int flags) 1268104522Srwatson{ 1269104522Srwatson int error; 1270104522Srwatson 1271105694Srwatson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1272104522Srwatson 1273104522Srwatson return (error); 1274104522Srwatson} 1275104522Srwatson 1276105694Srwatsonstatic int 1277105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements, 1278105694Srwatson char *outbuf, size_t outbuflen, int flags) 1279105694Srwatson{ 1280105694Srwatson int error; 1281105694Srwatson 1282105694Srwatson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1283105694Srwatson 1284105694Srwatson return (error); 1285105694Srwatson} 1286105694Srwatson 1287105694Srwatsonstatic int 1288105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements, 1289105694Srwatson char *outbuf, size_t outbuflen, int flags) 1290105694Srwatson{ 1291105694Srwatson int error; 1292105694Srwatson 1293105694Srwatson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1294105694Srwatson 1295105694Srwatson return (error); 1296105694Srwatson} 1297105694Srwatson 1298105694Srwatsonstatic int 1299105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements, 1300105694Srwatson char *outbuf, size_t outbuflen, int flags) 1301105694Srwatson{ 1302105694Srwatson int error; 1303105694Srwatson 1304105694Srwatson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1305105694Srwatson 1306105694Srwatson return (error); 1307105694Srwatson} 1308105694Srwatson 1309105694Srwatsonstatic int 1310105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements, 1311105694Srwatson char *outbuf, size_t outbuflen, int flags) 1312105694Srwatson{ 1313105694Srwatson int error; 1314105694Srwatson 1315105694Srwatson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1316105694Srwatson 1317105694Srwatson return (error); 1318105694Srwatson} 1319105694Srwatson 1320105694Srwatsonstatic int 1321105694Srwatsonmac_internalize_cred_label(struct label *label, char *string) 1322105694Srwatson{ 1323105694Srwatson int error; 1324105694Srwatson 1325105694Srwatson MAC_INTERNALIZE(cred_label, label, string); 1326105694Srwatson 1327105694Srwatson return (error); 1328105694Srwatson} 1329105694Srwatson 1330105694Srwatsonstatic int 1331105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string) 1332105694Srwatson{ 1333105694Srwatson int error; 1334105694Srwatson 1335105694Srwatson MAC_INTERNALIZE(ifnet_label, label, string); 1336105694Srwatson 1337105694Srwatson return (error); 1338105694Srwatson} 1339105694Srwatson 1340105694Srwatsonstatic int 1341105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string) 1342105694Srwatson{ 1343105694Srwatson int error; 1344105694Srwatson 1345105694Srwatson MAC_INTERNALIZE(pipe_label, label, string); 1346105694Srwatson 1347105694Srwatson return (error); 1348105694Srwatson} 1349105694Srwatson 1350105694Srwatsonstatic int 1351105694Srwatsonmac_internalize_socket_label(struct label *label, char *string) 1352105694Srwatson{ 1353105694Srwatson int error; 1354105694Srwatson 1355105694Srwatson MAC_INTERNALIZE(socket_label, label, string); 1356105694Srwatson 1357105694Srwatson return (error); 1358105694Srwatson} 1359105694Srwatson 1360105694Srwatsonstatic int 1361105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string) 1362105694Srwatson{ 1363105694Srwatson int error; 1364105694Srwatson 1365105694Srwatson MAC_INTERNALIZE(vnode_label, label, string); 1366105694Srwatson 1367105694Srwatson return (error); 1368105694Srwatson} 1369105694Srwatson 1370104522Srwatson/* 1371104522Srwatson * Initialize MAC label for the first kernel process, from which other 1372104522Srwatson * kernel processes and threads are spawned. 1373104522Srwatson */ 1374104521Srwatsonvoid 1375104522Srwatsonmac_create_proc0(struct ucred *cred) 1376104522Srwatson{ 1377104522Srwatson 1378104522Srwatson MAC_PERFORM(create_proc0, cred); 1379104522Srwatson} 1380104522Srwatson 1381104522Srwatson/* 1382104522Srwatson * Initialize MAC label for the first userland process, from which other 1383104522Srwatson * userland processes and threads are spawned. 1384104522Srwatson */ 1385104522Srwatsonvoid 1386104522Srwatsonmac_create_proc1(struct ucred *cred) 1387104522Srwatson{ 1388104522Srwatson 1389104522Srwatson MAC_PERFORM(create_proc1, cred); 1390104522Srwatson} 1391104522Srwatson 1392104522Srwatsonvoid 1393104522Srwatsonmac_thread_userret(struct thread *td) 1394104522Srwatson{ 1395104522Srwatson 1396104522Srwatson MAC_PERFORM(thread_userret, td); 1397104522Srwatson} 1398104522Srwatson 1399104522Srwatson/* 1400104522Srwatson * When a new process is created, its label must be initialized. Generally, 1401104522Srwatson * this involves inheritence from the parent process, modulo possible 1402104522Srwatson * deltas. This function allows that processing to take place. 1403104522Srwatson */ 1404104522Srwatsonvoid 1405104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1406104522Srwatson{ 1407104522Srwatson 1408104522Srwatson MAC_PERFORM(create_cred, parent_cred, child_cred); 1409104522Srwatson} 1410104522Srwatson 1411104522Srwatsonvoid 1412107698Srwatsonmac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 1413107698Srwatson struct vnode *vp) 1414100979Srwatson{ 1415100979Srwatson 1416107698Srwatson MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp, 1417107698Srwatson &vp->v_label); 1418100979Srwatson} 1419100979Srwatson 1420100979Srwatsonvoid 1421105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1422105988Srwatson struct vnode *vp) 1423100979Srwatson{ 1424100979Srwatson 1425105988Srwatson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1426105988Srwatson &de->de_label, vp, &vp->v_label); 1427100979Srwatson} 1428100979Srwatson 1429105988Srwatsonint 1430105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1431100979Srwatson{ 1432100979Srwatson int error; 1433100979Srwatson 1434105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1435100979Srwatson 1436105988Srwatson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1437105988Srwatson &vp->v_label); 1438100979Srwatson 1439100979Srwatson return (error); 1440100979Srwatson} 1441100979Srwatson 1442100979Srwatsonvoid 1443105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1444100979Srwatson{ 1445100979Srwatson 1446105988Srwatson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1447105988Srwatson &vp->v_label); 1448100979Srwatson} 1449100979Srwatson 1450100979Srwatsonint 1451105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1452105988Srwatson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1453100979Srwatson{ 1454105988Srwatson int error; 1455100979Srwatson 1456105988Srwatson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1457105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1458100979Srwatson 1459105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1460105988Srwatson if (error == EOPNOTSUPP) { 1461105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1462105988Srwatson if (ea_warn_once == 0) { 1463105988Srwatson printf("Warning: transactions not supported " 1464105988Srwatson "in EA write.\n"); 1465105988Srwatson ea_warn_once = 1; 1466105988Srwatson } 1467105988Srwatson } else if (error) 1468100979Srwatson return (error); 1469100979Srwatson 1470105988Srwatson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1471105988Srwatson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1472100979Srwatson 1473105988Srwatson if (error) { 1474105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1475100979Srwatson return (error); 1476100979Srwatson } 1477100979Srwatson 1478105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1479100979Srwatson 1480105988Srwatson if (error == EOPNOTSUPP) 1481105988Srwatson error = 0; /* XXX */ 1482100979Srwatson 1483100979Srwatson return (error); 1484100979Srwatson} 1485100979Srwatson 1486100979Srwatsonstatic int 1487105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1488105988Srwatson struct label *intlabel) 1489100979Srwatson{ 1490100979Srwatson int error; 1491100979Srwatson 1492105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1493100979Srwatson 1494105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1495105988Srwatson if (error == EOPNOTSUPP) { 1496105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1497105988Srwatson if (ea_warn_once == 0) { 1498105988Srwatson printf("Warning: transactions not supported " 1499105988Srwatson "in EA write.\n"); 1500105988Srwatson ea_warn_once = 1; 1501105988Srwatson } 1502105988Srwatson } else if (error) 1503105988Srwatson return (error); 1504100979Srwatson 1505105988Srwatson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1506100979Srwatson 1507105988Srwatson if (error) { 1508105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1509100979Srwatson return (error); 1510100979Srwatson } 1511100979Srwatson 1512105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1513100979Srwatson 1514105988Srwatson if (error == EOPNOTSUPP) 1515105988Srwatson error = 0; /* XXX */ 1516100979Srwatson 1517105988Srwatson return (error); 1518100979Srwatson} 1519100979Srwatson 1520106468Srwatsonint 1521106468Srwatsonmac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1522106468Srwatson struct label *execlabelstorage) 1523106468Srwatson{ 1524106468Srwatson struct mac mac; 1525106468Srwatson char *buffer; 1526106468Srwatson int error; 1527106468Srwatson 1528106468Srwatson if (mac_p == NULL) 1529106468Srwatson return (0); 1530106468Srwatson 1531106468Srwatson error = copyin(mac_p, &mac, sizeof(mac)); 1532106468Srwatson if (error) 1533106468Srwatson return (error); 1534106468Srwatson 1535106468Srwatson error = mac_check_structmac_consistent(&mac); 1536106468Srwatson if (error) 1537106468Srwatson return (error); 1538106468Srwatson 1539111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1540106468Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1541106468Srwatson if (error) { 1542106468Srwatson free(buffer, M_MACTEMP); 1543106468Srwatson return (error); 1544106468Srwatson } 1545106468Srwatson 1546106468Srwatson mac_init_cred_label(execlabelstorage); 1547106468Srwatson error = mac_internalize_cred_label(execlabelstorage, buffer); 1548106468Srwatson free(buffer, M_MACTEMP); 1549106468Srwatson if (error) { 1550106468Srwatson mac_destroy_cred_label(execlabelstorage); 1551106468Srwatson return (error); 1552106468Srwatson } 1553106468Srwatson imgp->execlabel = execlabelstorage; 1554106468Srwatson return (0); 1555106468Srwatson} 1556106468Srwatson 1557100979Srwatsonvoid 1558106468Srwatsonmac_execve_exit(struct image_params *imgp) 1559100979Srwatson{ 1560106468Srwatson if (imgp->execlabel != NULL) 1561106468Srwatson mac_destroy_cred_label(imgp->execlabel); 1562106468Srwatson} 1563100979Srwatson 1564106468Srwatsonvoid 1565106468Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1566106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1567106468Srwatson{ 1568106468Srwatson 1569100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1570100979Srwatson 1571106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1572106460Srwatson return; 1573106460Srwatson 1574106468Srwatson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1575106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1576100979Srwatson} 1577100979Srwatson 1578100979Srwatsonint 1579106468Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp, 1580106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1581100979Srwatson{ 1582105988Srwatson int result; 1583100979Srwatson 1584106460Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1585106460Srwatson 1586106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1587106460Srwatson return (0); 1588106460Srwatson 1589100979Srwatson result = 0; 1590106468Srwatson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1591106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1592100979Srwatson 1593100979Srwatson return (result); 1594100979Srwatson} 1595100979Srwatson 1596100979Srwatsonint 1597106212Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1598100979Srwatson{ 1599100979Srwatson int error; 1600100979Srwatson 1601100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1602100979Srwatson 1603100979Srwatson if (!mac_enforce_fs) 1604100979Srwatson return (0); 1605100979Srwatson 1606106212Srwatson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1607100979Srwatson return (error); 1608100979Srwatson} 1609100979Srwatson 1610100979Srwatsonint 1611100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1612100979Srwatson{ 1613100979Srwatson int error; 1614100979Srwatson 1615100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1616100979Srwatson 1617100979Srwatson if (!mac_enforce_fs) 1618100979Srwatson return (0); 1619100979Srwatson 1620100979Srwatson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1621100979Srwatson return (error); 1622100979Srwatson} 1623100979Srwatson 1624100979Srwatsonint 1625100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1626100979Srwatson{ 1627100979Srwatson int error; 1628100979Srwatson 1629100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1630100979Srwatson 1631100979Srwatson if (!mac_enforce_fs) 1632100979Srwatson return (0); 1633100979Srwatson 1634100979Srwatson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1635100979Srwatson return (error); 1636100979Srwatson} 1637100979Srwatson 1638100979Srwatsonint 1639100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1640100979Srwatson struct componentname *cnp, struct vattr *vap) 1641100979Srwatson{ 1642100979Srwatson int error; 1643100979Srwatson 1644100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1645100979Srwatson 1646100979Srwatson if (!mac_enforce_fs) 1647100979Srwatson return (0); 1648100979Srwatson 1649100979Srwatson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1650100979Srwatson return (error); 1651100979Srwatson} 1652100979Srwatson 1653100979Srwatsonint 1654100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1655100979Srwatson struct componentname *cnp) 1656100979Srwatson{ 1657100979Srwatson int error; 1658100979Srwatson 1659100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1660100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1661100979Srwatson 1662100979Srwatson if (!mac_enforce_fs) 1663100979Srwatson return (0); 1664100979Srwatson 1665100979Srwatson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1666100979Srwatson &vp->v_label, cnp); 1667100979Srwatson return (error); 1668100979Srwatson} 1669100979Srwatson 1670100979Srwatsonint 1671100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1672100979Srwatson acl_type_t type) 1673100979Srwatson{ 1674100979Srwatson int error; 1675100979Srwatson 1676100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1677100979Srwatson 1678100979Srwatson if (!mac_enforce_fs) 1679100979Srwatson return (0); 1680100979Srwatson 1681100979Srwatson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1682100979Srwatson return (error); 1683100979Srwatson} 1684100979Srwatson 1685100979Srwatsonint 1686106468Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1687106468Srwatson struct image_params *imgp) 1688100979Srwatson{ 1689100979Srwatson int error; 1690100979Srwatson 1691102102Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1692102102Srwatson 1693100979Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1694100979Srwatson return (0); 1695100979Srwatson 1696106647Srwatson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1697106647Srwatson imgp->execlabel); 1698100979Srwatson 1699100979Srwatson return (error); 1700100979Srwatson} 1701100979Srwatson 1702100979Srwatsonint 1703100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1704100979Srwatson{ 1705100979Srwatson int error; 1706100979Srwatson 1707100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1708100979Srwatson 1709100979Srwatson if (!mac_enforce_fs) 1710100979Srwatson return (0); 1711100979Srwatson 1712100979Srwatson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1713100979Srwatson return (error); 1714100979Srwatson} 1715100979Srwatson 1716100979Srwatsonint 1717100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1718100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1719100979Srwatson{ 1720100979Srwatson int error; 1721100979Srwatson 1722100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1723100979Srwatson 1724100979Srwatson if (!mac_enforce_fs) 1725100979Srwatson return (0); 1726100979Srwatson 1727100979Srwatson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1728100979Srwatson attrnamespace, name, uio); 1729100979Srwatson return (error); 1730100979Srwatson} 1731100979Srwatson 1732100979Srwatsonint 1733104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1734104529Srwatson struct vnode *vp, struct componentname *cnp) 1735104529Srwatson{ 1736104529Srwatson int error; 1737104529Srwatson 1738104529Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1739104529Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1740104529Srwatson 1741104529Srwatson if (!mac_enforce_fs) 1742104529Srwatson return (0); 1743104529Srwatson 1744104529Srwatson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1745104529Srwatson &vp->v_label, cnp); 1746104529Srwatson return (error); 1747104529Srwatson} 1748104529Srwatson 1749104529Srwatsonint 1750100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1751100979Srwatson struct componentname *cnp) 1752100979Srwatson{ 1753100979Srwatson int error; 1754100979Srwatson 1755100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1756100979Srwatson 1757100979Srwatson if (!mac_enforce_fs) 1758100979Srwatson return (0); 1759100979Srwatson 1760100979Srwatson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1761100979Srwatson return (error); 1762100979Srwatson} 1763100979Srwatson 1764104546Srwatsonint 1765104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1766100979Srwatson{ 1767104546Srwatson int error; 1768100979Srwatson 1769104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1770103514Srwatson 1771104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1772104546Srwatson return (0); 1773104546Srwatson 1774104546Srwatson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1775104546Srwatson return (error); 1776100979Srwatson} 1777100979Srwatson 1778104546Srwatsonvoid 1779104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1780104546Srwatson{ 1781104546Srwatson int result = *prot; 1782104546Srwatson 1783104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1784104546Srwatson 1785104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1786104546Srwatson return; 1787104546Srwatson 1788104546Srwatson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1789104546Srwatson &result); 1790104546Srwatson 1791104546Srwatson *prot = result; 1792104546Srwatson} 1793104546Srwatson 1794100979Srwatsonint 1795104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1796104546Srwatson{ 1797104546Srwatson int error; 1798104546Srwatson 1799104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1800104546Srwatson 1801104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1802104546Srwatson return (0); 1803104546Srwatson 1804104546Srwatson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1805104546Srwatson return (error); 1806104546Srwatson} 1807104546Srwatson 1808104546Srwatsonint 1809106212Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1810100979Srwatson{ 1811100979Srwatson int error; 1812100979Srwatson 1813102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1814102112Srwatson 1815100979Srwatson if (!mac_enforce_fs) 1816100979Srwatson return (0); 1817100979Srwatson 1818102112Srwatson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1819102112Srwatson return (error); 1820102112Srwatson} 1821102112Srwatson 1822102112Srwatsonint 1823102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1824102129Srwatson struct vnode *vp) 1825102112Srwatson{ 1826102112Srwatson int error; 1827102112Srwatson 1828102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1829102112Srwatson 1830102112Srwatson if (!mac_enforce_fs) 1831102112Srwatson return (0); 1832102112Srwatson 1833102129Srwatson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1834102129Srwatson &vp->v_label); 1835100979Srwatson 1836100979Srwatson return (error); 1837100979Srwatson} 1838100979Srwatson 1839100979Srwatsonint 1840102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1841102129Srwatson struct vnode *vp) 1842100979Srwatson{ 1843100979Srwatson int error; 1844100979Srwatson 1845102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1846100979Srwatson 1847100979Srwatson if (!mac_enforce_fs) 1848100979Srwatson return (0); 1849100979Srwatson 1850102129Srwatson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1851102129Srwatson &vp->v_label); 1852102112Srwatson 1853100979Srwatson return (error); 1854100979Srwatson} 1855100979Srwatson 1856100979Srwatsonint 1857100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1858100979Srwatson{ 1859100979Srwatson int error; 1860100979Srwatson 1861100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1862100979Srwatson 1863100979Srwatson if (!mac_enforce_fs) 1864100979Srwatson return (0); 1865100979Srwatson 1866100979Srwatson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1867100979Srwatson return (error); 1868100979Srwatson} 1869100979Srwatson 1870100979Srwatsonint 1871100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1872100979Srwatson{ 1873100979Srwatson int error; 1874100979Srwatson 1875100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1876100979Srwatson 1877100979Srwatson if (!mac_enforce_fs) 1878100979Srwatson return (0); 1879100979Srwatson 1880100979Srwatson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1881100979Srwatson return (error); 1882100979Srwatson} 1883100979Srwatson 1884100979Srwatsonstatic int 1885100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1886100979Srwatson struct label *newlabel) 1887100979Srwatson{ 1888100979Srwatson int error; 1889100979Srwatson 1890100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1891100979Srwatson 1892100979Srwatson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1893100979Srwatson 1894100979Srwatson return (error); 1895100979Srwatson} 1896100979Srwatson 1897100979Srwatsonint 1898100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1899100979Srwatson struct vnode *vp, struct componentname *cnp) 1900100979Srwatson{ 1901100979Srwatson int error; 1902100979Srwatson 1903100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1904100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1905100979Srwatson 1906100979Srwatson if (!mac_enforce_fs) 1907100979Srwatson return (0); 1908100979Srwatson 1909100979Srwatson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1910100979Srwatson &vp->v_label, cnp); 1911100979Srwatson return (error); 1912100979Srwatson} 1913100979Srwatson 1914100979Srwatsonint 1915100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1916100979Srwatson struct vnode *vp, int samedir, struct componentname *cnp) 1917100979Srwatson{ 1918100979Srwatson int error; 1919100979Srwatson 1920100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1921100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1922100979Srwatson 1923100979Srwatson if (!mac_enforce_fs) 1924100979Srwatson return (0); 1925100979Srwatson 1926100979Srwatson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1927100979Srwatson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1928100979Srwatson return (error); 1929100979Srwatson} 1930100979Srwatson 1931100979Srwatsonint 1932100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1933100979Srwatson{ 1934100979Srwatson int error; 1935100979Srwatson 1936100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1937100979Srwatson 1938100979Srwatson if (!mac_enforce_fs) 1939100979Srwatson return (0); 1940100979Srwatson 1941100979Srwatson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1942100979Srwatson return (error); 1943100979Srwatson} 1944100979Srwatson 1945100979Srwatsonint 1946100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1947100979Srwatson struct acl *acl) 1948100979Srwatson{ 1949100979Srwatson int error; 1950100979Srwatson 1951100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1952100979Srwatson 1953100979Srwatson if (!mac_enforce_fs) 1954100979Srwatson return (0); 1955100979Srwatson 1956100979Srwatson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1957100979Srwatson return (error); 1958100979Srwatson} 1959100979Srwatson 1960100979Srwatsonint 1961100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1962100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1963100979Srwatson{ 1964100979Srwatson int error; 1965100979Srwatson 1966100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1967100979Srwatson 1968100979Srwatson if (!mac_enforce_fs) 1969100979Srwatson return (0); 1970100979Srwatson 1971100979Srwatson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1972100979Srwatson attrnamespace, name, uio); 1973100979Srwatson return (error); 1974100979Srwatson} 1975100979Srwatson 1976100979Srwatsonint 1977100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1978100979Srwatson{ 1979100979Srwatson int error; 1980100979Srwatson 1981100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1982100979Srwatson 1983100979Srwatson if (!mac_enforce_fs) 1984100979Srwatson return (0); 1985100979Srwatson 1986100979Srwatson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1987100979Srwatson return (error); 1988100979Srwatson} 1989100979Srwatson 1990100979Srwatsonint 1991100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1992100979Srwatson{ 1993100979Srwatson int error; 1994100979Srwatson 1995100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1996100979Srwatson 1997100979Srwatson if (!mac_enforce_fs) 1998100979Srwatson return (0); 1999100979Srwatson 2000100979Srwatson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 2001100979Srwatson return (error); 2002100979Srwatson} 2003100979Srwatson 2004100979Srwatsonint 2005100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 2006100979Srwatson gid_t gid) 2007100979Srwatson{ 2008100979Srwatson int error; 2009100979Srwatson 2010100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 2011100979Srwatson 2012100979Srwatson if (!mac_enforce_fs) 2013100979Srwatson return (0); 2014100979Srwatson 2015100979Srwatson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 2016100979Srwatson return (error); 2017100979Srwatson} 2018100979Srwatson 2019100979Srwatsonint 2020100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2021100979Srwatson struct timespec atime, struct timespec mtime) 2022100979Srwatson{ 2023100979Srwatson int error; 2024100979Srwatson 2025100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 2026100979Srwatson 2027100979Srwatson if (!mac_enforce_fs) 2028100979Srwatson return (0); 2029100979Srwatson 2030100979Srwatson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 2031100979Srwatson mtime); 2032100979Srwatson return (error); 2033100979Srwatson} 2034100979Srwatson 2035100979Srwatsonint 2036102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2037102129Srwatson struct vnode *vp) 2038100979Srwatson{ 2039100979Srwatson int error; 2040100979Srwatson 2041100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2042100979Srwatson 2043100979Srwatson if (!mac_enforce_fs) 2044100979Srwatson return (0); 2045100979Srwatson 2046102129Srwatson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2047102129Srwatson &vp->v_label); 2048100979Srwatson return (error); 2049100979Srwatson} 2050100979Srwatson 2051102112Srwatsonint 2052102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2053102129Srwatson struct vnode *vp) 2054102112Srwatson{ 2055102112Srwatson int error; 2056102112Srwatson 2057102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2058102112Srwatson 2059102112Srwatson if (!mac_enforce_fs) 2060102112Srwatson return (0); 2061102112Srwatson 2062102129Srwatson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2063102129Srwatson &vp->v_label); 2064102112Srwatson 2065102112Srwatson return (error); 2066102112Srwatson} 2067102112Srwatson 2068100979Srwatson/* 2069100979Srwatson * When relabeling a process, call out to the policies for the maximum 2070100979Srwatson * permission allowed for each object type we know about in its 2071100979Srwatson * memory space, and revoke access (in the least surprising ways we 2072100979Srwatson * know) when necessary. The process lock is not held here. 2073100979Srwatson */ 2074107271Srwatsonvoid 2075100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2076100979Srwatson{ 2077100979Srwatson 2078100979Srwatson /* XXX freeze all other threads */ 2079100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2080100979Srwatson &td->td_proc->p_vmspace->vm_map); 2081100979Srwatson /* XXX allow other threads to continue */ 2082100979Srwatson} 2083100979Srwatson 2084100979Srwatsonstatic __inline const char * 2085100979Srwatsonprot2str(vm_prot_t prot) 2086100979Srwatson{ 2087100979Srwatson 2088100979Srwatson switch (prot & VM_PROT_ALL) { 2089100979Srwatson case VM_PROT_READ: 2090100979Srwatson return ("r--"); 2091100979Srwatson case VM_PROT_READ | VM_PROT_WRITE: 2092100979Srwatson return ("rw-"); 2093100979Srwatson case VM_PROT_READ | VM_PROT_EXECUTE: 2094100979Srwatson return ("r-x"); 2095100979Srwatson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2096100979Srwatson return ("rwx"); 2097100979Srwatson case VM_PROT_WRITE: 2098100979Srwatson return ("-w-"); 2099100979Srwatson case VM_PROT_EXECUTE: 2100100979Srwatson return ("--x"); 2101100979Srwatson case VM_PROT_WRITE | VM_PROT_EXECUTE: 2102100979Srwatson return ("-wx"); 2103100979Srwatson default: 2104100979Srwatson return ("---"); 2105100979Srwatson } 2106100979Srwatson} 2107100979Srwatson 2108100979Srwatsonstatic void 2109100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2110100979Srwatson struct vm_map *map) 2111100979Srwatson{ 2112100979Srwatson struct vm_map_entry *vme; 2113104546Srwatson int result; 2114104546Srwatson vm_prot_t revokeperms; 2115100979Srwatson vm_object_t object; 2116100979Srwatson vm_ooffset_t offset; 2117100979Srwatson struct vnode *vp; 2118100979Srwatson 2119103136Srwatson if (!mac_mmap_revocation) 2120103136Srwatson return; 2121103136Srwatson 2122100979Srwatson vm_map_lock_read(map); 2123100979Srwatson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2124100979Srwatson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2125100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2126100979Srwatson vme->object.sub_map); 2127100979Srwatson continue; 2128100979Srwatson } 2129100979Srwatson /* 2130100979Srwatson * Skip over entries that obviously are not shared. 2131100979Srwatson */ 2132100979Srwatson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2133100979Srwatson !vme->max_protection) 2134100979Srwatson continue; 2135100979Srwatson /* 2136100979Srwatson * Drill down to the deepest backing object. 2137100979Srwatson */ 2138100979Srwatson offset = vme->offset; 2139100979Srwatson object = vme->object.vm_object; 2140100979Srwatson if (object == NULL) 2141100979Srwatson continue; 2142100979Srwatson while (object->backing_object != NULL) { 2143100979Srwatson object = object->backing_object; 2144100979Srwatson offset += object->backing_object_offset; 2145100979Srwatson } 2146100979Srwatson /* 2147100979Srwatson * At the moment, vm_maps and objects aren't considered 2148100979Srwatson * by the MAC system, so only things with backing by a 2149100979Srwatson * normal object (read: vnodes) are checked. 2150100979Srwatson */ 2151100979Srwatson if (object->type != OBJT_VNODE) 2152100979Srwatson continue; 2153100979Srwatson vp = (struct vnode *)object->handle; 2154100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2155104546Srwatson result = vme->max_protection; 2156104546Srwatson mac_check_vnode_mmap_downgrade(cred, vp, &result); 2157100979Srwatson VOP_UNLOCK(vp, 0, td); 2158100979Srwatson /* 2159100979Srwatson * Find out what maximum protection we may be allowing 2160100979Srwatson * now but a policy needs to get removed. 2161100979Srwatson */ 2162100979Srwatson revokeperms = vme->max_protection & ~result; 2163100979Srwatson if (!revokeperms) 2164100979Srwatson continue; 2165102949Sbde printf("pid %ld: revoking %s perms from %#lx:%ld " 2166102949Sbde "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2167102949Sbde prot2str(revokeperms), (u_long)vme->start, 2168102949Sbde (long)(vme->end - vme->start), 2169100979Srwatson prot2str(vme->max_protection), prot2str(vme->protection)); 2170100979Srwatson vm_map_lock_upgrade(map); 2171100979Srwatson /* 2172100979Srwatson * This is the really simple case: if a map has more 2173100979Srwatson * max_protection than is allowed, but it's not being 2174100979Srwatson * actually used (that is, the current protection is 2175100979Srwatson * still allowed), we can just wipe it out and do 2176100979Srwatson * nothing more. 2177100979Srwatson */ 2178100979Srwatson if ((vme->protection & revokeperms) == 0) { 2179100979Srwatson vme->max_protection -= revokeperms; 2180100979Srwatson } else { 2181100979Srwatson if (revokeperms & VM_PROT_WRITE) { 2182100979Srwatson /* 2183100979Srwatson * In the more complicated case, flush out all 2184100979Srwatson * pending changes to the object then turn it 2185100979Srwatson * copy-on-write. 2186100979Srwatson */ 2187100979Srwatson vm_object_reference(object); 2188100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2189113955Salc VM_OBJECT_LOCK(object); 2190100979Srwatson vm_object_page_clean(object, 2191100979Srwatson OFF_TO_IDX(offset), 2192100979Srwatson OFF_TO_IDX(offset + vme->end - vme->start + 2193100979Srwatson PAGE_MASK), 2194100979Srwatson OBJPC_SYNC); 2195113955Salc VM_OBJECT_UNLOCK(object); 2196100979Srwatson VOP_UNLOCK(vp, 0, td); 2197100979Srwatson vm_object_deallocate(object); 2198100979Srwatson /* 2199100979Srwatson * Why bother if there's no read permissions 2200100979Srwatson * anymore? For the rest, we need to leave 2201100979Srwatson * the write permissions on for COW, or 2202100979Srwatson * remove them entirely if configured to. 2203100979Srwatson */ 2204100979Srwatson if (!mac_mmap_revocation_via_cow) { 2205100979Srwatson vme->max_protection &= ~VM_PROT_WRITE; 2206100979Srwatson vme->protection &= ~VM_PROT_WRITE; 2207100979Srwatson } if ((revokeperms & VM_PROT_READ) == 0) 2208100979Srwatson vme->eflags |= MAP_ENTRY_COW | 2209100979Srwatson MAP_ENTRY_NEEDS_COPY; 2210100979Srwatson } 2211100979Srwatson if (revokeperms & VM_PROT_EXECUTE) { 2212100979Srwatson vme->max_protection &= ~VM_PROT_EXECUTE; 2213100979Srwatson vme->protection &= ~VM_PROT_EXECUTE; 2214100979Srwatson } 2215100979Srwatson if (revokeperms & VM_PROT_READ) { 2216100979Srwatson vme->max_protection = 0; 2217100979Srwatson vme->protection = 0; 2218100979Srwatson } 2219100979Srwatson pmap_protect(map->pmap, vme->start, vme->end, 2220100979Srwatson vme->protection & ~revokeperms); 2221100979Srwatson vm_map_simplify_entry(map, vme); 2222100979Srwatson } 2223100979Srwatson vm_map_lock_downgrade(map); 2224100979Srwatson } 2225100979Srwatson vm_map_unlock_read(map); 2226100979Srwatson} 2227100979Srwatson 2228100979Srwatson/* 2229100979Srwatson * When the subject's label changes, it may require revocation of privilege 2230100979Srwatson * to mapped objects. This can't be done on-the-fly later with a unified 2231100979Srwatson * buffer cache. 2232100979Srwatson */ 2233100979Srwatsonstatic void 2234100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel) 2235100979Srwatson{ 2236100979Srwatson 2237100979Srwatson MAC_PERFORM(relabel_cred, cred, newlabel); 2238100979Srwatson} 2239100979Srwatson 2240100979Srwatsonvoid 2241100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2242100979Srwatson{ 2243100979Srwatson 2244100979Srwatson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2245100979Srwatson} 2246100979Srwatson 2247100979Srwatsonvoid 2248100979Srwatsonmac_create_ifnet(struct ifnet *ifnet) 2249100979Srwatson{ 2250100979Srwatson 2251100979Srwatson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2252100979Srwatson} 2253100979Srwatson 2254100979Srwatsonvoid 2255100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2256100979Srwatson{ 2257100979Srwatson 2258100979Srwatson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2259100979Srwatson} 2260100979Srwatson 2261100979Srwatsonvoid 2262100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket) 2263100979Srwatson{ 2264100979Srwatson 2265100979Srwatson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2266100979Srwatson} 2267100979Srwatson 2268100979Srwatsonvoid 2269100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe) 2270100979Srwatson{ 2271100979Srwatson 2272100979Srwatson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2273100979Srwatson} 2274100979Srwatson 2275100979Srwatsonvoid 2276100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket, 2277100979Srwatson struct socket *newsocket) 2278100979Srwatson{ 2279100979Srwatson 2280100979Srwatson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2281100979Srwatson newsocket, &newsocket->so_label); 2282100979Srwatson} 2283100979Srwatson 2284100979Srwatsonstatic void 2285100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket, 2286100979Srwatson struct label *newlabel) 2287100979Srwatson{ 2288100979Srwatson 2289100979Srwatson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2290100979Srwatson} 2291100979Srwatson 2292100979Srwatsonstatic void 2293100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2294100979Srwatson{ 2295100979Srwatson 2296100979Srwatson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2297100979Srwatson} 2298100979Srwatson 2299100979Srwatsonvoid 2300100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2301100979Srwatson{ 2302113482Srwatson struct label *label; 2303100979Srwatson 2304113482Srwatson label = mbuf_to_label(mbuf); 2305113482Srwatson 2306113482Srwatson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 2307113482Srwatson &socket->so_peerlabel); 2308100979Srwatson} 2309100979Srwatson 2310100979Srwatsonvoid 2311100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket, 2312100979Srwatson struct socket *newsocket) 2313100979Srwatson{ 2314100979Srwatson 2315100979Srwatson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2316100979Srwatson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2317100979Srwatson} 2318100979Srwatson 2319100979Srwatsonvoid 2320100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2321100979Srwatson{ 2322113482Srwatson struct label *label; 2323100979Srwatson 2324113482Srwatson label = mbuf_to_label(datagram); 2325113482Srwatson 2326100979Srwatson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2327113482Srwatson datagram, label); 2328100979Srwatson} 2329100979Srwatson 2330100979Srwatsonvoid 2331100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2332100979Srwatson{ 2333113482Srwatson struct label *datagramlabel, *fragmentlabel; 2334100979Srwatson 2335113482Srwatson datagramlabel = mbuf_to_label(datagram); 2336113482Srwatson fragmentlabel = mbuf_to_label(fragment); 2337113482Srwatson 2338113482Srwatson MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 2339113482Srwatson fragmentlabel); 2340100979Srwatson} 2341100979Srwatson 2342100979Srwatsonvoid 2343100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2344100979Srwatson{ 2345113482Srwatson struct label *label; 2346100979Srwatson 2347113482Srwatson label = mbuf_to_label(fragment); 2348113482Srwatson 2349113482Srwatson MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label); 2350100979Srwatson} 2351100979Srwatson 2352100979Srwatsonvoid 2353100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2354100979Srwatson{ 2355113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2356100979Srwatson 2357113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2358113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2359113482Srwatson 2360113482Srwatson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 2361113482Srwatson newmbuflabel); 2362100979Srwatson} 2363100979Srwatson 2364100979Srwatsonvoid 2365100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2366100979Srwatson{ 2367113482Srwatson struct label *label; 2368100979Srwatson 2369113482Srwatson label = mbuf_to_label(mbuf); 2370113482Srwatson 2371100979Srwatson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2372113482Srwatson label); 2373100979Srwatson} 2374100979Srwatson 2375100979Srwatsonvoid 2376100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2377100979Srwatson{ 2378113482Srwatson struct label *label; 2379100979Srwatson 2380113482Srwatson label = mbuf_to_label(mbuf); 2381113482Srwatson 2382100979Srwatson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2383113482Srwatson label); 2384100979Srwatson} 2385100979Srwatson 2386100979Srwatsonvoid 2387100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2388100979Srwatson{ 2389113482Srwatson struct label *label; 2390100979Srwatson 2391113482Srwatson label = mbuf_to_label(mbuf); 2392113482Srwatson 2393100979Srwatson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2394113482Srwatson label); 2395100979Srwatson} 2396100979Srwatson 2397100979Srwatsonvoid 2398100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2399100979Srwatson struct mbuf *newmbuf) 2400100979Srwatson{ 2401113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2402100979Srwatson 2403113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2404113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2405113482Srwatson 2406113482Srwatson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 2407113482Srwatson ifnet, &ifnet->if_label, newmbuf, newmbuflabel); 2408100979Srwatson} 2409100979Srwatson 2410100979Srwatsonvoid 2411100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2412100979Srwatson{ 2413113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2414100979Srwatson 2415113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2416113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2417113482Srwatson 2418113482Srwatson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 2419113482Srwatson newmbuflabel); 2420100979Srwatson} 2421100979Srwatson 2422100979Srwatsonint 2423100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2424100979Srwatson{ 2425113482Srwatson struct label *label; 2426100979Srwatson int result; 2427100979Srwatson 2428113482Srwatson label = mbuf_to_label(fragment); 2429113482Srwatson 2430100979Srwatson result = 1; 2431113482Srwatson MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 2432113482Srwatson &ipq->ipq_label); 2433100979Srwatson 2434100979Srwatson return (result); 2435100979Srwatson} 2436100979Srwatson 2437100979Srwatsonvoid 2438100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2439100979Srwatson{ 2440113482Srwatson struct label *label; 2441100979Srwatson 2442113482Srwatson label = mbuf_to_label(fragment); 2443113482Srwatson 2444113482Srwatson MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label); 2445100979Srwatson} 2446100979Srwatson 2447100979Srwatsonvoid 2448100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2449100979Srwatson{ 2450113482Srwatson struct label *label; 2451100979Srwatson 2452113482Srwatson label = mbuf_to_label(mbuf); 2453113482Srwatson 2454100979Srwatson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2455113482Srwatson label); 2456100979Srwatson} 2457100979Srwatson 2458100979Srwatsonvoid 2459100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp) 2460100979Srwatson{ 2461100979Srwatson 2462100979Srwatson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2463100979Srwatson &mp->mnt_fslabel); 2464100979Srwatson} 2465100979Srwatson 2466100979Srwatsonvoid 2467100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp) 2468100979Srwatson{ 2469100979Srwatson 2470100979Srwatson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2471100979Srwatson &mp->mnt_fslabel); 2472100979Srwatson} 2473100979Srwatson 2474100979Srwatsonint 2475100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2476100979Srwatson{ 2477100979Srwatson int error; 2478100979Srwatson 2479100979Srwatson if (!mac_enforce_network) 2480100979Srwatson return (0); 2481100979Srwatson 2482100979Srwatson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2483100979Srwatson &ifnet->if_label); 2484100979Srwatson 2485100979Srwatson return (error); 2486100979Srwatson} 2487100979Srwatson 2488100979Srwatsonstatic int 2489100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2490100979Srwatson{ 2491100979Srwatson int error; 2492100979Srwatson 2493100979Srwatson MAC_CHECK(check_cred_relabel, cred, newlabel); 2494100979Srwatson 2495100979Srwatson return (error); 2496100979Srwatson} 2497100979Srwatson 2498100979Srwatsonint 2499100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2500100979Srwatson{ 2501100979Srwatson int error; 2502100979Srwatson 2503100979Srwatson if (!mac_enforce_process) 2504100979Srwatson return (0); 2505100979Srwatson 2506100979Srwatson MAC_CHECK(check_cred_visible, u1, u2); 2507100979Srwatson 2508100979Srwatson return (error); 2509100979Srwatson} 2510100979Srwatson 2511100979Srwatsonint 2512100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2513100979Srwatson{ 2514113482Srwatson struct label *label; 2515100979Srwatson int error; 2516100979Srwatson 2517113487Srwatson M_ASSERTPKTHDR(mbuf); 2518113487Srwatson 2519100979Srwatson if (!mac_enforce_network) 2520100979Srwatson return (0); 2521100979Srwatson 2522113482Srwatson label = mbuf_to_label(mbuf); 2523100979Srwatson 2524100979Srwatson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2525113482Srwatson label); 2526100979Srwatson 2527100979Srwatson return (error); 2528100979Srwatson} 2529100979Srwatson 2530100979Srwatsonint 2531106308Srwatsonmac_check_kenv_dump(struct ucred *cred) 2532106308Srwatson{ 2533106308Srwatson int error; 2534106308Srwatson 2535106308Srwatson if (!mac_enforce_system) 2536106308Srwatson return (0); 2537106308Srwatson 2538106308Srwatson MAC_CHECK(check_kenv_dump, cred); 2539106308Srwatson 2540106308Srwatson return (error); 2541106308Srwatson} 2542106308Srwatson 2543106308Srwatsonint 2544106308Srwatsonmac_check_kenv_get(struct ucred *cred, char *name) 2545106308Srwatson{ 2546106308Srwatson int error; 2547106308Srwatson 2548106308Srwatson if (!mac_enforce_system) 2549106308Srwatson return (0); 2550106308Srwatson 2551106308Srwatson MAC_CHECK(check_kenv_get, cred, name); 2552106308Srwatson 2553106308Srwatson return (error); 2554106308Srwatson} 2555106308Srwatson 2556106308Srwatsonint 2557106308Srwatsonmac_check_kenv_set(struct ucred *cred, char *name, char *value) 2558106308Srwatson{ 2559106308Srwatson int error; 2560106308Srwatson 2561106308Srwatson if (!mac_enforce_system) 2562106308Srwatson return (0); 2563106308Srwatson 2564106308Srwatson MAC_CHECK(check_kenv_set, cred, name, value); 2565106308Srwatson 2566106308Srwatson return (error); 2567106308Srwatson} 2568106308Srwatson 2569106308Srwatsonint 2570106308Srwatsonmac_check_kenv_unset(struct ucred *cred, char *name) 2571106308Srwatson{ 2572106308Srwatson int error; 2573106308Srwatson 2574106308Srwatson if (!mac_enforce_system) 2575106308Srwatson return (0); 2576106308Srwatson 2577106308Srwatson MAC_CHECK(check_kenv_unset, cred, name); 2578106308Srwatson 2579106308Srwatson return (error); 2580106308Srwatson} 2581106308Srwatson 2582106308Srwatsonint 2583107089Srwatsonmac_check_kld_load(struct ucred *cred, struct vnode *vp) 2584107089Srwatson{ 2585107089Srwatson int error; 2586107089Srwatson 2587107089Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2588107089Srwatson 2589107089Srwatson if (!mac_enforce_kld) 2590107089Srwatson return (0); 2591107089Srwatson 2592107089Srwatson MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2593107089Srwatson 2594107089Srwatson return (error); 2595107089Srwatson} 2596107089Srwatson 2597107089Srwatsonint 2598107089Srwatsonmac_check_kld_stat(struct ucred *cred) 2599107089Srwatson{ 2600107089Srwatson int error; 2601107089Srwatson 2602107089Srwatson if (!mac_enforce_kld) 2603107089Srwatson return (0); 2604107089Srwatson 2605107089Srwatson MAC_CHECK(check_kld_stat, cred); 2606107089Srwatson 2607107089Srwatson return (error); 2608107089Srwatson} 2609107089Srwatson 2610107089Srwatsonint 2611107089Srwatsonmac_check_kld_unload(struct ucred *cred) 2612107089Srwatson{ 2613107089Srwatson int error; 2614107089Srwatson 2615107089Srwatson if (!mac_enforce_kld) 2616107089Srwatson return (0); 2617107089Srwatson 2618107089Srwatson MAC_CHECK(check_kld_unload, cred); 2619107089Srwatson 2620107089Srwatson return (error); 2621107089Srwatson} 2622107089Srwatson 2623107089Srwatsonint 2624100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount) 2625100979Srwatson{ 2626100979Srwatson int error; 2627100979Srwatson 2628100979Srwatson if (!mac_enforce_fs) 2629100979Srwatson return (0); 2630100979Srwatson 2631100979Srwatson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2632100979Srwatson 2633100979Srwatson return (error); 2634100979Srwatson} 2635100979Srwatson 2636100979Srwatsonint 2637100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2638100979Srwatson void *data) 2639100979Srwatson{ 2640100979Srwatson int error; 2641100979Srwatson 2642104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2643104269Srwatson 2644104269Srwatson if (!mac_enforce_pipe) 2645104269Srwatson return (0); 2646104269Srwatson 2647100979Srwatson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2648100979Srwatson 2649100979Srwatson return (error); 2650100979Srwatson} 2651100979Srwatson 2652100979Srwatsonint 2653102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2654100979Srwatson{ 2655100979Srwatson int error; 2656100979Srwatson 2657104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2658104269Srwatson 2659104269Srwatson if (!mac_enforce_pipe) 2660104269Srwatson return (0); 2661104269Srwatson 2662102115Srwatson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2663100979Srwatson 2664100979Srwatson return (error); 2665100979Srwatson} 2666100979Srwatson 2667102115Srwatsonint 2668102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2669102115Srwatson{ 2670102115Srwatson int error; 2671102115Srwatson 2672104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2673104269Srwatson 2674104269Srwatson if (!mac_enforce_pipe) 2675104269Srwatson return (0); 2676104269Srwatson 2677102115Srwatson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2678102115Srwatson 2679102115Srwatson return (error); 2680102115Srwatson} 2681102115Srwatson 2682100979Srwatsonstatic int 2683100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2684100979Srwatson struct label *newlabel) 2685100979Srwatson{ 2686100979Srwatson int error; 2687100979Srwatson 2688104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2689104269Srwatson 2690104269Srwatson if (!mac_enforce_pipe) 2691104269Srwatson return (0); 2692104269Srwatson 2693100979Srwatson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2694100979Srwatson 2695100979Srwatson return (error); 2696100979Srwatson} 2697100979Srwatson 2698100979Srwatsonint 2699102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2700102115Srwatson{ 2701102115Srwatson int error; 2702102115Srwatson 2703104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2704104269Srwatson 2705104269Srwatson if (!mac_enforce_pipe) 2706104269Srwatson return (0); 2707104269Srwatson 2708102115Srwatson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2709102115Srwatson 2710102115Srwatson return (error); 2711102115Srwatson} 2712102115Srwatson 2713102115Srwatsonint 2714102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2715102115Srwatson{ 2716102115Srwatson int error; 2717102115Srwatson 2718104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2719104269Srwatson 2720104269Srwatson if (!mac_enforce_pipe) 2721104269Srwatson return (0); 2722104269Srwatson 2723102115Srwatson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2724102115Srwatson 2725102115Srwatson return (error); 2726102115Srwatson} 2727102115Srwatson 2728102115Srwatsonint 2729100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc) 2730100979Srwatson{ 2731100979Srwatson int error; 2732100979Srwatson 2733102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2734102103Srwatson 2735100979Srwatson if (!mac_enforce_process) 2736100979Srwatson return (0); 2737100979Srwatson 2738100979Srwatson MAC_CHECK(check_proc_debug, cred, proc); 2739100979Srwatson 2740100979Srwatson return (error); 2741100979Srwatson} 2742100979Srwatson 2743100979Srwatsonint 2744100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc) 2745100979Srwatson{ 2746100979Srwatson int error; 2747100979Srwatson 2748102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2749102103Srwatson 2750100979Srwatson if (!mac_enforce_process) 2751100979Srwatson return (0); 2752100979Srwatson 2753100979Srwatson MAC_CHECK(check_proc_sched, cred, proc); 2754100979Srwatson 2755100979Srwatson return (error); 2756100979Srwatson} 2757100979Srwatson 2758100979Srwatsonint 2759100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2760100979Srwatson{ 2761100979Srwatson int error; 2762100979Srwatson 2763102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2764102103Srwatson 2765100979Srwatson if (!mac_enforce_process) 2766100979Srwatson return (0); 2767100979Srwatson 2768100979Srwatson MAC_CHECK(check_proc_signal, cred, proc, signum); 2769100979Srwatson 2770100979Srwatson return (error); 2771100979Srwatson} 2772100979Srwatson 2773100979Srwatsonint 2774100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2775100979Srwatson struct sockaddr *sockaddr) 2776100979Srwatson{ 2777100979Srwatson int error; 2778100979Srwatson 2779100979Srwatson if (!mac_enforce_socket) 2780100979Srwatson return (0); 2781100979Srwatson 2782100979Srwatson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2783100979Srwatson sockaddr); 2784100979Srwatson 2785100979Srwatson return (error); 2786100979Srwatson} 2787100979Srwatson 2788100979Srwatsonint 2789100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket, 2790100979Srwatson struct sockaddr *sockaddr) 2791100979Srwatson{ 2792100979Srwatson int error; 2793100979Srwatson 2794100979Srwatson if (!mac_enforce_socket) 2795100979Srwatson return (0); 2796100979Srwatson 2797100979Srwatson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2798100979Srwatson sockaddr); 2799100979Srwatson 2800100979Srwatson return (error); 2801100979Srwatson} 2802100979Srwatson 2803100979Srwatsonint 2804101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2805100979Srwatson{ 2806113482Srwatson struct label *label; 2807100979Srwatson int error; 2808100979Srwatson 2809100979Srwatson if (!mac_enforce_socket) 2810100979Srwatson return (0); 2811100979Srwatson 2812113482Srwatson label = mbuf_to_label(mbuf); 2813113482Srwatson 2814101933Srwatson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2815113482Srwatson label); 2816101933Srwatson 2817100979Srwatson return (error); 2818100979Srwatson} 2819100979Srwatson 2820100979Srwatsonint 2821101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket) 2822100979Srwatson{ 2823100979Srwatson int error; 2824100979Srwatson 2825100979Srwatson if (!mac_enforce_socket) 2826100979Srwatson return (0); 2827100979Srwatson 2828101933Srwatson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2829100979Srwatson return (error); 2830100979Srwatson} 2831100979Srwatson 2832104571Srwatsonint 2833104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so) 2834104571Srwatson{ 2835104571Srwatson int error; 2836104571Srwatson 2837104571Srwatson if (!mac_enforce_socket) 2838104571Srwatson return (0); 2839104571Srwatson 2840104571Srwatson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2841104571Srwatson 2842104571Srwatson return (error); 2843104571Srwatson} 2844104571Srwatson 2845100979Srwatsonstatic int 2846100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2847100979Srwatson struct label *newlabel) 2848100979Srwatson{ 2849100979Srwatson int error; 2850100979Srwatson 2851100979Srwatson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2852100979Srwatson newlabel); 2853100979Srwatson 2854100979Srwatson return (error); 2855100979Srwatson} 2856100979Srwatson 2857100979Srwatsonint 2858104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so) 2859104571Srwatson{ 2860104571Srwatson int error; 2861104571Srwatson 2862104571Srwatson if (!mac_enforce_socket) 2863104571Srwatson return (0); 2864104571Srwatson 2865104571Srwatson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2866104571Srwatson 2867104571Srwatson return (error); 2868104571Srwatson} 2869104571Srwatson 2870104571Srwatsonint 2871100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket) 2872100979Srwatson{ 2873100979Srwatson int error; 2874100979Srwatson 2875100979Srwatson if (!mac_enforce_socket) 2876100979Srwatson return (0); 2877105694Srwatson 2878100979Srwatson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2879105694Srwatson 2880100979Srwatson return (error); 2881100979Srwatson} 2882100979Srwatson 2883100979Srwatsonint 2884111939Srwatsonmac_check_sysarch_ioperm(struct ucred *cred) 2885111939Srwatson{ 2886111939Srwatson int error; 2887111939Srwatson 2888111939Srwatson if (!mac_enforce_system) 2889111939Srwatson return (0); 2890111939Srwatson 2891111939Srwatson MAC_CHECK(check_sysarch_ioperm, cred); 2892111939Srwatson return (error); 2893111939Srwatson} 2894111939Srwatson 2895111939Srwatsonint 2896106412Srwatsonmac_check_system_acct(struct ucred *cred, struct vnode *vp) 2897106412Srwatson{ 2898106412Srwatson int error; 2899106412Srwatson 2900106412Srwatson if (vp != NULL) { 2901106412Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2902106412Srwatson } 2903106412Srwatson 2904106412Srwatson if (!mac_enforce_system) 2905106412Srwatson return (0); 2906106412Srwatson 2907106412Srwatson MAC_CHECK(check_system_acct, cred, vp, 2908106412Srwatson vp != NULL ? &vp->v_label : NULL); 2909106412Srwatson 2910106412Srwatson return (error); 2911106412Srwatson} 2912106412Srwatson 2913106412Srwatsonint 2914106412Srwatsonmac_check_system_nfsd(struct ucred *cred) 2915106412Srwatson{ 2916106412Srwatson int error; 2917106412Srwatson 2918106412Srwatson if (!mac_enforce_system) 2919106412Srwatson return (0); 2920106412Srwatson 2921106412Srwatson MAC_CHECK(check_system_nfsd, cred); 2922106412Srwatson 2923106412Srwatson return (error); 2924106412Srwatson} 2925106412Srwatson 2926106412Srwatsonint 2927106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto) 2928106024Srwatson{ 2929106024Srwatson int error; 2930106024Srwatson 2931106045Srwatson if (!mac_enforce_system) 2932106024Srwatson return (0); 2933106024Srwatson 2934106024Srwatson MAC_CHECK(check_system_reboot, cred, howto); 2935106045Srwatson 2936106024Srwatson return (error); 2937106024Srwatson} 2938106024Srwatson 2939106024Srwatsonint 2940106369Srwatsonmac_check_system_settime(struct ucred *cred) 2941106369Srwatson{ 2942106369Srwatson int error; 2943106369Srwatson 2944106369Srwatson if (!mac_enforce_system) 2945106369Srwatson return (0); 2946106369Srwatson 2947106369Srwatson MAC_CHECK(check_system_settime, cred); 2948106369Srwatson 2949106369Srwatson return (error); 2950106369Srwatson} 2951106369Srwatson 2952106369Srwatsonint 2953106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2954106023Srwatson{ 2955106023Srwatson int error; 2956106023Srwatson 2957106023Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2958106023Srwatson 2959106045Srwatson if (!mac_enforce_system) 2960106023Srwatson return (0); 2961106023Srwatson 2962106023Srwatson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2963106023Srwatson return (error); 2964106023Srwatson} 2965106023Srwatson 2966106023Srwatsonint 2967111936Srwatsonmac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2968111936Srwatson{ 2969111936Srwatson int error; 2970111936Srwatson 2971111936Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2972111936Srwatson 2973111936Srwatson if (!mac_enforce_system) 2974111936Srwatson return (0); 2975111936Srwatson 2976111936Srwatson MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2977111936Srwatson return (error); 2978111936Srwatson} 2979111936Srwatson 2980111936Srwatsonint 2981106025Srwatsonmac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2982106025Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2983106025Srwatson{ 2984106025Srwatson int error; 2985106025Srwatson 2986106025Srwatson /* 2987106025Srwatson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2988106025Srwatson * but since it's not exported from kern_sysctl.c, we can't. 2989106025Srwatson */ 2990106045Srwatson if (!mac_enforce_system) 2991106025Srwatson return (0); 2992106025Srwatson 2993106025Srwatson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2994106025Srwatson inkernel, new, newlen); 2995106025Srwatson 2996106025Srwatson return (error); 2997106025Srwatson} 2998106025Srwatson 2999106025Srwatsonint 3000100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 3001100979Srwatson struct ifnet *ifnet) 3002100979Srwatson{ 3003105694Srwatson char *elements, *buffer; 3004105694Srwatson struct mac mac; 3005100979Srwatson int error; 3006100979Srwatson 3007105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3008100979Srwatson if (error) 3009100979Srwatson return (error); 3010100979Srwatson 3011105694Srwatson error = mac_check_structmac_consistent(&mac); 3012105694Srwatson if (error) 3013105694Srwatson return (error); 3014105694Srwatson 3015111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3016105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3017105694Srwatson if (error) { 3018105694Srwatson free(elements, M_MACTEMP); 3019105694Srwatson return (error); 3020105694Srwatson } 3021105694Srwatson 3022111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3023105694Srwatson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 3024111119Simp buffer, mac.m_buflen, M_WAITOK); 3025105694Srwatson if (error == 0) 3026105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3027105694Srwatson 3028105694Srwatson free(buffer, M_MACTEMP); 3029105694Srwatson free(elements, M_MACTEMP); 3030105694Srwatson 3031105694Srwatson return (error); 3032100979Srwatson} 3033100979Srwatson 3034100979Srwatsonint 3035100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 3036100979Srwatson struct ifnet *ifnet) 3037100979Srwatson{ 3038100979Srwatson struct label intlabel; 3039105694Srwatson struct mac mac; 3040105694Srwatson char *buffer; 3041100979Srwatson int error; 3042100979Srwatson 3043105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3044100979Srwatson if (error) 3045100979Srwatson return (error); 3046100979Srwatson 3047105694Srwatson error = mac_check_structmac_consistent(&mac); 3048100979Srwatson if (error) 3049100979Srwatson return (error); 3050100979Srwatson 3051111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3052105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3053105694Srwatson if (error) { 3054105694Srwatson free(buffer, M_MACTEMP); 3055105694Srwatson return (error); 3056105694Srwatson } 3057105694Srwatson 3058105694Srwatson mac_init_ifnet_label(&intlabel); 3059105694Srwatson error = mac_internalize_ifnet_label(&intlabel, buffer); 3060105694Srwatson free(buffer, M_MACTEMP); 3061105694Srwatson if (error) { 3062105694Srwatson mac_destroy_ifnet_label(&intlabel); 3063105694Srwatson return (error); 3064105694Srwatson } 3065105694Srwatson 3066100979Srwatson /* 3067100979Srwatson * XXX: Note that this is a redundant privilege check, since 3068100979Srwatson * policies impose this check themselves if required by the 3069100979Srwatson * policy. Eventually, this should go away. 3070100979Srwatson */ 3071100979Srwatson error = suser_cred(cred, 0); 3072105694Srwatson if (error) { 3073105694Srwatson mac_destroy_ifnet_label(&intlabel); 3074105694Srwatson return (error); 3075105694Srwatson } 3076100979Srwatson 3077100979Srwatson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3078100979Srwatson &intlabel); 3079105694Srwatson if (error) { 3080105694Srwatson mac_destroy_ifnet_label(&intlabel); 3081105694Srwatson return (error); 3082105694Srwatson } 3083100979Srwatson 3084100979Srwatson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3085100979Srwatson 3086105694Srwatson mac_destroy_ifnet_label(&intlabel); 3087105694Srwatson return (0); 3088100979Srwatson} 3089100979Srwatson 3090100979Srwatsonvoid 3091107698Srwatsonmac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de) 3092100979Srwatson{ 3093100979Srwatson 3094107698Srwatson MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label); 3095100979Srwatson} 3096100979Srwatson 3097104533Srwatsonvoid 3098107698Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 3099107698Srwatson struct devfs_dirent *dd, struct devfs_dirent *de) 3100104533Srwatson{ 3101104533Srwatson 3102107698Srwatson MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de, 3103104533Srwatson &de->de_label); 3104104533Srwatson} 3105104533Srwatson 3106100979Srwatsonvoid 3107107698Srwatsonmac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 3108100979Srwatson struct devfs_dirent *de) 3109100979Srwatson{ 3110100979Srwatson 3111107698Srwatson MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 3112100979Srwatson &de->de_label); 3113100979Srwatson} 3114100979Srwatson 3115100979Srwatsonint 3116100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3117105694Srwatson struct mac *mac) 3118100979Srwatson{ 3119100979Srwatson struct label intlabel; 3120105694Srwatson char *buffer; 3121100979Srwatson int error; 3122100979Srwatson 3123105694Srwatson error = mac_check_structmac_consistent(mac); 3124100979Srwatson if (error) 3125100979Srwatson return (error); 3126100979Srwatson 3127111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3128105694Srwatson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3129105694Srwatson if (error) { 3130105694Srwatson free(buffer, M_MACTEMP); 3131105694Srwatson return (error); 3132105694Srwatson } 3133105694Srwatson 3134111119Simp mac_init_socket_label(&intlabel, M_WAITOK); 3135105694Srwatson error = mac_internalize_socket_label(&intlabel, buffer); 3136105694Srwatson free(buffer, M_MACTEMP); 3137105694Srwatson if (error) { 3138105694Srwatson mac_destroy_socket_label(&intlabel); 3139105694Srwatson return (error); 3140105694Srwatson } 3141105694Srwatson 3142100979Srwatson mac_check_socket_relabel(cred, so, &intlabel); 3143100979Srwatson if (error) { 3144105694Srwatson mac_destroy_socket_label(&intlabel); 3145100979Srwatson return (error); 3146100979Srwatson } 3147100979Srwatson 3148100979Srwatson mac_relabel_socket(cred, so, &intlabel); 3149100979Srwatson 3150105694Srwatson mac_destroy_socket_label(&intlabel); 3151100979Srwatson return (0); 3152100979Srwatson} 3153100979Srwatson 3154100979Srwatsonint 3155100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3156100979Srwatson{ 3157100979Srwatson int error; 3158100979Srwatson 3159104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3160104269Srwatson 3161100979Srwatson error = mac_check_pipe_relabel(cred, pipe, label); 3162100979Srwatson if (error) 3163100979Srwatson return (error); 3164100979Srwatson 3165100979Srwatson mac_relabel_pipe(cred, pipe, label); 3166100979Srwatson 3167100979Srwatson return (0); 3168100979Srwatson} 3169100979Srwatson 3170100979Srwatsonint 3171100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3172105694Srwatson struct mac *mac) 3173100979Srwatson{ 3174105694Srwatson char *buffer, *elements; 3175105694Srwatson int error; 3176100979Srwatson 3177105694Srwatson error = mac_check_structmac_consistent(mac); 3178105694Srwatson if (error) 3179105694Srwatson return (error); 3180105694Srwatson 3181111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3182105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3183105694Srwatson if (error) { 3184105694Srwatson free(elements, M_MACTEMP); 3185105694Srwatson return (error); 3186105694Srwatson } 3187105694Srwatson 3188111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3189105694Srwatson error = mac_externalize_socket_label(&so->so_label, elements, 3190111119Simp buffer, mac->m_buflen, M_WAITOK); 3191105694Srwatson if (error == 0) 3192105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3193105694Srwatson 3194105694Srwatson free(buffer, M_MACTEMP); 3195105694Srwatson free(elements, M_MACTEMP); 3196105694Srwatson 3197105694Srwatson return (error); 3198100979Srwatson} 3199100979Srwatson 3200100979Srwatsonint 3201100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3202105694Srwatson struct mac *mac) 3203100979Srwatson{ 3204105694Srwatson char *elements, *buffer; 3205105694Srwatson int error; 3206100979Srwatson 3207105694Srwatson error = mac_check_structmac_consistent(mac); 3208105694Srwatson if (error) 3209105694Srwatson return (error); 3210105694Srwatson 3211111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3212105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3213105694Srwatson if (error) { 3214105694Srwatson free(elements, M_MACTEMP); 3215105694Srwatson return (error); 3216105694Srwatson } 3217105694Srwatson 3218111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3219105694Srwatson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3220111119Simp elements, buffer, mac->m_buflen, M_WAITOK); 3221105694Srwatson if (error == 0) 3222105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3223105694Srwatson 3224105694Srwatson free(buffer, M_MACTEMP); 3225105694Srwatson free(elements, M_MACTEMP); 3226105694Srwatson 3227105694Srwatson return (error); 3228100979Srwatson} 3229100979Srwatson 3230100979Srwatson/* 3231100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes 3232100979Srwatson * to store label data. Can be referenced by filesystems supporting 3233100979Srwatson * extended attributes. 3234100979Srwatson */ 3235100979Srwatsonint 3236100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3237100979Srwatson{ 3238100979Srwatson struct vnode *vp = ap->a_vp; 3239100979Srwatson struct label *intlabel = ap->a_label; 3240100979Srwatson int error; 3241100979Srwatson 3242100979Srwatson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3243100979Srwatson 3244105988Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3245105988Srwatson return (EOPNOTSUPP); 3246100979Srwatson 3247105988Srwatson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3248100979Srwatson if (error) 3249100979Srwatson return (error); 3250100979Srwatson 3251100979Srwatson mac_relabel_vnode(ap->a_cred, vp, intlabel); 3252100979Srwatson 3253100979Srwatson return (0); 3254100979Srwatson} 3255100979Srwatson 3256100979Srwatsonstatic int 3257100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3258100979Srwatson{ 3259100979Srwatson int error; 3260100979Srwatson 3261100979Srwatson if (vp->v_mount == NULL) { 3262100979Srwatson /* printf("vn_setlabel: null v_mount\n"); */ 3263103314Snjl if (vp->v_type != VNON) 3264103314Snjl printf("vn_setlabel: null v_mount with non-VNON\n"); 3265100979Srwatson return (EBADF); 3266100979Srwatson } 3267100979Srwatson 3268100979Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3269100979Srwatson return (EOPNOTSUPP); 3270100979Srwatson 3271100979Srwatson /* 3272100979Srwatson * Multi-phase commit. First check the policies to confirm the 3273100979Srwatson * change is OK. Then commit via the filesystem. Finally, 3274100979Srwatson * update the actual vnode label. Question: maybe the filesystem 3275100979Srwatson * should update the vnode at the end as part of VOP_SETLABEL()? 3276100979Srwatson */ 3277100979Srwatson error = mac_check_vnode_relabel(cred, vp, intlabel); 3278100979Srwatson if (error) 3279100979Srwatson return (error); 3280100979Srwatson 3281100979Srwatson /* 3282100979Srwatson * VADMIN provides the opportunity for the filesystem to make 3283100979Srwatson * decisions about who is and is not able to modify labels 3284100979Srwatson * and protections on files. This might not be right. We can't 3285100979Srwatson * assume VOP_SETLABEL() will do it, because we might implement 3286100979Srwatson * that as part of vop_stdsetlabel_ea(). 3287100979Srwatson */ 3288100979Srwatson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3289100979Srwatson if (error) 3290100979Srwatson return (error); 3291100979Srwatson 3292100979Srwatson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3293100979Srwatson if (error) 3294100979Srwatson return (error); 3295100979Srwatson 3296100979Srwatson return (0); 3297100979Srwatson} 3298100979Srwatson 3299105694Srwatsonint 3300105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3301105694Srwatson{ 3302105694Srwatson char *elements, *buffer; 3303105694Srwatson struct mac mac; 3304105694Srwatson struct proc *tproc; 3305105694Srwatson struct ucred *tcred; 3306105694Srwatson int error; 3307105694Srwatson 3308107849Salfred error = copyin(uap->mac_p, &mac, sizeof(mac)); 3309105694Srwatson if (error) 3310105694Srwatson return (error); 3311105694Srwatson 3312105694Srwatson error = mac_check_structmac_consistent(&mac); 3313105694Srwatson if (error) 3314105694Srwatson return (error); 3315105694Srwatson 3316105694Srwatson tproc = pfind(uap->pid); 3317105694Srwatson if (tproc == NULL) 3318105694Srwatson return (ESRCH); 3319105694Srwatson 3320105694Srwatson tcred = NULL; /* Satisfy gcc. */ 3321105694Srwatson error = p_cansee(td, tproc); 3322105694Srwatson if (error == 0) 3323105694Srwatson tcred = crhold(tproc->p_ucred); 3324105694Srwatson PROC_UNLOCK(tproc); 3325105694Srwatson if (error) 3326105694Srwatson return (error); 3327105694Srwatson 3328111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3329105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3330105694Srwatson if (error) { 3331105694Srwatson free(elements, M_MACTEMP); 3332105694Srwatson crfree(tcred); 3333105694Srwatson return (error); 3334105694Srwatson } 3335105694Srwatson 3336111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3337105694Srwatson error = mac_externalize_cred_label(&tcred->cr_label, elements, 3338111119Simp buffer, mac.m_buflen, M_WAITOK); 3339105694Srwatson if (error == 0) 3340105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3341105694Srwatson 3342105694Srwatson free(buffer, M_MACTEMP); 3343105694Srwatson free(elements, M_MACTEMP); 3344105694Srwatson crfree(tcred); 3345105694Srwatson return (error); 3346105694Srwatson} 3347105694Srwatson 3348100979Srwatson/* 3349100979Srwatson * MPSAFE 3350100979Srwatson */ 3351100979Srwatsonint 3352100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3353100894Srwatson{ 3354105694Srwatson char *elements, *buffer; 3355105694Srwatson struct mac mac; 3356100979Srwatson int error; 3357100894Srwatson 3358105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3359105694Srwatson if (error) 3360105694Srwatson return (error); 3361105694Srwatson 3362105694Srwatson error = mac_check_structmac_consistent(&mac); 3363105694Srwatson if (error) 3364105694Srwatson return (error); 3365105694Srwatson 3366111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3367105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3368105694Srwatson if (error) { 3369105694Srwatson free(elements, M_MACTEMP); 3370105694Srwatson return (error); 3371105694Srwatson } 3372105694Srwatson 3373111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3374105694Srwatson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3375111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3376100979Srwatson if (error == 0) 3377105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3378100979Srwatson 3379105694Srwatson free(buffer, M_MACTEMP); 3380105694Srwatson free(elements, M_MACTEMP); 3381100979Srwatson return (error); 3382100979Srwatson} 3383100979Srwatson 3384100979Srwatson/* 3385100979Srwatson * MPSAFE 3386100979Srwatson */ 3387100979Srwatsonint 3388100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3389100979Srwatson{ 3390100979Srwatson struct ucred *newcred, *oldcred; 3391105694Srwatson struct label intlabel; 3392100979Srwatson struct proc *p; 3393105694Srwatson struct mac mac; 3394105694Srwatson char *buffer; 3395100979Srwatson int error; 3396100979Srwatson 3397105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3398100979Srwatson if (error) 3399100979Srwatson return (error); 3400100979Srwatson 3401105694Srwatson error = mac_check_structmac_consistent(&mac); 3402100979Srwatson if (error) 3403100979Srwatson return (error); 3404100979Srwatson 3405111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3406105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3407105694Srwatson if (error) { 3408105694Srwatson free(buffer, M_MACTEMP); 3409105694Srwatson return (error); 3410105694Srwatson } 3411105694Srwatson 3412105694Srwatson mac_init_cred_label(&intlabel); 3413105694Srwatson error = mac_internalize_cred_label(&intlabel, buffer); 3414105694Srwatson free(buffer, M_MACTEMP); 3415105694Srwatson if (error) { 3416105694Srwatson mac_destroy_cred_label(&intlabel); 3417105694Srwatson return (error); 3418105694Srwatson } 3419105694Srwatson 3420100979Srwatson newcred = crget(); 3421100979Srwatson 3422100979Srwatson p = td->td_proc; 3423100979Srwatson PROC_LOCK(p); 3424100979Srwatson oldcred = p->p_ucred; 3425100979Srwatson 3426100979Srwatson error = mac_check_cred_relabel(oldcred, &intlabel); 3427100979Srwatson if (error) { 3428100979Srwatson PROC_UNLOCK(p); 3429100979Srwatson crfree(newcred); 3430105694Srwatson goto out; 3431100979Srwatson } 3432100979Srwatson 3433100979Srwatson setsugid(p); 3434100979Srwatson crcopy(newcred, oldcred); 3435100979Srwatson mac_relabel_cred(newcred, &intlabel); 3436102136Srwatson p->p_ucred = newcred; 3437100979Srwatson 3438102136Srwatson /* 3439102136Srwatson * Grab additional reference for use while revoking mmaps, prior 3440102136Srwatson * to releasing the proc lock and sharing the cred. 3441102136Srwatson */ 3442102136Srwatson crhold(newcred); 3443100979Srwatson PROC_UNLOCK(p); 3444102136Srwatson 3445105694Srwatson if (mac_enforce_vm) { 3446105694Srwatson mtx_lock(&Giant); 3447105694Srwatson mac_cred_mmapped_drop_perms(td, newcred); 3448105694Srwatson mtx_unlock(&Giant); 3449105694Srwatson } 3450102136Srwatson 3451102136Srwatson crfree(newcred); /* Free revocation reference. */ 3452100979Srwatson crfree(oldcred); 3453105694Srwatson 3454105694Srwatsonout: 3455105694Srwatson mac_destroy_cred_label(&intlabel); 3456105694Srwatson return (error); 3457100979Srwatson} 3458100979Srwatson 3459100979Srwatson/* 3460100979Srwatson * MPSAFE 3461100979Srwatson */ 3462100979Srwatsonint 3463100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3464100979Srwatson{ 3465105694Srwatson char *elements, *buffer; 3466105694Srwatson struct label intlabel; 3467100979Srwatson struct file *fp; 3468105694Srwatson struct mac mac; 3469100979Srwatson struct vnode *vp; 3470100979Srwatson struct pipe *pipe; 3471105694Srwatson short label_type; 3472100979Srwatson int error; 3473100979Srwatson 3474105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3475105694Srwatson if (error) 3476105694Srwatson return (error); 3477100979Srwatson 3478105694Srwatson error = mac_check_structmac_consistent(&mac); 3479105694Srwatson if (error) 3480105694Srwatson return (error); 3481105694Srwatson 3482111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3483105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3484105694Srwatson if (error) { 3485105694Srwatson free(elements, M_MACTEMP); 3486105694Srwatson return (error); 3487105694Srwatson } 3488105694Srwatson 3489111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3490105694Srwatson mtx_lock(&Giant); /* VFS */ 3491107849Salfred error = fget(td, uap->fd, &fp); 3492100979Srwatson if (error) 3493100979Srwatson goto out; 3494100979Srwatson 3495105694Srwatson label_type = fp->f_type; 3496100979Srwatson switch (fp->f_type) { 3497100979Srwatson case DTYPE_FIFO: 3498100979Srwatson case DTYPE_VNODE: 3499109153Sdillon vp = fp->f_data; 3500100979Srwatson 3501105694Srwatson mac_init_vnode_label(&intlabel); 3502105694Srwatson 3503100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3504105988Srwatson mac_copy_vnode_label(&vp->v_label, &intlabel); 3505100979Srwatson VOP_UNLOCK(vp, 0, td); 3506105694Srwatson 3507100979Srwatson break; 3508100979Srwatson case DTYPE_PIPE: 3509109153Sdillon pipe = fp->f_data; 3510105694Srwatson 3511105694Srwatson mac_init_pipe_label(&intlabel); 3512105694Srwatson 3513105694Srwatson PIPE_LOCK(pipe); 3514105694Srwatson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3515105694Srwatson PIPE_UNLOCK(pipe); 3516100979Srwatson break; 3517100979Srwatson default: 3518100979Srwatson error = EINVAL; 3519105694Srwatson fdrop(fp, td); 3520105694Srwatson goto out; 3521100979Srwatson } 3522105694Srwatson fdrop(fp, td); 3523100979Srwatson 3524105694Srwatson switch (label_type) { 3525105694Srwatson case DTYPE_FIFO: 3526105694Srwatson case DTYPE_VNODE: 3527105694Srwatson if (error == 0) 3528105694Srwatson error = mac_externalize_vnode_label(&intlabel, 3529111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3530105694Srwatson mac_destroy_vnode_label(&intlabel); 3531105694Srwatson break; 3532105694Srwatson case DTYPE_PIPE: 3533105694Srwatson error = mac_externalize_pipe_label(&intlabel, elements, 3534111119Simp buffer, mac.m_buflen, M_WAITOK); 3535105694Srwatson mac_destroy_pipe_label(&intlabel); 3536105694Srwatson break; 3537105694Srwatson default: 3538105694Srwatson panic("__mac_get_fd: corrupted label_type"); 3539105694Srwatson } 3540105694Srwatson 3541100979Srwatson if (error == 0) 3542105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3543100979Srwatson 3544105694Srwatsonout: 3545105694Srwatson mtx_unlock(&Giant); /* VFS */ 3546105694Srwatson free(buffer, M_MACTEMP); 3547105694Srwatson free(elements, M_MACTEMP); 3548100979Srwatson 3549100979Srwatson return (error); 3550100979Srwatson} 3551100979Srwatson 3552100979Srwatson/* 3553100979Srwatson * MPSAFE 3554100979Srwatson */ 3555100979Srwatsonint 3556100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3557100979Srwatson{ 3558105694Srwatson char *elements, *buffer; 3559100979Srwatson struct nameidata nd; 3560105694Srwatson struct label intlabel; 3561105694Srwatson struct mac mac; 3562100979Srwatson int error; 3563100979Srwatson 3564105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3565105694Srwatson if (error) 3566105694Srwatson return (error); 3567105694Srwatson 3568105694Srwatson error = mac_check_structmac_consistent(&mac); 3569105694Srwatson if (error) 3570105694Srwatson return (error); 3571105694Srwatson 3572111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3573105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3574105694Srwatson if (error) { 3575105694Srwatson free(elements, M_MACTEMP); 3576105694Srwatson return (error); 3577105694Srwatson } 3578105694Srwatson 3579111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3580105694Srwatson mtx_lock(&Giant); /* VFS */ 3581105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3582105694Srwatson td); 3583100979Srwatson error = namei(&nd); 3584100979Srwatson if (error) 3585100979Srwatson goto out; 3586100979Srwatson 3587105694Srwatson mac_init_vnode_label(&intlabel); 3588105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3589105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3590111119Simp mac.m_buflen, M_WAITOK); 3591105694Srwatson 3592100979Srwatson NDFREE(&nd, 0); 3593105694Srwatson mac_destroy_vnode_label(&intlabel); 3594105694Srwatson 3595105694Srwatson if (error == 0) 3596105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3597105694Srwatson 3598105694Srwatsonout: 3599105694Srwatson mtx_unlock(&Giant); /* VFS */ 3600105694Srwatson 3601105694Srwatson free(buffer, M_MACTEMP); 3602105694Srwatson free(elements, M_MACTEMP); 3603105694Srwatson 3604105694Srwatson return (error); 3605105694Srwatson} 3606105694Srwatson 3607105694Srwatson/* 3608105694Srwatson * MPSAFE 3609105694Srwatson */ 3610105694Srwatsonint 3611105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3612105694Srwatson{ 3613105694Srwatson char *elements, *buffer; 3614105694Srwatson struct nameidata nd; 3615105694Srwatson struct label intlabel; 3616105694Srwatson struct mac mac; 3617105694Srwatson int error; 3618105694Srwatson 3619105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3620100979Srwatson if (error) 3621105694Srwatson return (error); 3622105694Srwatson 3623105694Srwatson error = mac_check_structmac_consistent(&mac); 3624105694Srwatson if (error) 3625105694Srwatson return (error); 3626105694Srwatson 3627111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3628105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3629105694Srwatson if (error) { 3630105694Srwatson free(elements, M_MACTEMP); 3631105694Srwatson return (error); 3632105694Srwatson } 3633105694Srwatson 3634111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3635105694Srwatson mtx_lock(&Giant); /* VFS */ 3636105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3637105694Srwatson td); 3638105694Srwatson error = namei(&nd); 3639105694Srwatson if (error) 3640100979Srwatson goto out; 3641100979Srwatson 3642105694Srwatson mac_init_vnode_label(&intlabel); 3643105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3644105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3645111119Simp mac.m_buflen, M_WAITOK); 3646105694Srwatson NDFREE(&nd, 0); 3647105694Srwatson mac_destroy_vnode_label(&intlabel); 3648100979Srwatson 3649105694Srwatson if (error == 0) 3650105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3651105694Srwatson 3652100979Srwatsonout: 3653105694Srwatson mtx_unlock(&Giant); /* VFS */ 3654105694Srwatson 3655105694Srwatson free(buffer, M_MACTEMP); 3656105694Srwatson free(elements, M_MACTEMP); 3657105694Srwatson 3658100979Srwatson return (error); 3659100979Srwatson} 3660100979Srwatson 3661100979Srwatson/* 3662100979Srwatson * MPSAFE 3663100979Srwatson */ 3664100979Srwatsonint 3665100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3666100979Srwatson{ 3667105694Srwatson struct label intlabel; 3668105694Srwatson struct pipe *pipe; 3669100979Srwatson struct file *fp; 3670100979Srwatson struct mount *mp; 3671100979Srwatson struct vnode *vp; 3672105694Srwatson struct mac mac; 3673105694Srwatson char *buffer; 3674100979Srwatson int error; 3675100979Srwatson 3676105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3677100979Srwatson if (error) 3678105694Srwatson return (error); 3679100979Srwatson 3680105694Srwatson error = mac_check_structmac_consistent(&mac); 3681100979Srwatson if (error) 3682105694Srwatson return (error); 3683100979Srwatson 3684111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3685105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3686105694Srwatson if (error) { 3687105694Srwatson free(buffer, M_MACTEMP); 3688105694Srwatson return (error); 3689105694Srwatson } 3690105694Srwatson 3691105694Srwatson mtx_lock(&Giant); /* VFS */ 3692105694Srwatson 3693107849Salfred error = fget(td, uap->fd, &fp); 3694100979Srwatson if (error) 3695105694Srwatson goto out; 3696100979Srwatson 3697100979Srwatson switch (fp->f_type) { 3698100979Srwatson case DTYPE_FIFO: 3699100979Srwatson case DTYPE_VNODE: 3700105694Srwatson mac_init_vnode_label(&intlabel); 3701105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3702105694Srwatson if (error) { 3703105694Srwatson mac_destroy_vnode_label(&intlabel); 3704105694Srwatson break; 3705105694Srwatson } 3706105694Srwatson 3707109153Sdillon vp = fp->f_data; 3708100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3709105694Srwatson if (error != 0) { 3710105694Srwatson mac_destroy_vnode_label(&intlabel); 3711100979Srwatson break; 3712105694Srwatson } 3713100979Srwatson 3714100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3715100979Srwatson error = vn_setlabel(vp, &intlabel, td->td_ucred); 3716100979Srwatson VOP_UNLOCK(vp, 0, td); 3717100979Srwatson vn_finished_write(mp); 3718105694Srwatson 3719105694Srwatson mac_destroy_vnode_label(&intlabel); 3720100979Srwatson break; 3721105694Srwatson 3722100979Srwatson case DTYPE_PIPE: 3723105694Srwatson mac_init_pipe_label(&intlabel); 3724105694Srwatson error = mac_internalize_pipe_label(&intlabel, buffer); 3725105694Srwatson if (error == 0) { 3726109153Sdillon pipe = fp->f_data; 3727105694Srwatson PIPE_LOCK(pipe); 3728105694Srwatson error = mac_pipe_label_set(td->td_ucred, pipe, 3729105694Srwatson &intlabel); 3730105694Srwatson PIPE_UNLOCK(pipe); 3731105694Srwatson } 3732105694Srwatson 3733105694Srwatson mac_destroy_pipe_label(&intlabel); 3734100979Srwatson break; 3735105694Srwatson 3736100979Srwatson default: 3737100979Srwatson error = EINVAL; 3738100979Srwatson } 3739100979Srwatson 3740100979Srwatson fdrop(fp, td); 3741105694Srwatsonout: 3742105694Srwatson mtx_unlock(&Giant); /* VFS */ 3743105694Srwatson 3744105694Srwatson free(buffer, M_MACTEMP); 3745105694Srwatson 3746100979Srwatson return (error); 3747100979Srwatson} 3748100979Srwatson 3749100979Srwatson/* 3750100979Srwatson * MPSAFE 3751100979Srwatson */ 3752100979Srwatsonint 3753100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3754100979Srwatson{ 3755105694Srwatson struct label intlabel; 3756100979Srwatson struct nameidata nd; 3757100979Srwatson struct mount *mp; 3758105694Srwatson struct mac mac; 3759105694Srwatson char *buffer; 3760100979Srwatson int error; 3761100979Srwatson 3762105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3763100979Srwatson if (error) 3764105694Srwatson return (error); 3765100979Srwatson 3766105694Srwatson error = mac_check_structmac_consistent(&mac); 3767100979Srwatson if (error) 3768105694Srwatson return (error); 3769100979Srwatson 3770111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3771105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3772105694Srwatson if (error) { 3773105694Srwatson free(buffer, M_MACTEMP); 3774105694Srwatson return (error); 3775105694Srwatson } 3776105694Srwatson 3777105694Srwatson mac_init_vnode_label(&intlabel); 3778105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3779105694Srwatson free(buffer, M_MACTEMP); 3780105694Srwatson if (error) { 3781105694Srwatson mac_destroy_vnode_label(&intlabel); 3782105694Srwatson return (error); 3783105694Srwatson } 3784105694Srwatson 3785105694Srwatson mtx_lock(&Giant); /* VFS */ 3786105694Srwatson 3787105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3788105694Srwatson td); 3789100979Srwatson error = namei(&nd); 3790105694Srwatson if (error == 0) { 3791105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3792105694Srwatson if (error == 0) 3793105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3794105694Srwatson td->td_ucred); 3795105694Srwatson vn_finished_write(mp); 3796105694Srwatson } 3797105694Srwatson 3798105694Srwatson NDFREE(&nd, 0); 3799105694Srwatson mtx_unlock(&Giant); /* VFS */ 3800105694Srwatson mac_destroy_vnode_label(&intlabel); 3801105694Srwatson 3802105694Srwatson return (error); 3803105694Srwatson} 3804105694Srwatson 3805105694Srwatson/* 3806105694Srwatson * MPSAFE 3807105694Srwatson */ 3808105694Srwatsonint 3809105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3810105694Srwatson{ 3811105694Srwatson struct label intlabel; 3812105694Srwatson struct nameidata nd; 3813105694Srwatson struct mount *mp; 3814105694Srwatson struct mac mac; 3815105694Srwatson char *buffer; 3816105694Srwatson int error; 3817105694Srwatson 3818105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3819100979Srwatson if (error) 3820105694Srwatson return (error); 3821105694Srwatson 3822105694Srwatson error = mac_check_structmac_consistent(&mac); 3823100979Srwatson if (error) 3824105694Srwatson return (error); 3825100979Srwatson 3826111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3827105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3828105694Srwatson if (error) { 3829105694Srwatson free(buffer, M_MACTEMP); 3830105694Srwatson return (error); 3831105694Srwatson } 3832105694Srwatson 3833105694Srwatson mac_init_vnode_label(&intlabel); 3834105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3835105694Srwatson free(buffer, M_MACTEMP); 3836105694Srwatson if (error) { 3837105694Srwatson mac_destroy_vnode_label(&intlabel); 3838105694Srwatson return (error); 3839105694Srwatson } 3840105694Srwatson 3841105694Srwatson mtx_lock(&Giant); /* VFS */ 3842105694Srwatson 3843105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3844105694Srwatson td); 3845105694Srwatson error = namei(&nd); 3846105694Srwatson if (error == 0) { 3847105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3848105694Srwatson if (error == 0) 3849105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3850105694Srwatson td->td_ucred); 3851105694Srwatson vn_finished_write(mp); 3852105694Srwatson } 3853105694Srwatson 3854100979Srwatson NDFREE(&nd, 0); 3855105694Srwatson mtx_unlock(&Giant); /* VFS */ 3856105694Srwatson mac_destroy_vnode_label(&intlabel); 3857105694Srwatson 3858100979Srwatson return (error); 3859100979Srwatson} 3860100979Srwatson 3861105694Srwatson/* 3862105694Srwatson * MPSAFE 3863105694Srwatson */ 3864102123Srwatsonint 3865102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3866102123Srwatson{ 3867102123Srwatson struct mac_policy_conf *mpc; 3868102123Srwatson char target[MAC_MAX_POLICY_NAME]; 3869114806Srwatson int entrycount, error; 3870102123Srwatson 3871107849Salfred error = copyinstr(uap->policy, target, sizeof(target), NULL); 3872102123Srwatson if (error) 3873102123Srwatson return (error); 3874102123Srwatson 3875102123Srwatson error = ENOSYS; 3876102123Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3877102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3878102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3879102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3880107849Salfred uap->call, uap->arg); 3881102123Srwatson goto out; 3882102123Srwatson } 3883102123Srwatson } 3884102123Srwatson 3885114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { 3886114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3887114806Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3888114806Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3889114806Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3890114806Srwatson uap->call, uap->arg); 3891114806Srwatson break; 3892114806Srwatson } 3893114806Srwatson } 3894114806Srwatson mac_policy_list_unbusy(); 3895114806Srwatson } 3896102123Srwatsonout: 3897102123Srwatson return (error); 3898102123Srwatson} 3899102123Srwatson 3900100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3901100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3902100979Srwatson 3903100979Srwatson#else /* !MAC */ 3904100979Srwatson 3905100979Srwatsonint 3906105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3907105694Srwatson{ 3908105694Srwatson 3909105694Srwatson return (ENOSYS); 3910105694Srwatson} 3911105694Srwatson 3912105694Srwatsonint 3913100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3914100979Srwatson{ 3915100979Srwatson 3916100894Srwatson return (ENOSYS); 3917100894Srwatson} 3918100894Srwatson 3919100894Srwatsonint 3920100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3921100894Srwatson{ 3922100894Srwatson 3923100894Srwatson return (ENOSYS); 3924100894Srwatson} 3925100894Srwatson 3926100894Srwatsonint 3927100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3928100894Srwatson{ 3929100894Srwatson 3930100894Srwatson return (ENOSYS); 3931100894Srwatson} 3932100894Srwatson 3933100894Srwatsonint 3934100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3935100894Srwatson{ 3936100894Srwatson 3937100894Srwatson return (ENOSYS); 3938100894Srwatson} 3939100894Srwatson 3940100894Srwatsonint 3941105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3942105694Srwatson{ 3943105694Srwatson 3944105694Srwatson return (ENOSYS); 3945105694Srwatson} 3946105694Srwatson 3947105694Srwatsonint 3948100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3949100894Srwatson{ 3950100894Srwatson 3951100894Srwatson return (ENOSYS); 3952100894Srwatson} 3953100894Srwatson 3954100894Srwatsonint 3955100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3956100894Srwatson{ 3957100894Srwatson 3958100894Srwatson return (ENOSYS); 3959100894Srwatson} 3960100979Srwatson 3961102123Srwatsonint 3962105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3963105694Srwatson{ 3964105694Srwatson 3965105694Srwatson return (ENOSYS); 3966105694Srwatson} 3967105694Srwatson 3968105694Srwatsonint 3969102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3970102123Srwatson{ 3971102123Srwatson 3972102123Srwatson return (ENOSYS); 3973102123Srwatson} 3974102123Srwatson 3975105694Srwatson#endif 3976