mac_syscalls.c revision 120582
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 120582 2003-09-29 18:35:17Z 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 error_select(int error1, int error2); 239100979Srwatsonstatic int mac_policy_register(struct mac_policy_conf *mpc); 240100979Srwatsonstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 241100979Srwatson 242104546Srwatsonstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 243104546Srwatson struct vnode *vp, int *prot); 244100979Srwatsonstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 245100979Srwatson struct ucred *cred, struct vm_map *map); 246100979Srwatson 247104541Srwatsonstatic void mac_destroy_socket_label(struct label *label); 248104541Srwatson 249105988Srwatsonstatic int mac_setlabel_vnode_extattr(struct ucred *cred, 250105988Srwatson struct vnode *vp, struct label *intlabel); 251105988Srwatson 252100979SrwatsonMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 253105694SrwatsonMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 254100979Srwatson 255100979Srwatson/* 256114806Srwatson * mac_static_policy_list holds a list of policy modules that are not 257114806Srwatson * loaded while the system is "live", and cannot be unloaded. These 258114806Srwatson * policies can be invoked without holding the busy count. 259114806Srwatson * 260114806Srwatson * mac_policy_list stores the list of dynamic policies. A busy count is 261106856Srwatson * maintained for the list, stored in mac_policy_busy. The busy count 262114806Srwatson * is protected by mac_policy_mtx; the list may be modified only 263106856Srwatson * while the busy count is 0, requiring that the lock be held to 264106856Srwatson * prevent new references to the list from being acquired. For almost 265106856Srwatson * all operations, incrementing the busy count is sufficient to 266106856Srwatson * guarantee consistency, as the list cannot be modified while the 267106856Srwatson * busy count is elevated. For a few special operations involving a 268114806Srwatson * change to the list of active policies, the mtx itself must be held. 269114806Srwatson * A condition variable, mac_policy_cv, is used to signal potential 270114806Srwatson * exclusive consumers that they should try to acquire the lock if a 271114806Srwatson * first attempt at exclusive access fails. 272100979Srwatson */ 273114806Srwatsonstatic struct mtx mac_policy_mtx; 274114806Srwatsonstatic struct cv mac_policy_cv; 275114806Srwatsonstatic int mac_policy_count; 276100979Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 277114806Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_static_policy_list; 278100979Srwatson 279106856Srwatson/* 280111883Sjhb * We manually invoke WITNESS_WARN() to allow Witness to generate 281106856Srwatson * warnings even if we don't end up ever triggering the wait at 282106856Srwatson * run-time. The consumer of the exclusive interface must not hold 283106856Srwatson * any locks (other than potentially Giant) since we may sleep for 284106856Srwatson * long (potentially indefinite) periods of time waiting for the 285106856Srwatson * framework to become quiescent so that a policy list change may 286106856Srwatson * be made. 287106856Srwatson */ 288114806Srwatsonstatic __inline void 289114806Srwatsonmac_policy_grab_exclusive(void) 290114806Srwatson{ 291114806Srwatson WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, 292114806Srwatson "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__); 293114806Srwatson mtx_lock(&mac_policy_mtx); 294114806Srwatson while (mac_policy_count != 0) 295114806Srwatson cv_wait(&mac_policy_cv, &mac_policy_mtx); 296114806Srwatson} 297106856Srwatson 298114806Srwatsonstatic __inline void 299114806Srwatsonmac_policy_assert_exclusive(void) 300114806Srwatson{ 301114806Srwatson mtx_assert(&mac_policy_mtx, MA_OWNED); 302114806Srwatson KASSERT(mac_policy_count == 0, 303114806Srwatson ("mac_policy_assert_exclusive(): not exclusive")); 304114806Srwatson} 305113487Srwatson 306114806Srwatsonstatic __inline void 307114806Srwatsonmac_policy_release_exclusive(void) 308114806Srwatson{ 309100979Srwatson 310114806Srwatson KASSERT(mac_policy_count == 0, 311114806Srwatson ("mac_policy_release_exclusive(): not exclusive")); 312114806Srwatson mtx_unlock(&mac_policy_mtx); 313114806Srwatson cv_signal(&mac_policy_cv); 314114806Srwatson} 315100979Srwatson 316114806Srwatsonstatic __inline void 317114806Srwatsonmac_policy_list_busy(void) 318114806Srwatson{ 319114806Srwatson mtx_lock(&mac_policy_mtx); 320114806Srwatson mac_policy_count++; 321114806Srwatson mtx_unlock(&mac_policy_mtx); 322114806Srwatson} 323114806Srwatson 324114806Srwatsonstatic __inline int 325114806Srwatsonmac_policy_list_conditional_busy(void) 326114806Srwatson{ 327114806Srwatson int ret; 328114806Srwatson 329114806Srwatson mtx_lock(&mac_policy_mtx); 330114806Srwatson if (!LIST_EMPTY(&mac_policy_list)) { 331114806Srwatson mac_policy_count++; 332114806Srwatson ret = 1; 333114806Srwatson } else 334114806Srwatson ret = 0; 335114806Srwatson mtx_unlock(&mac_policy_mtx); 336114806Srwatson return (ret); 337114806Srwatson} 338114806Srwatson 339114806Srwatsonstatic __inline void 340114806Srwatsonmac_policy_list_unbusy(void) 341114806Srwatson{ 342114806Srwatson mtx_lock(&mac_policy_mtx); 343114806Srwatson mac_policy_count--; 344114806Srwatson KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK")); 345114806Srwatson if (mac_policy_count == 0) 346114806Srwatson cv_signal(&mac_policy_cv); 347114806Srwatson mtx_unlock(&mac_policy_mtx); 348114806Srwatson} 349114806Srwatson 350100979Srwatson/* 351100979Srwatson * MAC_CHECK performs the designated check by walking the policy 352100979Srwatson * module list and checking with each as to how it feels about the 353100979Srwatson * request. Note that it returns its value via 'error' in the scope 354100979Srwatson * of the caller. 355100979Srwatson */ 356100979Srwatson#define MAC_CHECK(check, args...) do { \ 357100979Srwatson struct mac_policy_conf *mpc; \ 358114806Srwatson int entrycount; \ 359100979Srwatson \ 360100979Srwatson error = 0; \ 361114806Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ 362100979Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 363100979Srwatson error = error_select( \ 364100979Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 365100979Srwatson error); \ 366100979Srwatson } \ 367114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ 368114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 369114806Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 370114806Srwatson error = error_select( \ 371114806Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 372114806Srwatson error); \ 373114806Srwatson } \ 374114806Srwatson mac_policy_list_unbusy(); \ 375114806Srwatson } \ 376100979Srwatson} while (0) 377100979Srwatson 378100979Srwatson/* 379100979Srwatson * MAC_BOOLEAN performs the designated boolean composition by walking 380100979Srwatson * the module list, invoking each instance of the operation, and 381100979Srwatson * combining the results using the passed C operator. Note that it 382100979Srwatson * returns its value via 'result' in the scope of the caller, which 383100979Srwatson * should be initialized by the caller in a meaningful way to get 384100979Srwatson * a meaningful result. 385100979Srwatson */ 386100979Srwatson#define MAC_BOOLEAN(operation, composition, args...) do { \ 387100979Srwatson struct mac_policy_conf *mpc; \ 388114806Srwatson int entrycount; \ 389100979Srwatson \ 390114806Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ 391100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 392100979Srwatson result = result composition \ 393100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 394100979Srwatson } \ 395114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ 396114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 397114806Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 398114806Srwatson result = result composition \ 399114806Srwatson mpc->mpc_ops->mpo_ ## operation \ 400114806Srwatson (args); \ 401114806Srwatson } \ 402114806Srwatson mac_policy_list_unbusy(); \ 403114806Srwatson } \ 404100979Srwatson} while (0) 405100979Srwatson 406105694Srwatson#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 407105694Srwatson outbuflen) do { \ 408116701Srwatson int claimed, first, ignorenotfound, savedlen; \ 409116701Srwatson char *element_name, *element_temp; \ 410116701Srwatson struct sbuf sb; \ 411105694Srwatson \ 412105694Srwatson error = 0; \ 413116701Srwatson first = 1; \ 414116701Srwatson sbuf_new(&sb, outbuf, outbuflen, SBUF_FIXEDLEN); \ 415105694Srwatson element_temp = elementlist; \ 416105694Srwatson while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 417105694Srwatson if (element_name[0] == '?') { \ 418105694Srwatson element_name++; \ 419105694Srwatson ignorenotfound = 1; \ 420116701Srwatson } else \ 421105694Srwatson ignorenotfound = 0; \ 422116701Srwatson savedlen = sbuf_len(&sb); \ 423105694Srwatson if (first) { \ 424116701Srwatson error = sbuf_printf(&sb, "%s/", element_name); \ 425105694Srwatson first = 0; \ 426105694Srwatson } else \ 427116701Srwatson error = sbuf_printf(&sb, ",%s/", element_name); \ 428116701Srwatson if (error == -1) { \ 429116701Srwatson error = EINVAL; /* XXX: E2BIG? */ \ 430105694Srwatson break; \ 431105694Srwatson } \ 432116701Srwatson claimed = 0; \ 433105694Srwatson MAC_CHECK(externalize_ ## type, label, element_name, \ 434116701Srwatson &sb, &claimed); \ 435105694Srwatson if (error) \ 436105694Srwatson break; \ 437116701Srwatson if (claimed == 0 && ignorenotfound) { \ 438116701Srwatson /* Revert last label name. */ \ 439116701Srwatson sbuf_setpos(&sb, savedlen); \ 440116701Srwatson } else if (claimed != 1) { \ 441116701Srwatson error = EINVAL; /* XXX: ENOLABEL? */ \ 442105694Srwatson break; \ 443105694Srwatson } \ 444105694Srwatson } \ 445116701Srwatson sbuf_finish(&sb); \ 446105694Srwatson} while (0) 447105694Srwatson 448105694Srwatson#define MAC_INTERNALIZE(type, label, instring) do { \ 449105694Srwatson char *element, *element_name, *element_data; \ 450105694Srwatson int claimed; \ 451105694Srwatson \ 452105694Srwatson error = 0; \ 453105694Srwatson element = instring; \ 454105694Srwatson while ((element_name = strsep(&element, ",")) != NULL) { \ 455105694Srwatson element_data = element_name; \ 456105694Srwatson element_name = strsep(&element_data, "/"); \ 457105694Srwatson if (element_data == NULL) { \ 458105694Srwatson error = EINVAL; \ 459105694Srwatson break; \ 460105694Srwatson } \ 461105694Srwatson claimed = 0; \ 462105694Srwatson MAC_CHECK(internalize_ ## type, label, element_name, \ 463105694Srwatson element_data, &claimed); \ 464105694Srwatson if (error) \ 465105694Srwatson break; \ 466105694Srwatson if (claimed != 1) { \ 467105694Srwatson /* XXXMAC: Another error here? */ \ 468105694Srwatson error = EINVAL; \ 469105694Srwatson break; \ 470105694Srwatson } \ 471105694Srwatson } \ 472105694Srwatson} while (0) 473105694Srwatson 474100979Srwatson/* 475100979Srwatson * MAC_PERFORM performs the designated operation by walking the policy 476100979Srwatson * module list and invoking that operation for each policy. 477100979Srwatson */ 478100979Srwatson#define MAC_PERFORM(operation, args...) do { \ 479100979Srwatson struct mac_policy_conf *mpc; \ 480114806Srwatson int entrycount; \ 481100979Srwatson \ 482114806Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \ 483100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 484100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 485100979Srwatson } \ 486114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \ 487114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 488114806Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 489114806Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 490114806Srwatson } \ 491114806Srwatson mac_policy_list_unbusy(); \ 492114806Srwatson } \ 493100979Srwatson} while (0) 494100979Srwatson 495100979Srwatson/* 496100979Srwatson * Initialize the MAC subsystem, including appropriate SMP locks. 497100979Srwatson */ 498100979Srwatsonstatic void 499100979Srwatsonmac_init(void) 500100979Srwatson{ 501100979Srwatson 502114806Srwatson LIST_INIT(&mac_static_policy_list); 503100979Srwatson LIST_INIT(&mac_policy_list); 504114806Srwatson 505114806Srwatson mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF); 506114806Srwatson cv_init(&mac_policy_cv, "mac_policy_cv"); 507100979Srwatson} 508100979Srwatson 509100979Srwatson/* 510100979Srwatson * For the purposes of modules that want to know if they were loaded 511100979Srwatson * "early", set the mac_late flag once we've processed modules either 512100979Srwatson * linked into the kernel, or loaded before the kernel startup. 513100979Srwatson */ 514100979Srwatsonstatic void 515100979Srwatsonmac_late_init(void) 516100979Srwatson{ 517100979Srwatson 518100979Srwatson mac_late = 1; 519100979Srwatson} 520100979Srwatson 521100979Srwatson/* 522113487Srwatson * After the policy list has changed, walk the list to update any global 523118308Srwatson * flags. Currently, we support only one flag, and it's conditionally 524118308Srwatson * defined; as a result, the entire function is conditional. Eventually, 525118308Srwatson * the #else case might also iterate across the policies. 526113487Srwatson */ 527113487Srwatsonstatic void 528113487Srwatsonmac_policy_updateflags(void) 529113487Srwatson{ 530118308Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 531113487Srwatson struct mac_policy_conf *tmpc; 532113487Srwatson int labelmbufs; 533113487Srwatson 534114806Srwatson mac_policy_assert_exclusive(); 535113487Srwatson 536113487Srwatson labelmbufs = 0; 537114806Srwatson LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { 538114806Srwatson if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) 539114806Srwatson labelmbufs++; 540114806Srwatson } 541113487Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 542113487Srwatson if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) 543113487Srwatson labelmbufs++; 544113487Srwatson } 545113487Srwatson mac_labelmbufs = (labelmbufs != 0); 546113487Srwatson#endif 547113487Srwatson} 548113487Srwatson 549113487Srwatson/* 550100979Srwatson * Allow MAC policy modules to register during boot, etc. 551100979Srwatson */ 552100894Srwatsonint 553100979Srwatsonmac_policy_modevent(module_t mod, int type, void *data) 554100979Srwatson{ 555100979Srwatson struct mac_policy_conf *mpc; 556100979Srwatson int error; 557100979Srwatson 558100979Srwatson error = 0; 559100979Srwatson mpc = (struct mac_policy_conf *) data; 560100979Srwatson 561100979Srwatson switch (type) { 562100979Srwatson case MOD_LOAD: 563100979Srwatson if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 564100979Srwatson mac_late) { 565100979Srwatson printf("mac_policy_modevent: can't load %s policy " 566100979Srwatson "after booting\n", mpc->mpc_name); 567100979Srwatson error = EBUSY; 568100979Srwatson break; 569100979Srwatson } 570100979Srwatson error = mac_policy_register(mpc); 571100979Srwatson break; 572100979Srwatson case MOD_UNLOAD: 573100979Srwatson /* Don't unregister the module if it was never registered. */ 574100979Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 575100979Srwatson != 0) 576100979Srwatson error = mac_policy_unregister(mpc); 577100979Srwatson else 578100979Srwatson error = 0; 579100979Srwatson break; 580100979Srwatson default: 581100979Srwatson break; 582100979Srwatson } 583100979Srwatson 584100979Srwatson return (error); 585100979Srwatson} 586100979Srwatson 587100979Srwatsonstatic int 588100979Srwatsonmac_policy_register(struct mac_policy_conf *mpc) 589100979Srwatson{ 590100979Srwatson struct mac_policy_conf *tmpc; 591114806Srwatson int error, slot, static_entry; 592100979Srwatson 593114806Srwatson error = 0; 594114806Srwatson 595114806Srwatson /* 596114806Srwatson * We don't technically need exclusive access while !mac_late, 597114806Srwatson * but hold it for assertion consistency. 598114806Srwatson */ 599114806Srwatson mac_policy_grab_exclusive(); 600114806Srwatson 601114806Srwatson /* 602114806Srwatson * If the module can potentially be unloaded, or we're loading 603114806Srwatson * late, we have to stick it in the non-static list and pay 604114806Srwatson * an extra performance overhead. Otherwise, we can pay a 605114806Srwatson * light locking cost and stick it in the static list. 606114806Srwatson */ 607114806Srwatson static_entry = (!mac_late && 608114806Srwatson !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK)); 609114806Srwatson 610114806Srwatson if (static_entry) { 611114806Srwatson LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { 612114806Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 613114806Srwatson error = EEXIST; 614114806Srwatson goto out; 615114806Srwatson } 616100979Srwatson } 617114806Srwatson } else { 618114806Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 619114806Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 620114806Srwatson error = EEXIST; 621114806Srwatson goto out; 622114806Srwatson } 623114806Srwatson } 624100979Srwatson } 625100979Srwatson if (mpc->mpc_field_off != NULL) { 626114846Srwatson slot = ffs(mac_slot_offsets_free); 627100979Srwatson if (slot == 0) { 628114806Srwatson error = ENOMEM; 629114806Srwatson goto out; 630100979Srwatson } 631100979Srwatson slot--; 632114846Srwatson mac_slot_offsets_free &= ~(1 << slot); 633100979Srwatson *mpc->mpc_field_off = slot; 634100979Srwatson } 635100979Srwatson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 636100979Srwatson 637114806Srwatson /* 638114806Srwatson * If we're loading a MAC module after the framework has 639114806Srwatson * initialized, it has to go into the dynamic list. If 640114806Srwatson * we're loading it before we've finished initializing, 641114806Srwatson * it can go into the static list with weaker locker 642114806Srwatson * requirements. 643114806Srwatson */ 644114806Srwatson if (static_entry) 645114806Srwatson LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list); 646114806Srwatson else 647114806Srwatson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 648114806Srwatson 649100979Srwatson /* Per-policy initialization. */ 650100979Srwatson if (mpc->mpc_ops->mpo_init != NULL) 651100979Srwatson (*(mpc->mpc_ops->mpo_init))(mpc); 652113487Srwatson mac_policy_updateflags(); 653100979Srwatson 654100979Srwatson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 655100979Srwatson mpc->mpc_name); 656100979Srwatson 657114806Srwatsonout: 658114806Srwatson mac_policy_release_exclusive(); 659114806Srwatson return (error); 660100979Srwatson} 661100979Srwatson 662100979Srwatsonstatic int 663100979Srwatsonmac_policy_unregister(struct mac_policy_conf *mpc) 664100979Srwatson{ 665100979Srwatson 666104520Srwatson /* 667104520Srwatson * If we fail the load, we may get a request to unload. Check 668104520Srwatson * to see if we did the run-time registration, and if not, 669104520Srwatson * silently succeed. 670104520Srwatson */ 671114806Srwatson mac_policy_grab_exclusive(); 672104520Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 673114806Srwatson mac_policy_release_exclusive(); 674104520Srwatson return (0); 675104520Srwatson } 676100979Srwatson#if 0 677100979Srwatson /* 678100979Srwatson * Don't allow unloading modules with private data. 679100979Srwatson */ 680104520Srwatson if (mpc->mpc_field_off != NULL) { 681104520Srwatson MAC_POLICY_LIST_UNLOCK(); 682100979Srwatson return (EBUSY); 683104520Srwatson } 684100979Srwatson#endif 685104520Srwatson /* 686104520Srwatson * Only allow the unload to proceed if the module is unloadable 687104520Srwatson * by its own definition. 688104520Srwatson */ 689104520Srwatson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 690114806Srwatson mac_policy_release_exclusive(); 691100979Srwatson return (EBUSY); 692104520Srwatson } 693100979Srwatson if (mpc->mpc_ops->mpo_destroy != NULL) 694100979Srwatson (*(mpc->mpc_ops->mpo_destroy))(mpc); 695100979Srwatson 696100979Srwatson LIST_REMOVE(mpc, mpc_list); 697106856Srwatson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 698113487Srwatson mac_policy_updateflags(); 699100979Srwatson 700114806Srwatson mac_policy_release_exclusive(); 701114806Srwatson 702100979Srwatson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 703100979Srwatson mpc->mpc_name); 704100979Srwatson 705100979Srwatson return (0); 706100979Srwatson} 707100979Srwatson 708100979Srwatson/* 709100979Srwatson * Define an error value precedence, and given two arguments, selects the 710100979Srwatson * value with the higher precedence. 711100979Srwatson */ 712100979Srwatsonstatic int 713100979Srwatsonerror_select(int error1, int error2) 714100979Srwatson{ 715100979Srwatson 716100979Srwatson /* Certain decision-making errors take top priority. */ 717100979Srwatson if (error1 == EDEADLK || error2 == EDEADLK) 718100979Srwatson return (EDEADLK); 719100979Srwatson 720100979Srwatson /* Invalid arguments should be reported where possible. */ 721100979Srwatson if (error1 == EINVAL || error2 == EINVAL) 722100979Srwatson return (EINVAL); 723100979Srwatson 724100979Srwatson /* Precedence goes to "visibility", with both process and file. */ 725100979Srwatson if (error1 == ESRCH || error2 == ESRCH) 726100979Srwatson return (ESRCH); 727100979Srwatson 728100979Srwatson if (error1 == ENOENT || error2 == ENOENT) 729100979Srwatson return (ENOENT); 730100979Srwatson 731100979Srwatson /* Precedence goes to DAC/MAC protections. */ 732100979Srwatson if (error1 == EACCES || error2 == EACCES) 733100979Srwatson return (EACCES); 734100979Srwatson 735100979Srwatson /* Precedence goes to privilege. */ 736100979Srwatson if (error1 == EPERM || error2 == EPERM) 737100979Srwatson return (EPERM); 738100979Srwatson 739100979Srwatson /* Precedence goes to error over success; otherwise, arbitrary. */ 740100979Srwatson if (error1 != 0) 741100979Srwatson return (error1); 742100979Srwatson return (error2); 743100979Srwatson} 744100979Srwatson 745113482Srwatsonstatic struct label * 746113482Srwatsonmbuf_to_label(struct mbuf *mbuf) 747113482Srwatson{ 748113487Srwatson struct m_tag *tag; 749113482Srwatson struct label *label; 750113482Srwatson 751113487Srwatson tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL); 752113487Srwatson label = (struct label *)(tag+1); 753113482Srwatson 754113482Srwatson return (label); 755113482Srwatson} 756113482Srwatson 757104521Srwatsonstatic void 758104521Srwatsonmac_init_label(struct label *label) 759104521Srwatson{ 760104521Srwatson 761104521Srwatson bzero(label, sizeof(*label)); 762104521Srwatson label->l_flags = MAC_FLAG_INITIALIZED; 763104521Srwatson} 764104521Srwatson 765104521Srwatsonstatic void 766104521Srwatsonmac_destroy_label(struct label *label) 767104521Srwatson{ 768104521Srwatson 769104521Srwatson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 770104521Srwatson ("destroying uninitialized label")); 771104521Srwatson 772104521Srwatson bzero(label, sizeof(*label)); 773104521Srwatson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 774104521Srwatson} 775104521Srwatson 776100979Srwatsonvoid 777104527Srwatsonmac_init_bpfdesc(struct bpf_d *bpf_d) 778104521Srwatson{ 779104521Srwatson 780104527Srwatson mac_init_label(&bpf_d->bd_label); 781104527Srwatson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 782119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacbpfdescs); 783104521Srwatson} 784104521Srwatson 785105694Srwatsonstatic void 786105694Srwatsonmac_init_cred_label(struct label *label) 787104521Srwatson{ 788104521Srwatson 789105694Srwatson mac_init_label(label); 790105694Srwatson MAC_PERFORM(init_cred_label, label); 791119184Srwatson MAC_DEBUG_COUNTER_INC(&nmaccreds); 792104521Srwatson} 793104521Srwatson 794104521Srwatsonvoid 795105694Srwatsonmac_init_cred(struct ucred *cred) 796105694Srwatson{ 797105694Srwatson 798105694Srwatson mac_init_cred_label(&cred->cr_label); 799105694Srwatson} 800105694Srwatson 801105694Srwatsonvoid 802104527Srwatsonmac_init_devfsdirent(struct devfs_dirent *de) 803104521Srwatson{ 804104521Srwatson 805104527Srwatson mac_init_label(&de->de_label); 806104527Srwatson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 807119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacdevfsdirents); 808104521Srwatson} 809104521Srwatson 810105694Srwatsonstatic void 811105694Srwatsonmac_init_ifnet_label(struct label *label) 812104521Srwatson{ 813104521Srwatson 814105694Srwatson mac_init_label(label); 815105694Srwatson MAC_PERFORM(init_ifnet_label, label); 816119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacifnets); 817104521Srwatson} 818104521Srwatson 819104521Srwatsonvoid 820105694Srwatsonmac_init_ifnet(struct ifnet *ifp) 821105694Srwatson{ 822105694Srwatson 823105694Srwatson mac_init_ifnet_label(&ifp->if_label); 824105694Srwatson} 825105694Srwatson 826112675Srwatsonint 827112675Srwatsonmac_init_ipq(struct ipq *ipq, int flag) 828104521Srwatson{ 829112675Srwatson int error; 830104521Srwatson 831104527Srwatson mac_init_label(&ipq->ipq_label); 832112675Srwatson 833112675Srwatson MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag); 834112675Srwatson if (error) { 835112675Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 836112675Srwatson mac_destroy_label(&ipq->ipq_label); 837119184Srwatson } else { 838119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacipqs); 839112675Srwatson } 840112675Srwatson return (error); 841104521Srwatson} 842104521Srwatson 843104527Srwatsonint 844113487Srwatsonmac_init_mbuf_tag(struct m_tag *tag, int flag) 845104527Srwatson{ 846113487Srwatson struct label *label; 847113526Srwatson int error; 848104528Srwatson 849113487Srwatson label = (struct label *) (tag + 1); 850113487Srwatson mac_init_label(label); 851104527Srwatson 852113526Srwatson MAC_CHECK(init_mbuf_label, label, flag); 853104528Srwatson if (error) { 854113487Srwatson MAC_PERFORM(destroy_mbuf_label, label); 855113487Srwatson mac_destroy_label(label); 856119184Srwatson } else { 857119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacmbufs); 858104528Srwatson } 859104528Srwatson return (error); 860104527Srwatson} 861104527Srwatson 862113487Srwatsonint 863113487Srwatsonmac_init_mbuf(struct mbuf *m, int flag) 864113487Srwatson{ 865113487Srwatson struct m_tag *tag; 866113487Srwatson int error; 867113487Srwatson 868113487Srwatson M_ASSERTPKTHDR(m); 869113487Srwatson 870113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 871113487Srwatson /* 872118308Srwatson * If conditionally allocating mbuf labels, don't allocate unless 873118308Srwatson * they are required. 874113487Srwatson */ 875118308Srwatson if (!mac_labelmbufs) 876118308Srwatson return (0); 877113487Srwatson#endif 878118308Srwatson tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 879118308Srwatson flag); 880118308Srwatson if (tag == NULL) 881118308Srwatson return (ENOMEM); 882118308Srwatson error = mac_init_mbuf_tag(tag, flag); 883118308Srwatson if (error) { 884118308Srwatson m_tag_free(tag); 885118308Srwatson return (error); 886113487Srwatson } 887118308Srwatson m_tag_prepend(m, tag); 888113487Srwatson return (0); 889113487Srwatson} 890113487Srwatson 891104521Srwatsonvoid 892104527Srwatsonmac_init_mount(struct mount *mp) 893104521Srwatson{ 894104521Srwatson 895104527Srwatson mac_init_label(&mp->mnt_mntlabel); 896104527Srwatson mac_init_label(&mp->mnt_fslabel); 897104527Srwatson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 898104527Srwatson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 899119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacmounts); 900104521Srwatson} 901104521Srwatson 902105694Srwatsonstatic void 903105694Srwatsonmac_init_pipe_label(struct label *label) 904105694Srwatson{ 905105694Srwatson 906105694Srwatson mac_init_label(label); 907105694Srwatson MAC_PERFORM(init_pipe_label, label); 908119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacpipes); 909105694Srwatson} 910105694Srwatson 911104521Srwatsonvoid 912104527Srwatsonmac_init_pipe(struct pipe *pipe) 913104521Srwatson{ 914104527Srwatson struct label *label; 915104521Srwatson 916111119Simp label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 917104527Srwatson pipe->pipe_label = label; 918104527Srwatson pipe->pipe_peer->pipe_label = label; 919105694Srwatson mac_init_pipe_label(label); 920104521Srwatson} 921104521Srwatson 922107105Srwatsonvoid 923107105Srwatsonmac_init_proc(struct proc *p) 924107105Srwatson{ 925107105Srwatson 926107105Srwatson mac_init_label(&p->p_label); 927107105Srwatson MAC_PERFORM(init_proc_label, &p->p_label); 928119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacprocs); 929107105Srwatson} 930107105Srwatson 931104541Srwatsonstatic int 932104541Srwatsonmac_init_socket_label(struct label *label, int flag) 933104521Srwatson{ 934104541Srwatson int error; 935104521Srwatson 936104541Srwatson mac_init_label(label); 937104541Srwatson 938104541Srwatson MAC_CHECK(init_socket_label, label, flag); 939104541Srwatson if (error) { 940104541Srwatson MAC_PERFORM(destroy_socket_label, label); 941104541Srwatson mac_destroy_label(label); 942119184Srwatson } else { 943119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacsockets); 944104541Srwatson } 945104541Srwatson 946104541Srwatson return (error); 947104521Srwatson} 948104521Srwatson 949104541Srwatsonstatic int 950104541Srwatsonmac_init_socket_peer_label(struct label *label, int flag) 951104541Srwatson{ 952104541Srwatson int error; 953104541Srwatson 954104541Srwatson mac_init_label(label); 955104541Srwatson 956104541Srwatson MAC_CHECK(init_socket_peer_label, label, flag); 957104541Srwatson if (error) { 958104541Srwatson MAC_PERFORM(destroy_socket_label, label); 959104541Srwatson mac_destroy_label(label); 960104541Srwatson } 961104541Srwatson 962104541Srwatson return (error); 963104541Srwatson} 964104541Srwatson 965104541Srwatsonint 966104541Srwatsonmac_init_socket(struct socket *socket, int flag) 967104541Srwatson{ 968104541Srwatson int error; 969104541Srwatson 970104541Srwatson error = mac_init_socket_label(&socket->so_label, flag); 971104541Srwatson if (error) 972104541Srwatson return (error); 973104541Srwatson 974104541Srwatson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 975104541Srwatson if (error) 976104541Srwatson mac_destroy_socket_label(&socket->so_label); 977104541Srwatson 978104541Srwatson return (error); 979104541Srwatson} 980104541Srwatson 981105988Srwatsonvoid 982105694Srwatsonmac_init_vnode_label(struct label *label) 983104521Srwatson{ 984104521Srwatson 985104527Srwatson mac_init_label(label); 986105694Srwatson MAC_PERFORM(init_vnode_label, label); 987119184Srwatson MAC_DEBUG_COUNTER_INC(&nmacvnodes); 988104521Srwatson} 989104521Srwatson 990104521Srwatsonvoid 991104527Srwatsonmac_init_vnode(struct vnode *vp) 992104521Srwatson{ 993104521Srwatson 994105694Srwatson mac_init_vnode_label(&vp->v_label); 995104521Srwatson} 996104521Srwatson 997104521Srwatsonvoid 998104527Srwatsonmac_destroy_bpfdesc(struct bpf_d *bpf_d) 999104521Srwatson{ 1000104521Srwatson 1001104527Srwatson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 1002104527Srwatson mac_destroy_label(&bpf_d->bd_label); 1003119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs); 1004104521Srwatson} 1005104521Srwatson 1006105694Srwatsonstatic void 1007105694Srwatsonmac_destroy_cred_label(struct label *label) 1008104521Srwatson{ 1009104521Srwatson 1010105694Srwatson MAC_PERFORM(destroy_cred_label, label); 1011105694Srwatson mac_destroy_label(label); 1012119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmaccreds); 1013104521Srwatson} 1014104521Srwatson 1015104521Srwatsonvoid 1016105694Srwatsonmac_destroy_cred(struct ucred *cred) 1017105694Srwatson{ 1018105694Srwatson 1019105694Srwatson mac_destroy_cred_label(&cred->cr_label); 1020105694Srwatson} 1021105694Srwatson 1022105694Srwatsonvoid 1023104527Srwatsonmac_destroy_devfsdirent(struct devfs_dirent *de) 1024104521Srwatson{ 1025104521Srwatson 1026104527Srwatson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 1027104527Srwatson mac_destroy_label(&de->de_label); 1028119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacdevfsdirents); 1029104521Srwatson} 1030104521Srwatson 1031105694Srwatsonstatic void 1032105694Srwatsonmac_destroy_ifnet_label(struct label *label) 1033104521Srwatson{ 1034104521Srwatson 1035105694Srwatson MAC_PERFORM(destroy_ifnet_label, label); 1036105694Srwatson mac_destroy_label(label); 1037119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacifnets); 1038104521Srwatson} 1039104521Srwatson 1040104521Srwatsonvoid 1041105694Srwatsonmac_destroy_ifnet(struct ifnet *ifp) 1042105694Srwatson{ 1043105694Srwatson 1044105694Srwatson mac_destroy_ifnet_label(&ifp->if_label); 1045105694Srwatson} 1046105694Srwatson 1047105694Srwatsonvoid 1048104527Srwatsonmac_destroy_ipq(struct ipq *ipq) 1049104521Srwatson{ 1050104521Srwatson 1051104527Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1052104527Srwatson mac_destroy_label(&ipq->ipq_label); 1053119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacipqs); 1054104521Srwatson} 1055104521Srwatson 1056104527Srwatsonvoid 1057113487Srwatsonmac_destroy_mbuf_tag(struct m_tag *tag) 1058104521Srwatson{ 1059113487Srwatson struct label *label; 1060104521Srwatson 1061113487Srwatson label = (struct label *)(tag+1); 1062113487Srwatson 1063113487Srwatson MAC_PERFORM(destroy_mbuf_label, label); 1064113487Srwatson mac_destroy_label(label); 1065119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacmbufs); 1066104521Srwatson} 1067104521Srwatson 1068104527Srwatsonvoid 1069104527Srwatsonmac_destroy_mount(struct mount *mp) 1070104521Srwatson{ 1071104521Srwatson 1072104527Srwatson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1073104527Srwatson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1074104527Srwatson mac_destroy_label(&mp->mnt_fslabel); 1075104527Srwatson mac_destroy_label(&mp->mnt_mntlabel); 1076119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacmounts); 1077104521Srwatson} 1078104521Srwatson 1079105694Srwatsonstatic void 1080105694Srwatsonmac_destroy_pipe_label(struct label *label) 1081104521Srwatson{ 1082104521Srwatson 1083105694Srwatson MAC_PERFORM(destroy_pipe_label, label); 1084105694Srwatson mac_destroy_label(label); 1085119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacpipes); 1086104521Srwatson} 1087104521Srwatson 1088105694Srwatsonvoid 1089105694Srwatsonmac_destroy_pipe(struct pipe *pipe) 1090105694Srwatson{ 1091105694Srwatson 1092105694Srwatson mac_destroy_pipe_label(pipe->pipe_label); 1093105694Srwatson free(pipe->pipe_label, M_MACPIPELABEL); 1094105694Srwatson} 1095105694Srwatson 1096107105Srwatsonvoid 1097107105Srwatsonmac_destroy_proc(struct proc *p) 1098107105Srwatson{ 1099107105Srwatson 1100107105Srwatson MAC_PERFORM(destroy_proc_label, &p->p_label); 1101107105Srwatson mac_destroy_label(&p->p_label); 1102119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacprocs); 1103107105Srwatson} 1104107105Srwatson 1105104541Srwatsonstatic void 1106104541Srwatsonmac_destroy_socket_label(struct label *label) 1107104521Srwatson{ 1108104521Srwatson 1109104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1110104541Srwatson mac_destroy_label(label); 1111119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacsockets); 1112104521Srwatson} 1113104521Srwatson 1114104527Srwatsonstatic void 1115104541Srwatsonmac_destroy_socket_peer_label(struct label *label) 1116104541Srwatson{ 1117104541Srwatson 1118104541Srwatson MAC_PERFORM(destroy_socket_peer_label, label); 1119104541Srwatson mac_destroy_label(label); 1120104541Srwatson} 1121104541Srwatson 1122104541Srwatsonvoid 1123104541Srwatsonmac_destroy_socket(struct socket *socket) 1124104541Srwatson{ 1125104541Srwatson 1126104541Srwatson mac_destroy_socket_label(&socket->so_label); 1127104541Srwatson mac_destroy_socket_peer_label(&socket->so_peerlabel); 1128104541Srwatson} 1129104541Srwatson 1130105988Srwatsonvoid 1131105694Srwatsonmac_destroy_vnode_label(struct label *label) 1132104521Srwatson{ 1133104521Srwatson 1134105694Srwatson MAC_PERFORM(destroy_vnode_label, label); 1135104527Srwatson mac_destroy_label(label); 1136119184Srwatson MAC_DEBUG_COUNTER_DEC(&nmacvnodes); 1137104521Srwatson} 1138104521Srwatson 1139104521Srwatsonvoid 1140104527Srwatsonmac_destroy_vnode(struct vnode *vp) 1141104521Srwatson{ 1142104521Srwatson 1143105694Srwatson mac_destroy_vnode_label(&vp->v_label); 1144104521Srwatson} 1145104521Srwatson 1146113487Srwatsonvoid 1147113487Srwatsonmac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 1148113487Srwatson{ 1149113487Srwatson struct label *src_label, *dest_label; 1150113487Srwatson 1151113487Srwatson src_label = (struct label *)(src+1); 1152113487Srwatson dest_label = (struct label *)(dest+1); 1153113487Srwatson 1154113487Srwatson /* 1155113487Srwatson * mac_init_mbuf_tag() is called on the target tag in 1156113487Srwatson * m_tag_copy(), so we don't need to call it here. 1157113487Srwatson */ 1158113487Srwatson MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 1159113487Srwatson} 1160113487Srwatson 1161105694Srwatsonstatic void 1162105694Srwatsonmac_copy_pipe_label(struct label *src, struct label *dest) 1163105694Srwatson{ 1164105694Srwatson 1165105694Srwatson MAC_PERFORM(copy_pipe_label, src, dest); 1166105694Srwatson} 1167105694Srwatson 1168105988Srwatsonvoid 1169105694Srwatsonmac_copy_vnode_label(struct label *src, struct label *dest) 1170105694Srwatson{ 1171105694Srwatson 1172105694Srwatson MAC_PERFORM(copy_vnode_label, src, dest); 1173105694Srwatson} 1174105694Srwatson 1175104522Srwatsonstatic int 1176105694Srwatsonmac_check_structmac_consistent(struct mac *mac) 1177104522Srwatson{ 1178105694Srwatson 1179120582Srwatson if (mac->m_buflen < 0 || 1180120582Srwatson mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1181105694Srwatson return (EINVAL); 1182105694Srwatson 1183105694Srwatson return (0); 1184105694Srwatson} 1185105694Srwatson 1186105694Srwatsonstatic int 1187105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements, 1188105694Srwatson char *outbuf, size_t outbuflen, int flags) 1189105694Srwatson{ 1190104522Srwatson int error; 1191104522Srwatson 1192105694Srwatson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1193104522Srwatson 1194104522Srwatson return (error); 1195104522Srwatson} 1196104522Srwatson 1197104522Srwatsonstatic int 1198105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements, 1199105694Srwatson char *outbuf, size_t outbuflen, int flags) 1200104522Srwatson{ 1201104522Srwatson int error; 1202104522Srwatson 1203105694Srwatson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1204104522Srwatson 1205104522Srwatson return (error); 1206104522Srwatson} 1207104522Srwatson 1208105694Srwatsonstatic int 1209105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements, 1210105694Srwatson char *outbuf, size_t outbuflen, int flags) 1211105694Srwatson{ 1212105694Srwatson int error; 1213105694Srwatson 1214105694Srwatson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1215105694Srwatson 1216105694Srwatson return (error); 1217105694Srwatson} 1218105694Srwatson 1219105694Srwatsonstatic int 1220105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements, 1221105694Srwatson char *outbuf, size_t outbuflen, int flags) 1222105694Srwatson{ 1223105694Srwatson int error; 1224105694Srwatson 1225105694Srwatson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1226105694Srwatson 1227105694Srwatson return (error); 1228105694Srwatson} 1229105694Srwatson 1230105694Srwatsonstatic int 1231105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements, 1232105694Srwatson char *outbuf, size_t outbuflen, int flags) 1233105694Srwatson{ 1234105694Srwatson int error; 1235105694Srwatson 1236105694Srwatson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1237105694Srwatson 1238105694Srwatson return (error); 1239105694Srwatson} 1240105694Srwatson 1241105694Srwatsonstatic int 1242105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements, 1243105694Srwatson char *outbuf, size_t outbuflen, int flags) 1244105694Srwatson{ 1245105694Srwatson int error; 1246105694Srwatson 1247105694Srwatson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1248105694Srwatson 1249105694Srwatson return (error); 1250105694Srwatson} 1251105694Srwatson 1252105694Srwatsonstatic int 1253105694Srwatsonmac_internalize_cred_label(struct label *label, char *string) 1254105694Srwatson{ 1255105694Srwatson int error; 1256105694Srwatson 1257105694Srwatson MAC_INTERNALIZE(cred_label, label, string); 1258105694Srwatson 1259105694Srwatson return (error); 1260105694Srwatson} 1261105694Srwatson 1262105694Srwatsonstatic int 1263105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string) 1264105694Srwatson{ 1265105694Srwatson int error; 1266105694Srwatson 1267105694Srwatson MAC_INTERNALIZE(ifnet_label, label, string); 1268105694Srwatson 1269105694Srwatson return (error); 1270105694Srwatson} 1271105694Srwatson 1272105694Srwatsonstatic int 1273105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string) 1274105694Srwatson{ 1275105694Srwatson int error; 1276105694Srwatson 1277105694Srwatson MAC_INTERNALIZE(pipe_label, label, string); 1278105694Srwatson 1279105694Srwatson return (error); 1280105694Srwatson} 1281105694Srwatson 1282105694Srwatsonstatic int 1283105694Srwatsonmac_internalize_socket_label(struct label *label, char *string) 1284105694Srwatson{ 1285105694Srwatson int error; 1286105694Srwatson 1287105694Srwatson MAC_INTERNALIZE(socket_label, label, string); 1288105694Srwatson 1289105694Srwatson return (error); 1290105694Srwatson} 1291105694Srwatson 1292105694Srwatsonstatic int 1293105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string) 1294105694Srwatson{ 1295105694Srwatson int error; 1296105694Srwatson 1297105694Srwatson MAC_INTERNALIZE(vnode_label, label, string); 1298105694Srwatson 1299105694Srwatson return (error); 1300105694Srwatson} 1301105694Srwatson 1302104522Srwatson/* 1303104522Srwatson * Initialize MAC label for the first kernel process, from which other 1304104522Srwatson * kernel processes and threads are spawned. 1305104522Srwatson */ 1306104521Srwatsonvoid 1307104522Srwatsonmac_create_proc0(struct ucred *cred) 1308104522Srwatson{ 1309104522Srwatson 1310104522Srwatson MAC_PERFORM(create_proc0, cred); 1311104522Srwatson} 1312104522Srwatson 1313104522Srwatson/* 1314104522Srwatson * Initialize MAC label for the first userland process, from which other 1315104522Srwatson * userland processes and threads are spawned. 1316104522Srwatson */ 1317104522Srwatsonvoid 1318104522Srwatsonmac_create_proc1(struct ucred *cred) 1319104522Srwatson{ 1320104522Srwatson 1321104522Srwatson MAC_PERFORM(create_proc1, cred); 1322104522Srwatson} 1323104522Srwatson 1324104522Srwatsonvoid 1325104522Srwatsonmac_thread_userret(struct thread *td) 1326104522Srwatson{ 1327104522Srwatson 1328104522Srwatson MAC_PERFORM(thread_userret, td); 1329104522Srwatson} 1330104522Srwatson 1331104522Srwatson/* 1332104522Srwatson * When a new process is created, its label must be initialized. Generally, 1333104522Srwatson * this involves inheritence from the parent process, modulo possible 1334104522Srwatson * deltas. This function allows that processing to take place. 1335104522Srwatson */ 1336104522Srwatsonvoid 1337104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1338104522Srwatson{ 1339104522Srwatson 1340104522Srwatson MAC_PERFORM(create_cred, parent_cred, child_cred); 1341104522Srwatson} 1342104522Srwatson 1343104522Srwatsonvoid 1344107698Srwatsonmac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 1345107698Srwatson struct vnode *vp) 1346100979Srwatson{ 1347100979Srwatson 1348107698Srwatson MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp, 1349107698Srwatson &vp->v_label); 1350100979Srwatson} 1351100979Srwatson 1352100979Srwatsonvoid 1353105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1354105988Srwatson struct vnode *vp) 1355100979Srwatson{ 1356100979Srwatson 1357105988Srwatson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1358105988Srwatson &de->de_label, vp, &vp->v_label); 1359100979Srwatson} 1360100979Srwatson 1361105988Srwatsonint 1362105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1363100979Srwatson{ 1364100979Srwatson int error; 1365100979Srwatson 1366105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1367100979Srwatson 1368105988Srwatson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1369105988Srwatson &vp->v_label); 1370100979Srwatson 1371100979Srwatson return (error); 1372100979Srwatson} 1373100979Srwatson 1374100979Srwatsonvoid 1375105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1376100979Srwatson{ 1377100979Srwatson 1378105988Srwatson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1379105988Srwatson &vp->v_label); 1380100979Srwatson} 1381100979Srwatson 1382100979Srwatsonint 1383105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1384105988Srwatson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1385100979Srwatson{ 1386105988Srwatson int error; 1387100979Srwatson 1388105988Srwatson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1389105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1390100979Srwatson 1391105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1392105988Srwatson if (error == EOPNOTSUPP) { 1393105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1394105988Srwatson if (ea_warn_once == 0) { 1395105988Srwatson printf("Warning: transactions not supported " 1396105988Srwatson "in EA write.\n"); 1397105988Srwatson ea_warn_once = 1; 1398105988Srwatson } 1399105988Srwatson } else if (error) 1400100979Srwatson return (error); 1401100979Srwatson 1402105988Srwatson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1403105988Srwatson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1404100979Srwatson 1405105988Srwatson if (error) { 1406105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1407100979Srwatson return (error); 1408100979Srwatson } 1409100979Srwatson 1410105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1411100979Srwatson 1412105988Srwatson if (error == EOPNOTSUPP) 1413105988Srwatson error = 0; /* XXX */ 1414100979Srwatson 1415100979Srwatson return (error); 1416100979Srwatson} 1417100979Srwatson 1418100979Srwatsonstatic int 1419105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1420105988Srwatson struct label *intlabel) 1421100979Srwatson{ 1422100979Srwatson int error; 1423100979Srwatson 1424105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1425100979Srwatson 1426105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1427105988Srwatson if (error == EOPNOTSUPP) { 1428105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1429105988Srwatson if (ea_warn_once == 0) { 1430105988Srwatson printf("Warning: transactions not supported " 1431105988Srwatson "in EA write.\n"); 1432105988Srwatson ea_warn_once = 1; 1433105988Srwatson } 1434105988Srwatson } else if (error) 1435105988Srwatson return (error); 1436100979Srwatson 1437105988Srwatson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1438100979Srwatson 1439105988Srwatson if (error) { 1440105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1441100979Srwatson return (error); 1442100979Srwatson } 1443100979Srwatson 1444105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1445100979Srwatson 1446105988Srwatson if (error == EOPNOTSUPP) 1447105988Srwatson error = 0; /* XXX */ 1448100979Srwatson 1449105988Srwatson return (error); 1450100979Srwatson} 1451100979Srwatson 1452106468Srwatsonint 1453106468Srwatsonmac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1454106468Srwatson struct label *execlabelstorage) 1455106468Srwatson{ 1456106468Srwatson struct mac mac; 1457106468Srwatson char *buffer; 1458106468Srwatson int error; 1459106468Srwatson 1460106468Srwatson if (mac_p == NULL) 1461106468Srwatson return (0); 1462106468Srwatson 1463106468Srwatson error = copyin(mac_p, &mac, sizeof(mac)); 1464106468Srwatson if (error) 1465106468Srwatson return (error); 1466106468Srwatson 1467106468Srwatson error = mac_check_structmac_consistent(&mac); 1468106468Srwatson if (error) 1469106468Srwatson return (error); 1470106468Srwatson 1471111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1472106468Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1473106468Srwatson if (error) { 1474106468Srwatson free(buffer, M_MACTEMP); 1475106468Srwatson return (error); 1476106468Srwatson } 1477106468Srwatson 1478106468Srwatson mac_init_cred_label(execlabelstorage); 1479106468Srwatson error = mac_internalize_cred_label(execlabelstorage, buffer); 1480106468Srwatson free(buffer, M_MACTEMP); 1481106468Srwatson if (error) { 1482106468Srwatson mac_destroy_cred_label(execlabelstorage); 1483106468Srwatson return (error); 1484106468Srwatson } 1485106468Srwatson imgp->execlabel = execlabelstorage; 1486106468Srwatson return (0); 1487106468Srwatson} 1488106468Srwatson 1489100979Srwatsonvoid 1490106468Srwatsonmac_execve_exit(struct image_params *imgp) 1491100979Srwatson{ 1492106468Srwatson if (imgp->execlabel != NULL) 1493106468Srwatson mac_destroy_cred_label(imgp->execlabel); 1494106468Srwatson} 1495100979Srwatson 1496106468Srwatsonvoid 1497106468Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1498106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1499106468Srwatson{ 1500106468Srwatson 1501100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1502100979Srwatson 1503106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1504106460Srwatson return; 1505106460Srwatson 1506106468Srwatson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1507106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1508100979Srwatson} 1509100979Srwatson 1510100979Srwatsonint 1511106468Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp, 1512106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1513100979Srwatson{ 1514105988Srwatson int result; 1515100979Srwatson 1516106460Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1517106460Srwatson 1518106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1519106460Srwatson return (0); 1520106460Srwatson 1521100979Srwatson result = 0; 1522106468Srwatson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1523106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1524100979Srwatson 1525100979Srwatson return (result); 1526100979Srwatson} 1527100979Srwatson 1528100979Srwatsonint 1529106212Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1530100979Srwatson{ 1531100979Srwatson int error; 1532100979Srwatson 1533100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1534100979Srwatson 1535100979Srwatson if (!mac_enforce_fs) 1536100979Srwatson return (0); 1537100979Srwatson 1538106212Srwatson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1539100979Srwatson return (error); 1540100979Srwatson} 1541100979Srwatson 1542100979Srwatsonint 1543100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1544100979Srwatson{ 1545100979Srwatson int error; 1546100979Srwatson 1547100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1548100979Srwatson 1549100979Srwatson if (!mac_enforce_fs) 1550100979Srwatson return (0); 1551100979Srwatson 1552100979Srwatson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1553100979Srwatson return (error); 1554100979Srwatson} 1555100979Srwatson 1556100979Srwatsonint 1557100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1558100979Srwatson{ 1559100979Srwatson int error; 1560100979Srwatson 1561100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1562100979Srwatson 1563100979Srwatson if (!mac_enforce_fs) 1564100979Srwatson return (0); 1565100979Srwatson 1566100979Srwatson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1567100979Srwatson return (error); 1568100979Srwatson} 1569100979Srwatson 1570100979Srwatsonint 1571100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1572100979Srwatson struct componentname *cnp, struct vattr *vap) 1573100979Srwatson{ 1574100979Srwatson int error; 1575100979Srwatson 1576100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1577100979Srwatson 1578100979Srwatson if (!mac_enforce_fs) 1579100979Srwatson return (0); 1580100979Srwatson 1581100979Srwatson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1582100979Srwatson return (error); 1583100979Srwatson} 1584100979Srwatson 1585100979Srwatsonint 1586100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1587100979Srwatson struct componentname *cnp) 1588100979Srwatson{ 1589100979Srwatson int error; 1590100979Srwatson 1591100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1592100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1593100979Srwatson 1594100979Srwatson if (!mac_enforce_fs) 1595100979Srwatson return (0); 1596100979Srwatson 1597100979Srwatson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1598100979Srwatson &vp->v_label, cnp); 1599100979Srwatson return (error); 1600100979Srwatson} 1601100979Srwatson 1602100979Srwatsonint 1603100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1604100979Srwatson acl_type_t type) 1605100979Srwatson{ 1606100979Srwatson int error; 1607100979Srwatson 1608100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1609100979Srwatson 1610100979Srwatson if (!mac_enforce_fs) 1611100979Srwatson return (0); 1612100979Srwatson 1613100979Srwatson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1614100979Srwatson return (error); 1615100979Srwatson} 1616100979Srwatson 1617100979Srwatsonint 1618119198Srwatsonmac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 1619119198Srwatson int attrnamespace, const char *name) 1620119198Srwatson{ 1621119198Srwatson int error; 1622119198Srwatson 1623119198Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteextattr"); 1624119198Srwatson 1625119198Srwatson if (!mac_enforce_fs) 1626119198Srwatson return (0); 1627119198Srwatson 1628119198Srwatson MAC_CHECK(check_vnode_deleteextattr, cred, vp, &vp->v_label, 1629119198Srwatson attrnamespace, name); 1630119198Srwatson return (error); 1631119198Srwatson} 1632119198Srwatson 1633119198Srwatsonint 1634106468Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1635106468Srwatson struct image_params *imgp) 1636100979Srwatson{ 1637100979Srwatson int error; 1638100979Srwatson 1639102102Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1640102102Srwatson 1641100979Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1642100979Srwatson return (0); 1643100979Srwatson 1644106647Srwatson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1645106647Srwatson imgp->execlabel); 1646100979Srwatson 1647100979Srwatson return (error); 1648100979Srwatson} 1649100979Srwatson 1650100979Srwatsonint 1651100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1652100979Srwatson{ 1653100979Srwatson int error; 1654100979Srwatson 1655100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1656100979Srwatson 1657100979Srwatson if (!mac_enforce_fs) 1658100979Srwatson return (0); 1659100979Srwatson 1660100979Srwatson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1661100979Srwatson return (error); 1662100979Srwatson} 1663100979Srwatson 1664100979Srwatsonint 1665100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1666100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1667100979Srwatson{ 1668100979Srwatson int error; 1669100979Srwatson 1670100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1671100979Srwatson 1672100979Srwatson if (!mac_enforce_fs) 1673100979Srwatson return (0); 1674100979Srwatson 1675100979Srwatson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1676100979Srwatson attrnamespace, name, uio); 1677100979Srwatson return (error); 1678100979Srwatson} 1679100979Srwatson 1680100979Srwatsonint 1681104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1682104529Srwatson struct vnode *vp, struct componentname *cnp) 1683104529Srwatson{ 1684104529Srwatson int error; 1685104529Srwatson 1686104529Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1687104529Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1688104529Srwatson 1689104529Srwatson if (!mac_enforce_fs) 1690104529Srwatson return (0); 1691104529Srwatson 1692104529Srwatson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1693104529Srwatson &vp->v_label, cnp); 1694104529Srwatson return (error); 1695104529Srwatson} 1696104529Srwatson 1697104529Srwatsonint 1698119198Srwatsonmac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 1699119198Srwatson int attrnamespace) 1700119198Srwatson{ 1701119198Srwatson int error; 1702119198Srwatson 1703119198Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_listextattr"); 1704119198Srwatson 1705119198Srwatson if (!mac_enforce_fs) 1706119198Srwatson return (0); 1707119198Srwatson 1708119198Srwatson MAC_CHECK(check_vnode_listextattr, cred, vp, &vp->v_label, 1709119198Srwatson attrnamespace); 1710119198Srwatson return (error); 1711119198Srwatson} 1712119198Srwatson 1713119198Srwatsonint 1714100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1715100979Srwatson struct componentname *cnp) 1716100979Srwatson{ 1717100979Srwatson int error; 1718100979Srwatson 1719100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1720100979Srwatson 1721100979Srwatson if (!mac_enforce_fs) 1722100979Srwatson return (0); 1723100979Srwatson 1724100979Srwatson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1725100979Srwatson return (error); 1726100979Srwatson} 1727100979Srwatson 1728104546Srwatsonint 1729104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1730100979Srwatson{ 1731104546Srwatson int error; 1732100979Srwatson 1733104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1734103514Srwatson 1735104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1736104546Srwatson return (0); 1737104546Srwatson 1738104546Srwatson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1739104546Srwatson return (error); 1740100979Srwatson} 1741100979Srwatson 1742104546Srwatsonvoid 1743104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1744104546Srwatson{ 1745104546Srwatson int result = *prot; 1746104546Srwatson 1747104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1748104546Srwatson 1749104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1750104546Srwatson return; 1751104546Srwatson 1752104546Srwatson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1753104546Srwatson &result); 1754104546Srwatson 1755104546Srwatson *prot = result; 1756104546Srwatson} 1757104546Srwatson 1758100979Srwatsonint 1759104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1760104546Srwatson{ 1761104546Srwatson int error; 1762104546Srwatson 1763104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1764104546Srwatson 1765104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1766104546Srwatson return (0); 1767104546Srwatson 1768104546Srwatson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1769104546Srwatson return (error); 1770104546Srwatson} 1771104546Srwatson 1772104546Srwatsonint 1773106212Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1774100979Srwatson{ 1775100979Srwatson int error; 1776100979Srwatson 1777102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1778102112Srwatson 1779100979Srwatson if (!mac_enforce_fs) 1780100979Srwatson return (0); 1781100979Srwatson 1782102112Srwatson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1783102112Srwatson return (error); 1784102112Srwatson} 1785102112Srwatson 1786102112Srwatsonint 1787102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1788102129Srwatson struct vnode *vp) 1789102112Srwatson{ 1790102112Srwatson int error; 1791102112Srwatson 1792102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1793102112Srwatson 1794102112Srwatson if (!mac_enforce_fs) 1795102112Srwatson return (0); 1796102112Srwatson 1797102129Srwatson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1798102129Srwatson &vp->v_label); 1799100979Srwatson 1800100979Srwatson return (error); 1801100979Srwatson} 1802100979Srwatson 1803100979Srwatsonint 1804102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1805102129Srwatson struct vnode *vp) 1806100979Srwatson{ 1807100979Srwatson int error; 1808100979Srwatson 1809102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1810100979Srwatson 1811100979Srwatson if (!mac_enforce_fs) 1812100979Srwatson return (0); 1813100979Srwatson 1814102129Srwatson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1815102129Srwatson &vp->v_label); 1816102112Srwatson 1817100979Srwatson return (error); 1818100979Srwatson} 1819100979Srwatson 1820100979Srwatsonint 1821100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1822100979Srwatson{ 1823100979Srwatson int error; 1824100979Srwatson 1825100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1826100979Srwatson 1827100979Srwatson if (!mac_enforce_fs) 1828100979Srwatson return (0); 1829100979Srwatson 1830100979Srwatson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1831100979Srwatson return (error); 1832100979Srwatson} 1833100979Srwatson 1834100979Srwatsonint 1835100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1836100979Srwatson{ 1837100979Srwatson int error; 1838100979Srwatson 1839100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1840100979Srwatson 1841100979Srwatson if (!mac_enforce_fs) 1842100979Srwatson return (0); 1843100979Srwatson 1844100979Srwatson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1845100979Srwatson return (error); 1846100979Srwatson} 1847100979Srwatson 1848100979Srwatsonstatic int 1849100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1850100979Srwatson struct label *newlabel) 1851100979Srwatson{ 1852100979Srwatson int error; 1853100979Srwatson 1854100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1855100979Srwatson 1856100979Srwatson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1857100979Srwatson 1858100979Srwatson return (error); 1859100979Srwatson} 1860100979Srwatson 1861100979Srwatsonint 1862100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1863100979Srwatson struct vnode *vp, struct componentname *cnp) 1864100979Srwatson{ 1865100979Srwatson int error; 1866100979Srwatson 1867100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1868100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1869100979Srwatson 1870100979Srwatson if (!mac_enforce_fs) 1871100979Srwatson return (0); 1872100979Srwatson 1873100979Srwatson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1874100979Srwatson &vp->v_label, cnp); 1875100979Srwatson return (error); 1876100979Srwatson} 1877100979Srwatson 1878100979Srwatsonint 1879100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1880100979Srwatson struct vnode *vp, int samedir, struct componentname *cnp) 1881100979Srwatson{ 1882100979Srwatson int error; 1883100979Srwatson 1884100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1885100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1886100979Srwatson 1887100979Srwatson if (!mac_enforce_fs) 1888100979Srwatson return (0); 1889100979Srwatson 1890100979Srwatson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1891100979Srwatson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1892100979Srwatson return (error); 1893100979Srwatson} 1894100979Srwatson 1895100979Srwatsonint 1896100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1897100979Srwatson{ 1898100979Srwatson int error; 1899100979Srwatson 1900100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1901100979Srwatson 1902100979Srwatson if (!mac_enforce_fs) 1903100979Srwatson return (0); 1904100979Srwatson 1905100979Srwatson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1906100979Srwatson return (error); 1907100979Srwatson} 1908100979Srwatson 1909100979Srwatsonint 1910100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1911100979Srwatson struct acl *acl) 1912100979Srwatson{ 1913100979Srwatson int error; 1914100979Srwatson 1915100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1916100979Srwatson 1917100979Srwatson if (!mac_enforce_fs) 1918100979Srwatson return (0); 1919100979Srwatson 1920100979Srwatson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1921100979Srwatson return (error); 1922100979Srwatson} 1923100979Srwatson 1924100979Srwatsonint 1925100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1926100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1927100979Srwatson{ 1928100979Srwatson int error; 1929100979Srwatson 1930100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1931100979Srwatson 1932100979Srwatson if (!mac_enforce_fs) 1933100979Srwatson return (0); 1934100979Srwatson 1935100979Srwatson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1936100979Srwatson attrnamespace, name, uio); 1937100979Srwatson return (error); 1938100979Srwatson} 1939100979Srwatson 1940100979Srwatsonint 1941100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1942100979Srwatson{ 1943100979Srwatson int error; 1944100979Srwatson 1945100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1946100979Srwatson 1947100979Srwatson if (!mac_enforce_fs) 1948100979Srwatson return (0); 1949100979Srwatson 1950100979Srwatson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1951100979Srwatson return (error); 1952100979Srwatson} 1953100979Srwatson 1954100979Srwatsonint 1955100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1956100979Srwatson{ 1957100979Srwatson int error; 1958100979Srwatson 1959100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1960100979Srwatson 1961100979Srwatson if (!mac_enforce_fs) 1962100979Srwatson return (0); 1963100979Srwatson 1964100979Srwatson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1965100979Srwatson return (error); 1966100979Srwatson} 1967100979Srwatson 1968100979Srwatsonint 1969100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1970100979Srwatson gid_t gid) 1971100979Srwatson{ 1972100979Srwatson int error; 1973100979Srwatson 1974100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1975100979Srwatson 1976100979Srwatson if (!mac_enforce_fs) 1977100979Srwatson return (0); 1978100979Srwatson 1979100979Srwatson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1980100979Srwatson return (error); 1981100979Srwatson} 1982100979Srwatson 1983100979Srwatsonint 1984100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1985100979Srwatson struct timespec atime, struct timespec mtime) 1986100979Srwatson{ 1987100979Srwatson int error; 1988100979Srwatson 1989100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1990100979Srwatson 1991100979Srwatson if (!mac_enforce_fs) 1992100979Srwatson return (0); 1993100979Srwatson 1994100979Srwatson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1995100979Srwatson mtime); 1996100979Srwatson return (error); 1997100979Srwatson} 1998100979Srwatson 1999100979Srwatsonint 2000102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2001102129Srwatson struct vnode *vp) 2002100979Srwatson{ 2003100979Srwatson int error; 2004100979Srwatson 2005100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2006100979Srwatson 2007100979Srwatson if (!mac_enforce_fs) 2008100979Srwatson return (0); 2009100979Srwatson 2010102129Srwatson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2011102129Srwatson &vp->v_label); 2012100979Srwatson return (error); 2013100979Srwatson} 2014100979Srwatson 2015102112Srwatsonint 2016102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2017102129Srwatson struct vnode *vp) 2018102112Srwatson{ 2019102112Srwatson int error; 2020102112Srwatson 2021102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2022102112Srwatson 2023102112Srwatson if (!mac_enforce_fs) 2024102112Srwatson return (0); 2025102112Srwatson 2026102129Srwatson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2027102129Srwatson &vp->v_label); 2028102112Srwatson 2029102112Srwatson return (error); 2030102112Srwatson} 2031102112Srwatson 2032100979Srwatson/* 2033100979Srwatson * When relabeling a process, call out to the policies for the maximum 2034100979Srwatson * permission allowed for each object type we know about in its 2035100979Srwatson * memory space, and revoke access (in the least surprising ways we 2036100979Srwatson * know) when necessary. The process lock is not held here. 2037100979Srwatson */ 2038107271Srwatsonvoid 2039100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2040100979Srwatson{ 2041100979Srwatson 2042100979Srwatson /* XXX freeze all other threads */ 2043100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2044100979Srwatson &td->td_proc->p_vmspace->vm_map); 2045100979Srwatson /* XXX allow other threads to continue */ 2046100979Srwatson} 2047100979Srwatson 2048100979Srwatsonstatic __inline const char * 2049100979Srwatsonprot2str(vm_prot_t prot) 2050100979Srwatson{ 2051100979Srwatson 2052100979Srwatson switch (prot & VM_PROT_ALL) { 2053100979Srwatson case VM_PROT_READ: 2054100979Srwatson return ("r--"); 2055100979Srwatson case VM_PROT_READ | VM_PROT_WRITE: 2056100979Srwatson return ("rw-"); 2057100979Srwatson case VM_PROT_READ | VM_PROT_EXECUTE: 2058100979Srwatson return ("r-x"); 2059100979Srwatson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2060100979Srwatson return ("rwx"); 2061100979Srwatson case VM_PROT_WRITE: 2062100979Srwatson return ("-w-"); 2063100979Srwatson case VM_PROT_EXECUTE: 2064100979Srwatson return ("--x"); 2065100979Srwatson case VM_PROT_WRITE | VM_PROT_EXECUTE: 2066100979Srwatson return ("-wx"); 2067100979Srwatson default: 2068100979Srwatson return ("---"); 2069100979Srwatson } 2070100979Srwatson} 2071100979Srwatson 2072100979Srwatsonstatic void 2073100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2074100979Srwatson struct vm_map *map) 2075100979Srwatson{ 2076100979Srwatson struct vm_map_entry *vme; 2077104546Srwatson int result; 2078104546Srwatson vm_prot_t revokeperms; 2079100979Srwatson vm_object_t object; 2080100979Srwatson vm_ooffset_t offset; 2081100979Srwatson struct vnode *vp; 2082100979Srwatson 2083103136Srwatson if (!mac_mmap_revocation) 2084103136Srwatson return; 2085103136Srwatson 2086100979Srwatson vm_map_lock_read(map); 2087100979Srwatson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2088100979Srwatson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2089100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2090100979Srwatson vme->object.sub_map); 2091100979Srwatson continue; 2092100979Srwatson } 2093100979Srwatson /* 2094100979Srwatson * Skip over entries that obviously are not shared. 2095100979Srwatson */ 2096100979Srwatson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2097100979Srwatson !vme->max_protection) 2098100979Srwatson continue; 2099100979Srwatson /* 2100100979Srwatson * Drill down to the deepest backing object. 2101100979Srwatson */ 2102100979Srwatson offset = vme->offset; 2103100979Srwatson object = vme->object.vm_object; 2104100979Srwatson if (object == NULL) 2105100979Srwatson continue; 2106100979Srwatson while (object->backing_object != NULL) { 2107100979Srwatson object = object->backing_object; 2108100979Srwatson offset += object->backing_object_offset; 2109100979Srwatson } 2110100979Srwatson /* 2111100979Srwatson * At the moment, vm_maps and objects aren't considered 2112100979Srwatson * by the MAC system, so only things with backing by a 2113100979Srwatson * normal object (read: vnodes) are checked. 2114100979Srwatson */ 2115100979Srwatson if (object->type != OBJT_VNODE) 2116100979Srwatson continue; 2117100979Srwatson vp = (struct vnode *)object->handle; 2118100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2119104546Srwatson result = vme->max_protection; 2120104546Srwatson mac_check_vnode_mmap_downgrade(cred, vp, &result); 2121100979Srwatson VOP_UNLOCK(vp, 0, td); 2122100979Srwatson /* 2123100979Srwatson * Find out what maximum protection we may be allowing 2124100979Srwatson * now but a policy needs to get removed. 2125100979Srwatson */ 2126100979Srwatson revokeperms = vme->max_protection & ~result; 2127100979Srwatson if (!revokeperms) 2128100979Srwatson continue; 2129102949Sbde printf("pid %ld: revoking %s perms from %#lx:%ld " 2130102949Sbde "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2131102949Sbde prot2str(revokeperms), (u_long)vme->start, 2132102949Sbde (long)(vme->end - vme->start), 2133100979Srwatson prot2str(vme->max_protection), prot2str(vme->protection)); 2134100979Srwatson vm_map_lock_upgrade(map); 2135100979Srwatson /* 2136100979Srwatson * This is the really simple case: if a map has more 2137100979Srwatson * max_protection than is allowed, but it's not being 2138100979Srwatson * actually used (that is, the current protection is 2139100979Srwatson * still allowed), we can just wipe it out and do 2140100979Srwatson * nothing more. 2141100979Srwatson */ 2142100979Srwatson if ((vme->protection & revokeperms) == 0) { 2143100979Srwatson vme->max_protection -= revokeperms; 2144100979Srwatson } else { 2145100979Srwatson if (revokeperms & VM_PROT_WRITE) { 2146100979Srwatson /* 2147100979Srwatson * In the more complicated case, flush out all 2148100979Srwatson * pending changes to the object then turn it 2149100979Srwatson * copy-on-write. 2150100979Srwatson */ 2151100979Srwatson vm_object_reference(object); 2152100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2153113955Salc VM_OBJECT_LOCK(object); 2154100979Srwatson vm_object_page_clean(object, 2155100979Srwatson OFF_TO_IDX(offset), 2156100979Srwatson OFF_TO_IDX(offset + vme->end - vme->start + 2157100979Srwatson PAGE_MASK), 2158100979Srwatson OBJPC_SYNC); 2159113955Salc VM_OBJECT_UNLOCK(object); 2160100979Srwatson VOP_UNLOCK(vp, 0, td); 2161100979Srwatson vm_object_deallocate(object); 2162100979Srwatson /* 2163100979Srwatson * Why bother if there's no read permissions 2164100979Srwatson * anymore? For the rest, we need to leave 2165100979Srwatson * the write permissions on for COW, or 2166100979Srwatson * remove them entirely if configured to. 2167100979Srwatson */ 2168100979Srwatson if (!mac_mmap_revocation_via_cow) { 2169100979Srwatson vme->max_protection &= ~VM_PROT_WRITE; 2170100979Srwatson vme->protection &= ~VM_PROT_WRITE; 2171100979Srwatson } if ((revokeperms & VM_PROT_READ) == 0) 2172100979Srwatson vme->eflags |= MAP_ENTRY_COW | 2173100979Srwatson MAP_ENTRY_NEEDS_COPY; 2174100979Srwatson } 2175100979Srwatson if (revokeperms & VM_PROT_EXECUTE) { 2176100979Srwatson vme->max_protection &= ~VM_PROT_EXECUTE; 2177100979Srwatson vme->protection &= ~VM_PROT_EXECUTE; 2178100979Srwatson } 2179100979Srwatson if (revokeperms & VM_PROT_READ) { 2180100979Srwatson vme->max_protection = 0; 2181100979Srwatson vme->protection = 0; 2182100979Srwatson } 2183100979Srwatson pmap_protect(map->pmap, vme->start, vme->end, 2184100979Srwatson vme->protection & ~revokeperms); 2185100979Srwatson vm_map_simplify_entry(map, vme); 2186100979Srwatson } 2187100979Srwatson vm_map_lock_downgrade(map); 2188100979Srwatson } 2189100979Srwatson vm_map_unlock_read(map); 2190100979Srwatson} 2191100979Srwatson 2192100979Srwatson/* 2193100979Srwatson * When the subject's label changes, it may require revocation of privilege 2194100979Srwatson * to mapped objects. This can't be done on-the-fly later with a unified 2195100979Srwatson * buffer cache. 2196100979Srwatson */ 2197100979Srwatsonstatic void 2198100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel) 2199100979Srwatson{ 2200100979Srwatson 2201100979Srwatson MAC_PERFORM(relabel_cred, cred, newlabel); 2202100979Srwatson} 2203100979Srwatson 2204100979Srwatsonvoid 2205100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2206100979Srwatson{ 2207100979Srwatson 2208100979Srwatson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2209100979Srwatson} 2210100979Srwatson 2211100979Srwatsonvoid 2212100979Srwatsonmac_create_ifnet(struct ifnet *ifnet) 2213100979Srwatson{ 2214100979Srwatson 2215100979Srwatson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2216100979Srwatson} 2217100979Srwatson 2218100979Srwatsonvoid 2219100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2220100979Srwatson{ 2221100979Srwatson 2222100979Srwatson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2223100979Srwatson} 2224100979Srwatson 2225100979Srwatsonvoid 2226100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket) 2227100979Srwatson{ 2228100979Srwatson 2229100979Srwatson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2230100979Srwatson} 2231100979Srwatson 2232100979Srwatsonvoid 2233100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe) 2234100979Srwatson{ 2235100979Srwatson 2236100979Srwatson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2237100979Srwatson} 2238100979Srwatson 2239100979Srwatsonvoid 2240100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket, 2241100979Srwatson struct socket *newsocket) 2242100979Srwatson{ 2243100979Srwatson 2244100979Srwatson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2245100979Srwatson newsocket, &newsocket->so_label); 2246100979Srwatson} 2247100979Srwatson 2248100979Srwatsonstatic void 2249100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket, 2250100979Srwatson struct label *newlabel) 2251100979Srwatson{ 2252100979Srwatson 2253100979Srwatson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2254100979Srwatson} 2255100979Srwatson 2256100979Srwatsonstatic void 2257100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2258100979Srwatson{ 2259100979Srwatson 2260100979Srwatson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2261100979Srwatson} 2262100979Srwatson 2263100979Srwatsonvoid 2264100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2265100979Srwatson{ 2266113482Srwatson struct label *label; 2267100979Srwatson 2268113482Srwatson label = mbuf_to_label(mbuf); 2269113482Srwatson 2270113482Srwatson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 2271113482Srwatson &socket->so_peerlabel); 2272100979Srwatson} 2273100979Srwatson 2274100979Srwatsonvoid 2275100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket, 2276100979Srwatson struct socket *newsocket) 2277100979Srwatson{ 2278100979Srwatson 2279100979Srwatson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2280100979Srwatson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2281100979Srwatson} 2282100979Srwatson 2283100979Srwatsonvoid 2284100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2285100979Srwatson{ 2286113482Srwatson struct label *label; 2287100979Srwatson 2288113482Srwatson label = mbuf_to_label(datagram); 2289113482Srwatson 2290100979Srwatson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2291113482Srwatson datagram, label); 2292100979Srwatson} 2293100979Srwatson 2294100979Srwatsonvoid 2295100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2296100979Srwatson{ 2297113482Srwatson struct label *datagramlabel, *fragmentlabel; 2298100979Srwatson 2299113482Srwatson datagramlabel = mbuf_to_label(datagram); 2300113482Srwatson fragmentlabel = mbuf_to_label(fragment); 2301113482Srwatson 2302113482Srwatson MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 2303113482Srwatson fragmentlabel); 2304100979Srwatson} 2305100979Srwatson 2306100979Srwatsonvoid 2307100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2308100979Srwatson{ 2309113482Srwatson struct label *label; 2310100979Srwatson 2311113482Srwatson label = mbuf_to_label(fragment); 2312113482Srwatson 2313113482Srwatson MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label); 2314100979Srwatson} 2315100979Srwatson 2316100979Srwatsonvoid 2317100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2318100979Srwatson{ 2319113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2320100979Srwatson 2321113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2322113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2323113482Srwatson 2324113482Srwatson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 2325113482Srwatson newmbuflabel); 2326100979Srwatson} 2327100979Srwatson 2328100979Srwatsonvoid 2329100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2330100979Srwatson{ 2331113482Srwatson struct label *label; 2332100979Srwatson 2333113482Srwatson label = mbuf_to_label(mbuf); 2334113482Srwatson 2335100979Srwatson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2336113482Srwatson label); 2337100979Srwatson} 2338100979Srwatson 2339100979Srwatsonvoid 2340100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2341100979Srwatson{ 2342113482Srwatson struct label *label; 2343100979Srwatson 2344113482Srwatson label = mbuf_to_label(mbuf); 2345113482Srwatson 2346100979Srwatson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2347113482Srwatson label); 2348100979Srwatson} 2349100979Srwatson 2350100979Srwatsonvoid 2351100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2352100979Srwatson{ 2353113482Srwatson struct label *label; 2354100979Srwatson 2355113482Srwatson label = mbuf_to_label(mbuf); 2356113482Srwatson 2357100979Srwatson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2358113482Srwatson label); 2359100979Srwatson} 2360100979Srwatson 2361100979Srwatsonvoid 2362100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2363100979Srwatson struct mbuf *newmbuf) 2364100979Srwatson{ 2365113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2366100979Srwatson 2367113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2368113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2369113482Srwatson 2370113482Srwatson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 2371113482Srwatson ifnet, &ifnet->if_label, newmbuf, newmbuflabel); 2372100979Srwatson} 2373100979Srwatson 2374100979Srwatsonvoid 2375100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2376100979Srwatson{ 2377113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2378100979Srwatson 2379113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2380113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2381113482Srwatson 2382113482Srwatson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 2383113482Srwatson newmbuflabel); 2384100979Srwatson} 2385100979Srwatson 2386100979Srwatsonint 2387100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2388100979Srwatson{ 2389113482Srwatson struct label *label; 2390100979Srwatson int result; 2391100979Srwatson 2392113482Srwatson label = mbuf_to_label(fragment); 2393113482Srwatson 2394100979Srwatson result = 1; 2395113482Srwatson MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 2396113482Srwatson &ipq->ipq_label); 2397100979Srwatson 2398100979Srwatson return (result); 2399100979Srwatson} 2400100979Srwatson 2401100979Srwatsonvoid 2402119244Srwatsonmac_reflect_mbuf_icmp(struct mbuf *m) 2403119244Srwatson{ 2404119244Srwatson struct label *label; 2405119244Srwatson 2406119244Srwatson label = mbuf_to_label(m); 2407119244Srwatson 2408119244Srwatson MAC_PERFORM(reflect_mbuf_icmp, m, label); 2409119244Srwatson} 2410119244Srwatsonvoid 2411119244Srwatsonmac_reflect_mbuf_tcp(struct mbuf *m) 2412119244Srwatson{ 2413119244Srwatson struct label *label; 2414119244Srwatson 2415119244Srwatson label = mbuf_to_label(m); 2416119244Srwatson 2417119244Srwatson MAC_PERFORM(reflect_mbuf_tcp, m, label); 2418119244Srwatson} 2419119244Srwatson 2420119244Srwatsonvoid 2421100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2422100979Srwatson{ 2423113482Srwatson struct label *label; 2424100979Srwatson 2425113482Srwatson label = mbuf_to_label(fragment); 2426113482Srwatson 2427113482Srwatson MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label); 2428100979Srwatson} 2429100979Srwatson 2430100979Srwatsonvoid 2431100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2432100979Srwatson{ 2433113482Srwatson struct label *label; 2434100979Srwatson 2435113482Srwatson label = mbuf_to_label(mbuf); 2436113482Srwatson 2437100979Srwatson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2438113482Srwatson label); 2439100979Srwatson} 2440100979Srwatson 2441100979Srwatsonvoid 2442100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp) 2443100979Srwatson{ 2444100979Srwatson 2445100979Srwatson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2446100979Srwatson &mp->mnt_fslabel); 2447100979Srwatson} 2448100979Srwatson 2449100979Srwatsonvoid 2450100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp) 2451100979Srwatson{ 2452100979Srwatson 2453100979Srwatson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2454100979Srwatson &mp->mnt_fslabel); 2455100979Srwatson} 2456100979Srwatson 2457100979Srwatsonint 2458100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2459100979Srwatson{ 2460100979Srwatson int error; 2461100979Srwatson 2462100979Srwatson if (!mac_enforce_network) 2463100979Srwatson return (0); 2464100979Srwatson 2465100979Srwatson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2466100979Srwatson &ifnet->if_label); 2467100979Srwatson 2468100979Srwatson return (error); 2469100979Srwatson} 2470100979Srwatson 2471100979Srwatsonstatic int 2472100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2473100979Srwatson{ 2474100979Srwatson int error; 2475100979Srwatson 2476100979Srwatson MAC_CHECK(check_cred_relabel, cred, newlabel); 2477100979Srwatson 2478100979Srwatson return (error); 2479100979Srwatson} 2480100979Srwatson 2481100979Srwatsonint 2482100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2483100979Srwatson{ 2484100979Srwatson int error; 2485100979Srwatson 2486100979Srwatson if (!mac_enforce_process) 2487100979Srwatson return (0); 2488100979Srwatson 2489100979Srwatson MAC_CHECK(check_cred_visible, u1, u2); 2490100979Srwatson 2491100979Srwatson return (error); 2492100979Srwatson} 2493100979Srwatson 2494100979Srwatsonint 2495100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2496100979Srwatson{ 2497113482Srwatson struct label *label; 2498100979Srwatson int error; 2499100979Srwatson 2500113487Srwatson M_ASSERTPKTHDR(mbuf); 2501113487Srwatson 2502100979Srwatson if (!mac_enforce_network) 2503100979Srwatson return (0); 2504100979Srwatson 2505113482Srwatson label = mbuf_to_label(mbuf); 2506100979Srwatson 2507100979Srwatson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2508113482Srwatson label); 2509100979Srwatson 2510100979Srwatson return (error); 2511100979Srwatson} 2512100979Srwatson 2513100979Srwatsonint 2514106308Srwatsonmac_check_kenv_dump(struct ucred *cred) 2515106308Srwatson{ 2516106308Srwatson int error; 2517106308Srwatson 2518106308Srwatson if (!mac_enforce_system) 2519106308Srwatson return (0); 2520106308Srwatson 2521106308Srwatson MAC_CHECK(check_kenv_dump, cred); 2522106308Srwatson 2523106308Srwatson return (error); 2524106308Srwatson} 2525106308Srwatson 2526106308Srwatsonint 2527106308Srwatsonmac_check_kenv_get(struct ucred *cred, char *name) 2528106308Srwatson{ 2529106308Srwatson int error; 2530106308Srwatson 2531106308Srwatson if (!mac_enforce_system) 2532106308Srwatson return (0); 2533106308Srwatson 2534106308Srwatson MAC_CHECK(check_kenv_get, cred, name); 2535106308Srwatson 2536106308Srwatson return (error); 2537106308Srwatson} 2538106308Srwatson 2539106308Srwatsonint 2540106308Srwatsonmac_check_kenv_set(struct ucred *cred, char *name, char *value) 2541106308Srwatson{ 2542106308Srwatson int error; 2543106308Srwatson 2544106308Srwatson if (!mac_enforce_system) 2545106308Srwatson return (0); 2546106308Srwatson 2547106308Srwatson MAC_CHECK(check_kenv_set, cred, name, value); 2548106308Srwatson 2549106308Srwatson return (error); 2550106308Srwatson} 2551106308Srwatson 2552106308Srwatsonint 2553106308Srwatsonmac_check_kenv_unset(struct ucred *cred, char *name) 2554106308Srwatson{ 2555106308Srwatson int error; 2556106308Srwatson 2557106308Srwatson if (!mac_enforce_system) 2558106308Srwatson return (0); 2559106308Srwatson 2560106308Srwatson MAC_CHECK(check_kenv_unset, cred, name); 2561106308Srwatson 2562106308Srwatson return (error); 2563106308Srwatson} 2564106308Srwatson 2565106308Srwatsonint 2566107089Srwatsonmac_check_kld_load(struct ucred *cred, struct vnode *vp) 2567107089Srwatson{ 2568107089Srwatson int error; 2569107089Srwatson 2570107089Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2571107089Srwatson 2572107089Srwatson if (!mac_enforce_kld) 2573107089Srwatson return (0); 2574107089Srwatson 2575107089Srwatson MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2576107089Srwatson 2577107089Srwatson return (error); 2578107089Srwatson} 2579107089Srwatson 2580107089Srwatsonint 2581107089Srwatsonmac_check_kld_stat(struct ucred *cred) 2582107089Srwatson{ 2583107089Srwatson int error; 2584107089Srwatson 2585107089Srwatson if (!mac_enforce_kld) 2586107089Srwatson return (0); 2587107089Srwatson 2588107089Srwatson MAC_CHECK(check_kld_stat, cred); 2589107089Srwatson 2590107089Srwatson return (error); 2591107089Srwatson} 2592107089Srwatson 2593107089Srwatsonint 2594107089Srwatsonmac_check_kld_unload(struct ucred *cred) 2595107089Srwatson{ 2596107089Srwatson int error; 2597107089Srwatson 2598107089Srwatson if (!mac_enforce_kld) 2599107089Srwatson return (0); 2600107089Srwatson 2601107089Srwatson MAC_CHECK(check_kld_unload, cred); 2602107089Srwatson 2603107089Srwatson return (error); 2604107089Srwatson} 2605107089Srwatson 2606107089Srwatsonint 2607100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount) 2608100979Srwatson{ 2609100979Srwatson int error; 2610100979Srwatson 2611100979Srwatson if (!mac_enforce_fs) 2612100979Srwatson return (0); 2613100979Srwatson 2614100979Srwatson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2615100979Srwatson 2616100979Srwatson return (error); 2617100979Srwatson} 2618100979Srwatson 2619100979Srwatsonint 2620100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2621100979Srwatson void *data) 2622100979Srwatson{ 2623100979Srwatson int error; 2624100979Srwatson 2625104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2626104269Srwatson 2627104269Srwatson if (!mac_enforce_pipe) 2628104269Srwatson return (0); 2629104269Srwatson 2630100979Srwatson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2631100979Srwatson 2632100979Srwatson return (error); 2633100979Srwatson} 2634100979Srwatson 2635100979Srwatsonint 2636102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2637100979Srwatson{ 2638100979Srwatson int error; 2639100979Srwatson 2640104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2641104269Srwatson 2642104269Srwatson if (!mac_enforce_pipe) 2643104269Srwatson return (0); 2644104269Srwatson 2645102115Srwatson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2646100979Srwatson 2647100979Srwatson return (error); 2648100979Srwatson} 2649100979Srwatson 2650102115Srwatsonint 2651102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2652102115Srwatson{ 2653102115Srwatson int error; 2654102115Srwatson 2655104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2656104269Srwatson 2657104269Srwatson if (!mac_enforce_pipe) 2658104269Srwatson return (0); 2659104269Srwatson 2660102115Srwatson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2661102115Srwatson 2662102115Srwatson return (error); 2663102115Srwatson} 2664102115Srwatson 2665100979Srwatsonstatic int 2666100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2667100979Srwatson struct label *newlabel) 2668100979Srwatson{ 2669100979Srwatson int error; 2670100979Srwatson 2671104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2672104269Srwatson 2673104269Srwatson if (!mac_enforce_pipe) 2674104269Srwatson return (0); 2675104269Srwatson 2676100979Srwatson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2677100979Srwatson 2678100979Srwatson return (error); 2679100979Srwatson} 2680100979Srwatson 2681100979Srwatsonint 2682102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2683102115Srwatson{ 2684102115Srwatson int error; 2685102115Srwatson 2686104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2687104269Srwatson 2688104269Srwatson if (!mac_enforce_pipe) 2689104269Srwatson return (0); 2690104269Srwatson 2691102115Srwatson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2692102115Srwatson 2693102115Srwatson return (error); 2694102115Srwatson} 2695102115Srwatson 2696102115Srwatsonint 2697102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2698102115Srwatson{ 2699102115Srwatson int error; 2700102115Srwatson 2701104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2702104269Srwatson 2703104269Srwatson if (!mac_enforce_pipe) 2704104269Srwatson return (0); 2705104269Srwatson 2706102115Srwatson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2707102115Srwatson 2708102115Srwatson return (error); 2709102115Srwatson} 2710102115Srwatson 2711102115Srwatsonint 2712100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc) 2713100979Srwatson{ 2714100979Srwatson int error; 2715100979Srwatson 2716102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2717102103Srwatson 2718100979Srwatson if (!mac_enforce_process) 2719100979Srwatson return (0); 2720100979Srwatson 2721100979Srwatson MAC_CHECK(check_proc_debug, cred, proc); 2722100979Srwatson 2723100979Srwatson return (error); 2724100979Srwatson} 2725100979Srwatson 2726100979Srwatsonint 2727100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc) 2728100979Srwatson{ 2729100979Srwatson int error; 2730100979Srwatson 2731102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2732102103Srwatson 2733100979Srwatson if (!mac_enforce_process) 2734100979Srwatson return (0); 2735100979Srwatson 2736100979Srwatson MAC_CHECK(check_proc_sched, cred, proc); 2737100979Srwatson 2738100979Srwatson return (error); 2739100979Srwatson} 2740100979Srwatson 2741100979Srwatsonint 2742100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2743100979Srwatson{ 2744100979Srwatson int error; 2745100979Srwatson 2746102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2747102103Srwatson 2748100979Srwatson if (!mac_enforce_process) 2749100979Srwatson return (0); 2750100979Srwatson 2751100979Srwatson MAC_CHECK(check_proc_signal, cred, proc, signum); 2752100979Srwatson 2753100979Srwatson return (error); 2754100979Srwatson} 2755100979Srwatson 2756100979Srwatsonint 2757100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2758100979Srwatson struct sockaddr *sockaddr) 2759100979Srwatson{ 2760100979Srwatson int error; 2761100979Srwatson 2762100979Srwatson if (!mac_enforce_socket) 2763100979Srwatson return (0); 2764100979Srwatson 2765100979Srwatson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2766100979Srwatson sockaddr); 2767100979Srwatson 2768100979Srwatson return (error); 2769100979Srwatson} 2770100979Srwatson 2771100979Srwatsonint 2772100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket, 2773100979Srwatson struct sockaddr *sockaddr) 2774100979Srwatson{ 2775100979Srwatson int error; 2776100979Srwatson 2777100979Srwatson if (!mac_enforce_socket) 2778100979Srwatson return (0); 2779100979Srwatson 2780100979Srwatson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2781100979Srwatson sockaddr); 2782100979Srwatson 2783100979Srwatson return (error); 2784100979Srwatson} 2785100979Srwatson 2786100979Srwatsonint 2787101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2788100979Srwatson{ 2789113482Srwatson struct label *label; 2790100979Srwatson int error; 2791100979Srwatson 2792100979Srwatson if (!mac_enforce_socket) 2793100979Srwatson return (0); 2794100979Srwatson 2795113482Srwatson label = mbuf_to_label(mbuf); 2796113482Srwatson 2797101933Srwatson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2798113482Srwatson label); 2799101933Srwatson 2800100979Srwatson return (error); 2801100979Srwatson} 2802100979Srwatson 2803100979Srwatsonint 2804101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket) 2805100979Srwatson{ 2806100979Srwatson int error; 2807100979Srwatson 2808100979Srwatson if (!mac_enforce_socket) 2809100979Srwatson return (0); 2810100979Srwatson 2811101933Srwatson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2812100979Srwatson return (error); 2813100979Srwatson} 2814100979Srwatson 2815104571Srwatsonint 2816104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so) 2817104571Srwatson{ 2818104571Srwatson int error; 2819104571Srwatson 2820104571Srwatson if (!mac_enforce_socket) 2821104571Srwatson return (0); 2822104571Srwatson 2823104571Srwatson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2824104571Srwatson 2825104571Srwatson return (error); 2826104571Srwatson} 2827104571Srwatson 2828100979Srwatsonstatic int 2829100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2830100979Srwatson struct label *newlabel) 2831100979Srwatson{ 2832100979Srwatson int error; 2833100979Srwatson 2834100979Srwatson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2835100979Srwatson newlabel); 2836100979Srwatson 2837100979Srwatson return (error); 2838100979Srwatson} 2839100979Srwatson 2840100979Srwatsonint 2841104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so) 2842104571Srwatson{ 2843104571Srwatson int error; 2844104571Srwatson 2845104571Srwatson if (!mac_enforce_socket) 2846104571Srwatson return (0); 2847104571Srwatson 2848104571Srwatson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2849104571Srwatson 2850104571Srwatson return (error); 2851104571Srwatson} 2852104571Srwatson 2853104571Srwatsonint 2854100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket) 2855100979Srwatson{ 2856100979Srwatson int error; 2857100979Srwatson 2858100979Srwatson if (!mac_enforce_socket) 2859100979Srwatson return (0); 2860105694Srwatson 2861100979Srwatson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2862105694Srwatson 2863100979Srwatson return (error); 2864100979Srwatson} 2865100979Srwatson 2866100979Srwatsonint 2867111939Srwatsonmac_check_sysarch_ioperm(struct ucred *cred) 2868111939Srwatson{ 2869111939Srwatson int error; 2870111939Srwatson 2871111939Srwatson if (!mac_enforce_system) 2872111939Srwatson return (0); 2873111939Srwatson 2874111939Srwatson MAC_CHECK(check_sysarch_ioperm, cred); 2875111939Srwatson return (error); 2876111939Srwatson} 2877111939Srwatson 2878111939Srwatsonint 2879106412Srwatsonmac_check_system_acct(struct ucred *cred, struct vnode *vp) 2880106412Srwatson{ 2881106412Srwatson int error; 2882106412Srwatson 2883106412Srwatson if (vp != NULL) { 2884106412Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2885106412Srwatson } 2886106412Srwatson 2887106412Srwatson if (!mac_enforce_system) 2888106412Srwatson return (0); 2889106412Srwatson 2890106412Srwatson MAC_CHECK(check_system_acct, cred, vp, 2891106412Srwatson vp != NULL ? &vp->v_label : NULL); 2892106412Srwatson 2893106412Srwatson return (error); 2894106412Srwatson} 2895106412Srwatson 2896106412Srwatsonint 2897106412Srwatsonmac_check_system_nfsd(struct ucred *cred) 2898106412Srwatson{ 2899106412Srwatson int error; 2900106412Srwatson 2901106412Srwatson if (!mac_enforce_system) 2902106412Srwatson return (0); 2903106412Srwatson 2904106412Srwatson MAC_CHECK(check_system_nfsd, cred); 2905106412Srwatson 2906106412Srwatson return (error); 2907106412Srwatson} 2908106412Srwatson 2909106412Srwatsonint 2910106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto) 2911106024Srwatson{ 2912106024Srwatson int error; 2913106024Srwatson 2914106045Srwatson if (!mac_enforce_system) 2915106024Srwatson return (0); 2916106024Srwatson 2917106024Srwatson MAC_CHECK(check_system_reboot, cred, howto); 2918106045Srwatson 2919106024Srwatson return (error); 2920106024Srwatson} 2921106024Srwatson 2922106024Srwatsonint 2923106369Srwatsonmac_check_system_settime(struct ucred *cred) 2924106369Srwatson{ 2925106369Srwatson int error; 2926106369Srwatson 2927106369Srwatson if (!mac_enforce_system) 2928106369Srwatson return (0); 2929106369Srwatson 2930106369Srwatson MAC_CHECK(check_system_settime, cred); 2931106369Srwatson 2932106369Srwatson return (error); 2933106369Srwatson} 2934106369Srwatson 2935106369Srwatsonint 2936106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2937106023Srwatson{ 2938106023Srwatson int error; 2939106023Srwatson 2940106023Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2941106023Srwatson 2942106045Srwatson if (!mac_enforce_system) 2943106023Srwatson return (0); 2944106023Srwatson 2945106023Srwatson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2946106023Srwatson return (error); 2947106023Srwatson} 2948106023Srwatson 2949106023Srwatsonint 2950111936Srwatsonmac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2951111936Srwatson{ 2952111936Srwatson int error; 2953111936Srwatson 2954111936Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2955111936Srwatson 2956111936Srwatson if (!mac_enforce_system) 2957111936Srwatson return (0); 2958111936Srwatson 2959111936Srwatson MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2960111936Srwatson return (error); 2961111936Srwatson} 2962111936Srwatson 2963111936Srwatsonint 2964106025Srwatsonmac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2965106025Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2966106025Srwatson{ 2967106025Srwatson int error; 2968106025Srwatson 2969106025Srwatson /* 2970106025Srwatson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2971106025Srwatson * but since it's not exported from kern_sysctl.c, we can't. 2972106025Srwatson */ 2973106045Srwatson if (!mac_enforce_system) 2974106025Srwatson return (0); 2975106025Srwatson 2976106025Srwatson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2977106025Srwatson inkernel, new, newlen); 2978106025Srwatson 2979106025Srwatson return (error); 2980106025Srwatson} 2981106025Srwatson 2982106025Srwatsonint 2983100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2984100979Srwatson struct ifnet *ifnet) 2985100979Srwatson{ 2986105694Srwatson char *elements, *buffer; 2987105694Srwatson struct mac mac; 2988100979Srwatson int error; 2989100979Srwatson 2990105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2991100979Srwatson if (error) 2992100979Srwatson return (error); 2993100979Srwatson 2994105694Srwatson error = mac_check_structmac_consistent(&mac); 2995105694Srwatson if (error) 2996105694Srwatson return (error); 2997105694Srwatson 2998111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2999105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3000105694Srwatson if (error) { 3001105694Srwatson free(elements, M_MACTEMP); 3002105694Srwatson return (error); 3003105694Srwatson } 3004105694Srwatson 3005111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3006105694Srwatson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 3007111119Simp buffer, mac.m_buflen, M_WAITOK); 3008105694Srwatson if (error == 0) 3009105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3010105694Srwatson 3011105694Srwatson free(buffer, M_MACTEMP); 3012105694Srwatson free(elements, M_MACTEMP); 3013105694Srwatson 3014105694Srwatson return (error); 3015100979Srwatson} 3016100979Srwatson 3017100979Srwatsonint 3018100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 3019100979Srwatson struct ifnet *ifnet) 3020100979Srwatson{ 3021100979Srwatson struct label intlabel; 3022105694Srwatson struct mac mac; 3023105694Srwatson char *buffer; 3024100979Srwatson int error; 3025100979Srwatson 3026105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 3027100979Srwatson if (error) 3028100979Srwatson return (error); 3029100979Srwatson 3030105694Srwatson error = mac_check_structmac_consistent(&mac); 3031100979Srwatson if (error) 3032100979Srwatson return (error); 3033100979Srwatson 3034111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3035105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3036105694Srwatson if (error) { 3037105694Srwatson free(buffer, M_MACTEMP); 3038105694Srwatson return (error); 3039105694Srwatson } 3040105694Srwatson 3041105694Srwatson mac_init_ifnet_label(&intlabel); 3042105694Srwatson error = mac_internalize_ifnet_label(&intlabel, buffer); 3043105694Srwatson free(buffer, M_MACTEMP); 3044105694Srwatson if (error) { 3045105694Srwatson mac_destroy_ifnet_label(&intlabel); 3046105694Srwatson return (error); 3047105694Srwatson } 3048105694Srwatson 3049100979Srwatson /* 3050100979Srwatson * XXX: Note that this is a redundant privilege check, since 3051100979Srwatson * policies impose this check themselves if required by the 3052100979Srwatson * policy. Eventually, this should go away. 3053100979Srwatson */ 3054100979Srwatson error = suser_cred(cred, 0); 3055105694Srwatson if (error) { 3056105694Srwatson mac_destroy_ifnet_label(&intlabel); 3057105694Srwatson return (error); 3058105694Srwatson } 3059100979Srwatson 3060100979Srwatson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3061100979Srwatson &intlabel); 3062105694Srwatson if (error) { 3063105694Srwatson mac_destroy_ifnet_label(&intlabel); 3064105694Srwatson return (error); 3065105694Srwatson } 3066100979Srwatson 3067100979Srwatson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3068100979Srwatson 3069105694Srwatson mac_destroy_ifnet_label(&intlabel); 3070105694Srwatson return (0); 3071100979Srwatson} 3072100979Srwatson 3073100979Srwatsonvoid 3074107698Srwatsonmac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de) 3075100979Srwatson{ 3076100979Srwatson 3077107698Srwatson MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label); 3078100979Srwatson} 3079100979Srwatson 3080104533Srwatsonvoid 3081107698Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 3082107698Srwatson struct devfs_dirent *dd, struct devfs_dirent *de) 3083104533Srwatson{ 3084104533Srwatson 3085107698Srwatson MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de, 3086104533Srwatson &de->de_label); 3087104533Srwatson} 3088104533Srwatson 3089100979Srwatsonvoid 3090107698Srwatsonmac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 3091100979Srwatson struct devfs_dirent *de) 3092100979Srwatson{ 3093100979Srwatson 3094107698Srwatson MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 3095100979Srwatson &de->de_label); 3096100979Srwatson} 3097100979Srwatson 3098100979Srwatsonint 3099100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3100105694Srwatson struct mac *mac) 3101100979Srwatson{ 3102100979Srwatson struct label intlabel; 3103105694Srwatson char *buffer; 3104100979Srwatson int error; 3105100979Srwatson 3106105694Srwatson error = mac_check_structmac_consistent(mac); 3107100979Srwatson if (error) 3108100979Srwatson return (error); 3109100979Srwatson 3110111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3111105694Srwatson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3112105694Srwatson if (error) { 3113105694Srwatson free(buffer, M_MACTEMP); 3114105694Srwatson return (error); 3115105694Srwatson } 3116105694Srwatson 3117111119Simp mac_init_socket_label(&intlabel, M_WAITOK); 3118105694Srwatson error = mac_internalize_socket_label(&intlabel, buffer); 3119105694Srwatson free(buffer, M_MACTEMP); 3120105694Srwatson if (error) { 3121105694Srwatson mac_destroy_socket_label(&intlabel); 3122105694Srwatson return (error); 3123105694Srwatson } 3124105694Srwatson 3125100979Srwatson mac_check_socket_relabel(cred, so, &intlabel); 3126100979Srwatson if (error) { 3127105694Srwatson mac_destroy_socket_label(&intlabel); 3128100979Srwatson return (error); 3129100979Srwatson } 3130100979Srwatson 3131100979Srwatson mac_relabel_socket(cred, so, &intlabel); 3132100979Srwatson 3133105694Srwatson mac_destroy_socket_label(&intlabel); 3134100979Srwatson return (0); 3135100979Srwatson} 3136100979Srwatson 3137100979Srwatsonint 3138100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3139100979Srwatson{ 3140100979Srwatson int error; 3141100979Srwatson 3142104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3143104269Srwatson 3144100979Srwatson error = mac_check_pipe_relabel(cred, pipe, label); 3145100979Srwatson if (error) 3146100979Srwatson return (error); 3147100979Srwatson 3148100979Srwatson mac_relabel_pipe(cred, pipe, label); 3149100979Srwatson 3150100979Srwatson return (0); 3151100979Srwatson} 3152100979Srwatson 3153100979Srwatsonint 3154100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3155105694Srwatson struct mac *mac) 3156100979Srwatson{ 3157105694Srwatson char *buffer, *elements; 3158105694Srwatson int error; 3159100979Srwatson 3160105694Srwatson error = mac_check_structmac_consistent(mac); 3161105694Srwatson if (error) 3162105694Srwatson return (error); 3163105694Srwatson 3164111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3165105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3166105694Srwatson if (error) { 3167105694Srwatson free(elements, M_MACTEMP); 3168105694Srwatson return (error); 3169105694Srwatson } 3170105694Srwatson 3171111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3172105694Srwatson error = mac_externalize_socket_label(&so->so_label, elements, 3173111119Simp buffer, mac->m_buflen, M_WAITOK); 3174105694Srwatson if (error == 0) 3175105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3176105694Srwatson 3177105694Srwatson free(buffer, M_MACTEMP); 3178105694Srwatson free(elements, M_MACTEMP); 3179105694Srwatson 3180105694Srwatson return (error); 3181100979Srwatson} 3182100979Srwatson 3183100979Srwatsonint 3184100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3185105694Srwatson struct mac *mac) 3186100979Srwatson{ 3187105694Srwatson char *elements, *buffer; 3188105694Srwatson int error; 3189100979Srwatson 3190105694Srwatson error = mac_check_structmac_consistent(mac); 3191105694Srwatson if (error) 3192105694Srwatson return (error); 3193105694Srwatson 3194111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3195105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3196105694Srwatson if (error) { 3197105694Srwatson free(elements, M_MACTEMP); 3198105694Srwatson return (error); 3199105694Srwatson } 3200105694Srwatson 3201111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3202105694Srwatson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3203111119Simp elements, buffer, mac->m_buflen, M_WAITOK); 3204105694Srwatson if (error == 0) 3205105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3206105694Srwatson 3207105694Srwatson free(buffer, M_MACTEMP); 3208105694Srwatson free(elements, M_MACTEMP); 3209105694Srwatson 3210105694Srwatson return (error); 3211100979Srwatson} 3212100979Srwatson 3213100979Srwatson/* 3214100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes 3215100979Srwatson * to store label data. Can be referenced by filesystems supporting 3216100979Srwatson * extended attributes. 3217100979Srwatson */ 3218100979Srwatsonint 3219100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3220100979Srwatson{ 3221100979Srwatson struct vnode *vp = ap->a_vp; 3222100979Srwatson struct label *intlabel = ap->a_label; 3223100979Srwatson int error; 3224100979Srwatson 3225100979Srwatson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3226100979Srwatson 3227105988Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3228105988Srwatson return (EOPNOTSUPP); 3229100979Srwatson 3230105988Srwatson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3231100979Srwatson if (error) 3232100979Srwatson return (error); 3233100979Srwatson 3234100979Srwatson mac_relabel_vnode(ap->a_cred, vp, intlabel); 3235100979Srwatson 3236100979Srwatson return (0); 3237100979Srwatson} 3238100979Srwatson 3239100979Srwatsonstatic int 3240100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3241100979Srwatson{ 3242100979Srwatson int error; 3243100979Srwatson 3244100979Srwatson if (vp->v_mount == NULL) { 3245100979Srwatson /* printf("vn_setlabel: null v_mount\n"); */ 3246103314Snjl if (vp->v_type != VNON) 3247103314Snjl printf("vn_setlabel: null v_mount with non-VNON\n"); 3248100979Srwatson return (EBADF); 3249100979Srwatson } 3250100979Srwatson 3251100979Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3252100979Srwatson return (EOPNOTSUPP); 3253100979Srwatson 3254100979Srwatson /* 3255100979Srwatson * Multi-phase commit. First check the policies to confirm the 3256100979Srwatson * change is OK. Then commit via the filesystem. Finally, 3257100979Srwatson * update the actual vnode label. Question: maybe the filesystem 3258100979Srwatson * should update the vnode at the end as part of VOP_SETLABEL()? 3259100979Srwatson */ 3260100979Srwatson error = mac_check_vnode_relabel(cred, vp, intlabel); 3261100979Srwatson if (error) 3262100979Srwatson return (error); 3263100979Srwatson 3264100979Srwatson /* 3265100979Srwatson * VADMIN provides the opportunity for the filesystem to make 3266100979Srwatson * decisions about who is and is not able to modify labels 3267100979Srwatson * and protections on files. This might not be right. We can't 3268100979Srwatson * assume VOP_SETLABEL() will do it, because we might implement 3269100979Srwatson * that as part of vop_stdsetlabel_ea(). 3270100979Srwatson */ 3271100979Srwatson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3272100979Srwatson if (error) 3273100979Srwatson return (error); 3274100979Srwatson 3275100979Srwatson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3276100979Srwatson if (error) 3277100979Srwatson return (error); 3278100979Srwatson 3279100979Srwatson return (0); 3280100979Srwatson} 3281100979Srwatson 3282105694Srwatsonint 3283105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3284105694Srwatson{ 3285105694Srwatson char *elements, *buffer; 3286105694Srwatson struct mac mac; 3287105694Srwatson struct proc *tproc; 3288105694Srwatson struct ucred *tcred; 3289105694Srwatson int error; 3290105694Srwatson 3291107849Salfred error = copyin(uap->mac_p, &mac, sizeof(mac)); 3292105694Srwatson if (error) 3293105694Srwatson return (error); 3294105694Srwatson 3295105694Srwatson error = mac_check_structmac_consistent(&mac); 3296105694Srwatson if (error) 3297105694Srwatson return (error); 3298105694Srwatson 3299105694Srwatson tproc = pfind(uap->pid); 3300105694Srwatson if (tproc == NULL) 3301105694Srwatson return (ESRCH); 3302105694Srwatson 3303105694Srwatson tcred = NULL; /* Satisfy gcc. */ 3304105694Srwatson error = p_cansee(td, tproc); 3305105694Srwatson if (error == 0) 3306105694Srwatson tcred = crhold(tproc->p_ucred); 3307105694Srwatson PROC_UNLOCK(tproc); 3308105694Srwatson if (error) 3309105694Srwatson return (error); 3310105694Srwatson 3311111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3312105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3313105694Srwatson if (error) { 3314105694Srwatson free(elements, M_MACTEMP); 3315105694Srwatson crfree(tcred); 3316105694Srwatson return (error); 3317105694Srwatson } 3318105694Srwatson 3319111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3320105694Srwatson error = mac_externalize_cred_label(&tcred->cr_label, elements, 3321111119Simp buffer, mac.m_buflen, M_WAITOK); 3322105694Srwatson if (error == 0) 3323105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3324105694Srwatson 3325105694Srwatson free(buffer, M_MACTEMP); 3326105694Srwatson free(elements, M_MACTEMP); 3327105694Srwatson crfree(tcred); 3328105694Srwatson return (error); 3329105694Srwatson} 3330105694Srwatson 3331100979Srwatson/* 3332100979Srwatson * MPSAFE 3333100979Srwatson */ 3334100979Srwatsonint 3335100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3336100894Srwatson{ 3337105694Srwatson char *elements, *buffer; 3338105694Srwatson struct mac mac; 3339100979Srwatson int error; 3340100894Srwatson 3341105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3342105694Srwatson if (error) 3343105694Srwatson return (error); 3344105694Srwatson 3345105694Srwatson error = mac_check_structmac_consistent(&mac); 3346105694Srwatson if (error) 3347105694Srwatson return (error); 3348105694Srwatson 3349111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3350105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3351105694Srwatson if (error) { 3352105694Srwatson free(elements, M_MACTEMP); 3353105694Srwatson return (error); 3354105694Srwatson } 3355105694Srwatson 3356111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3357105694Srwatson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3358111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3359100979Srwatson if (error == 0) 3360105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3361100979Srwatson 3362105694Srwatson free(buffer, M_MACTEMP); 3363105694Srwatson free(elements, M_MACTEMP); 3364100979Srwatson return (error); 3365100979Srwatson} 3366100979Srwatson 3367100979Srwatson/* 3368100979Srwatson * MPSAFE 3369100979Srwatson */ 3370100979Srwatsonint 3371100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3372100979Srwatson{ 3373100979Srwatson struct ucred *newcred, *oldcred; 3374105694Srwatson struct label intlabel; 3375100979Srwatson struct proc *p; 3376105694Srwatson struct mac mac; 3377105694Srwatson char *buffer; 3378100979Srwatson int error; 3379100979Srwatson 3380105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3381100979Srwatson if (error) 3382100979Srwatson return (error); 3383100979Srwatson 3384105694Srwatson error = mac_check_structmac_consistent(&mac); 3385100979Srwatson if (error) 3386100979Srwatson return (error); 3387100979Srwatson 3388111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3389105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3390105694Srwatson if (error) { 3391105694Srwatson free(buffer, M_MACTEMP); 3392105694Srwatson return (error); 3393105694Srwatson } 3394105694Srwatson 3395105694Srwatson mac_init_cred_label(&intlabel); 3396105694Srwatson error = mac_internalize_cred_label(&intlabel, buffer); 3397105694Srwatson free(buffer, M_MACTEMP); 3398105694Srwatson if (error) { 3399105694Srwatson mac_destroy_cred_label(&intlabel); 3400105694Srwatson return (error); 3401105694Srwatson } 3402105694Srwatson 3403100979Srwatson newcred = crget(); 3404100979Srwatson 3405100979Srwatson p = td->td_proc; 3406100979Srwatson PROC_LOCK(p); 3407100979Srwatson oldcred = p->p_ucred; 3408100979Srwatson 3409100979Srwatson error = mac_check_cred_relabel(oldcred, &intlabel); 3410100979Srwatson if (error) { 3411100979Srwatson PROC_UNLOCK(p); 3412100979Srwatson crfree(newcred); 3413105694Srwatson goto out; 3414100979Srwatson } 3415100979Srwatson 3416100979Srwatson setsugid(p); 3417100979Srwatson crcopy(newcred, oldcred); 3418100979Srwatson mac_relabel_cred(newcred, &intlabel); 3419102136Srwatson p->p_ucred = newcred; 3420100979Srwatson 3421102136Srwatson /* 3422102136Srwatson * Grab additional reference for use while revoking mmaps, prior 3423102136Srwatson * to releasing the proc lock and sharing the cred. 3424102136Srwatson */ 3425102136Srwatson crhold(newcred); 3426100979Srwatson PROC_UNLOCK(p); 3427102136Srwatson 3428105694Srwatson if (mac_enforce_vm) { 3429105694Srwatson mtx_lock(&Giant); 3430105694Srwatson mac_cred_mmapped_drop_perms(td, newcred); 3431105694Srwatson mtx_unlock(&Giant); 3432105694Srwatson } 3433102136Srwatson 3434102136Srwatson crfree(newcred); /* Free revocation reference. */ 3435100979Srwatson crfree(oldcred); 3436105694Srwatson 3437105694Srwatsonout: 3438105694Srwatson mac_destroy_cred_label(&intlabel); 3439105694Srwatson return (error); 3440100979Srwatson} 3441100979Srwatson 3442100979Srwatson/* 3443100979Srwatson * MPSAFE 3444100979Srwatson */ 3445100979Srwatsonint 3446100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3447100979Srwatson{ 3448105694Srwatson char *elements, *buffer; 3449105694Srwatson struct label intlabel; 3450100979Srwatson struct file *fp; 3451105694Srwatson struct mac mac; 3452100979Srwatson struct vnode *vp; 3453100979Srwatson struct pipe *pipe; 3454105694Srwatson short label_type; 3455100979Srwatson int error; 3456100979Srwatson 3457105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3458105694Srwatson if (error) 3459105694Srwatson return (error); 3460100979Srwatson 3461105694Srwatson error = mac_check_structmac_consistent(&mac); 3462105694Srwatson if (error) 3463105694Srwatson return (error); 3464105694Srwatson 3465111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3466105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3467105694Srwatson if (error) { 3468105694Srwatson free(elements, M_MACTEMP); 3469105694Srwatson return (error); 3470105694Srwatson } 3471105694Srwatson 3472111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3473105694Srwatson mtx_lock(&Giant); /* VFS */ 3474107849Salfred error = fget(td, uap->fd, &fp); 3475100979Srwatson if (error) 3476100979Srwatson goto out; 3477100979Srwatson 3478105694Srwatson label_type = fp->f_type; 3479100979Srwatson switch (fp->f_type) { 3480100979Srwatson case DTYPE_FIFO: 3481100979Srwatson case DTYPE_VNODE: 3482116678Sphk vp = fp->f_vnode; 3483100979Srwatson 3484105694Srwatson mac_init_vnode_label(&intlabel); 3485105694Srwatson 3486100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3487105988Srwatson mac_copy_vnode_label(&vp->v_label, &intlabel); 3488100979Srwatson VOP_UNLOCK(vp, 0, td); 3489105694Srwatson 3490100979Srwatson break; 3491100979Srwatson case DTYPE_PIPE: 3492109153Sdillon pipe = fp->f_data; 3493105694Srwatson 3494105694Srwatson mac_init_pipe_label(&intlabel); 3495105694Srwatson 3496105694Srwatson PIPE_LOCK(pipe); 3497105694Srwatson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3498105694Srwatson PIPE_UNLOCK(pipe); 3499100979Srwatson break; 3500100979Srwatson default: 3501100979Srwatson error = EINVAL; 3502105694Srwatson fdrop(fp, td); 3503105694Srwatson goto out; 3504100979Srwatson } 3505105694Srwatson fdrop(fp, td); 3506100979Srwatson 3507105694Srwatson switch (label_type) { 3508105694Srwatson case DTYPE_FIFO: 3509105694Srwatson case DTYPE_VNODE: 3510105694Srwatson if (error == 0) 3511105694Srwatson error = mac_externalize_vnode_label(&intlabel, 3512111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3513105694Srwatson mac_destroy_vnode_label(&intlabel); 3514105694Srwatson break; 3515105694Srwatson case DTYPE_PIPE: 3516105694Srwatson error = mac_externalize_pipe_label(&intlabel, elements, 3517111119Simp buffer, mac.m_buflen, M_WAITOK); 3518105694Srwatson mac_destroy_pipe_label(&intlabel); 3519105694Srwatson break; 3520105694Srwatson default: 3521105694Srwatson panic("__mac_get_fd: corrupted label_type"); 3522105694Srwatson } 3523105694Srwatson 3524100979Srwatson if (error == 0) 3525105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3526100979Srwatson 3527105694Srwatsonout: 3528105694Srwatson mtx_unlock(&Giant); /* VFS */ 3529105694Srwatson free(buffer, M_MACTEMP); 3530105694Srwatson free(elements, M_MACTEMP); 3531100979Srwatson 3532100979Srwatson return (error); 3533100979Srwatson} 3534100979Srwatson 3535100979Srwatson/* 3536100979Srwatson * MPSAFE 3537100979Srwatson */ 3538100979Srwatsonint 3539100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3540100979Srwatson{ 3541105694Srwatson char *elements, *buffer; 3542100979Srwatson struct nameidata nd; 3543105694Srwatson struct label intlabel; 3544105694Srwatson struct mac mac; 3545100979Srwatson int error; 3546100979Srwatson 3547105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3548105694Srwatson if (error) 3549105694Srwatson return (error); 3550105694Srwatson 3551105694Srwatson error = mac_check_structmac_consistent(&mac); 3552105694Srwatson if (error) 3553105694Srwatson return (error); 3554105694Srwatson 3555111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3556105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3557105694Srwatson if (error) { 3558105694Srwatson free(elements, M_MACTEMP); 3559105694Srwatson return (error); 3560105694Srwatson } 3561105694Srwatson 3562111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3563105694Srwatson mtx_lock(&Giant); /* VFS */ 3564105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3565105694Srwatson td); 3566100979Srwatson error = namei(&nd); 3567100979Srwatson if (error) 3568100979Srwatson goto out; 3569100979Srwatson 3570105694Srwatson mac_init_vnode_label(&intlabel); 3571105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3572105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3573111119Simp mac.m_buflen, M_WAITOK); 3574105694Srwatson 3575100979Srwatson NDFREE(&nd, 0); 3576105694Srwatson mac_destroy_vnode_label(&intlabel); 3577105694Srwatson 3578105694Srwatson if (error == 0) 3579105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3580105694Srwatson 3581105694Srwatsonout: 3582105694Srwatson mtx_unlock(&Giant); /* VFS */ 3583105694Srwatson 3584105694Srwatson free(buffer, M_MACTEMP); 3585105694Srwatson free(elements, M_MACTEMP); 3586105694Srwatson 3587105694Srwatson return (error); 3588105694Srwatson} 3589105694Srwatson 3590105694Srwatson/* 3591105694Srwatson * MPSAFE 3592105694Srwatson */ 3593105694Srwatsonint 3594105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3595105694Srwatson{ 3596105694Srwatson char *elements, *buffer; 3597105694Srwatson struct nameidata nd; 3598105694Srwatson struct label intlabel; 3599105694Srwatson struct mac mac; 3600105694Srwatson int error; 3601105694Srwatson 3602105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3603100979Srwatson if (error) 3604105694Srwatson return (error); 3605105694Srwatson 3606105694Srwatson error = mac_check_structmac_consistent(&mac); 3607105694Srwatson if (error) 3608105694Srwatson return (error); 3609105694Srwatson 3610111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3611105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3612105694Srwatson if (error) { 3613105694Srwatson free(elements, M_MACTEMP); 3614105694Srwatson return (error); 3615105694Srwatson } 3616105694Srwatson 3617111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3618105694Srwatson mtx_lock(&Giant); /* VFS */ 3619105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3620105694Srwatson td); 3621105694Srwatson error = namei(&nd); 3622105694Srwatson if (error) 3623100979Srwatson goto out; 3624100979Srwatson 3625105694Srwatson mac_init_vnode_label(&intlabel); 3626105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3627105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3628111119Simp mac.m_buflen, M_WAITOK); 3629105694Srwatson NDFREE(&nd, 0); 3630105694Srwatson mac_destroy_vnode_label(&intlabel); 3631100979Srwatson 3632105694Srwatson if (error == 0) 3633105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3634105694Srwatson 3635100979Srwatsonout: 3636105694Srwatson mtx_unlock(&Giant); /* VFS */ 3637105694Srwatson 3638105694Srwatson free(buffer, M_MACTEMP); 3639105694Srwatson free(elements, M_MACTEMP); 3640105694Srwatson 3641100979Srwatson return (error); 3642100979Srwatson} 3643100979Srwatson 3644100979Srwatson/* 3645100979Srwatson * MPSAFE 3646100979Srwatson */ 3647100979Srwatsonint 3648100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3649100979Srwatson{ 3650105694Srwatson struct label intlabel; 3651105694Srwatson struct pipe *pipe; 3652100979Srwatson struct file *fp; 3653100979Srwatson struct mount *mp; 3654100979Srwatson struct vnode *vp; 3655105694Srwatson struct mac mac; 3656105694Srwatson char *buffer; 3657100979Srwatson int error; 3658100979Srwatson 3659105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3660100979Srwatson if (error) 3661105694Srwatson return (error); 3662100979Srwatson 3663105694Srwatson error = mac_check_structmac_consistent(&mac); 3664100979Srwatson if (error) 3665105694Srwatson return (error); 3666100979Srwatson 3667111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3668105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3669105694Srwatson if (error) { 3670105694Srwatson free(buffer, M_MACTEMP); 3671105694Srwatson return (error); 3672105694Srwatson } 3673105694Srwatson 3674105694Srwatson mtx_lock(&Giant); /* VFS */ 3675105694Srwatson 3676107849Salfred error = fget(td, uap->fd, &fp); 3677100979Srwatson if (error) 3678105694Srwatson goto out; 3679100979Srwatson 3680100979Srwatson switch (fp->f_type) { 3681100979Srwatson case DTYPE_FIFO: 3682100979Srwatson case DTYPE_VNODE: 3683105694Srwatson mac_init_vnode_label(&intlabel); 3684105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3685105694Srwatson if (error) { 3686105694Srwatson mac_destroy_vnode_label(&intlabel); 3687105694Srwatson break; 3688105694Srwatson } 3689105694Srwatson 3690116678Sphk vp = fp->f_vnode; 3691100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3692105694Srwatson if (error != 0) { 3693105694Srwatson mac_destroy_vnode_label(&intlabel); 3694100979Srwatson break; 3695105694Srwatson } 3696100979Srwatson 3697100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3698100979Srwatson error = vn_setlabel(vp, &intlabel, td->td_ucred); 3699100979Srwatson VOP_UNLOCK(vp, 0, td); 3700100979Srwatson vn_finished_write(mp); 3701105694Srwatson 3702105694Srwatson mac_destroy_vnode_label(&intlabel); 3703100979Srwatson break; 3704105694Srwatson 3705100979Srwatson case DTYPE_PIPE: 3706105694Srwatson mac_init_pipe_label(&intlabel); 3707105694Srwatson error = mac_internalize_pipe_label(&intlabel, buffer); 3708105694Srwatson if (error == 0) { 3709109153Sdillon pipe = fp->f_data; 3710105694Srwatson PIPE_LOCK(pipe); 3711105694Srwatson error = mac_pipe_label_set(td->td_ucred, pipe, 3712105694Srwatson &intlabel); 3713105694Srwatson PIPE_UNLOCK(pipe); 3714105694Srwatson } 3715105694Srwatson 3716105694Srwatson mac_destroy_pipe_label(&intlabel); 3717100979Srwatson break; 3718105694Srwatson 3719100979Srwatson default: 3720100979Srwatson error = EINVAL; 3721100979Srwatson } 3722100979Srwatson 3723100979Srwatson fdrop(fp, td); 3724105694Srwatsonout: 3725105694Srwatson mtx_unlock(&Giant); /* VFS */ 3726105694Srwatson 3727105694Srwatson free(buffer, M_MACTEMP); 3728105694Srwatson 3729100979Srwatson return (error); 3730100979Srwatson} 3731100979Srwatson 3732100979Srwatson/* 3733100979Srwatson * MPSAFE 3734100979Srwatson */ 3735100979Srwatsonint 3736100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3737100979Srwatson{ 3738105694Srwatson struct label intlabel; 3739100979Srwatson struct nameidata nd; 3740100979Srwatson struct mount *mp; 3741105694Srwatson struct mac mac; 3742105694Srwatson char *buffer; 3743100979Srwatson int error; 3744100979Srwatson 3745105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3746100979Srwatson if (error) 3747105694Srwatson return (error); 3748100979Srwatson 3749105694Srwatson error = mac_check_structmac_consistent(&mac); 3750100979Srwatson if (error) 3751105694Srwatson return (error); 3752100979Srwatson 3753111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3754105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3755105694Srwatson if (error) { 3756105694Srwatson free(buffer, M_MACTEMP); 3757105694Srwatson return (error); 3758105694Srwatson } 3759105694Srwatson 3760105694Srwatson mac_init_vnode_label(&intlabel); 3761105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3762105694Srwatson free(buffer, M_MACTEMP); 3763105694Srwatson if (error) { 3764105694Srwatson mac_destroy_vnode_label(&intlabel); 3765105694Srwatson return (error); 3766105694Srwatson } 3767105694Srwatson 3768105694Srwatson mtx_lock(&Giant); /* VFS */ 3769105694Srwatson 3770105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3771105694Srwatson td); 3772100979Srwatson error = namei(&nd); 3773105694Srwatson if (error == 0) { 3774105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3775105694Srwatson if (error == 0) 3776105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3777105694Srwatson td->td_ucred); 3778105694Srwatson vn_finished_write(mp); 3779105694Srwatson } 3780105694Srwatson 3781105694Srwatson NDFREE(&nd, 0); 3782105694Srwatson mtx_unlock(&Giant); /* VFS */ 3783105694Srwatson mac_destroy_vnode_label(&intlabel); 3784105694Srwatson 3785105694Srwatson return (error); 3786105694Srwatson} 3787105694Srwatson 3788105694Srwatson/* 3789105694Srwatson * MPSAFE 3790105694Srwatson */ 3791105694Srwatsonint 3792105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3793105694Srwatson{ 3794105694Srwatson struct label intlabel; 3795105694Srwatson struct nameidata nd; 3796105694Srwatson struct mount *mp; 3797105694Srwatson struct mac mac; 3798105694Srwatson char *buffer; 3799105694Srwatson int error; 3800105694Srwatson 3801105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3802100979Srwatson if (error) 3803105694Srwatson return (error); 3804105694Srwatson 3805105694Srwatson error = mac_check_structmac_consistent(&mac); 3806100979Srwatson if (error) 3807105694Srwatson return (error); 3808100979Srwatson 3809111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3810105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3811105694Srwatson if (error) { 3812105694Srwatson free(buffer, M_MACTEMP); 3813105694Srwatson return (error); 3814105694Srwatson } 3815105694Srwatson 3816105694Srwatson mac_init_vnode_label(&intlabel); 3817105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3818105694Srwatson free(buffer, M_MACTEMP); 3819105694Srwatson if (error) { 3820105694Srwatson mac_destroy_vnode_label(&intlabel); 3821105694Srwatson return (error); 3822105694Srwatson } 3823105694Srwatson 3824105694Srwatson mtx_lock(&Giant); /* VFS */ 3825105694Srwatson 3826105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3827105694Srwatson td); 3828105694Srwatson error = namei(&nd); 3829105694Srwatson if (error == 0) { 3830105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3831105694Srwatson if (error == 0) 3832105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3833105694Srwatson td->td_ucred); 3834105694Srwatson vn_finished_write(mp); 3835105694Srwatson } 3836105694Srwatson 3837100979Srwatson NDFREE(&nd, 0); 3838105694Srwatson mtx_unlock(&Giant); /* VFS */ 3839105694Srwatson mac_destroy_vnode_label(&intlabel); 3840105694Srwatson 3841100979Srwatson return (error); 3842100979Srwatson} 3843100979Srwatson 3844105694Srwatson/* 3845105694Srwatson * MPSAFE 3846105694Srwatson */ 3847102123Srwatsonint 3848102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3849102123Srwatson{ 3850102123Srwatson struct mac_policy_conf *mpc; 3851102123Srwatson char target[MAC_MAX_POLICY_NAME]; 3852114806Srwatson int entrycount, error; 3853102123Srwatson 3854107849Salfred error = copyinstr(uap->policy, target, sizeof(target), NULL); 3855102123Srwatson if (error) 3856102123Srwatson return (error); 3857102123Srwatson 3858102123Srwatson error = ENOSYS; 3859119494Srwatson LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { 3860102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3861102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3862102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3863107849Salfred uap->call, uap->arg); 3864102123Srwatson goto out; 3865102123Srwatson } 3866102123Srwatson } 3867102123Srwatson 3868114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { 3869114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3870114806Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3871114806Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3872114806Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3873114806Srwatson uap->call, uap->arg); 3874114806Srwatson break; 3875114806Srwatson } 3876114806Srwatson } 3877114806Srwatson mac_policy_list_unbusy(); 3878114806Srwatson } 3879102123Srwatsonout: 3880102123Srwatson return (error); 3881102123Srwatson} 3882102123Srwatson 3883100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3884100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3885100979Srwatson 3886100979Srwatson#else /* !MAC */ 3887100979Srwatson 3888100979Srwatsonint 3889105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3890105694Srwatson{ 3891105694Srwatson 3892105694Srwatson return (ENOSYS); 3893105694Srwatson} 3894105694Srwatson 3895105694Srwatsonint 3896100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3897100979Srwatson{ 3898100979Srwatson 3899100894Srwatson return (ENOSYS); 3900100894Srwatson} 3901100894Srwatson 3902100894Srwatsonint 3903100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3904100894Srwatson{ 3905100894Srwatson 3906100894Srwatson return (ENOSYS); 3907100894Srwatson} 3908100894Srwatson 3909100894Srwatsonint 3910100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3911100894Srwatson{ 3912100894Srwatson 3913100894Srwatson return (ENOSYS); 3914100894Srwatson} 3915100894Srwatson 3916100894Srwatsonint 3917100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3918100894Srwatson{ 3919100894Srwatson 3920100894Srwatson return (ENOSYS); 3921100894Srwatson} 3922100894Srwatson 3923100894Srwatsonint 3924105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3925105694Srwatson{ 3926105694Srwatson 3927105694Srwatson return (ENOSYS); 3928105694Srwatson} 3929105694Srwatson 3930105694Srwatsonint 3931100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3932100894Srwatson{ 3933100894Srwatson 3934100894Srwatson return (ENOSYS); 3935100894Srwatson} 3936100894Srwatson 3937100894Srwatsonint 3938100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3939100894Srwatson{ 3940100894Srwatson 3941100894Srwatson return (ENOSYS); 3942100894Srwatson} 3943100979Srwatson 3944102123Srwatsonint 3945105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3946105694Srwatson{ 3947105694Srwatson 3948105694Srwatson return (ENOSYS); 3949105694Srwatson} 3950105694Srwatson 3951105694Srwatsonint 3952102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3953102123Srwatson{ 3954102123Srwatson 3955102123Srwatson return (ENOSYS); 3956102123Srwatson} 3957102123Srwatson 3958105694Srwatson#endif 3959