mac_syscalls.c revision 121371
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_syscalls.c 121371 2003-10-22 20:42:22Z rwatson $"); 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> 59116701Srwatson#include <sys/sbuf.h> 60100979Srwatson#include <sys/systm.h> 61100894Srwatson#include <sys/sysproto.h> 62100894Srwatson#include <sys/sysent.h> 63100979Srwatson#include <sys/vnode.h> 64100979Srwatson#include <sys/mount.h> 65100979Srwatson#include <sys/file.h> 66100979Srwatson#include <sys/namei.h> 67100979Srwatson#include <sys/socket.h> 68100979Srwatson#include <sys/pipe.h> 69100979Srwatson#include <sys/socketvar.h> 70100979Srwatson#include <sys/sysctl.h> 71100894Srwatson 72100979Srwatson#include <vm/vm.h> 73100979Srwatson#include <vm/pmap.h> 74100979Srwatson#include <vm/vm_map.h> 75100979Srwatson#include <vm/vm_object.h> 76100979Srwatson 77100979Srwatson#include <sys/mac_policy.h> 78100979Srwatson 79100979Srwatson#include <fs/devfs/devfs.h> 80100979Srwatson 81100979Srwatson#include <net/bpfdesc.h> 82100979Srwatson#include <net/if.h> 83100979Srwatson#include <net/if_var.h> 84100979Srwatson 85100979Srwatson#include <netinet/in.h> 86100979Srwatson#include <netinet/ip_var.h> 87100979Srwatson 88100979Srwatson#ifdef MAC 89100979Srwatson 90101712Srwatson/* 91101712Srwatson * Declare that the kernel provides MAC support, version 1. This permits 92101712Srwatson * modules to refuse to be loaded if the necessary support isn't present, 93101712Srwatson * even if it's pre-boot. 94101712Srwatson */ 95101712SrwatsonMODULE_VERSION(kernel_mac_support, 1); 96101712Srwatson 97100979SrwatsonSYSCTL_DECL(_security); 98100979Srwatson 99100979SrwatsonSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 100100979Srwatson "TrustedBSD MAC policy controls"); 101104517Srwatson 102114846Srwatson#if MAC_MAX_SLOTS > 32 103114846Srwatson#error "MAC_MAX_SLOTS too large" 104100979Srwatson#endif 105105497Srwatson 106114846Srwatsonstatic unsigned int mac_max_slots = MAC_MAX_SLOTS; 107114846Srwatsonstatic unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1; 108114846SrwatsonSYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD, 109114846Srwatson &mac_max_slots, 0, ""); 110100979Srwatson 111105959Srwatson/* 112105959Srwatson * Has the kernel started generating labeled objects yet? All read/write 113105959Srwatson * access to this variable is serialized during the boot process. Following 114105959Srwatson * the end of serialization, we don't update this flag; no locking. 115105959Srwatson */ 116100979Srwatsonstatic int mac_late = 0; 117100979Srwatson 118105988Srwatson/* 119105988Srwatson * Warn about EA transactions only the first time they happen. 120105988Srwatson * Weak coherency, no locking. 121105988Srwatson */ 122105988Srwatsonstatic int ea_warn_once = 0; 123105988Srwatson 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 */ 135118308Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 136113487Srwatsonstatic int mac_labelmbufs = 0; 137113487Srwatson#endif 138113487Srwatson 139100979Srwatsonstatic int mac_enforce_fs = 1; 140100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 141100979Srwatson &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 142100979SrwatsonTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 143100979Srwatson 144107089Srwatsonstatic int mac_enforce_kld = 1; 145107089SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW, 146107089Srwatson &mac_enforce_kld, 0, "Enforce MAC policy on kld operations"); 147107089SrwatsonTUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld); 148107089Srwatson 149100979Srwatsonstatic int mac_enforce_network = 1; 150100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 151100979Srwatson &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 152100979SrwatsonTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 153100979Srwatson 154103513Srwatsonstatic int mac_enforce_pipe = 1; 155103513SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 156103513Srwatson &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 157104236SrwatsonTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 158103513Srwatson 159100979Srwatsonstatic int mac_enforce_process = 1; 160100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 161100979Srwatson &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 162100979SrwatsonTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 163100979Srwatson 164100979Srwatsonstatic int mac_enforce_socket = 1; 165100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 166100979Srwatson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 167100979SrwatsonTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 168100979Srwatson 169106045Srwatsonstatic int mac_enforce_system = 1; 170106045SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 171106045Srwatson &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 172106045SrwatsonTUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 173106025Srwatson 174106045Srwatsonstatic int mac_enforce_vm = 1; 175103514SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 176103514Srwatson &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 177104236SrwatsonTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 178103514Srwatson 179103136Srwatsonstatic int mac_mmap_revocation = 1; 180103136SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 181103136Srwatson &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 182103136Srwatson "relabel"); 183101892Srwatsonstatic int mac_mmap_revocation_via_cow = 0; 184100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 185100979Srwatson &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 186100979Srwatson "copy-on-write semantics, or by removing all write access"); 187100979Srwatson 188101988Srwatson#ifdef MAC_DEBUG 189104268SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 190104268Srwatson "TrustedBSD MAC debug info"); 191104268Srwatson 192104268Srwatsonstatic int mac_debug_label_fallback = 0; 193104268SrwatsonSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 194104268Srwatson &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 195104268Srwatson "when label is corrupted."); 196104268SrwatsonTUNABLE_INT("security.mac.debug_label_fallback", 197104268Srwatson &mac_debug_label_fallback); 198104268Srwatson 199104517SrwatsonSYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 200104517Srwatson "TrustedBSD MAC object counters"); 201104517Srwatson 202100979Srwatsonstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 203100979Srwatson nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 204107105Srwatson nmacipqs, nmacpipes, nmacprocs; 205104517Srwatson 206119184Srwatson#define MAC_DEBUG_COUNTER_INC(x) atomic_add_int(x, 1); 207119184Srwatson#define MAC_DEBUG_COUNTER_DEC(x) atomic_subtract_int(x, 1); 208119184Srwatson 209104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 210100979Srwatson &nmacmbufs, 0, "number of mbufs in use"); 211104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 212100979Srwatson &nmaccreds, 0, "number of ucreds in use"); 213104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 214100979Srwatson &nmacifnets, 0, "number of ifnets in use"); 215104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 216100979Srwatson &nmacipqs, 0, "number of ipqs in use"); 217104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 218100979Srwatson &nmacbpfdescs, 0, "number of bpfdescs in use"); 219104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 220100979Srwatson &nmacsockets, 0, "number of sockets in use"); 221104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 222100979Srwatson &nmacpipes, 0, "number of pipes in use"); 223107105SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, procs, CTLFLAG_RD, 224107105Srwatson &nmacprocs, 0, "number of procs in use"); 225104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 226100979Srwatson &nmacmounts, 0, "number of mounts in use"); 227104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 228100979Srwatson &nmactemp, 0, "number of temporary labels in use"); 229104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 230100979Srwatson &nmacvnodes, 0, "number of vnodes in use"); 231104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 232100979Srwatson &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 233119184Srwatson#else 234119184Srwatson#define MAC_DEBUG_COUNTER_INC(x) 235119184Srwatson#define MAC_DEBUG_COUNTER_DEC(x) 236101988Srwatson#endif 237100979Srwatson 238100979Srwatsonstatic int mac_policy_register(struct mac_policy_conf *mpc); 239100979Srwatsonstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 240100979Srwatson 241104546Srwatsonstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 242104546Srwatson struct vnode *vp, int *prot); 243100979Srwatsonstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 244100979Srwatson struct ucred *cred, struct vm_map *map); 245100979Srwatson 246104541Srwatsonstatic void mac_destroy_socket_label(struct label *label); 247104541Srwatson 248105988Srwatsonstatic int mac_setlabel_vnode_extattr(struct ucred *cred, 249105988Srwatson struct vnode *vp, struct label *intlabel); 250105988Srwatson 251100979SrwatsonMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 252105694SrwatsonMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 253100979Srwatson 254100979Srwatson/* 255114806Srwatson * mac_static_policy_list holds a list of policy modules that are not 256114806Srwatson * loaded while the system is "live", and cannot be unloaded. These 257114806Srwatson * policies can be invoked without holding the busy count. 258114806Srwatson * 259114806Srwatson * mac_policy_list stores the list of dynamic policies. A busy count is 260106856Srwatson * maintained for the list, stored in mac_policy_busy. The busy count 261114806Srwatson * is protected by mac_policy_mtx; the list may be modified only 262106856Srwatson * while the busy count is 0, requiring that the lock be held to 263106856Srwatson * prevent new references to the list from being acquired. For almost 264106856Srwatson * all operations, incrementing the busy count is sufficient to 265106856Srwatson * guarantee consistency, as the list cannot be modified while the 266106856Srwatson * busy count is elevated. For a few special operations involving a 267114806Srwatson * change to the list of active policies, the mtx itself must be held. 268114806Srwatson * A condition variable, mac_policy_cv, is used to signal potential 269114806Srwatson * exclusive consumers that they should try to acquire the lock if a 270114806Srwatson * first attempt at exclusive access fails. 271100979Srwatson */ 272114806Srwatsonstatic struct mtx mac_policy_mtx; 273114806Srwatsonstatic struct cv mac_policy_cv; 274114806Srwatsonstatic int mac_policy_count; 275100979Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 276114806Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_static_policy_list; 277100979Srwatson 278106856Srwatson/* 279111883Sjhb * We manually invoke WITNESS_WARN() to allow Witness to generate 280106856Srwatson * warnings even if we don't end up ever triggering the wait at 281106856Srwatson * run-time. The consumer of the exclusive interface must not hold 282106856Srwatson * any locks (other than potentially Giant) since we may sleep for 283106856Srwatson * long (potentially indefinite) periods of time waiting for the 284106856Srwatson * framework to become quiescent so that a policy list change may 285106856Srwatson * be made. 286106856Srwatson */ 287114806Srwatsonstatic __inline void 288114806Srwatsonmac_policy_grab_exclusive(void) 289114806Srwatson{ 290114806Srwatson WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 291114806Srwatson "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__); 292114806Srwatson mtx_lock(&mac_policy_mtx); 293114806Srwatson while (mac_policy_count != 0) 294114806Srwatson cv_wait(&mac_policy_cv, &mac_policy_mtx); 295114806Srwatson} 296106856Srwatson 297114806Srwatsonstatic __inline void 298114806Srwatsonmac_policy_assert_exclusive(void) 299114806Srwatson{ 300114806Srwatson mtx_assert(&mac_policy_mtx, MA_OWNED); 301114806Srwatson KASSERT(mac_policy_count == 0, 302114806Srwatson ("mac_policy_assert_exclusive(): not exclusive")); 303114806Srwatson} 304113487Srwatson 305114806Srwatsonstatic __inline void 306114806Srwatsonmac_policy_release_exclusive(void) 307114806Srwatson{ 308100979Srwatson 309114806Srwatson KASSERT(mac_policy_count == 0, 310114806Srwatson ("mac_policy_release_exclusive(): not exclusive")); 311114806Srwatson mtx_unlock(&mac_policy_mtx); 312114806Srwatson cv_signal(&mac_policy_cv); 313114806Srwatson} 314100979Srwatson 315114806Srwatsonstatic __inline void 316114806Srwatsonmac_policy_list_busy(void) 317114806Srwatson{ 318114806Srwatson mtx_lock(&mac_policy_mtx); 319114806Srwatson mac_policy_count++; 320114806Srwatson mtx_unlock(&mac_policy_mtx); 321114806Srwatson} 322114806Srwatson 323114806Srwatsonstatic __inline int 324114806Srwatsonmac_policy_list_conditional_busy(void) 325114806Srwatson{ 326114806Srwatson int ret; 327114806Srwatson 328114806Srwatson mtx_lock(&mac_policy_mtx); 329114806Srwatson if (!LIST_EMPTY(&mac_policy_list)) { 330114806Srwatson mac_policy_count++; 331114806Srwatson ret = 1; 332114806Srwatson } else 333114806Srwatson ret = 0; 334114806Srwatson mtx_unlock(&mac_policy_mtx); 335114806Srwatson return (ret); 336114806Srwatson} 337114806Srwatson 338114806Srwatsonstatic __inline void 339114806Srwatsonmac_policy_list_unbusy(void) 340114806Srwatson{ 341114806Srwatson mtx_lock(&mac_policy_mtx); 342114806Srwatson mac_policy_count--; 343114806Srwatson KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK")); 344114806Srwatson if (mac_policy_count == 0) 345114806Srwatson cv_signal(&mac_policy_cv); 346114806Srwatson mtx_unlock(&mac_policy_mtx); 347114806Srwatson} 348114806Srwatson 349100979Srwatson/* 350100979Srwatson * MAC_CHECK performs the designated check by walking the policy 351100979Srwatson * module list and checking with each as to how it feels about the 352100979Srwatson * request. Note that it returns its value via 'error' in the scope 353100979Srwatson * of the caller. 354100979Srwatson */ 355100979Srwatson#define MAC_CHECK(check, args...) do { \ 356100979Srwatson struct mac_policy_conf *mpc; \ 357114806Srwatson int entrycount; \ 358100979Srwatson \ 359100979Srwatson error = 0; \ 360114806Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ 361100979Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 362121371Srwatson error = mac_error_select( \ 363100979Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 364100979Srwatson error); \ 365100979Srwatson } \ 366114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ 367114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 368114806Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 369121371Srwatson error = mac_error_select( \ 370114806Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 371114806Srwatson error); \ 372114806Srwatson } \ 373114806Srwatson mac_policy_list_unbusy(); \ 374114806Srwatson } \ 375100979Srwatson} while (0) 376100979Srwatson 377100979Srwatson/* 378100979Srwatson * MAC_BOOLEAN performs the designated boolean composition by walking 379100979Srwatson * the module list, invoking each instance of the operation, and 380100979Srwatson * combining the results using the passed C operator. Note that it 381100979Srwatson * returns its value via 'result' in the scope of the caller, which 382100979Srwatson * should be initialized by the caller in a meaningful way to get 383100979Srwatson * a meaningful result. 384100979Srwatson */ 385100979Srwatson#define MAC_BOOLEAN(operation, composition, args...) do { \ 386100979Srwatson struct mac_policy_conf *mpc; \ 387114806Srwatson int entrycount; \ 388100979Srwatson \ 389114806Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ 390100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 391100979Srwatson result = result composition \ 392100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 393100979Srwatson } \ 394114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ 395114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 396114806Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 397114806Srwatson result = result composition \ 398114806Srwatson mpc->mpc_ops->mpo_ ## operation \ 399114806Srwatson (args); \ 400114806Srwatson } \ 401114806Srwatson mac_policy_list_unbusy(); \ 402114806Srwatson } \ 403100979Srwatson} while (0) 404100979Srwatson 405105694Srwatson#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 406105694Srwatson outbuflen) do { \ 407116701Srwatson int claimed, first, ignorenotfound, savedlen; \ 408116701Srwatson char *element_name, *element_temp; \ 409116701Srwatson struct sbuf sb; \ 410105694Srwatson \ 411105694Srwatson error = 0; \ 412116701Srwatson first = 1; \ 413116701Srwatson sbuf_new(&sb, outbuf, outbuflen, SBUF_FIXEDLEN); \ 414105694Srwatson element_temp = elementlist; \ 415105694Srwatson while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 416105694Srwatson if (element_name[0] == '?') { \ 417105694Srwatson element_name++; \ 418105694Srwatson ignorenotfound = 1; \ 419116701Srwatson } else \ 420105694Srwatson ignorenotfound = 0; \ 421116701Srwatson savedlen = sbuf_len(&sb); \ 422105694Srwatson if (first) { \ 423116701Srwatson error = sbuf_printf(&sb, "%s/", element_name); \ 424105694Srwatson first = 0; \ 425105694Srwatson } else \ 426116701Srwatson error = sbuf_printf(&sb, ",%s/", element_name); \ 427116701Srwatson if (error == -1) { \ 428116701Srwatson error = EINVAL; /* XXX: E2BIG? */ \ 429105694Srwatson break; \ 430105694Srwatson } \ 431116701Srwatson claimed = 0; \ 432105694Srwatson MAC_CHECK(externalize_ ## type, label, element_name, \ 433116701Srwatson &sb, &claimed); \ 434105694Srwatson if (error) \ 435105694Srwatson break; \ 436116701Srwatson if (claimed == 0 && ignorenotfound) { \ 437116701Srwatson /* Revert last label name. */ \ 438116701Srwatson sbuf_setpos(&sb, savedlen); \ 439116701Srwatson } else if (claimed != 1) { \ 440116701Srwatson error = EINVAL; /* XXX: ENOLABEL? */ \ 441105694Srwatson break; \ 442105694Srwatson } \ 443105694Srwatson } \ 444116701Srwatson sbuf_finish(&sb); \ 445105694Srwatson} while (0) 446105694Srwatson 447105694Srwatson#define MAC_INTERNALIZE(type, label, instring) do { \ 448105694Srwatson char *element, *element_name, *element_data; \ 449105694Srwatson int claimed; \ 450105694Srwatson \ 451105694Srwatson error = 0; \ 452105694Srwatson element = instring; \ 453105694Srwatson while ((element_name = strsep(&element, ",")) != NULL) { \ 454105694Srwatson element_data = element_name; \ 455105694Srwatson element_name = strsep(&element_data, "/"); \ 456105694Srwatson if (element_data == NULL) { \ 457105694Srwatson error = EINVAL; \ 458105694Srwatson break; \ 459105694Srwatson } \ 460105694Srwatson claimed = 0; \ 461105694Srwatson MAC_CHECK(internalize_ ## type, label, element_name, \ 462105694Srwatson element_data, &claimed); \ 463105694Srwatson if (error) \ 464105694Srwatson break; \ 465105694Srwatson if (claimed != 1) { \ 466105694Srwatson /* XXXMAC: Another error here? */ \ 467105694Srwatson error = EINVAL; \ 468105694Srwatson break; \ 469105694Srwatson } \ 470105694Srwatson } \ 471105694Srwatson} while (0) 472105694Srwatson 473100979Srwatson/* 474100979Srwatson * MAC_PERFORM performs the designated operation by walking the policy 475100979Srwatson * module list and invoking that operation for each policy. 476100979Srwatson */ 477100979Srwatson#define MAC_PERFORM(operation, args...) do { \ 478100979Srwatson struct mac_policy_conf *mpc; \ 479114806Srwatson int entrycount; \ 480100979Srwatson \ 481114806Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ 482100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 483100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 484100979Srwatson } \ 485114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ 486114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 487114806Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 488114806Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 489114806Srwatson } \ 490114806Srwatson mac_policy_list_unbusy(); \ 491114806Srwatson } \ 492100979Srwatson} while (0) 493100979Srwatson 494100979Srwatson/* 495100979Srwatson * Initialize the MAC subsystem, including appropriate SMP locks. 496100979Srwatson */ 497100979Srwatsonstatic void 498100979Srwatsonmac_init(void) 499100979Srwatson{ 500100979Srwatson 501114806Srwatson LIST_INIT(&mac_static_policy_list); 502100979Srwatson LIST_INIT(&mac_policy_list); 503114806Srwatson 504114806Srwatson mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF); 505114806Srwatson cv_init(&mac_policy_cv, "mac_policy_cv"); 506100979Srwatson} 507100979Srwatson 508100979Srwatson/* 509100979Srwatson * For the purposes of modules that want to know if they were loaded 510100979Srwatson * "early", set the mac_late flag once we've processed modules either 511100979Srwatson * linked into the kernel, or loaded before the kernel startup. 512100979Srwatson */ 513100979Srwatsonstatic void 514100979Srwatsonmac_late_init(void) 515100979Srwatson{ 516100979Srwatson 517100979Srwatson mac_late = 1; 518100979Srwatson} 519100979Srwatson 520100979Srwatson/* 521113487Srwatson * After the policy list has changed, walk the list to update any global 522118308Srwatson * flags. Currently, we support only one flag, and it's conditionally 523118308Srwatson * defined; as a result, the entire function is conditional. Eventually, 524118308Srwatson * the #else case might also iterate across the policies. 525113487Srwatson */ 526113487Srwatsonstatic void 527113487Srwatsonmac_policy_updateflags(void) 528113487Srwatson{ 529118308Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 530113487Srwatson struct mac_policy_conf *tmpc; 531113487Srwatson int labelmbufs; 532113487Srwatson 533114806Srwatson mac_policy_assert_exclusive(); 534113487Srwatson 535113487Srwatson labelmbufs = 0; 536114806Srwatson LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { 537114806Srwatson if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) 538114806Srwatson labelmbufs++; 539114806Srwatson } 540113487Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 541113487Srwatson if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) 542113487Srwatson labelmbufs++; 543113487Srwatson } 544113487Srwatson mac_labelmbufs = (labelmbufs != 0); 545113487Srwatson#endif 546113487Srwatson} 547113487Srwatson 548113487Srwatson/* 549100979Srwatson * Allow MAC policy modules to register during boot, etc. 550100979Srwatson */ 551100894Srwatsonint 552100979Srwatsonmac_policy_modevent(module_t mod, int type, void *data) 553100979Srwatson{ 554100979Srwatson struct mac_policy_conf *mpc; 555100979Srwatson int error; 556100979Srwatson 557100979Srwatson error = 0; 558100979Srwatson mpc = (struct mac_policy_conf *) data; 559100979Srwatson 560100979Srwatson switch (type) { 561100979Srwatson case MOD_LOAD: 562100979Srwatson if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 563100979Srwatson mac_late) { 564100979Srwatson printf("mac_policy_modevent: can't load %s policy " 565100979Srwatson "after booting\n", mpc->mpc_name); 566100979Srwatson error = EBUSY; 567100979Srwatson break; 568100979Srwatson } 569100979Srwatson error = mac_policy_register(mpc); 570100979Srwatson break; 571100979Srwatson case MOD_UNLOAD: 572100979Srwatson /* Don't unregister the module if it was never registered. */ 573100979Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 574100979Srwatson != 0) 575100979Srwatson error = mac_policy_unregister(mpc); 576100979Srwatson else 577100979Srwatson error = 0; 578100979Srwatson break; 579100979Srwatson default: 580100979Srwatson break; 581100979Srwatson } 582100979Srwatson 583100979Srwatson return (error); 584100979Srwatson} 585100979Srwatson 586100979Srwatsonstatic int 587100979Srwatsonmac_policy_register(struct mac_policy_conf *mpc) 588100979Srwatson{ 589100979Srwatson struct mac_policy_conf *tmpc; 590114806Srwatson int error, slot, static_entry; 591100979Srwatson 592114806Srwatson error = 0; 593114806Srwatson 594114806Srwatson /* 595114806Srwatson * We don't technically need exclusive access while !mac_late, 596114806Srwatson * but hold it for assertion consistency. 597114806Srwatson */ 598114806Srwatson mac_policy_grab_exclusive(); 599114806Srwatson 600114806Srwatson /* 601114806Srwatson * If the module can potentially be unloaded, or we're loading 602114806Srwatson * late, we have to stick it in the non-static list and pay 603114806Srwatson * an extra performance overhead. Otherwise, we can pay a 604114806Srwatson * light locking cost and stick it in the static list. 605114806Srwatson */ 606114806Srwatson static_entry = (!mac_late && 607114806Srwatson !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK)); 608114806Srwatson 609114806Srwatson if (static_entry) { 610114806Srwatson LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { 611114806Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 612114806Srwatson error = EEXIST; 613114806Srwatson goto out; 614114806Srwatson } 615100979Srwatson } 616114806Srwatson } else { 617114806Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 618114806Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 619114806Srwatson error = EEXIST; 620114806Srwatson goto out; 621114806Srwatson } 622114806Srwatson } 623100979Srwatson } 624100979Srwatson if (mpc->mpc_field_off != NULL) { 625114846Srwatson slot = ffs(mac_slot_offsets_free); 626100979Srwatson if (slot == 0) { 627114806Srwatson error = ENOMEM; 628114806Srwatson goto out; 629100979Srwatson } 630100979Srwatson slot--; 631114846Srwatson mac_slot_offsets_free &= ~(1 << slot); 632100979Srwatson *mpc->mpc_field_off = slot; 633100979Srwatson } 634100979Srwatson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 635100979Srwatson 636114806Srwatson /* 637114806Srwatson * If we're loading a MAC module after the framework has 638114806Srwatson * initialized, it has to go into the dynamic list. If 639114806Srwatson * we're loading it before we've finished initializing, 640114806Srwatson * it can go into the static list with weaker locker 641114806Srwatson * requirements. 642114806Srwatson */ 643114806Srwatson if (static_entry) 644114806Srwatson LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list); 645114806Srwatson else 646114806Srwatson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 647114806Srwatson 648100979Srwatson /* Per-policy initialization. */ 649100979Srwatson if (mpc->mpc_ops->mpo_init != NULL) 650100979Srwatson (*(mpc->mpc_ops->mpo_init))(mpc); 651113487Srwatson mac_policy_updateflags(); 652100979Srwatson 653100979Srwatson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 654100979Srwatson mpc->mpc_name); 655100979Srwatson 656114806Srwatsonout: 657114806Srwatson mac_policy_release_exclusive(); 658114806Srwatson return (error); 659100979Srwatson} 660100979Srwatson 661100979Srwatsonstatic int 662100979Srwatsonmac_policy_unregister(struct mac_policy_conf *mpc) 663100979Srwatson{ 664100979Srwatson 665104520Srwatson /* 666104520Srwatson * If we fail the load, we may get a request to unload. Check 667104520Srwatson * to see if we did the run-time registration, and if not, 668104520Srwatson * silently succeed. 669104520Srwatson */ 670114806Srwatson mac_policy_grab_exclusive(); 671104520Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 672114806Srwatson mac_policy_release_exclusive(); 673104520Srwatson return (0); 674104520Srwatson } 675100979Srwatson#if 0 676100979Srwatson /* 677100979Srwatson * Don't allow unloading modules with private data. 678100979Srwatson */ 679104520Srwatson if (mpc->mpc_field_off != NULL) { 680104520Srwatson MAC_POLICY_LIST_UNLOCK(); 681100979Srwatson return (EBUSY); 682104520Srwatson } 683100979Srwatson#endif 684104520Srwatson /* 685104520Srwatson * Only allow the unload to proceed if the module is unloadable 686104520Srwatson * by its own definition. 687104520Srwatson */ 688104520Srwatson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 689114806Srwatson mac_policy_release_exclusive(); 690100979Srwatson return (EBUSY); 691104520Srwatson } 692100979Srwatson if (mpc->mpc_ops->mpo_destroy != NULL) 693100979Srwatson (*(mpc->mpc_ops->mpo_destroy))(mpc); 694100979Srwatson 695100979Srwatson LIST_REMOVE(mpc, mpc_list); 696106856Srwatson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 697113487Srwatson mac_policy_updateflags(); 698100979Srwatson 699114806Srwatson mac_policy_release_exclusive(); 700114806Srwatson 701100979Srwatson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 702100979Srwatson mpc->mpc_name); 703100979Srwatson 704100979Srwatson return (0); 705100979Srwatson} 706100979Srwatson 707100979Srwatson/* 708100979Srwatson * Define an error value precedence, and given two arguments, selects the 709100979Srwatson * value with the higher precedence. 710100979Srwatson */ 711121371Srwatsonint 712121371Srwatsonmac_error_select(int error1, int error2) 713100979Srwatson{ 714100979Srwatson 715100979Srwatson /* Certain decision-making errors take top priority. */ 716100979Srwatson if (error1 == EDEADLK || error2 == EDEADLK) 717100979Srwatson return (EDEADLK); 718100979Srwatson 719100979Srwatson /* Invalid arguments should be reported where possible. */ 720100979Srwatson if (error1 == EINVAL || error2 == EINVAL) 721100979Srwatson return (EINVAL); 722100979Srwatson 723100979Srwatson /* Precedence goes to "visibility", with both process and file. */ 724100979Srwatson if (error1 == ESRCH || error2 == ESRCH) 725100979Srwatson return (ESRCH); 726100979Srwatson 727100979Srwatson if (error1 == ENOENT || error2 == ENOENT) 728100979Srwatson return (ENOENT); 729100979Srwatson 730100979Srwatson /* Precedence goes to DAC/MAC protections. */ 731100979Srwatson if (error1 == EACCES || error2 == EACCES) 732100979Srwatson return (EACCES); 733100979Srwatson 734100979Srwatson /* Precedence goes to privilege. */ 735100979Srwatson if (error1 == EPERM || error2 == EPERM) 736100979Srwatson return (EPERM); 737100979Srwatson 738100979Srwatson /* Precedence goes to error over success; otherwise, arbitrary. */ 739100979Srwatson if (error1 != 0) 740100979Srwatson return (error1); 741100979Srwatson return (error2); 742100979Srwatson} 743100979Srwatson 744113482Srwatsonstatic struct label * 745113482Srwatsonmbuf_to_label(struct mbuf *mbuf) 746113482Srwatson{ 747113487Srwatson struct m_tag *tag; 748113482Srwatson struct label *label; 749113482Srwatson 750113487Srwatson tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL); 751113487Srwatson label = (struct label *)(tag+1); 752113482Srwatson 753113482Srwatson return (label); 754113482Srwatson} 755113482Srwatson 756104521Srwatsonstatic void 757104521Srwatsonmac_init_label(struct label *label) 758104521Srwatson{ 759104521Srwatson 760104521Srwatson bzero(label, sizeof(*label)); 761104521Srwatson label->l_flags = MAC_FLAG_INITIALIZED; 762104521Srwatson} 763104521Srwatson 764104521Srwatsonstatic void 765104521Srwatsonmac_destroy_label(struct label *label) 766104521Srwatson{ 767104521Srwatson 768104521Srwatson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 769104521Srwatson ("destroying uninitialized label")); 770104521Srwatson 771104521Srwatson bzero(label, sizeof(*label)); 772104521Srwatson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 773104521Srwatson} 774104521Srwatson 775100979Srwatsonvoid 776104527Srwatsonmac_init_bpfdesc(struct bpf_d *bpf_d) 777104521Srwatson{ 778104521Srwatson 779104527Srwatson mac_init_label(&bpf_d->bd_label); 780104527Srwatson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 781119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacbpfdescs); 782104521Srwatson} 783104521Srwatson 784105694Srwatsonstatic void 785105694Srwatsonmac_init_cred_label(struct label *label) 786104521Srwatson{ 787104521Srwatson 788105694Srwatson mac_init_label(label); 789105694Srwatson MAC_PERFORM(init_cred_label, label); 790119184Srwatson MAC_DEBUG_COUNTER_INC(&nmaccreds); 791104521Srwatson} 792104521Srwatson 793104521Srwatsonvoid 794105694Srwatsonmac_init_cred(struct ucred *cred) 795105694Srwatson{ 796105694Srwatson 797105694Srwatson mac_init_cred_label(&cred->cr_label); 798105694Srwatson} 799105694Srwatson 800105694Srwatsonvoid 801104527Srwatsonmac_init_devfsdirent(struct devfs_dirent *de) 802104521Srwatson{ 803104521Srwatson 804104527Srwatson mac_init_label(&de->de_label); 805104527Srwatson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 806119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacdevfsdirents); 807104521Srwatson} 808104521Srwatson 809105694Srwatsonstatic void 810105694Srwatsonmac_init_ifnet_label(struct label *label) 811104521Srwatson{ 812104521Srwatson 813105694Srwatson mac_init_label(label); 814105694Srwatson MAC_PERFORM(init_ifnet_label, label); 815119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacifnets); 816104521Srwatson} 817104521Srwatson 818104521Srwatsonvoid 819105694Srwatsonmac_init_ifnet(struct ifnet *ifp) 820105694Srwatson{ 821105694Srwatson 822105694Srwatson mac_init_ifnet_label(&ifp->if_label); 823105694Srwatson} 824105694Srwatson 825112675Srwatsonint 826112675Srwatsonmac_init_ipq(struct ipq *ipq, int flag) 827104521Srwatson{ 828112675Srwatson int error; 829104521Srwatson 830104527Srwatson mac_init_label(&ipq->ipq_label); 831112675Srwatson 832112675Srwatson MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag); 833112675Srwatson if (error) { 834112675Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 835112675Srwatson mac_destroy_label(&ipq->ipq_label); 836119184Srwatson } else { 837119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacipqs); 838112675Srwatson } 839112675Srwatson return (error); 840104521Srwatson} 841104521Srwatson 842104527Srwatsonint 843113487Srwatsonmac_init_mbuf_tag(struct m_tag *tag, int flag) 844104527Srwatson{ 845113487Srwatson struct label *label; 846113526Srwatson int error; 847104528Srwatson 848113487Srwatson label = (struct label *) (tag + 1); 849113487Srwatson mac_init_label(label); 850104527Srwatson 851113526Srwatson MAC_CHECK(init_mbuf_label, label, flag); 852104528Srwatson if (error) { 853113487Srwatson MAC_PERFORM(destroy_mbuf_label, label); 854113487Srwatson mac_destroy_label(label); 855119184Srwatson } else { 856119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacmbufs); 857104528Srwatson } 858104528Srwatson return (error); 859104527Srwatson} 860104527Srwatson 861113487Srwatsonint 862113487Srwatsonmac_init_mbuf(struct mbuf *m, int flag) 863113487Srwatson{ 864113487Srwatson struct m_tag *tag; 865113487Srwatson int error; 866113487Srwatson 867113487Srwatson M_ASSERTPKTHDR(m); 868113487Srwatson 869113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 870113487Srwatson /* 871118308Srwatson * If conditionally allocating mbuf labels, don't allocate unless 872118308Srwatson * they are required. 873113487Srwatson */ 874118308Srwatson if (!mac_labelmbufs) 875118308Srwatson return (0); 876113487Srwatson#endif 877118308Srwatson tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 878118308Srwatson flag); 879118308Srwatson if (tag == NULL) 880118308Srwatson return (ENOMEM); 881118308Srwatson error = mac_init_mbuf_tag(tag, flag); 882118308Srwatson if (error) { 883118308Srwatson m_tag_free(tag); 884118308Srwatson return (error); 885113487Srwatson } 886118308Srwatson m_tag_prepend(m, tag); 887113487Srwatson return (0); 888113487Srwatson} 889113487Srwatson 890104521Srwatsonvoid 891104527Srwatsonmac_init_mount(struct mount *mp) 892104521Srwatson{ 893104521Srwatson 894104527Srwatson mac_init_label(&mp->mnt_mntlabel); 895104527Srwatson mac_init_label(&mp->mnt_fslabel); 896104527Srwatson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 897104527Srwatson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 898119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacmounts); 899104521Srwatson} 900104521Srwatson 901105694Srwatsonstatic void 902105694Srwatsonmac_init_pipe_label(struct label *label) 903105694Srwatson{ 904105694Srwatson 905105694Srwatson mac_init_label(label); 906105694Srwatson MAC_PERFORM(init_pipe_label, label); 907119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacpipes); 908105694Srwatson} 909105694Srwatson 910104521Srwatsonvoid 911104527Srwatsonmac_init_pipe(struct pipe *pipe) 912104521Srwatson{ 913104527Srwatson struct label *label; 914104521Srwatson 915111119Simp label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 916104527Srwatson pipe->pipe_label = label; 917104527Srwatson pipe->pipe_peer->pipe_label = label; 918105694Srwatson mac_init_pipe_label(label); 919104521Srwatson} 920104521Srwatson 921107105Srwatsonvoid 922107105Srwatsonmac_init_proc(struct proc *p) 923107105Srwatson{ 924107105Srwatson 925107105Srwatson mac_init_label(&p->p_label); 926107105Srwatson MAC_PERFORM(init_proc_label, &p->p_label); 927119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacprocs); 928107105Srwatson} 929107105Srwatson 930104541Srwatsonstatic int 931104541Srwatsonmac_init_socket_label(struct label *label, int flag) 932104521Srwatson{ 933104541Srwatson int error; 934104521Srwatson 935104541Srwatson mac_init_label(label); 936104541Srwatson 937104541Srwatson MAC_CHECK(init_socket_label, label, flag); 938104541Srwatson if (error) { 939104541Srwatson MAC_PERFORM(destroy_socket_label, label); 940104541Srwatson mac_destroy_label(label); 941119184Srwatson } else { 942119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacsockets); 943104541Srwatson } 944104541Srwatson 945104541Srwatson return (error); 946104521Srwatson} 947104521Srwatson 948104541Srwatsonstatic int 949104541Srwatsonmac_init_socket_peer_label(struct label *label, int flag) 950104541Srwatson{ 951104541Srwatson int error; 952104541Srwatson 953104541Srwatson mac_init_label(label); 954104541Srwatson 955104541Srwatson MAC_CHECK(init_socket_peer_label, label, flag); 956104541Srwatson if (error) { 957104541Srwatson MAC_PERFORM(destroy_socket_label, label); 958104541Srwatson mac_destroy_label(label); 959104541Srwatson } 960104541Srwatson 961104541Srwatson return (error); 962104541Srwatson} 963104541Srwatson 964104541Srwatsonint 965104541Srwatsonmac_init_socket(struct socket *socket, int flag) 966104541Srwatson{ 967104541Srwatson int error; 968104541Srwatson 969104541Srwatson error = mac_init_socket_label(&socket->so_label, flag); 970104541Srwatson if (error) 971104541Srwatson return (error); 972104541Srwatson 973104541Srwatson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 974104541Srwatson if (error) 975104541Srwatson mac_destroy_socket_label(&socket->so_label); 976104541Srwatson 977104541Srwatson return (error); 978104541Srwatson} 979104541Srwatson 980105988Srwatsonvoid 981105694Srwatsonmac_init_vnode_label(struct label *label) 982104521Srwatson{ 983104521Srwatson 984104527Srwatson mac_init_label(label); 985105694Srwatson MAC_PERFORM(init_vnode_label, label); 986119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacvnodes); 987104521Srwatson} 988104521Srwatson 989104521Srwatsonvoid 990104527Srwatsonmac_init_vnode(struct vnode *vp) 991104521Srwatson{ 992104521Srwatson 993105694Srwatson mac_init_vnode_label(&vp->v_label); 994104521Srwatson} 995104521Srwatson 996104521Srwatsonvoid 997104527Srwatsonmac_destroy_bpfdesc(struct bpf_d *bpf_d) 998104521Srwatson{ 999104521Srwatson 1000104527Srwatson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 1001104527Srwatson mac_destroy_label(&bpf_d->bd_label); 1002119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs); 1003104521Srwatson} 1004104521Srwatson 1005105694Srwatsonstatic void 1006105694Srwatsonmac_destroy_cred_label(struct label *label) 1007104521Srwatson{ 1008104521Srwatson 1009105694Srwatson MAC_PERFORM(destroy_cred_label, label); 1010105694Srwatson mac_destroy_label(label); 1011119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmaccreds); 1012104521Srwatson} 1013104521Srwatson 1014104521Srwatsonvoid 1015105694Srwatsonmac_destroy_cred(struct ucred *cred) 1016105694Srwatson{ 1017105694Srwatson 1018105694Srwatson mac_destroy_cred_label(&cred->cr_label); 1019105694Srwatson} 1020105694Srwatson 1021105694Srwatsonvoid 1022104527Srwatsonmac_destroy_devfsdirent(struct devfs_dirent *de) 1023104521Srwatson{ 1024104521Srwatson 1025104527Srwatson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 1026104527Srwatson mac_destroy_label(&de->de_label); 1027119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacdevfsdirents); 1028104521Srwatson} 1029104521Srwatson 1030105694Srwatsonstatic void 1031105694Srwatsonmac_destroy_ifnet_label(struct label *label) 1032104521Srwatson{ 1033104521Srwatson 1034105694Srwatson MAC_PERFORM(destroy_ifnet_label, label); 1035105694Srwatson mac_destroy_label(label); 1036119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacifnets); 1037104521Srwatson} 1038104521Srwatson 1039104521Srwatsonvoid 1040105694Srwatsonmac_destroy_ifnet(struct ifnet *ifp) 1041105694Srwatson{ 1042105694Srwatson 1043105694Srwatson mac_destroy_ifnet_label(&ifp->if_label); 1044105694Srwatson} 1045105694Srwatson 1046105694Srwatsonvoid 1047104527Srwatsonmac_destroy_ipq(struct ipq *ipq) 1048104521Srwatson{ 1049104521Srwatson 1050104527Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1051104527Srwatson mac_destroy_label(&ipq->ipq_label); 1052119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacipqs); 1053104521Srwatson} 1054104521Srwatson 1055104527Srwatsonvoid 1056113487Srwatsonmac_destroy_mbuf_tag(struct m_tag *tag) 1057104521Srwatson{ 1058113487Srwatson struct label *label; 1059104521Srwatson 1060113487Srwatson label = (struct label *)(tag+1); 1061113487Srwatson 1062113487Srwatson MAC_PERFORM(destroy_mbuf_label, label); 1063113487Srwatson mac_destroy_label(label); 1064119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacmbufs); 1065104521Srwatson} 1066104521Srwatson 1067104527Srwatsonvoid 1068104527Srwatsonmac_destroy_mount(struct mount *mp) 1069104521Srwatson{ 1070104521Srwatson 1071104527Srwatson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1072104527Srwatson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1073104527Srwatson mac_destroy_label(&mp->mnt_fslabel); 1074104527Srwatson mac_destroy_label(&mp->mnt_mntlabel); 1075119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacmounts); 1076104521Srwatson} 1077104521Srwatson 1078105694Srwatsonstatic void 1079105694Srwatsonmac_destroy_pipe_label(struct label *label) 1080104521Srwatson{ 1081104521Srwatson 1082105694Srwatson MAC_PERFORM(destroy_pipe_label, label); 1083105694Srwatson mac_destroy_label(label); 1084119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacpipes); 1085104521Srwatson} 1086104521Srwatson 1087105694Srwatsonvoid 1088105694Srwatsonmac_destroy_pipe(struct pipe *pipe) 1089105694Srwatson{ 1090105694Srwatson 1091105694Srwatson mac_destroy_pipe_label(pipe->pipe_label); 1092105694Srwatson free(pipe->pipe_label, M_MACPIPELABEL); 1093105694Srwatson} 1094105694Srwatson 1095107105Srwatsonvoid 1096107105Srwatsonmac_destroy_proc(struct proc *p) 1097107105Srwatson{ 1098107105Srwatson 1099107105Srwatson MAC_PERFORM(destroy_proc_label, &p->p_label); 1100107105Srwatson mac_destroy_label(&p->p_label); 1101119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacprocs); 1102107105Srwatson} 1103107105Srwatson 1104104541Srwatsonstatic void 1105104541Srwatsonmac_destroy_socket_label(struct label *label) 1106104521Srwatson{ 1107104521Srwatson 1108104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1109104541Srwatson mac_destroy_label(label); 1110119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacsockets); 1111104521Srwatson} 1112104521Srwatson 1113104527Srwatsonstatic void 1114104541Srwatsonmac_destroy_socket_peer_label(struct label *label) 1115104541Srwatson{ 1116104541Srwatson 1117104541Srwatson MAC_PERFORM(destroy_socket_peer_label, label); 1118104541Srwatson mac_destroy_label(label); 1119104541Srwatson} 1120104541Srwatson 1121104541Srwatsonvoid 1122104541Srwatsonmac_destroy_socket(struct socket *socket) 1123104541Srwatson{ 1124104541Srwatson 1125104541Srwatson mac_destroy_socket_label(&socket->so_label); 1126104541Srwatson mac_destroy_socket_peer_label(&socket->so_peerlabel); 1127104541Srwatson} 1128104541Srwatson 1129105988Srwatsonvoid 1130105694Srwatsonmac_destroy_vnode_label(struct label *label) 1131104521Srwatson{ 1132104521Srwatson 1133105694Srwatson MAC_PERFORM(destroy_vnode_label, label); 1134104527Srwatson mac_destroy_label(label); 1135119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacvnodes); 1136104521Srwatson} 1137104521Srwatson 1138104521Srwatsonvoid 1139104527Srwatsonmac_destroy_vnode(struct vnode *vp) 1140104521Srwatson{ 1141104521Srwatson 1142105694Srwatson mac_destroy_vnode_label(&vp->v_label); 1143104521Srwatson} 1144104521Srwatson 1145113487Srwatsonvoid 1146113487Srwatsonmac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 1147113487Srwatson{ 1148113487Srwatson struct label *src_label, *dest_label; 1149113487Srwatson 1150113487Srwatson src_label = (struct label *)(src+1); 1151113487Srwatson dest_label = (struct label *)(dest+1); 1152113487Srwatson 1153113487Srwatson /* 1154113487Srwatson * mac_init_mbuf_tag() is called on the target tag in 1155113487Srwatson * m_tag_copy(), so we don't need to call it here. 1156113487Srwatson */ 1157113487Srwatson MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 1158113487Srwatson} 1159113487Srwatson 1160105694Srwatsonstatic void 1161105694Srwatsonmac_copy_pipe_label(struct label *src, struct label *dest) 1162105694Srwatson{ 1163105694Srwatson 1164105694Srwatson MAC_PERFORM(copy_pipe_label, src, dest); 1165105694Srwatson} 1166105694Srwatson 1167105988Srwatsonvoid 1168105694Srwatsonmac_copy_vnode_label(struct label *src, struct label *dest) 1169105694Srwatson{ 1170105694Srwatson 1171105694Srwatson MAC_PERFORM(copy_vnode_label, src, dest); 1172105694Srwatson} 1173105694Srwatson 1174104522Srwatsonstatic int 1175105694Srwatsonmac_check_structmac_consistent(struct mac *mac) 1176104522Srwatson{ 1177105694Srwatson 1178120582Srwatson if (mac->m_buflen < 0 || 1179120582Srwatson mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1180105694Srwatson return (EINVAL); 1181105694Srwatson 1182105694Srwatson return (0); 1183105694Srwatson} 1184105694Srwatson 1185105694Srwatsonstatic int 1186105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements, 1187105694Srwatson char *outbuf, size_t outbuflen, int flags) 1188105694Srwatson{ 1189104522Srwatson int error; 1190104522Srwatson 1191105694Srwatson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1192104522Srwatson 1193104522Srwatson return (error); 1194104522Srwatson} 1195104522Srwatson 1196104522Srwatsonstatic int 1197105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements, 1198105694Srwatson char *outbuf, size_t outbuflen, int flags) 1199104522Srwatson{ 1200104522Srwatson int error; 1201104522Srwatson 1202105694Srwatson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1203104522Srwatson 1204104522Srwatson return (error); 1205104522Srwatson} 1206104522Srwatson 1207105694Srwatsonstatic int 1208105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements, 1209105694Srwatson char *outbuf, size_t outbuflen, int flags) 1210105694Srwatson{ 1211105694Srwatson int error; 1212105694Srwatson 1213105694Srwatson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1214105694Srwatson 1215105694Srwatson return (error); 1216105694Srwatson} 1217105694Srwatson 1218105694Srwatsonstatic int 1219105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements, 1220105694Srwatson char *outbuf, size_t outbuflen, int flags) 1221105694Srwatson{ 1222105694Srwatson int error; 1223105694Srwatson 1224105694Srwatson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1225105694Srwatson 1226105694Srwatson return (error); 1227105694Srwatson} 1228105694Srwatson 1229105694Srwatsonstatic int 1230105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements, 1231105694Srwatson char *outbuf, size_t outbuflen, int flags) 1232105694Srwatson{ 1233105694Srwatson int error; 1234105694Srwatson 1235105694Srwatson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1236105694Srwatson 1237105694Srwatson return (error); 1238105694Srwatson} 1239105694Srwatson 1240105694Srwatsonstatic int 1241105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements, 1242105694Srwatson char *outbuf, size_t outbuflen, int flags) 1243105694Srwatson{ 1244105694Srwatson int error; 1245105694Srwatson 1246105694Srwatson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1247105694Srwatson 1248105694Srwatson return (error); 1249105694Srwatson} 1250105694Srwatson 1251105694Srwatsonstatic int 1252105694Srwatsonmac_internalize_cred_label(struct label *label, char *string) 1253105694Srwatson{ 1254105694Srwatson int error; 1255105694Srwatson 1256105694Srwatson MAC_INTERNALIZE(cred_label, label, string); 1257105694Srwatson 1258105694Srwatson return (error); 1259105694Srwatson} 1260105694Srwatson 1261105694Srwatsonstatic int 1262105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string) 1263105694Srwatson{ 1264105694Srwatson int error; 1265105694Srwatson 1266105694Srwatson MAC_INTERNALIZE(ifnet_label, label, string); 1267105694Srwatson 1268105694Srwatson return (error); 1269105694Srwatson} 1270105694Srwatson 1271105694Srwatsonstatic int 1272105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string) 1273105694Srwatson{ 1274105694Srwatson int error; 1275105694Srwatson 1276105694Srwatson MAC_INTERNALIZE(pipe_label, label, string); 1277105694Srwatson 1278105694Srwatson return (error); 1279105694Srwatson} 1280105694Srwatson 1281105694Srwatsonstatic int 1282105694Srwatsonmac_internalize_socket_label(struct label *label, char *string) 1283105694Srwatson{ 1284105694Srwatson int error; 1285105694Srwatson 1286105694Srwatson MAC_INTERNALIZE(socket_label, label, string); 1287105694Srwatson 1288105694Srwatson return (error); 1289105694Srwatson} 1290105694Srwatson 1291105694Srwatsonstatic int 1292105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string) 1293105694Srwatson{ 1294105694Srwatson int error; 1295105694Srwatson 1296105694Srwatson MAC_INTERNALIZE(vnode_label, label, string); 1297105694Srwatson 1298105694Srwatson return (error); 1299105694Srwatson} 1300105694Srwatson 1301104522Srwatson/* 1302104522Srwatson * Initialize MAC label for the first kernel process, from which other 1303104522Srwatson * kernel processes and threads are spawned. 1304104522Srwatson */ 1305104521Srwatsonvoid 1306104522Srwatsonmac_create_proc0(struct ucred *cred) 1307104522Srwatson{ 1308104522Srwatson 1309104522Srwatson MAC_PERFORM(create_proc0, cred); 1310104522Srwatson} 1311104522Srwatson 1312104522Srwatson/* 1313104522Srwatson * Initialize MAC label for the first userland process, from which other 1314104522Srwatson * userland processes and threads are spawned. 1315104522Srwatson */ 1316104522Srwatsonvoid 1317104522Srwatsonmac_create_proc1(struct ucred *cred) 1318104522Srwatson{ 1319104522Srwatson 1320104522Srwatson MAC_PERFORM(create_proc1, cred); 1321104522Srwatson} 1322104522Srwatson 1323104522Srwatsonvoid 1324104522Srwatsonmac_thread_userret(struct thread *td) 1325104522Srwatson{ 1326104522Srwatson 1327104522Srwatson MAC_PERFORM(thread_userret, td); 1328104522Srwatson} 1329104522Srwatson 1330104522Srwatson/* 1331104522Srwatson * When a new process is created, its label must be initialized. Generally, 1332104522Srwatson * this involves inheritence from the parent process, modulo possible 1333104522Srwatson * deltas. This function allows that processing to take place. 1334104522Srwatson */ 1335104522Srwatsonvoid 1336104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1337104522Srwatson{ 1338104522Srwatson 1339104522Srwatson MAC_PERFORM(create_cred, parent_cred, child_cred); 1340104522Srwatson} 1341104522Srwatson 1342104522Srwatsonvoid 1343107698Srwatsonmac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 1344107698Srwatson struct vnode *vp) 1345100979Srwatson{ 1346100979Srwatson 1347107698Srwatson MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp, 1348107698Srwatson &vp->v_label); 1349100979Srwatson} 1350100979Srwatson 1351100979Srwatsonvoid 1352105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1353105988Srwatson struct vnode *vp) 1354100979Srwatson{ 1355100979Srwatson 1356105988Srwatson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1357105988Srwatson &de->de_label, vp, &vp->v_label); 1358100979Srwatson} 1359100979Srwatson 1360105988Srwatsonint 1361105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1362100979Srwatson{ 1363100979Srwatson int error; 1364100979Srwatson 1365105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1366100979Srwatson 1367105988Srwatson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1368105988Srwatson &vp->v_label); 1369100979Srwatson 1370100979Srwatson return (error); 1371100979Srwatson} 1372100979Srwatson 1373100979Srwatsonvoid 1374105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1375100979Srwatson{ 1376100979Srwatson 1377105988Srwatson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1378105988Srwatson &vp->v_label); 1379100979Srwatson} 1380100979Srwatson 1381100979Srwatsonint 1382105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1383105988Srwatson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1384100979Srwatson{ 1385105988Srwatson int error; 1386100979Srwatson 1387105988Srwatson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1388105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1389100979Srwatson 1390105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1391105988Srwatson if (error == EOPNOTSUPP) { 1392105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1393105988Srwatson if (ea_warn_once == 0) { 1394105988Srwatson printf("Warning: transactions not supported " 1395105988Srwatson "in EA write.\n"); 1396105988Srwatson ea_warn_once = 1; 1397105988Srwatson } 1398105988Srwatson } else if (error) 1399100979Srwatson return (error); 1400100979Srwatson 1401105988Srwatson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1402105988Srwatson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1403100979Srwatson 1404105988Srwatson if (error) { 1405105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1406100979Srwatson return (error); 1407100979Srwatson } 1408100979Srwatson 1409105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1410100979Srwatson 1411105988Srwatson if (error == EOPNOTSUPP) 1412105988Srwatson error = 0; /* XXX */ 1413100979Srwatson 1414100979Srwatson return (error); 1415100979Srwatson} 1416100979Srwatson 1417100979Srwatsonstatic int 1418105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1419105988Srwatson struct label *intlabel) 1420100979Srwatson{ 1421100979Srwatson int error; 1422100979Srwatson 1423105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1424100979Srwatson 1425105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1426105988Srwatson if (error == EOPNOTSUPP) { 1427105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1428105988Srwatson if (ea_warn_once == 0) { 1429105988Srwatson printf("Warning: transactions not supported " 1430105988Srwatson "in EA write.\n"); 1431105988Srwatson ea_warn_once = 1; 1432105988Srwatson } 1433105988Srwatson } else if (error) 1434105988Srwatson return (error); 1435100979Srwatson 1436105988Srwatson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1437100979Srwatson 1438105988Srwatson if (error) { 1439105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1440100979Srwatson return (error); 1441100979Srwatson } 1442100979Srwatson 1443105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1444100979Srwatson 1445105988Srwatson if (error == EOPNOTSUPP) 1446105988Srwatson error = 0; /* XXX */ 1447100979Srwatson 1448105988Srwatson return (error); 1449100979Srwatson} 1450100979Srwatson 1451106468Srwatsonint 1452106468Srwatsonmac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1453106468Srwatson struct label *execlabelstorage) 1454106468Srwatson{ 1455106468Srwatson struct mac mac; 1456106468Srwatson char *buffer; 1457106468Srwatson int error; 1458106468Srwatson 1459106468Srwatson if (mac_p == NULL) 1460106468Srwatson return (0); 1461106468Srwatson 1462106468Srwatson error = copyin(mac_p, &mac, sizeof(mac)); 1463106468Srwatson if (error) 1464106468Srwatson return (error); 1465106468Srwatson 1466106468Srwatson error = mac_check_structmac_consistent(&mac); 1467106468Srwatson if (error) 1468106468Srwatson return (error); 1469106468Srwatson 1470111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1471106468Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1472106468Srwatson if (error) { 1473106468Srwatson free(buffer, M_MACTEMP); 1474106468Srwatson return (error); 1475106468Srwatson } 1476106468Srwatson 1477106468Srwatson mac_init_cred_label(execlabelstorage); 1478106468Srwatson error = mac_internalize_cred_label(execlabelstorage, buffer); 1479106468Srwatson free(buffer, M_MACTEMP); 1480106468Srwatson if (error) { 1481106468Srwatson mac_destroy_cred_label(execlabelstorage); 1482106468Srwatson return (error); 1483106468Srwatson } 1484106468Srwatson imgp->execlabel = execlabelstorage; 1485106468Srwatson return (0); 1486106468Srwatson} 1487106468Srwatson 1488100979Srwatsonvoid 1489106468Srwatsonmac_execve_exit(struct image_params *imgp) 1490100979Srwatson{ 1491106468Srwatson if (imgp->execlabel != NULL) 1492106468Srwatson mac_destroy_cred_label(imgp->execlabel); 1493106468Srwatson} 1494100979Srwatson 1495106468Srwatsonvoid 1496106468Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1497106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1498106468Srwatson{ 1499106468Srwatson 1500100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1501100979Srwatson 1502106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1503106460Srwatson return; 1504106460Srwatson 1505106468Srwatson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1506106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1507100979Srwatson} 1508100979Srwatson 1509100979Srwatsonint 1510106468Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp, 1511106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1512100979Srwatson{ 1513105988Srwatson int result; 1514100979Srwatson 1515106460Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1516106460Srwatson 1517106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1518106460Srwatson return (0); 1519106460Srwatson 1520100979Srwatson result = 0; 1521106468Srwatson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1522106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1523100979Srwatson 1524100979Srwatson return (result); 1525100979Srwatson} 1526100979Srwatson 1527100979Srwatsonint 1528106212Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1529100979Srwatson{ 1530100979Srwatson int error; 1531100979Srwatson 1532100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1533100979Srwatson 1534100979Srwatson if (!mac_enforce_fs) 1535100979Srwatson return (0); 1536100979Srwatson 1537106212Srwatson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1538100979Srwatson return (error); 1539100979Srwatson} 1540100979Srwatson 1541100979Srwatsonint 1542100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1543100979Srwatson{ 1544100979Srwatson int error; 1545100979Srwatson 1546100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1547100979Srwatson 1548100979Srwatson if (!mac_enforce_fs) 1549100979Srwatson return (0); 1550100979Srwatson 1551100979Srwatson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1552100979Srwatson return (error); 1553100979Srwatson} 1554100979Srwatson 1555100979Srwatsonint 1556100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1557100979Srwatson{ 1558100979Srwatson int error; 1559100979Srwatson 1560100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1561100979Srwatson 1562100979Srwatson if (!mac_enforce_fs) 1563100979Srwatson return (0); 1564100979Srwatson 1565100979Srwatson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1566100979Srwatson return (error); 1567100979Srwatson} 1568100979Srwatson 1569100979Srwatsonint 1570100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1571100979Srwatson struct componentname *cnp, struct vattr *vap) 1572100979Srwatson{ 1573100979Srwatson int error; 1574100979Srwatson 1575100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1576100979Srwatson 1577100979Srwatson if (!mac_enforce_fs) 1578100979Srwatson return (0); 1579100979Srwatson 1580100979Srwatson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1581100979Srwatson return (error); 1582100979Srwatson} 1583100979Srwatson 1584100979Srwatsonint 1585100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1586100979Srwatson struct componentname *cnp) 1587100979Srwatson{ 1588100979Srwatson int error; 1589100979Srwatson 1590100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1591100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1592100979Srwatson 1593100979Srwatson if (!mac_enforce_fs) 1594100979Srwatson return (0); 1595100979Srwatson 1596100979Srwatson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1597100979Srwatson &vp->v_label, cnp); 1598100979Srwatson return (error); 1599100979Srwatson} 1600100979Srwatson 1601100979Srwatsonint 1602100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1603100979Srwatson acl_type_t type) 1604100979Srwatson{ 1605100979Srwatson int error; 1606100979Srwatson 1607100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1608100979Srwatson 1609100979Srwatson if (!mac_enforce_fs) 1610100979Srwatson return (0); 1611100979Srwatson 1612100979Srwatson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1613100979Srwatson return (error); 1614100979Srwatson} 1615100979Srwatson 1616100979Srwatsonint 1617119198Srwatsonmac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 1618119198Srwatson int attrnamespace, const char *name) 1619119198Srwatson{ 1620119198Srwatson int error; 1621119198Srwatson 1622119198Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr"); 1623119198Srwatson 1624119198Srwatson if (!mac_enforce_fs) 1625119198Srwatson return (0); 1626119198Srwatson 1627119198Srwatson MAC_CHECK(check_vnode_deleteextattr, cred, vp, &vp->v_label, 1628119198Srwatson attrnamespace, name); 1629119198Srwatson return (error); 1630119198Srwatson} 1631119198Srwatson 1632119198Srwatsonint 1633106468Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1634106468Srwatson struct image_params *imgp) 1635100979Srwatson{ 1636100979Srwatson int error; 1637100979Srwatson 1638102102Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1639102102Srwatson 1640100979Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1641100979Srwatson return (0); 1642100979Srwatson 1643106647Srwatson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1644106647Srwatson imgp->execlabel); 1645100979Srwatson 1646100979Srwatson return (error); 1647100979Srwatson} 1648100979Srwatson 1649100979Srwatsonint 1650100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1651100979Srwatson{ 1652100979Srwatson int error; 1653100979Srwatson 1654100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1655100979Srwatson 1656100979Srwatson if (!mac_enforce_fs) 1657100979Srwatson return (0); 1658100979Srwatson 1659100979Srwatson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1660100979Srwatson return (error); 1661100979Srwatson} 1662100979Srwatson 1663100979Srwatsonint 1664100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1665100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1666100979Srwatson{ 1667100979Srwatson int error; 1668100979Srwatson 1669100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1670100979Srwatson 1671100979Srwatson if (!mac_enforce_fs) 1672100979Srwatson return (0); 1673100979Srwatson 1674100979Srwatson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1675100979Srwatson attrnamespace, name, uio); 1676100979Srwatson return (error); 1677100979Srwatson} 1678100979Srwatson 1679100979Srwatsonint 1680104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1681104529Srwatson struct vnode *vp, struct componentname *cnp) 1682104529Srwatson{ 1683104529Srwatson int error; 1684104529Srwatson 1685104529Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1686104529Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1687104529Srwatson 1688104529Srwatson if (!mac_enforce_fs) 1689104529Srwatson return (0); 1690104529Srwatson 1691104529Srwatson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1692104529Srwatson &vp->v_label, cnp); 1693104529Srwatson return (error); 1694104529Srwatson} 1695104529Srwatson 1696104529Srwatsonint 1697119198Srwatsonmac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 1698119198Srwatson int attrnamespace) 1699119198Srwatson{ 1700119198Srwatson int error; 1701119198Srwatson 1702119198Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr"); 1703119198Srwatson 1704119198Srwatson if (!mac_enforce_fs) 1705119198Srwatson return (0); 1706119198Srwatson 1707119198Srwatson MAC_CHECK(check_vnode_listextattr, cred, vp, &vp->v_label, 1708119198Srwatson attrnamespace); 1709119198Srwatson return (error); 1710119198Srwatson} 1711119198Srwatson 1712119198Srwatsonint 1713100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1714100979Srwatson struct componentname *cnp) 1715100979Srwatson{ 1716100979Srwatson int error; 1717100979Srwatson 1718100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1719100979Srwatson 1720100979Srwatson if (!mac_enforce_fs) 1721100979Srwatson return (0); 1722100979Srwatson 1723100979Srwatson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1724100979Srwatson return (error); 1725100979Srwatson} 1726100979Srwatson 1727104546Srwatsonint 1728104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1729100979Srwatson{ 1730104546Srwatson int error; 1731100979Srwatson 1732104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1733103514Srwatson 1734104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1735104546Srwatson return (0); 1736104546Srwatson 1737104546Srwatson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1738104546Srwatson return (error); 1739100979Srwatson} 1740100979Srwatson 1741104546Srwatsonvoid 1742104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1743104546Srwatson{ 1744104546Srwatson int result = *prot; 1745104546Srwatson 1746104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1747104546Srwatson 1748104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1749104546Srwatson return; 1750104546Srwatson 1751104546Srwatson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1752104546Srwatson &result); 1753104546Srwatson 1754104546Srwatson *prot = result; 1755104546Srwatson} 1756104546Srwatson 1757100979Srwatsonint 1758104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1759104546Srwatson{ 1760104546Srwatson int error; 1761104546Srwatson 1762104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1763104546Srwatson 1764104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1765104546Srwatson return (0); 1766104546Srwatson 1767104546Srwatson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1768104546Srwatson return (error); 1769104546Srwatson} 1770104546Srwatson 1771104546Srwatsonint 1772106212Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1773100979Srwatson{ 1774100979Srwatson int error; 1775100979Srwatson 1776102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1777102112Srwatson 1778100979Srwatson if (!mac_enforce_fs) 1779100979Srwatson return (0); 1780100979Srwatson 1781102112Srwatson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1782102112Srwatson return (error); 1783102112Srwatson} 1784102112Srwatson 1785102112Srwatsonint 1786102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1787102129Srwatson struct vnode *vp) 1788102112Srwatson{ 1789102112Srwatson int error; 1790102112Srwatson 1791102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1792102112Srwatson 1793102112Srwatson if (!mac_enforce_fs) 1794102112Srwatson return (0); 1795102112Srwatson 1796102129Srwatson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1797102129Srwatson &vp->v_label); 1798100979Srwatson 1799100979Srwatson return (error); 1800100979Srwatson} 1801100979Srwatson 1802100979Srwatsonint 1803102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1804102129Srwatson struct vnode *vp) 1805100979Srwatson{ 1806100979Srwatson int error; 1807100979Srwatson 1808102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1809100979Srwatson 1810100979Srwatson if (!mac_enforce_fs) 1811100979Srwatson return (0); 1812100979Srwatson 1813102129Srwatson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1814102129Srwatson &vp->v_label); 1815102112Srwatson 1816100979Srwatson return (error); 1817100979Srwatson} 1818100979Srwatson 1819100979Srwatsonint 1820100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1821100979Srwatson{ 1822100979Srwatson int error; 1823100979Srwatson 1824100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1825100979Srwatson 1826100979Srwatson if (!mac_enforce_fs) 1827100979Srwatson return (0); 1828100979Srwatson 1829100979Srwatson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1830100979Srwatson return (error); 1831100979Srwatson} 1832100979Srwatson 1833100979Srwatsonint 1834100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1835100979Srwatson{ 1836100979Srwatson int error; 1837100979Srwatson 1838100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1839100979Srwatson 1840100979Srwatson if (!mac_enforce_fs) 1841100979Srwatson return (0); 1842100979Srwatson 1843100979Srwatson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1844100979Srwatson return (error); 1845100979Srwatson} 1846100979Srwatson 1847100979Srwatsonstatic int 1848100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1849100979Srwatson struct label *newlabel) 1850100979Srwatson{ 1851100979Srwatson int error; 1852100979Srwatson 1853100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1854100979Srwatson 1855100979Srwatson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1856100979Srwatson 1857100979Srwatson return (error); 1858100979Srwatson} 1859100979Srwatson 1860100979Srwatsonint 1861100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1862100979Srwatson struct vnode *vp, struct componentname *cnp) 1863100979Srwatson{ 1864100979Srwatson int error; 1865100979Srwatson 1866100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1867100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1868100979Srwatson 1869100979Srwatson if (!mac_enforce_fs) 1870100979Srwatson return (0); 1871100979Srwatson 1872100979Srwatson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1873100979Srwatson &vp->v_label, cnp); 1874100979Srwatson return (error); 1875100979Srwatson} 1876100979Srwatson 1877100979Srwatsonint 1878100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1879100979Srwatson struct vnode *vp, int samedir, struct componentname *cnp) 1880100979Srwatson{ 1881100979Srwatson int error; 1882100979Srwatson 1883100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1884100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1885100979Srwatson 1886100979Srwatson if (!mac_enforce_fs) 1887100979Srwatson return (0); 1888100979Srwatson 1889100979Srwatson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1890100979Srwatson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1891100979Srwatson return (error); 1892100979Srwatson} 1893100979Srwatson 1894100979Srwatsonint 1895100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1896100979Srwatson{ 1897100979Srwatson int error; 1898100979Srwatson 1899100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1900100979Srwatson 1901100979Srwatson if (!mac_enforce_fs) 1902100979Srwatson return (0); 1903100979Srwatson 1904100979Srwatson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1905100979Srwatson return (error); 1906100979Srwatson} 1907100979Srwatson 1908100979Srwatsonint 1909100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1910100979Srwatson struct acl *acl) 1911100979Srwatson{ 1912100979Srwatson int error; 1913100979Srwatson 1914100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1915100979Srwatson 1916100979Srwatson if (!mac_enforce_fs) 1917100979Srwatson return (0); 1918100979Srwatson 1919100979Srwatson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1920100979Srwatson return (error); 1921100979Srwatson} 1922100979Srwatson 1923100979Srwatsonint 1924100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1925100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1926100979Srwatson{ 1927100979Srwatson int error; 1928100979Srwatson 1929100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1930100979Srwatson 1931100979Srwatson if (!mac_enforce_fs) 1932100979Srwatson return (0); 1933100979Srwatson 1934100979Srwatson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1935100979Srwatson attrnamespace, name, uio); 1936100979Srwatson return (error); 1937100979Srwatson} 1938100979Srwatson 1939100979Srwatsonint 1940100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1941100979Srwatson{ 1942100979Srwatson int error; 1943100979Srwatson 1944100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1945100979Srwatson 1946100979Srwatson if (!mac_enforce_fs) 1947100979Srwatson return (0); 1948100979Srwatson 1949100979Srwatson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1950100979Srwatson return (error); 1951100979Srwatson} 1952100979Srwatson 1953100979Srwatsonint 1954100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1955100979Srwatson{ 1956100979Srwatson int error; 1957100979Srwatson 1958100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1959100979Srwatson 1960100979Srwatson if (!mac_enforce_fs) 1961100979Srwatson return (0); 1962100979Srwatson 1963100979Srwatson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1964100979Srwatson return (error); 1965100979Srwatson} 1966100979Srwatson 1967100979Srwatsonint 1968100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1969100979Srwatson gid_t gid) 1970100979Srwatson{ 1971100979Srwatson int error; 1972100979Srwatson 1973100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1974100979Srwatson 1975100979Srwatson if (!mac_enforce_fs) 1976100979Srwatson return (0); 1977100979Srwatson 1978100979Srwatson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1979100979Srwatson return (error); 1980100979Srwatson} 1981100979Srwatson 1982100979Srwatsonint 1983100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1984100979Srwatson struct timespec atime, struct timespec mtime) 1985100979Srwatson{ 1986100979Srwatson int error; 1987100979Srwatson 1988100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1989100979Srwatson 1990100979Srwatson if (!mac_enforce_fs) 1991100979Srwatson return (0); 1992100979Srwatson 1993100979Srwatson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1994100979Srwatson mtime); 1995100979Srwatson return (error); 1996100979Srwatson} 1997100979Srwatson 1998100979Srwatsonint 1999102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2000102129Srwatson struct vnode *vp) 2001100979Srwatson{ 2002100979Srwatson int error; 2003100979Srwatson 2004100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2005100979Srwatson 2006100979Srwatson if (!mac_enforce_fs) 2007100979Srwatson return (0); 2008100979Srwatson 2009102129Srwatson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2010102129Srwatson &vp->v_label); 2011100979Srwatson return (error); 2012100979Srwatson} 2013100979Srwatson 2014102112Srwatsonint 2015102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2016102129Srwatson struct vnode *vp) 2017102112Srwatson{ 2018102112Srwatson int error; 2019102112Srwatson 2020102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2021102112Srwatson 2022102112Srwatson if (!mac_enforce_fs) 2023102112Srwatson return (0); 2024102112Srwatson 2025102129Srwatson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2026102129Srwatson &vp->v_label); 2027102112Srwatson 2028102112Srwatson return (error); 2029102112Srwatson} 2030102112Srwatson 2031100979Srwatson/* 2032100979Srwatson * When relabeling a process, call out to the policies for the maximum 2033100979Srwatson * permission allowed for each object type we know about in its 2034100979Srwatson * memory space, and revoke access (in the least surprising ways we 2035100979Srwatson * know) when necessary. The process lock is not held here. 2036100979Srwatson */ 2037107271Srwatsonvoid 2038100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2039100979Srwatson{ 2040100979Srwatson 2041100979Srwatson /* XXX freeze all other threads */ 2042100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2043100979Srwatson &td->td_proc->p_vmspace->vm_map); 2044100979Srwatson /* XXX allow other threads to continue */ 2045100979Srwatson} 2046100979Srwatson 2047100979Srwatsonstatic __inline const char * 2048100979Srwatsonprot2str(vm_prot_t prot) 2049100979Srwatson{ 2050100979Srwatson 2051100979Srwatson switch (prot & VM_PROT_ALL) { 2052100979Srwatson case VM_PROT_READ: 2053100979Srwatson return ("r--"); 2054100979Srwatson case VM_PROT_READ | VM_PROT_WRITE: 2055100979Srwatson return ("rw-"); 2056100979Srwatson case VM_PROT_READ | VM_PROT_EXECUTE: 2057100979Srwatson return ("r-x"); 2058100979Srwatson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2059100979Srwatson return ("rwx"); 2060100979Srwatson case VM_PROT_WRITE: 2061100979Srwatson return ("-w-"); 2062100979Srwatson case VM_PROT_EXECUTE: 2063100979Srwatson return ("--x"); 2064100979Srwatson case VM_PROT_WRITE | VM_PROT_EXECUTE: 2065100979Srwatson return ("-wx"); 2066100979Srwatson default: 2067100979Srwatson return ("---"); 2068100979Srwatson } 2069100979Srwatson} 2070100979Srwatson 2071100979Srwatsonstatic void 2072100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2073100979Srwatson struct vm_map *map) 2074100979Srwatson{ 2075100979Srwatson struct vm_map_entry *vme; 2076104546Srwatson int result; 2077104546Srwatson vm_prot_t revokeperms; 2078100979Srwatson vm_object_t object; 2079100979Srwatson vm_ooffset_t offset; 2080100979Srwatson struct vnode *vp; 2081100979Srwatson 2082103136Srwatson if (!mac_mmap_revocation) 2083103136Srwatson return; 2084103136Srwatson 2085100979Srwatson vm_map_lock_read(map); 2086100979Srwatson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2087100979Srwatson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2088100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2089100979Srwatson vme->object.sub_map); 2090100979Srwatson continue; 2091100979Srwatson } 2092100979Srwatson /* 2093100979Srwatson * Skip over entries that obviously are not shared. 2094100979Srwatson */ 2095100979Srwatson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2096100979Srwatson !vme->max_protection) 2097100979Srwatson continue; 2098100979Srwatson /* 2099100979Srwatson * Drill down to the deepest backing object. 2100100979Srwatson */ 2101100979Srwatson offset = vme->offset; 2102100979Srwatson object = vme->object.vm_object; 2103100979Srwatson if (object == NULL) 2104100979Srwatson continue; 2105100979Srwatson while (object->backing_object != NULL) { 2106100979Srwatson object = object->backing_object; 2107100979Srwatson offset += object->backing_object_offset; 2108100979Srwatson } 2109100979Srwatson /* 2110100979Srwatson * At the moment, vm_maps and objects aren't considered 2111100979Srwatson * by the MAC system, so only things with backing by a 2112100979Srwatson * normal object (read: vnodes) are checked. 2113100979Srwatson */ 2114100979Srwatson if (object->type != OBJT_VNODE) 2115100979Srwatson continue; 2116100979Srwatson vp = (struct vnode *)object->handle; 2117100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2118104546Srwatson result = vme->max_protection; 2119104546Srwatson mac_check_vnode_mmap_downgrade(cred, vp, &result); 2120100979Srwatson VOP_UNLOCK(vp, 0, td); 2121100979Srwatson /* 2122100979Srwatson * Find out what maximum protection we may be allowing 2123100979Srwatson * now but a policy needs to get removed. 2124100979Srwatson */ 2125100979Srwatson revokeperms = vme->max_protection & ~result; 2126100979Srwatson if (!revokeperms) 2127100979Srwatson continue; 2128102949Sbde printf("pid %ld: revoking %s perms from %#lx:%ld " 2129102949Sbde "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2130102949Sbde prot2str(revokeperms), (u_long)vme->start, 2131102949Sbde (long)(vme->end - vme->start), 2132100979Srwatson prot2str(vme->max_protection), prot2str(vme->protection)); 2133100979Srwatson vm_map_lock_upgrade(map); 2134100979Srwatson /* 2135100979Srwatson * This is the really simple case: if a map has more 2136100979Srwatson * max_protection than is allowed, but it's not being 2137100979Srwatson * actually used (that is, the current protection is 2138100979Srwatson * still allowed), we can just wipe it out and do 2139100979Srwatson * nothing more. 2140100979Srwatson */ 2141100979Srwatson if ((vme->protection & revokeperms) == 0) { 2142100979Srwatson vme->max_protection -= revokeperms; 2143100979Srwatson } else { 2144100979Srwatson if (revokeperms & VM_PROT_WRITE) { 2145100979Srwatson /* 2146100979Srwatson * In the more complicated case, flush out all 2147100979Srwatson * pending changes to the object then turn it 2148100979Srwatson * copy-on-write. 2149100979Srwatson */ 2150100979Srwatson vm_object_reference(object); 2151100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2152113955Salc VM_OBJECT_LOCK(object); 2153100979Srwatson vm_object_page_clean(object, 2154100979Srwatson OFF_TO_IDX(offset), 2155100979Srwatson OFF_TO_IDX(offset + vme->end - vme->start + 2156100979Srwatson PAGE_MASK), 2157100979Srwatson OBJPC_SYNC); 2158113955Salc VM_OBJECT_UNLOCK(object); 2159100979Srwatson VOP_UNLOCK(vp, 0, td); 2160100979Srwatson vm_object_deallocate(object); 2161100979Srwatson /* 2162100979Srwatson * Why bother if there's no read permissions 2163100979Srwatson * anymore? For the rest, we need to leave 2164100979Srwatson * the write permissions on for COW, or 2165100979Srwatson * remove them entirely if configured to. 2166100979Srwatson */ 2167100979Srwatson if (!mac_mmap_revocation_via_cow) { 2168100979Srwatson vme->max_protection &= ~VM_PROT_WRITE; 2169100979Srwatson vme->protection &= ~VM_PROT_WRITE; 2170100979Srwatson } if ((revokeperms & VM_PROT_READ) == 0) 2171100979Srwatson vme->eflags |= MAP_ENTRY_COW | 2172100979Srwatson MAP_ENTRY_NEEDS_COPY; 2173100979Srwatson } 2174100979Srwatson if (revokeperms & VM_PROT_EXECUTE) { 2175100979Srwatson vme->max_protection &= ~VM_PROT_EXECUTE; 2176100979Srwatson vme->protection &= ~VM_PROT_EXECUTE; 2177100979Srwatson } 2178100979Srwatson if (revokeperms & VM_PROT_READ) { 2179100979Srwatson vme->max_protection = 0; 2180100979Srwatson vme->protection = 0; 2181100979Srwatson } 2182100979Srwatson pmap_protect(map->pmap, vme->start, vme->end, 2183100979Srwatson vme->protection & ~revokeperms); 2184100979Srwatson vm_map_simplify_entry(map, vme); 2185100979Srwatson } 2186100979Srwatson vm_map_lock_downgrade(map); 2187100979Srwatson } 2188100979Srwatson vm_map_unlock_read(map); 2189100979Srwatson} 2190100979Srwatson 2191100979Srwatson/* 2192100979Srwatson * When the subject's label changes, it may require revocation of privilege 2193100979Srwatson * to mapped objects. This can't be done on-the-fly later with a unified 2194100979Srwatson * buffer cache. 2195100979Srwatson */ 2196100979Srwatsonstatic void 2197100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel) 2198100979Srwatson{ 2199100979Srwatson 2200100979Srwatson MAC_PERFORM(relabel_cred, cred, newlabel); 2201100979Srwatson} 2202100979Srwatson 2203100979Srwatsonvoid 2204100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2205100979Srwatson{ 2206100979Srwatson 2207100979Srwatson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2208100979Srwatson} 2209100979Srwatson 2210100979Srwatsonvoid 2211100979Srwatsonmac_create_ifnet(struct ifnet *ifnet) 2212100979Srwatson{ 2213100979Srwatson 2214100979Srwatson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2215100979Srwatson} 2216100979Srwatson 2217100979Srwatsonvoid 2218100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2219100979Srwatson{ 2220100979Srwatson 2221100979Srwatson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2222100979Srwatson} 2223100979Srwatson 2224100979Srwatsonvoid 2225100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket) 2226100979Srwatson{ 2227100979Srwatson 2228100979Srwatson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2229100979Srwatson} 2230100979Srwatson 2231100979Srwatsonvoid 2232100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe) 2233100979Srwatson{ 2234100979Srwatson 2235100979Srwatson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2236100979Srwatson} 2237100979Srwatson 2238100979Srwatsonvoid 2239100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket, 2240100979Srwatson struct socket *newsocket) 2241100979Srwatson{ 2242100979Srwatson 2243100979Srwatson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2244100979Srwatson newsocket, &newsocket->so_label); 2245100979Srwatson} 2246100979Srwatson 2247100979Srwatsonstatic void 2248100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket, 2249100979Srwatson struct label *newlabel) 2250100979Srwatson{ 2251100979Srwatson 2252100979Srwatson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2253100979Srwatson} 2254100979Srwatson 2255100979Srwatsonstatic void 2256100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2257100979Srwatson{ 2258100979Srwatson 2259100979Srwatson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2260100979Srwatson} 2261100979Srwatson 2262100979Srwatsonvoid 2263100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2264100979Srwatson{ 2265113482Srwatson struct label *label; 2266100979Srwatson 2267113482Srwatson label = mbuf_to_label(mbuf); 2268113482Srwatson 2269113482Srwatson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 2270113482Srwatson &socket->so_peerlabel); 2271100979Srwatson} 2272100979Srwatson 2273100979Srwatsonvoid 2274100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket, 2275100979Srwatson struct socket *newsocket) 2276100979Srwatson{ 2277100979Srwatson 2278100979Srwatson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2279100979Srwatson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2280100979Srwatson} 2281100979Srwatson 2282100979Srwatsonvoid 2283100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2284100979Srwatson{ 2285113482Srwatson struct label *label; 2286100979Srwatson 2287113482Srwatson label = mbuf_to_label(datagram); 2288113482Srwatson 2289100979Srwatson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2290113482Srwatson datagram, label); 2291100979Srwatson} 2292100979Srwatson 2293100979Srwatsonvoid 2294100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2295100979Srwatson{ 2296113482Srwatson struct label *datagramlabel, *fragmentlabel; 2297100979Srwatson 2298113482Srwatson datagramlabel = mbuf_to_label(datagram); 2299113482Srwatson fragmentlabel = mbuf_to_label(fragment); 2300113482Srwatson 2301113482Srwatson MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 2302113482Srwatson fragmentlabel); 2303100979Srwatson} 2304100979Srwatson 2305100979Srwatsonvoid 2306100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2307100979Srwatson{ 2308113482Srwatson struct label *label; 2309100979Srwatson 2310113482Srwatson label = mbuf_to_label(fragment); 2311113482Srwatson 2312113482Srwatson MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label); 2313100979Srwatson} 2314100979Srwatson 2315100979Srwatsonvoid 2316100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2317100979Srwatson{ 2318113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2319100979Srwatson 2320113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2321113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2322113482Srwatson 2323113482Srwatson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 2324113482Srwatson newmbuflabel); 2325100979Srwatson} 2326100979Srwatson 2327100979Srwatsonvoid 2328100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2329100979Srwatson{ 2330113482Srwatson struct label *label; 2331100979Srwatson 2332113482Srwatson label = mbuf_to_label(mbuf); 2333113482Srwatson 2334100979Srwatson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2335113482Srwatson label); 2336100979Srwatson} 2337100979Srwatson 2338100979Srwatsonvoid 2339100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2340100979Srwatson{ 2341113482Srwatson struct label *label; 2342100979Srwatson 2343113482Srwatson label = mbuf_to_label(mbuf); 2344113482Srwatson 2345100979Srwatson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2346113482Srwatson label); 2347100979Srwatson} 2348100979Srwatson 2349100979Srwatsonvoid 2350100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2351100979Srwatson{ 2352113482Srwatson struct label *label; 2353100979Srwatson 2354113482Srwatson label = mbuf_to_label(mbuf); 2355113482Srwatson 2356100979Srwatson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2357113482Srwatson label); 2358100979Srwatson} 2359100979Srwatson 2360100979Srwatsonvoid 2361100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2362100979Srwatson struct mbuf *newmbuf) 2363100979Srwatson{ 2364113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2365100979Srwatson 2366113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2367113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2368113482Srwatson 2369113482Srwatson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 2370113482Srwatson ifnet, &ifnet->if_label, newmbuf, newmbuflabel); 2371100979Srwatson} 2372100979Srwatson 2373100979Srwatsonvoid 2374100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2375100979Srwatson{ 2376113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2377100979Srwatson 2378113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2379113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2380113482Srwatson 2381113482Srwatson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 2382113482Srwatson newmbuflabel); 2383100979Srwatson} 2384100979Srwatson 2385100979Srwatsonint 2386100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2387100979Srwatson{ 2388113482Srwatson struct label *label; 2389100979Srwatson int result; 2390100979Srwatson 2391113482Srwatson label = mbuf_to_label(fragment); 2392113482Srwatson 2393100979Srwatson result = 1; 2394113482Srwatson MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 2395113482Srwatson &ipq->ipq_label); 2396100979Srwatson 2397100979Srwatson return (result); 2398100979Srwatson} 2399100979Srwatson 2400100979Srwatsonvoid 2401119244Srwatsonmac_reflect_mbuf_icmp(struct mbuf *m) 2402119244Srwatson{ 2403119244Srwatson struct label *label; 2404119244Srwatson 2405119244Srwatson label = mbuf_to_label(m); 2406119244Srwatson 2407119244Srwatson MAC_PERFORM(reflect_mbuf_icmp, m, label); 2408119244Srwatson} 2409119244Srwatsonvoid 2410119244Srwatsonmac_reflect_mbuf_tcp(struct mbuf *m) 2411119244Srwatson{ 2412119244Srwatson struct label *label; 2413119244Srwatson 2414119244Srwatson label = mbuf_to_label(m); 2415119244Srwatson 2416119244Srwatson MAC_PERFORM(reflect_mbuf_tcp, m, label); 2417119244Srwatson} 2418119244Srwatson 2419119244Srwatsonvoid 2420100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2421100979Srwatson{ 2422113482Srwatson struct label *label; 2423100979Srwatson 2424113482Srwatson label = mbuf_to_label(fragment); 2425113482Srwatson 2426113482Srwatson MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label); 2427100979Srwatson} 2428100979Srwatson 2429100979Srwatsonvoid 2430100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2431100979Srwatson{ 2432113482Srwatson struct label *label; 2433100979Srwatson 2434113482Srwatson label = mbuf_to_label(mbuf); 2435113482Srwatson 2436100979Srwatson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2437113482Srwatson label); 2438100979Srwatson} 2439100979Srwatson 2440100979Srwatsonvoid 2441100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp) 2442100979Srwatson{ 2443100979Srwatson 2444100979Srwatson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2445100979Srwatson &mp->mnt_fslabel); 2446100979Srwatson} 2447100979Srwatson 2448100979Srwatsonvoid 2449100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp) 2450100979Srwatson{ 2451100979Srwatson 2452100979Srwatson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2453100979Srwatson &mp->mnt_fslabel); 2454100979Srwatson} 2455100979Srwatson 2456100979Srwatsonint 2457100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2458100979Srwatson{ 2459100979Srwatson int error; 2460100979Srwatson 2461100979Srwatson if (!mac_enforce_network) 2462100979Srwatson return (0); 2463100979Srwatson 2464100979Srwatson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2465100979Srwatson &ifnet->if_label); 2466100979Srwatson 2467100979Srwatson return (error); 2468100979Srwatson} 2469100979Srwatson 2470100979Srwatsonstatic int 2471100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2472100979Srwatson{ 2473100979Srwatson int error; 2474100979Srwatson 2475100979Srwatson MAC_CHECK(check_cred_relabel, cred, newlabel); 2476100979Srwatson 2477100979Srwatson return (error); 2478100979Srwatson} 2479100979Srwatson 2480100979Srwatsonint 2481100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2482100979Srwatson{ 2483100979Srwatson int error; 2484100979Srwatson 2485100979Srwatson if (!mac_enforce_process) 2486100979Srwatson return (0); 2487100979Srwatson 2488100979Srwatson MAC_CHECK(check_cred_visible, u1, u2); 2489100979Srwatson 2490100979Srwatson return (error); 2491100979Srwatson} 2492100979Srwatson 2493100979Srwatsonint 2494100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2495100979Srwatson{ 2496113482Srwatson struct label *label; 2497100979Srwatson int error; 2498100979Srwatson 2499113487Srwatson M_ASSERTPKTHDR(mbuf); 2500113487Srwatson 2501100979Srwatson if (!mac_enforce_network) 2502100979Srwatson return (0); 2503100979Srwatson 2504113482Srwatson label = mbuf_to_label(mbuf); 2505100979Srwatson 2506100979Srwatson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2507113482Srwatson label); 2508100979Srwatson 2509100979Srwatson return (error); 2510100979Srwatson} 2511100979Srwatson 2512100979Srwatsonint 2513106308Srwatsonmac_check_kenv_dump(struct ucred *cred) 2514106308Srwatson{ 2515106308Srwatson int error; 2516106308Srwatson 2517106308Srwatson if (!mac_enforce_system) 2518106308Srwatson return (0); 2519106308Srwatson 2520106308Srwatson MAC_CHECK(check_kenv_dump, cred); 2521106308Srwatson 2522106308Srwatson return (error); 2523106308Srwatson} 2524106308Srwatson 2525106308Srwatsonint 2526106308Srwatsonmac_check_kenv_get(struct ucred *cred, char *name) 2527106308Srwatson{ 2528106308Srwatson int error; 2529106308Srwatson 2530106308Srwatson if (!mac_enforce_system) 2531106308Srwatson return (0); 2532106308Srwatson 2533106308Srwatson MAC_CHECK(check_kenv_get, cred, name); 2534106308Srwatson 2535106308Srwatson return (error); 2536106308Srwatson} 2537106308Srwatson 2538106308Srwatsonint 2539106308Srwatsonmac_check_kenv_set(struct ucred *cred, char *name, char *value) 2540106308Srwatson{ 2541106308Srwatson int error; 2542106308Srwatson 2543106308Srwatson if (!mac_enforce_system) 2544106308Srwatson return (0); 2545106308Srwatson 2546106308Srwatson MAC_CHECK(check_kenv_set, cred, name, value); 2547106308Srwatson 2548106308Srwatson return (error); 2549106308Srwatson} 2550106308Srwatson 2551106308Srwatsonint 2552106308Srwatsonmac_check_kenv_unset(struct ucred *cred, char *name) 2553106308Srwatson{ 2554106308Srwatson int error; 2555106308Srwatson 2556106308Srwatson if (!mac_enforce_system) 2557106308Srwatson return (0); 2558106308Srwatson 2559106308Srwatson MAC_CHECK(check_kenv_unset, cred, name); 2560106308Srwatson 2561106308Srwatson return (error); 2562106308Srwatson} 2563106308Srwatson 2564106308Srwatsonint 2565107089Srwatsonmac_check_kld_load(struct ucred *cred, struct vnode *vp) 2566107089Srwatson{ 2567107089Srwatson int error; 2568107089Srwatson 2569107089Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2570107089Srwatson 2571107089Srwatson if (!mac_enforce_kld) 2572107089Srwatson return (0); 2573107089Srwatson 2574107089Srwatson MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2575107089Srwatson 2576107089Srwatson return (error); 2577107089Srwatson} 2578107089Srwatson 2579107089Srwatsonint 2580107089Srwatsonmac_check_kld_stat(struct ucred *cred) 2581107089Srwatson{ 2582107089Srwatson int error; 2583107089Srwatson 2584107089Srwatson if (!mac_enforce_kld) 2585107089Srwatson return (0); 2586107089Srwatson 2587107089Srwatson MAC_CHECK(check_kld_stat, cred); 2588107089Srwatson 2589107089Srwatson return (error); 2590107089Srwatson} 2591107089Srwatson 2592107089Srwatsonint 2593107089Srwatsonmac_check_kld_unload(struct ucred *cred) 2594107089Srwatson{ 2595107089Srwatson int error; 2596107089Srwatson 2597107089Srwatson if (!mac_enforce_kld) 2598107089Srwatson return (0); 2599107089Srwatson 2600107089Srwatson MAC_CHECK(check_kld_unload, cred); 2601107089Srwatson 2602107089Srwatson return (error); 2603107089Srwatson} 2604107089Srwatson 2605107089Srwatsonint 2606100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount) 2607100979Srwatson{ 2608100979Srwatson int error; 2609100979Srwatson 2610100979Srwatson if (!mac_enforce_fs) 2611100979Srwatson return (0); 2612100979Srwatson 2613100979Srwatson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2614100979Srwatson 2615100979Srwatson return (error); 2616100979Srwatson} 2617100979Srwatson 2618100979Srwatsonint 2619100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2620100979Srwatson void *data) 2621100979Srwatson{ 2622100979Srwatson int error; 2623100979Srwatson 2624104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2625104269Srwatson 2626104269Srwatson if (!mac_enforce_pipe) 2627104269Srwatson return (0); 2628104269Srwatson 2629100979Srwatson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2630100979Srwatson 2631100979Srwatson return (error); 2632100979Srwatson} 2633100979Srwatson 2634100979Srwatsonint 2635102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2636100979Srwatson{ 2637100979Srwatson int error; 2638100979Srwatson 2639104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2640104269Srwatson 2641104269Srwatson if (!mac_enforce_pipe) 2642104269Srwatson return (0); 2643104269Srwatson 2644102115Srwatson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2645100979Srwatson 2646100979Srwatson return (error); 2647100979Srwatson} 2648100979Srwatson 2649102115Srwatsonint 2650102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2651102115Srwatson{ 2652102115Srwatson int error; 2653102115Srwatson 2654104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2655104269Srwatson 2656104269Srwatson if (!mac_enforce_pipe) 2657104269Srwatson return (0); 2658104269Srwatson 2659102115Srwatson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2660102115Srwatson 2661102115Srwatson return (error); 2662102115Srwatson} 2663102115Srwatson 2664100979Srwatsonstatic int 2665100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2666100979Srwatson struct label *newlabel) 2667100979Srwatson{ 2668100979Srwatson int error; 2669100979Srwatson 2670104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2671104269Srwatson 2672104269Srwatson if (!mac_enforce_pipe) 2673104269Srwatson return (0); 2674104269Srwatson 2675100979Srwatson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2676100979Srwatson 2677100979Srwatson return (error); 2678100979Srwatson} 2679100979Srwatson 2680100979Srwatsonint 2681102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2682102115Srwatson{ 2683102115Srwatson int error; 2684102115Srwatson 2685104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2686104269Srwatson 2687104269Srwatson if (!mac_enforce_pipe) 2688104269Srwatson return (0); 2689104269Srwatson 2690102115Srwatson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2691102115Srwatson 2692102115Srwatson return (error); 2693102115Srwatson} 2694102115Srwatson 2695102115Srwatsonint 2696102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2697102115Srwatson{ 2698102115Srwatson int error; 2699102115Srwatson 2700104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2701104269Srwatson 2702104269Srwatson if (!mac_enforce_pipe) 2703104269Srwatson return (0); 2704104269Srwatson 2705102115Srwatson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2706102115Srwatson 2707102115Srwatson return (error); 2708102115Srwatson} 2709102115Srwatson 2710102115Srwatsonint 2711100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc) 2712100979Srwatson{ 2713100979Srwatson int error; 2714100979Srwatson 2715102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2716102103Srwatson 2717100979Srwatson if (!mac_enforce_process) 2718100979Srwatson return (0); 2719100979Srwatson 2720100979Srwatson MAC_CHECK(check_proc_debug, cred, proc); 2721100979Srwatson 2722100979Srwatson return (error); 2723100979Srwatson} 2724100979Srwatson 2725100979Srwatsonint 2726100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc) 2727100979Srwatson{ 2728100979Srwatson int error; 2729100979Srwatson 2730102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2731102103Srwatson 2732100979Srwatson if (!mac_enforce_process) 2733100979Srwatson return (0); 2734100979Srwatson 2735100979Srwatson MAC_CHECK(check_proc_sched, cred, proc); 2736100979Srwatson 2737100979Srwatson return (error); 2738100979Srwatson} 2739100979Srwatson 2740100979Srwatsonint 2741100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2742100979Srwatson{ 2743100979Srwatson int error; 2744100979Srwatson 2745102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2746102103Srwatson 2747100979Srwatson if (!mac_enforce_process) 2748100979Srwatson return (0); 2749100979Srwatson 2750100979Srwatson MAC_CHECK(check_proc_signal, cred, proc, signum); 2751100979Srwatson 2752100979Srwatson return (error); 2753100979Srwatson} 2754100979Srwatson 2755100979Srwatsonint 2756100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2757100979Srwatson struct sockaddr *sockaddr) 2758100979Srwatson{ 2759100979Srwatson int error; 2760100979Srwatson 2761100979Srwatson if (!mac_enforce_socket) 2762100979Srwatson return (0); 2763100979Srwatson 2764100979Srwatson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2765100979Srwatson sockaddr); 2766100979Srwatson 2767100979Srwatson return (error); 2768100979Srwatson} 2769100979Srwatson 2770100979Srwatsonint 2771100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket, 2772100979Srwatson struct sockaddr *sockaddr) 2773100979Srwatson{ 2774100979Srwatson int error; 2775100979Srwatson 2776100979Srwatson if (!mac_enforce_socket) 2777100979Srwatson return (0); 2778100979Srwatson 2779100979Srwatson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2780100979Srwatson sockaddr); 2781100979Srwatson 2782100979Srwatson return (error); 2783100979Srwatson} 2784100979Srwatson 2785100979Srwatsonint 2786101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2787100979Srwatson{ 2788113482Srwatson struct label *label; 2789100979Srwatson int error; 2790100979Srwatson 2791100979Srwatson if (!mac_enforce_socket) 2792100979Srwatson return (0); 2793100979Srwatson 2794113482Srwatson label = mbuf_to_label(mbuf); 2795113482Srwatson 2796101933Srwatson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2797113482Srwatson label); 2798101933Srwatson 2799100979Srwatson return (error); 2800100979Srwatson} 2801100979Srwatson 2802100979Srwatsonint 2803101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket) 2804100979Srwatson{ 2805100979Srwatson int error; 2806100979Srwatson 2807100979Srwatson if (!mac_enforce_socket) 2808100979Srwatson return (0); 2809100979Srwatson 2810101933Srwatson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2811100979Srwatson return (error); 2812100979Srwatson} 2813100979Srwatson 2814104571Srwatsonint 2815104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so) 2816104571Srwatson{ 2817104571Srwatson int error; 2818104571Srwatson 2819104571Srwatson if (!mac_enforce_socket) 2820104571Srwatson return (0); 2821104571Srwatson 2822104571Srwatson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2823104571Srwatson 2824104571Srwatson return (error); 2825104571Srwatson} 2826104571Srwatson 2827100979Srwatsonstatic int 2828100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2829100979Srwatson struct label *newlabel) 2830100979Srwatson{ 2831100979Srwatson int error; 2832100979Srwatson 2833100979Srwatson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2834100979Srwatson newlabel); 2835100979Srwatson 2836100979Srwatson return (error); 2837100979Srwatson} 2838100979Srwatson 2839100979Srwatsonint 2840104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so) 2841104571Srwatson{ 2842104571Srwatson int error; 2843104571Srwatson 2844104571Srwatson if (!mac_enforce_socket) 2845104571Srwatson return (0); 2846104571Srwatson 2847104571Srwatson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2848104571Srwatson 2849104571Srwatson return (error); 2850104571Srwatson} 2851104571Srwatson 2852104571Srwatsonint 2853100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket) 2854100979Srwatson{ 2855100979Srwatson int error; 2856100979Srwatson 2857100979Srwatson if (!mac_enforce_socket) 2858100979Srwatson return (0); 2859105694Srwatson 2860100979Srwatson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2861105694Srwatson 2862100979Srwatson return (error); 2863100979Srwatson} 2864100979Srwatson 2865100979Srwatsonint 2866111939Srwatsonmac_check_sysarch_ioperm(struct ucred *cred) 2867111939Srwatson{ 2868111939Srwatson int error; 2869111939Srwatson 2870111939Srwatson if (!mac_enforce_system) 2871111939Srwatson return (0); 2872111939Srwatson 2873111939Srwatson MAC_CHECK(check_sysarch_ioperm, cred); 2874111939Srwatson return (error); 2875111939Srwatson} 2876111939Srwatson 2877111939Srwatsonint 2878106412Srwatsonmac_check_system_acct(struct ucred *cred, struct vnode *vp) 2879106412Srwatson{ 2880106412Srwatson int error; 2881106412Srwatson 2882106412Srwatson if (vp != NULL) { 2883106412Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2884106412Srwatson } 2885106412Srwatson 2886106412Srwatson if (!mac_enforce_system) 2887106412Srwatson return (0); 2888106412Srwatson 2889106412Srwatson MAC_CHECK(check_system_acct, cred, vp, 2890106412Srwatson vp != NULL ? &vp->v_label : NULL); 2891106412Srwatson 2892106412Srwatson return (error); 2893106412Srwatson} 2894106412Srwatson 2895106412Srwatsonint 2896106412Srwatsonmac_check_system_nfsd(struct ucred *cred) 2897106412Srwatson{ 2898106412Srwatson int error; 2899106412Srwatson 2900106412Srwatson if (!mac_enforce_system) 2901106412Srwatson return (0); 2902106412Srwatson 2903106412Srwatson MAC_CHECK(check_system_nfsd, cred); 2904106412Srwatson 2905106412Srwatson return (error); 2906106412Srwatson} 2907106412Srwatson 2908106412Srwatsonint 2909106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto) 2910106024Srwatson{ 2911106024Srwatson int error; 2912106024Srwatson 2913106045Srwatson if (!mac_enforce_system) 2914106024Srwatson return (0); 2915106024Srwatson 2916106024Srwatson MAC_CHECK(check_system_reboot, cred, howto); 2917106045Srwatson 2918106024Srwatson return (error); 2919106024Srwatson} 2920106024Srwatson 2921106024Srwatsonint 2922106369Srwatsonmac_check_system_settime(struct ucred *cred) 2923106369Srwatson{ 2924106369Srwatson int error; 2925106369Srwatson 2926106369Srwatson if (!mac_enforce_system) 2927106369Srwatson return (0); 2928106369Srwatson 2929106369Srwatson MAC_CHECK(check_system_settime, cred); 2930106369Srwatson 2931106369Srwatson return (error); 2932106369Srwatson} 2933106369Srwatson 2934106369Srwatsonint 2935106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2936106023Srwatson{ 2937106023Srwatson int error; 2938106023Srwatson 2939106023Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2940106023Srwatson 2941106045Srwatson if (!mac_enforce_system) 2942106023Srwatson return (0); 2943106023Srwatson 2944106023Srwatson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2945106023Srwatson return (error); 2946106023Srwatson} 2947106023Srwatson 2948106023Srwatsonint 2949111936Srwatsonmac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2950111936Srwatson{ 2951111936Srwatson int error; 2952111936Srwatson 2953111936Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2954111936Srwatson 2955111936Srwatson if (!mac_enforce_system) 2956111936Srwatson return (0); 2957111936Srwatson 2958111936Srwatson MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2959111936Srwatson return (error); 2960111936Srwatson} 2961111936Srwatson 2962111936Srwatsonint 2963106025Srwatsonmac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2964106025Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2965106025Srwatson{ 2966106025Srwatson int error; 2967106025Srwatson 2968106025Srwatson /* 2969106025Srwatson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2970106025Srwatson * but since it's not exported from kern_sysctl.c, we can't. 2971106025Srwatson */ 2972106045Srwatson if (!mac_enforce_system) 2973106025Srwatson return (0); 2974106025Srwatson 2975106025Srwatson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2976106025Srwatson inkernel, new, newlen); 2977106025Srwatson 2978106025Srwatson return (error); 2979106025Srwatson} 2980106025Srwatson 2981106025Srwatsonint 2982100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2983100979Srwatson struct ifnet *ifnet) 2984100979Srwatson{ 2985105694Srwatson char *elements, *buffer; 2986105694Srwatson struct mac mac; 2987100979Srwatson int error; 2988100979Srwatson 2989105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2990100979Srwatson if (error) 2991100979Srwatson return (error); 2992100979Srwatson 2993105694Srwatson error = mac_check_structmac_consistent(&mac); 2994105694Srwatson if (error) 2995105694Srwatson return (error); 2996105694Srwatson 2997111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2998105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2999105694Srwatson if (error) { 3000105694Srwatson free(elements, M_MACTEMP); 3001105694Srwatson return (error); 3002105694Srwatson } 3003105694Srwatson 3004111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3005105694Srwatson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 3006111119Simp buffer, mac.m_buflen, M_WAITOK); 3007105694Srwatson if (error == 0) 3008105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3009105694Srwatson 3010105694Srwatson free(buffer, M_MACTEMP); 3011105694Srwatson free(elements, M_MACTEMP); 3012105694Srwatson 3013105694Srwatson return (error); 3014100979Srwatson} 3015100979Srwatson 3016100979Srwatsonint 3017100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 3018100979Srwatson struct ifnet *ifnet) 3019100979Srwatson{ 3020100979Srwatson struct label intlabel; 3021105694Srwatson struct mac mac; 3022105694Srwatson char *buffer; 3023100979Srwatson int error; 3024100979Srwatson 3025105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3026100979Srwatson if (error) 3027100979Srwatson return (error); 3028100979Srwatson 3029105694Srwatson error = mac_check_structmac_consistent(&mac); 3030100979Srwatson if (error) 3031100979Srwatson return (error); 3032100979Srwatson 3033111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3034105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3035105694Srwatson if (error) { 3036105694Srwatson free(buffer, M_MACTEMP); 3037105694Srwatson return (error); 3038105694Srwatson } 3039105694Srwatson 3040105694Srwatson mac_init_ifnet_label(&intlabel); 3041105694Srwatson error = mac_internalize_ifnet_label(&intlabel, buffer); 3042105694Srwatson free(buffer, M_MACTEMP); 3043105694Srwatson if (error) { 3044105694Srwatson mac_destroy_ifnet_label(&intlabel); 3045105694Srwatson return (error); 3046105694Srwatson } 3047105694Srwatson 3048100979Srwatson /* 3049100979Srwatson * XXX: Note that this is a redundant privilege check, since 3050100979Srwatson * policies impose this check themselves if required by the 3051100979Srwatson * policy. Eventually, this should go away. 3052100979Srwatson */ 3053100979Srwatson error = suser_cred(cred, 0); 3054105694Srwatson if (error) { 3055105694Srwatson mac_destroy_ifnet_label(&intlabel); 3056105694Srwatson return (error); 3057105694Srwatson } 3058100979Srwatson 3059100979Srwatson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3060100979Srwatson &intlabel); 3061105694Srwatson if (error) { 3062105694Srwatson mac_destroy_ifnet_label(&intlabel); 3063105694Srwatson return (error); 3064105694Srwatson } 3065100979Srwatson 3066100979Srwatson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3067100979Srwatson 3068105694Srwatson mac_destroy_ifnet_label(&intlabel); 3069105694Srwatson return (0); 3070100979Srwatson} 3071100979Srwatson 3072100979Srwatsonvoid 3073107698Srwatsonmac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de) 3074100979Srwatson{ 3075100979Srwatson 3076107698Srwatson MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label); 3077100979Srwatson} 3078100979Srwatson 3079104533Srwatsonvoid 3080107698Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 3081107698Srwatson struct devfs_dirent *dd, struct devfs_dirent *de) 3082104533Srwatson{ 3083104533Srwatson 3084107698Srwatson MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de, 3085104533Srwatson &de->de_label); 3086104533Srwatson} 3087104533Srwatson 3088100979Srwatsonvoid 3089107698Srwatsonmac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 3090100979Srwatson struct devfs_dirent *de) 3091100979Srwatson{ 3092100979Srwatson 3093107698Srwatson MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 3094100979Srwatson &de->de_label); 3095100979Srwatson} 3096100979Srwatson 3097100979Srwatsonint 3098100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3099105694Srwatson struct mac *mac) 3100100979Srwatson{ 3101100979Srwatson struct label intlabel; 3102105694Srwatson char *buffer; 3103100979Srwatson int error; 3104100979Srwatson 3105105694Srwatson error = mac_check_structmac_consistent(mac); 3106100979Srwatson if (error) 3107100979Srwatson return (error); 3108100979Srwatson 3109111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3110105694Srwatson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3111105694Srwatson if (error) { 3112105694Srwatson free(buffer, M_MACTEMP); 3113105694Srwatson return (error); 3114105694Srwatson } 3115105694Srwatson 3116111119Simp mac_init_socket_label(&intlabel, M_WAITOK); 3117105694Srwatson error = mac_internalize_socket_label(&intlabel, buffer); 3118105694Srwatson free(buffer, M_MACTEMP); 3119105694Srwatson if (error) { 3120105694Srwatson mac_destroy_socket_label(&intlabel); 3121105694Srwatson return (error); 3122105694Srwatson } 3123105694Srwatson 3124100979Srwatson mac_check_socket_relabel(cred, so, &intlabel); 3125100979Srwatson if (error) { 3126105694Srwatson mac_destroy_socket_label(&intlabel); 3127100979Srwatson return (error); 3128100979Srwatson } 3129100979Srwatson 3130100979Srwatson mac_relabel_socket(cred, so, &intlabel); 3131100979Srwatson 3132105694Srwatson mac_destroy_socket_label(&intlabel); 3133100979Srwatson return (0); 3134100979Srwatson} 3135100979Srwatson 3136100979Srwatsonint 3137100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3138100979Srwatson{ 3139100979Srwatson int error; 3140100979Srwatson 3141104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3142104269Srwatson 3143100979Srwatson error = mac_check_pipe_relabel(cred, pipe, label); 3144100979Srwatson if (error) 3145100979Srwatson return (error); 3146100979Srwatson 3147100979Srwatson mac_relabel_pipe(cred, pipe, label); 3148100979Srwatson 3149100979Srwatson return (0); 3150100979Srwatson} 3151100979Srwatson 3152100979Srwatsonint 3153100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3154105694Srwatson struct mac *mac) 3155100979Srwatson{ 3156105694Srwatson char *buffer, *elements; 3157105694Srwatson int error; 3158100979Srwatson 3159105694Srwatson error = mac_check_structmac_consistent(mac); 3160105694Srwatson if (error) 3161105694Srwatson return (error); 3162105694Srwatson 3163111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3164105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3165105694Srwatson if (error) { 3166105694Srwatson free(elements, M_MACTEMP); 3167105694Srwatson return (error); 3168105694Srwatson } 3169105694Srwatson 3170111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3171105694Srwatson error = mac_externalize_socket_label(&so->so_label, elements, 3172111119Simp buffer, mac->m_buflen, M_WAITOK); 3173105694Srwatson if (error == 0) 3174105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3175105694Srwatson 3176105694Srwatson free(buffer, M_MACTEMP); 3177105694Srwatson free(elements, M_MACTEMP); 3178105694Srwatson 3179105694Srwatson return (error); 3180100979Srwatson} 3181100979Srwatson 3182100979Srwatsonint 3183100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3184105694Srwatson struct mac *mac) 3185100979Srwatson{ 3186105694Srwatson char *elements, *buffer; 3187105694Srwatson int error; 3188100979Srwatson 3189105694Srwatson error = mac_check_structmac_consistent(mac); 3190105694Srwatson if (error) 3191105694Srwatson return (error); 3192105694Srwatson 3193111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3194105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3195105694Srwatson if (error) { 3196105694Srwatson free(elements, M_MACTEMP); 3197105694Srwatson return (error); 3198105694Srwatson } 3199105694Srwatson 3200111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3201105694Srwatson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3202111119Simp elements, buffer, mac->m_buflen, M_WAITOK); 3203105694Srwatson if (error == 0) 3204105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3205105694Srwatson 3206105694Srwatson free(buffer, M_MACTEMP); 3207105694Srwatson free(elements, M_MACTEMP); 3208105694Srwatson 3209105694Srwatson return (error); 3210100979Srwatson} 3211100979Srwatson 3212100979Srwatson/* 3213100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes 3214100979Srwatson * to store label data. Can be referenced by filesystems supporting 3215100979Srwatson * extended attributes. 3216100979Srwatson */ 3217100979Srwatsonint 3218100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3219100979Srwatson{ 3220100979Srwatson struct vnode *vp = ap->a_vp; 3221100979Srwatson struct label *intlabel = ap->a_label; 3222100979Srwatson int error; 3223100979Srwatson 3224100979Srwatson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3225100979Srwatson 3226105988Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3227105988Srwatson return (EOPNOTSUPP); 3228100979Srwatson 3229105988Srwatson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3230100979Srwatson if (error) 3231100979Srwatson return (error); 3232100979Srwatson 3233100979Srwatson mac_relabel_vnode(ap->a_cred, vp, intlabel); 3234100979Srwatson 3235100979Srwatson return (0); 3236100979Srwatson} 3237100979Srwatson 3238100979Srwatsonstatic int 3239100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3240100979Srwatson{ 3241100979Srwatson int error; 3242100979Srwatson 3243100979Srwatson if (vp->v_mount == NULL) { 3244100979Srwatson /* printf("vn_setlabel: null v_mount\n"); */ 3245103314Snjl if (vp->v_type != VNON) 3246103314Snjl printf("vn_setlabel: null v_mount with non-VNON\n"); 3247100979Srwatson return (EBADF); 3248100979Srwatson } 3249100979Srwatson 3250100979Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3251100979Srwatson return (EOPNOTSUPP); 3252100979Srwatson 3253100979Srwatson /* 3254100979Srwatson * Multi-phase commit. First check the policies to confirm the 3255100979Srwatson * change is OK. Then commit via the filesystem. Finally, 3256100979Srwatson * update the actual vnode label. Question: maybe the filesystem 3257100979Srwatson * should update the vnode at the end as part of VOP_SETLABEL()? 3258100979Srwatson */ 3259100979Srwatson error = mac_check_vnode_relabel(cred, vp, intlabel); 3260100979Srwatson if (error) 3261100979Srwatson return (error); 3262100979Srwatson 3263100979Srwatson /* 3264100979Srwatson * VADMIN provides the opportunity for the filesystem to make 3265100979Srwatson * decisions about who is and is not able to modify labels 3266100979Srwatson * and protections on files. This might not be right. We can't 3267100979Srwatson * assume VOP_SETLABEL() will do it, because we might implement 3268100979Srwatson * that as part of vop_stdsetlabel_ea(). 3269100979Srwatson */ 3270100979Srwatson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3271100979Srwatson if (error) 3272100979Srwatson return (error); 3273100979Srwatson 3274100979Srwatson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3275100979Srwatson if (error) 3276100979Srwatson return (error); 3277100979Srwatson 3278100979Srwatson return (0); 3279100979Srwatson} 3280100979Srwatson 3281105694Srwatsonint 3282105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3283105694Srwatson{ 3284105694Srwatson char *elements, *buffer; 3285105694Srwatson struct mac mac; 3286105694Srwatson struct proc *tproc; 3287105694Srwatson struct ucred *tcred; 3288105694Srwatson int error; 3289105694Srwatson 3290107849Salfred error = copyin(uap->mac_p, &mac, sizeof(mac)); 3291105694Srwatson if (error) 3292105694Srwatson return (error); 3293105694Srwatson 3294105694Srwatson error = mac_check_structmac_consistent(&mac); 3295105694Srwatson if (error) 3296105694Srwatson return (error); 3297105694Srwatson 3298105694Srwatson tproc = pfind(uap->pid); 3299105694Srwatson if (tproc == NULL) 3300105694Srwatson return (ESRCH); 3301105694Srwatson 3302105694Srwatson tcred = NULL; /* Satisfy gcc. */ 3303105694Srwatson error = p_cansee(td, tproc); 3304105694Srwatson if (error == 0) 3305105694Srwatson tcred = crhold(tproc->p_ucred); 3306105694Srwatson PROC_UNLOCK(tproc); 3307105694Srwatson if (error) 3308105694Srwatson return (error); 3309105694Srwatson 3310111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3311105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3312105694Srwatson if (error) { 3313105694Srwatson free(elements, M_MACTEMP); 3314105694Srwatson crfree(tcred); 3315105694Srwatson return (error); 3316105694Srwatson } 3317105694Srwatson 3318111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3319105694Srwatson error = mac_externalize_cred_label(&tcred->cr_label, elements, 3320111119Simp buffer, mac.m_buflen, M_WAITOK); 3321105694Srwatson if (error == 0) 3322105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3323105694Srwatson 3324105694Srwatson free(buffer, M_MACTEMP); 3325105694Srwatson free(elements, M_MACTEMP); 3326105694Srwatson crfree(tcred); 3327105694Srwatson return (error); 3328105694Srwatson} 3329105694Srwatson 3330100979Srwatson/* 3331100979Srwatson * MPSAFE 3332100979Srwatson */ 3333100979Srwatsonint 3334100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3335100894Srwatson{ 3336105694Srwatson char *elements, *buffer; 3337105694Srwatson struct mac mac; 3338100979Srwatson int error; 3339100894Srwatson 3340105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3341105694Srwatson if (error) 3342105694Srwatson return (error); 3343105694Srwatson 3344105694Srwatson error = mac_check_structmac_consistent(&mac); 3345105694Srwatson if (error) 3346105694Srwatson return (error); 3347105694Srwatson 3348111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3349105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3350105694Srwatson if (error) { 3351105694Srwatson free(elements, M_MACTEMP); 3352105694Srwatson return (error); 3353105694Srwatson } 3354105694Srwatson 3355111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3356105694Srwatson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3357111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3358100979Srwatson if (error == 0) 3359105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3360100979Srwatson 3361105694Srwatson free(buffer, M_MACTEMP); 3362105694Srwatson free(elements, M_MACTEMP); 3363100979Srwatson return (error); 3364100979Srwatson} 3365100979Srwatson 3366100979Srwatson/* 3367100979Srwatson * MPSAFE 3368100979Srwatson */ 3369100979Srwatsonint 3370100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3371100979Srwatson{ 3372100979Srwatson struct ucred *newcred, *oldcred; 3373105694Srwatson struct label intlabel; 3374100979Srwatson struct proc *p; 3375105694Srwatson struct mac mac; 3376105694Srwatson char *buffer; 3377100979Srwatson int error; 3378100979Srwatson 3379105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3380100979Srwatson if (error) 3381100979Srwatson return (error); 3382100979Srwatson 3383105694Srwatson error = mac_check_structmac_consistent(&mac); 3384100979Srwatson if (error) 3385100979Srwatson return (error); 3386100979Srwatson 3387111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3388105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3389105694Srwatson if (error) { 3390105694Srwatson free(buffer, M_MACTEMP); 3391105694Srwatson return (error); 3392105694Srwatson } 3393105694Srwatson 3394105694Srwatson mac_init_cred_label(&intlabel); 3395105694Srwatson error = mac_internalize_cred_label(&intlabel, buffer); 3396105694Srwatson free(buffer, M_MACTEMP); 3397105694Srwatson if (error) { 3398105694Srwatson mac_destroy_cred_label(&intlabel); 3399105694Srwatson return (error); 3400105694Srwatson } 3401105694Srwatson 3402100979Srwatson newcred = crget(); 3403100979Srwatson 3404100979Srwatson p = td->td_proc; 3405100979Srwatson PROC_LOCK(p); 3406100979Srwatson oldcred = p->p_ucred; 3407100979Srwatson 3408100979Srwatson error = mac_check_cred_relabel(oldcred, &intlabel); 3409100979Srwatson if (error) { 3410100979Srwatson PROC_UNLOCK(p); 3411100979Srwatson crfree(newcred); 3412105694Srwatson goto out; 3413100979Srwatson } 3414100979Srwatson 3415100979Srwatson setsugid(p); 3416100979Srwatson crcopy(newcred, oldcred); 3417100979Srwatson mac_relabel_cred(newcred, &intlabel); 3418102136Srwatson p->p_ucred = newcred; 3419100979Srwatson 3420102136Srwatson /* 3421102136Srwatson * Grab additional reference for use while revoking mmaps, prior 3422102136Srwatson * to releasing the proc lock and sharing the cred. 3423102136Srwatson */ 3424102136Srwatson crhold(newcred); 3425100979Srwatson PROC_UNLOCK(p); 3426102136Srwatson 3427105694Srwatson if (mac_enforce_vm) { 3428105694Srwatson mtx_lock(&Giant); 3429105694Srwatson mac_cred_mmapped_drop_perms(td, newcred); 3430105694Srwatson mtx_unlock(&Giant); 3431105694Srwatson } 3432102136Srwatson 3433102136Srwatson crfree(newcred); /* Free revocation reference. */ 3434100979Srwatson crfree(oldcred); 3435105694Srwatson 3436105694Srwatsonout: 3437105694Srwatson mac_destroy_cred_label(&intlabel); 3438105694Srwatson return (error); 3439100979Srwatson} 3440100979Srwatson 3441100979Srwatson/* 3442100979Srwatson * MPSAFE 3443100979Srwatson */ 3444100979Srwatsonint 3445100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3446100979Srwatson{ 3447105694Srwatson char *elements, *buffer; 3448105694Srwatson struct label intlabel; 3449100979Srwatson struct file *fp; 3450105694Srwatson struct mac mac; 3451100979Srwatson struct vnode *vp; 3452100979Srwatson struct pipe *pipe; 3453105694Srwatson short label_type; 3454100979Srwatson int error; 3455100979Srwatson 3456105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3457105694Srwatson if (error) 3458105694Srwatson return (error); 3459100979Srwatson 3460105694Srwatson error = mac_check_structmac_consistent(&mac); 3461105694Srwatson if (error) 3462105694Srwatson return (error); 3463105694Srwatson 3464111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3465105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3466105694Srwatson if (error) { 3467105694Srwatson free(elements, M_MACTEMP); 3468105694Srwatson return (error); 3469105694Srwatson } 3470105694Srwatson 3471111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3472105694Srwatson mtx_lock(&Giant); /* VFS */ 3473107849Salfred error = fget(td, uap->fd, &fp); 3474100979Srwatson if (error) 3475100979Srwatson goto out; 3476100979Srwatson 3477105694Srwatson label_type = fp->f_type; 3478100979Srwatson switch (fp->f_type) { 3479100979Srwatson case DTYPE_FIFO: 3480100979Srwatson case DTYPE_VNODE: 3481116678Sphk vp = fp->f_vnode; 3482100979Srwatson 3483105694Srwatson mac_init_vnode_label(&intlabel); 3484105694Srwatson 3485100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3486105988Srwatson mac_copy_vnode_label(&vp->v_label, &intlabel); 3487100979Srwatson VOP_UNLOCK(vp, 0, td); 3488105694Srwatson 3489100979Srwatson break; 3490100979Srwatson case DTYPE_PIPE: 3491109153Sdillon pipe = fp->f_data; 3492105694Srwatson 3493105694Srwatson mac_init_pipe_label(&intlabel); 3494105694Srwatson 3495105694Srwatson PIPE_LOCK(pipe); 3496105694Srwatson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3497105694Srwatson PIPE_UNLOCK(pipe); 3498100979Srwatson break; 3499100979Srwatson default: 3500100979Srwatson error = EINVAL; 3501105694Srwatson fdrop(fp, td); 3502105694Srwatson goto out; 3503100979Srwatson } 3504105694Srwatson fdrop(fp, td); 3505100979Srwatson 3506105694Srwatson switch (label_type) { 3507105694Srwatson case DTYPE_FIFO: 3508105694Srwatson case DTYPE_VNODE: 3509105694Srwatson if (error == 0) 3510105694Srwatson error = mac_externalize_vnode_label(&intlabel, 3511111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3512105694Srwatson mac_destroy_vnode_label(&intlabel); 3513105694Srwatson break; 3514105694Srwatson case DTYPE_PIPE: 3515105694Srwatson error = mac_externalize_pipe_label(&intlabel, elements, 3516111119Simp buffer, mac.m_buflen, M_WAITOK); 3517105694Srwatson mac_destroy_pipe_label(&intlabel); 3518105694Srwatson break; 3519105694Srwatson default: 3520105694Srwatson panic("__mac_get_fd: corrupted label_type"); 3521105694Srwatson } 3522105694Srwatson 3523100979Srwatson if (error == 0) 3524105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3525100979Srwatson 3526105694Srwatsonout: 3527105694Srwatson mtx_unlock(&Giant); /* VFS */ 3528105694Srwatson free(buffer, M_MACTEMP); 3529105694Srwatson free(elements, M_MACTEMP); 3530100979Srwatson 3531100979Srwatson return (error); 3532100979Srwatson} 3533100979Srwatson 3534100979Srwatson/* 3535100979Srwatson * MPSAFE 3536100979Srwatson */ 3537100979Srwatsonint 3538100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3539100979Srwatson{ 3540105694Srwatson char *elements, *buffer; 3541100979Srwatson struct nameidata nd; 3542105694Srwatson struct label intlabel; 3543105694Srwatson struct mac mac; 3544100979Srwatson int error; 3545100979Srwatson 3546105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3547105694Srwatson if (error) 3548105694Srwatson return (error); 3549105694Srwatson 3550105694Srwatson error = mac_check_structmac_consistent(&mac); 3551105694Srwatson if (error) 3552105694Srwatson return (error); 3553105694Srwatson 3554111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3555105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3556105694Srwatson if (error) { 3557105694Srwatson free(elements, M_MACTEMP); 3558105694Srwatson return (error); 3559105694Srwatson } 3560105694Srwatson 3561111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3562105694Srwatson mtx_lock(&Giant); /* VFS */ 3563105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3564105694Srwatson td); 3565100979Srwatson error = namei(&nd); 3566100979Srwatson if (error) 3567100979Srwatson goto out; 3568100979Srwatson 3569105694Srwatson mac_init_vnode_label(&intlabel); 3570105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3571105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3572111119Simp mac.m_buflen, M_WAITOK); 3573105694Srwatson 3574100979Srwatson NDFREE(&nd, 0); 3575105694Srwatson mac_destroy_vnode_label(&intlabel); 3576105694Srwatson 3577105694Srwatson if (error == 0) 3578105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3579105694Srwatson 3580105694Srwatsonout: 3581105694Srwatson mtx_unlock(&Giant); /* VFS */ 3582105694Srwatson 3583105694Srwatson free(buffer, M_MACTEMP); 3584105694Srwatson free(elements, M_MACTEMP); 3585105694Srwatson 3586105694Srwatson return (error); 3587105694Srwatson} 3588105694Srwatson 3589105694Srwatson/* 3590105694Srwatson * MPSAFE 3591105694Srwatson */ 3592105694Srwatsonint 3593105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3594105694Srwatson{ 3595105694Srwatson char *elements, *buffer; 3596105694Srwatson struct nameidata nd; 3597105694Srwatson struct label intlabel; 3598105694Srwatson struct mac mac; 3599105694Srwatson int error; 3600105694Srwatson 3601105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3602100979Srwatson if (error) 3603105694Srwatson return (error); 3604105694Srwatson 3605105694Srwatson error = mac_check_structmac_consistent(&mac); 3606105694Srwatson if (error) 3607105694Srwatson return (error); 3608105694Srwatson 3609111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3610105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3611105694Srwatson if (error) { 3612105694Srwatson free(elements, M_MACTEMP); 3613105694Srwatson return (error); 3614105694Srwatson } 3615105694Srwatson 3616111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3617105694Srwatson mtx_lock(&Giant); /* VFS */ 3618105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3619105694Srwatson td); 3620105694Srwatson error = namei(&nd); 3621105694Srwatson if (error) 3622100979Srwatson goto out; 3623100979Srwatson 3624105694Srwatson mac_init_vnode_label(&intlabel); 3625105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3626105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3627111119Simp mac.m_buflen, M_WAITOK); 3628105694Srwatson NDFREE(&nd, 0); 3629105694Srwatson mac_destroy_vnode_label(&intlabel); 3630100979Srwatson 3631105694Srwatson if (error == 0) 3632105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3633105694Srwatson 3634100979Srwatsonout: 3635105694Srwatson mtx_unlock(&Giant); /* VFS */ 3636105694Srwatson 3637105694Srwatson free(buffer, M_MACTEMP); 3638105694Srwatson free(elements, M_MACTEMP); 3639105694Srwatson 3640100979Srwatson return (error); 3641100979Srwatson} 3642100979Srwatson 3643100979Srwatson/* 3644100979Srwatson * MPSAFE 3645100979Srwatson */ 3646100979Srwatsonint 3647100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3648100979Srwatson{ 3649105694Srwatson struct label intlabel; 3650105694Srwatson struct pipe *pipe; 3651100979Srwatson struct file *fp; 3652100979Srwatson struct mount *mp; 3653100979Srwatson struct vnode *vp; 3654105694Srwatson struct mac mac; 3655105694Srwatson char *buffer; 3656100979Srwatson int error; 3657100979Srwatson 3658105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3659100979Srwatson if (error) 3660105694Srwatson return (error); 3661100979Srwatson 3662105694Srwatson error = mac_check_structmac_consistent(&mac); 3663100979Srwatson if (error) 3664105694Srwatson return (error); 3665100979Srwatson 3666111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3667105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3668105694Srwatson if (error) { 3669105694Srwatson free(buffer, M_MACTEMP); 3670105694Srwatson return (error); 3671105694Srwatson } 3672105694Srwatson 3673105694Srwatson mtx_lock(&Giant); /* VFS */ 3674105694Srwatson 3675107849Salfred error = fget(td, uap->fd, &fp); 3676100979Srwatson if (error) 3677105694Srwatson goto out; 3678100979Srwatson 3679100979Srwatson switch (fp->f_type) { 3680100979Srwatson case DTYPE_FIFO: 3681100979Srwatson case DTYPE_VNODE: 3682105694Srwatson mac_init_vnode_label(&intlabel); 3683105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3684105694Srwatson if (error) { 3685105694Srwatson mac_destroy_vnode_label(&intlabel); 3686105694Srwatson break; 3687105694Srwatson } 3688105694Srwatson 3689116678Sphk vp = fp->f_vnode; 3690100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3691105694Srwatson if (error != 0) { 3692105694Srwatson mac_destroy_vnode_label(&intlabel); 3693100979Srwatson break; 3694105694Srwatson } 3695100979Srwatson 3696100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3697100979Srwatson error = vn_setlabel(vp, &intlabel, td->td_ucred); 3698100979Srwatson VOP_UNLOCK(vp, 0, td); 3699100979Srwatson vn_finished_write(mp); 3700105694Srwatson 3701105694Srwatson mac_destroy_vnode_label(&intlabel); 3702100979Srwatson break; 3703105694Srwatson 3704100979Srwatson case DTYPE_PIPE: 3705105694Srwatson mac_init_pipe_label(&intlabel); 3706105694Srwatson error = mac_internalize_pipe_label(&intlabel, buffer); 3707105694Srwatson if (error == 0) { 3708109153Sdillon pipe = fp->f_data; 3709105694Srwatson PIPE_LOCK(pipe); 3710105694Srwatson error = mac_pipe_label_set(td->td_ucred, pipe, 3711105694Srwatson &intlabel); 3712105694Srwatson PIPE_UNLOCK(pipe); 3713105694Srwatson } 3714105694Srwatson 3715105694Srwatson mac_destroy_pipe_label(&intlabel); 3716100979Srwatson break; 3717105694Srwatson 3718100979Srwatson default: 3719100979Srwatson error = EINVAL; 3720100979Srwatson } 3721100979Srwatson 3722100979Srwatson fdrop(fp, td); 3723105694Srwatsonout: 3724105694Srwatson mtx_unlock(&Giant); /* VFS */ 3725105694Srwatson 3726105694Srwatson free(buffer, M_MACTEMP); 3727105694Srwatson 3728100979Srwatson return (error); 3729100979Srwatson} 3730100979Srwatson 3731100979Srwatson/* 3732100979Srwatson * MPSAFE 3733100979Srwatson */ 3734100979Srwatsonint 3735100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3736100979Srwatson{ 3737105694Srwatson struct label intlabel; 3738100979Srwatson struct nameidata nd; 3739100979Srwatson struct mount *mp; 3740105694Srwatson struct mac mac; 3741105694Srwatson char *buffer; 3742100979Srwatson int error; 3743100979Srwatson 3744105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3745100979Srwatson if (error) 3746105694Srwatson return (error); 3747100979Srwatson 3748105694Srwatson error = mac_check_structmac_consistent(&mac); 3749100979Srwatson if (error) 3750105694Srwatson return (error); 3751100979Srwatson 3752111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3753105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3754105694Srwatson if (error) { 3755105694Srwatson free(buffer, M_MACTEMP); 3756105694Srwatson return (error); 3757105694Srwatson } 3758105694Srwatson 3759105694Srwatson mac_init_vnode_label(&intlabel); 3760105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3761105694Srwatson free(buffer, M_MACTEMP); 3762105694Srwatson if (error) { 3763105694Srwatson mac_destroy_vnode_label(&intlabel); 3764105694Srwatson return (error); 3765105694Srwatson } 3766105694Srwatson 3767105694Srwatson mtx_lock(&Giant); /* VFS */ 3768105694Srwatson 3769105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3770105694Srwatson td); 3771100979Srwatson error = namei(&nd); 3772105694Srwatson if (error == 0) { 3773105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3774105694Srwatson if (error == 0) 3775105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3776105694Srwatson td->td_ucred); 3777105694Srwatson vn_finished_write(mp); 3778105694Srwatson } 3779105694Srwatson 3780105694Srwatson NDFREE(&nd, 0); 3781105694Srwatson mtx_unlock(&Giant); /* VFS */ 3782105694Srwatson mac_destroy_vnode_label(&intlabel); 3783105694Srwatson 3784105694Srwatson return (error); 3785105694Srwatson} 3786105694Srwatson 3787105694Srwatson/* 3788105694Srwatson * MPSAFE 3789105694Srwatson */ 3790105694Srwatsonint 3791105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3792105694Srwatson{ 3793105694Srwatson struct label intlabel; 3794105694Srwatson struct nameidata nd; 3795105694Srwatson struct mount *mp; 3796105694Srwatson struct mac mac; 3797105694Srwatson char *buffer; 3798105694Srwatson int error; 3799105694Srwatson 3800105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3801100979Srwatson if (error) 3802105694Srwatson return (error); 3803105694Srwatson 3804105694Srwatson error = mac_check_structmac_consistent(&mac); 3805100979Srwatson if (error) 3806105694Srwatson return (error); 3807100979Srwatson 3808111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3809105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3810105694Srwatson if (error) { 3811105694Srwatson free(buffer, M_MACTEMP); 3812105694Srwatson return (error); 3813105694Srwatson } 3814105694Srwatson 3815105694Srwatson mac_init_vnode_label(&intlabel); 3816105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3817105694Srwatson free(buffer, M_MACTEMP); 3818105694Srwatson if (error) { 3819105694Srwatson mac_destroy_vnode_label(&intlabel); 3820105694Srwatson return (error); 3821105694Srwatson } 3822105694Srwatson 3823105694Srwatson mtx_lock(&Giant); /* VFS */ 3824105694Srwatson 3825105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3826105694Srwatson td); 3827105694Srwatson error = namei(&nd); 3828105694Srwatson if (error == 0) { 3829105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3830105694Srwatson if (error == 0) 3831105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3832105694Srwatson td->td_ucred); 3833105694Srwatson vn_finished_write(mp); 3834105694Srwatson } 3835105694Srwatson 3836100979Srwatson NDFREE(&nd, 0); 3837105694Srwatson mtx_unlock(&Giant); /* VFS */ 3838105694Srwatson mac_destroy_vnode_label(&intlabel); 3839105694Srwatson 3840100979Srwatson return (error); 3841100979Srwatson} 3842100979Srwatson 3843105694Srwatson/* 3844105694Srwatson * MPSAFE 3845105694Srwatson */ 3846102123Srwatsonint 3847102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3848102123Srwatson{ 3849102123Srwatson struct mac_policy_conf *mpc; 3850102123Srwatson char target[MAC_MAX_POLICY_NAME]; 3851114806Srwatson int entrycount, error; 3852102123Srwatson 3853107849Salfred error = copyinstr(uap->policy, target, sizeof(target), NULL); 3854102123Srwatson if (error) 3855102123Srwatson return (error); 3856102123Srwatson 3857102123Srwatson error = ENOSYS; 3858119494Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { 3859102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3860102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3861102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3862107849Salfred uap->call, uap->arg); 3863102123Srwatson goto out; 3864102123Srwatson } 3865102123Srwatson } 3866102123Srwatson 3867114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { 3868114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3869114806Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3870114806Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3871114806Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3872114806Srwatson uap->call, uap->arg); 3873114806Srwatson break; 3874114806Srwatson } 3875114806Srwatson } 3876114806Srwatson mac_policy_list_unbusy(); 3877114806Srwatson } 3878102123Srwatsonout: 3879102123Srwatson return (error); 3880102123Srwatson} 3881102123Srwatson 3882100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3883100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3884100979Srwatson 3885100979Srwatson#else /* !MAC */ 3886100979Srwatson 3887100979Srwatsonint 3888105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3889105694Srwatson{ 3890105694Srwatson 3891105694Srwatson return (ENOSYS); 3892105694Srwatson} 3893105694Srwatson 3894105694Srwatsonint 3895100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3896100979Srwatson{ 3897100979Srwatson 3898100894Srwatson return (ENOSYS); 3899100894Srwatson} 3900100894Srwatson 3901100894Srwatsonint 3902100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3903100894Srwatson{ 3904100894Srwatson 3905100894Srwatson return (ENOSYS); 3906100894Srwatson} 3907100894Srwatson 3908100894Srwatsonint 3909100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3910100894Srwatson{ 3911100894Srwatson 3912100894Srwatson return (ENOSYS); 3913100894Srwatson} 3914100894Srwatson 3915100894Srwatsonint 3916100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3917100894Srwatson{ 3918100894Srwatson 3919100894Srwatson return (ENOSYS); 3920100894Srwatson} 3921100894Srwatson 3922100894Srwatsonint 3923105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3924105694Srwatson{ 3925105694Srwatson 3926105694Srwatson return (ENOSYS); 3927105694Srwatson} 3928105694Srwatson 3929105694Srwatsonint 3930100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3931100894Srwatson{ 3932100894Srwatson 3933100894Srwatson return (ENOSYS); 3934100894Srwatson} 3935100894Srwatson 3936100894Srwatsonint 3937100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3938100894Srwatson{ 3939100894Srwatson 3940100894Srwatson return (ENOSYS); 3941100894Srwatson} 3942100979Srwatson 3943102123Srwatsonint 3944105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3945105694Srwatson{ 3946105694Srwatson 3947105694Srwatson return (ENOSYS); 3948105694Srwatson} 3949105694Srwatson 3950105694Srwatsonint 3951102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3952102123Srwatson{ 3953102123Srwatson 3954102123Srwatson return (ENOSYS); 3955102123Srwatson} 3956102123Srwatson 3957105694Srwatson#endif 3958