mac_process.c revision 119184
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_process.c 119184 2003-08-20 19:16:49Z 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 1179105694Srwatson if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1180105694Srwatson return (EINVAL); 1181105694Srwatson 1182105694Srwatson return (0); 1183105694Srwatson} 1184105694Srwatson 1185105694Srwatsonstatic int 1186105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements, 1187105694Srwatson char *outbuf, size_t outbuflen, int flags) 1188105694Srwatson{ 1189104522Srwatson int error; 1190104522Srwatson 1191105694Srwatson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1192104522Srwatson 1193104522Srwatson return (error); 1194104522Srwatson} 1195104522Srwatson 1196104522Srwatsonstatic int 1197105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements, 1198105694Srwatson char *outbuf, size_t outbuflen, int flags) 1199104522Srwatson{ 1200104522Srwatson int error; 1201104522Srwatson 1202105694Srwatson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1203104522Srwatson 1204104522Srwatson return (error); 1205104522Srwatson} 1206104522Srwatson 1207105694Srwatsonstatic int 1208105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements, 1209105694Srwatson char *outbuf, size_t outbuflen, int flags) 1210105694Srwatson{ 1211105694Srwatson int error; 1212105694Srwatson 1213105694Srwatson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1214105694Srwatson 1215105694Srwatson return (error); 1216105694Srwatson} 1217105694Srwatson 1218105694Srwatsonstatic int 1219105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements, 1220105694Srwatson char *outbuf, size_t outbuflen, int flags) 1221105694Srwatson{ 1222105694Srwatson int error; 1223105694Srwatson 1224105694Srwatson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1225105694Srwatson 1226105694Srwatson return (error); 1227105694Srwatson} 1228105694Srwatson 1229105694Srwatsonstatic int 1230105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements, 1231105694Srwatson char *outbuf, size_t outbuflen, int flags) 1232105694Srwatson{ 1233105694Srwatson int error; 1234105694Srwatson 1235105694Srwatson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1236105694Srwatson 1237105694Srwatson return (error); 1238105694Srwatson} 1239105694Srwatson 1240105694Srwatsonstatic int 1241105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements, 1242105694Srwatson char *outbuf, size_t outbuflen, int flags) 1243105694Srwatson{ 1244105694Srwatson int error; 1245105694Srwatson 1246105694Srwatson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1247105694Srwatson 1248105694Srwatson return (error); 1249105694Srwatson} 1250105694Srwatson 1251105694Srwatsonstatic int 1252105694Srwatsonmac_internalize_cred_label(struct label *label, char *string) 1253105694Srwatson{ 1254105694Srwatson int error; 1255105694Srwatson 1256105694Srwatson MAC_INTERNALIZE(cred_label, label, string); 1257105694Srwatson 1258105694Srwatson return (error); 1259105694Srwatson} 1260105694Srwatson 1261105694Srwatsonstatic int 1262105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string) 1263105694Srwatson{ 1264105694Srwatson int error; 1265105694Srwatson 1266105694Srwatson MAC_INTERNALIZE(ifnet_label, label, string); 1267105694Srwatson 1268105694Srwatson return (error); 1269105694Srwatson} 1270105694Srwatson 1271105694Srwatsonstatic int 1272105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string) 1273105694Srwatson{ 1274105694Srwatson int error; 1275105694Srwatson 1276105694Srwatson MAC_INTERNALIZE(pipe_label, label, string); 1277105694Srwatson 1278105694Srwatson return (error); 1279105694Srwatson} 1280105694Srwatson 1281105694Srwatsonstatic int 1282105694Srwatsonmac_internalize_socket_label(struct label *label, char *string) 1283105694Srwatson{ 1284105694Srwatson int error; 1285105694Srwatson 1286105694Srwatson MAC_INTERNALIZE(socket_label, label, string); 1287105694Srwatson 1288105694Srwatson return (error); 1289105694Srwatson} 1290105694Srwatson 1291105694Srwatsonstatic int 1292105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string) 1293105694Srwatson{ 1294105694Srwatson int error; 1295105694Srwatson 1296105694Srwatson MAC_INTERNALIZE(vnode_label, label, string); 1297105694Srwatson 1298105694Srwatson return (error); 1299105694Srwatson} 1300105694Srwatson 1301104522Srwatson/* 1302104522Srwatson * Initialize MAC label for the first kernel process, from which other 1303104522Srwatson * kernel processes and threads are spawned. 1304104522Srwatson */ 1305104521Srwatsonvoid 1306104522Srwatsonmac_create_proc0(struct ucred *cred) 1307104522Srwatson{ 1308104522Srwatson 1309104522Srwatson MAC_PERFORM(create_proc0, cred); 1310104522Srwatson} 1311104522Srwatson 1312104522Srwatson/* 1313104522Srwatson * Initialize MAC label for the first userland process, from which other 1314104522Srwatson * userland processes and threads are spawned. 1315104522Srwatson */ 1316104522Srwatsonvoid 1317104522Srwatsonmac_create_proc1(struct ucred *cred) 1318104522Srwatson{ 1319104522Srwatson 1320104522Srwatson MAC_PERFORM(create_proc1, cred); 1321104522Srwatson} 1322104522Srwatson 1323104522Srwatsonvoid 1324104522Srwatsonmac_thread_userret(struct thread *td) 1325104522Srwatson{ 1326104522Srwatson 1327104522Srwatson MAC_PERFORM(thread_userret, td); 1328104522Srwatson} 1329104522Srwatson 1330104522Srwatson/* 1331104522Srwatson * When a new process is created, its label must be initialized. Generally, 1332104522Srwatson * this involves inheritence from the parent process, modulo possible 1333104522Srwatson * deltas. This function allows that processing to take place. 1334104522Srwatson */ 1335104522Srwatsonvoid 1336104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1337104522Srwatson{ 1338104522Srwatson 1339104522Srwatson MAC_PERFORM(create_cred, parent_cred, child_cred); 1340104522Srwatson} 1341104522Srwatson 1342104522Srwatsonvoid 1343107698Srwatsonmac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 1344107698Srwatson struct vnode *vp) 1345100979Srwatson{ 1346100979Srwatson 1347107698Srwatson MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp, 1348107698Srwatson &vp->v_label); 1349100979Srwatson} 1350100979Srwatson 1351100979Srwatsonvoid 1352105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1353105988Srwatson struct vnode *vp) 1354100979Srwatson{ 1355100979Srwatson 1356105988Srwatson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1357105988Srwatson &de->de_label, vp, &vp->v_label); 1358100979Srwatson} 1359100979Srwatson 1360105988Srwatsonint 1361105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1362100979Srwatson{ 1363100979Srwatson int error; 1364100979Srwatson 1365105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1366100979Srwatson 1367105988Srwatson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1368105988Srwatson &vp->v_label); 1369100979Srwatson 1370100979Srwatson return (error); 1371100979Srwatson} 1372100979Srwatson 1373100979Srwatsonvoid 1374105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1375100979Srwatson{ 1376100979Srwatson 1377105988Srwatson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1378105988Srwatson &vp->v_label); 1379100979Srwatson} 1380100979Srwatson 1381100979Srwatsonint 1382105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1383105988Srwatson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1384100979Srwatson{ 1385105988Srwatson int error; 1386100979Srwatson 1387105988Srwatson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1388105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1389100979Srwatson 1390105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1391105988Srwatson if (error == EOPNOTSUPP) { 1392105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1393105988Srwatson if (ea_warn_once == 0) { 1394105988Srwatson printf("Warning: transactions not supported " 1395105988Srwatson "in EA write.\n"); 1396105988Srwatson ea_warn_once = 1; 1397105988Srwatson } 1398105988Srwatson } else if (error) 1399100979Srwatson return (error); 1400100979Srwatson 1401105988Srwatson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1402105988Srwatson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1403100979Srwatson 1404105988Srwatson if (error) { 1405105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1406100979Srwatson return (error); 1407100979Srwatson } 1408100979Srwatson 1409105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1410100979Srwatson 1411105988Srwatson if (error == EOPNOTSUPP) 1412105988Srwatson error = 0; /* XXX */ 1413100979Srwatson 1414100979Srwatson return (error); 1415100979Srwatson} 1416100979Srwatson 1417100979Srwatsonstatic int 1418105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1419105988Srwatson struct label *intlabel) 1420100979Srwatson{ 1421100979Srwatson int error; 1422100979Srwatson 1423105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1424100979Srwatson 1425105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1426105988Srwatson if (error == EOPNOTSUPP) { 1427105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1428105988Srwatson if (ea_warn_once == 0) { 1429105988Srwatson printf("Warning: transactions not supported " 1430105988Srwatson "in EA write.\n"); 1431105988Srwatson ea_warn_once = 1; 1432105988Srwatson } 1433105988Srwatson } else if (error) 1434105988Srwatson return (error); 1435100979Srwatson 1436105988Srwatson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1437100979Srwatson 1438105988Srwatson if (error) { 1439105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1440100979Srwatson return (error); 1441100979Srwatson } 1442100979Srwatson 1443105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1444100979Srwatson 1445105988Srwatson if (error == EOPNOTSUPP) 1446105988Srwatson error = 0; /* XXX */ 1447100979Srwatson 1448105988Srwatson return (error); 1449100979Srwatson} 1450100979Srwatson 1451106468Srwatsonint 1452106468Srwatsonmac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1453106468Srwatson struct label *execlabelstorage) 1454106468Srwatson{ 1455106468Srwatson struct mac mac; 1456106468Srwatson char *buffer; 1457106468Srwatson int error; 1458106468Srwatson 1459106468Srwatson if (mac_p == NULL) 1460106468Srwatson return (0); 1461106468Srwatson 1462106468Srwatson error = copyin(mac_p, &mac, sizeof(mac)); 1463106468Srwatson if (error) 1464106468Srwatson return (error); 1465106468Srwatson 1466106468Srwatson error = mac_check_structmac_consistent(&mac); 1467106468Srwatson if (error) 1468106468Srwatson return (error); 1469106468Srwatson 1470111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1471106468Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1472106468Srwatson if (error) { 1473106468Srwatson free(buffer, M_MACTEMP); 1474106468Srwatson return (error); 1475106468Srwatson } 1476106468Srwatson 1477106468Srwatson mac_init_cred_label(execlabelstorage); 1478106468Srwatson error = mac_internalize_cred_label(execlabelstorage, buffer); 1479106468Srwatson free(buffer, M_MACTEMP); 1480106468Srwatson if (error) { 1481106468Srwatson mac_destroy_cred_label(execlabelstorage); 1482106468Srwatson return (error); 1483106468Srwatson } 1484106468Srwatson imgp->execlabel = execlabelstorage; 1485106468Srwatson return (0); 1486106468Srwatson} 1487106468Srwatson 1488100979Srwatsonvoid 1489106468Srwatsonmac_execve_exit(struct image_params *imgp) 1490100979Srwatson{ 1491106468Srwatson if (imgp->execlabel != NULL) 1492106468Srwatson mac_destroy_cred_label(imgp->execlabel); 1493106468Srwatson} 1494100979Srwatson 1495106468Srwatsonvoid 1496106468Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1497106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1498106468Srwatson{ 1499106468Srwatson 1500100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1501100979Srwatson 1502106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1503106460Srwatson return; 1504106460Srwatson 1505106468Srwatson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1506106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1507100979Srwatson} 1508100979Srwatson 1509100979Srwatsonint 1510106468Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp, 1511106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1512100979Srwatson{ 1513105988Srwatson int result; 1514100979Srwatson 1515106460Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1516106460Srwatson 1517106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1518106460Srwatson return (0); 1519106460Srwatson 1520100979Srwatson result = 0; 1521106468Srwatson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1522106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1523100979Srwatson 1524100979Srwatson return (result); 1525100979Srwatson} 1526100979Srwatson 1527100979Srwatsonint 1528106212Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1529100979Srwatson{ 1530100979Srwatson int error; 1531100979Srwatson 1532100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1533100979Srwatson 1534100979Srwatson if (!mac_enforce_fs) 1535100979Srwatson return (0); 1536100979Srwatson 1537106212Srwatson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1538100979Srwatson return (error); 1539100979Srwatson} 1540100979Srwatson 1541100979Srwatsonint 1542100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1543100979Srwatson{ 1544100979Srwatson int error; 1545100979Srwatson 1546100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1547100979Srwatson 1548100979Srwatson if (!mac_enforce_fs) 1549100979Srwatson return (0); 1550100979Srwatson 1551100979Srwatson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1552100979Srwatson return (error); 1553100979Srwatson} 1554100979Srwatson 1555100979Srwatsonint 1556100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1557100979Srwatson{ 1558100979Srwatson int error; 1559100979Srwatson 1560100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1561100979Srwatson 1562100979Srwatson if (!mac_enforce_fs) 1563100979Srwatson return (0); 1564100979Srwatson 1565100979Srwatson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1566100979Srwatson return (error); 1567100979Srwatson} 1568100979Srwatson 1569100979Srwatsonint 1570100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1571100979Srwatson struct componentname *cnp, struct vattr *vap) 1572100979Srwatson{ 1573100979Srwatson int error; 1574100979Srwatson 1575100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1576100979Srwatson 1577100979Srwatson if (!mac_enforce_fs) 1578100979Srwatson return (0); 1579100979Srwatson 1580100979Srwatson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1581100979Srwatson return (error); 1582100979Srwatson} 1583100979Srwatson 1584100979Srwatsonint 1585100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1586100979Srwatson struct componentname *cnp) 1587100979Srwatson{ 1588100979Srwatson int error; 1589100979Srwatson 1590100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1591100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1592100979Srwatson 1593100979Srwatson if (!mac_enforce_fs) 1594100979Srwatson return (0); 1595100979Srwatson 1596100979Srwatson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1597100979Srwatson &vp->v_label, cnp); 1598100979Srwatson return (error); 1599100979Srwatson} 1600100979Srwatson 1601100979Srwatsonint 1602100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1603100979Srwatson acl_type_t type) 1604100979Srwatson{ 1605100979Srwatson int error; 1606100979Srwatson 1607100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1608100979Srwatson 1609100979Srwatson if (!mac_enforce_fs) 1610100979Srwatson return (0); 1611100979Srwatson 1612100979Srwatson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1613100979Srwatson return (error); 1614100979Srwatson} 1615100979Srwatson 1616100979Srwatsonint 1617106468Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1618106468Srwatson struct image_params *imgp) 1619100979Srwatson{ 1620100979Srwatson int error; 1621100979Srwatson 1622102102Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1623102102Srwatson 1624100979Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1625100979Srwatson return (0); 1626100979Srwatson 1627106647Srwatson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1628106647Srwatson imgp->execlabel); 1629100979Srwatson 1630100979Srwatson return (error); 1631100979Srwatson} 1632100979Srwatson 1633100979Srwatsonint 1634100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1635100979Srwatson{ 1636100979Srwatson int error; 1637100979Srwatson 1638100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1639100979Srwatson 1640100979Srwatson if (!mac_enforce_fs) 1641100979Srwatson return (0); 1642100979Srwatson 1643100979Srwatson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1644100979Srwatson return (error); 1645100979Srwatson} 1646100979Srwatson 1647100979Srwatsonint 1648100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1649100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1650100979Srwatson{ 1651100979Srwatson int error; 1652100979Srwatson 1653100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1654100979Srwatson 1655100979Srwatson if (!mac_enforce_fs) 1656100979Srwatson return (0); 1657100979Srwatson 1658100979Srwatson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1659100979Srwatson attrnamespace, name, uio); 1660100979Srwatson return (error); 1661100979Srwatson} 1662100979Srwatson 1663100979Srwatsonint 1664104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1665104529Srwatson struct vnode *vp, struct componentname *cnp) 1666104529Srwatson{ 1667104529Srwatson int error; 1668104529Srwatson 1669104529Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1670104529Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1671104529Srwatson 1672104529Srwatson if (!mac_enforce_fs) 1673104529Srwatson return (0); 1674104529Srwatson 1675104529Srwatson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1676104529Srwatson &vp->v_label, cnp); 1677104529Srwatson return (error); 1678104529Srwatson} 1679104529Srwatson 1680104529Srwatsonint 1681100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1682100979Srwatson struct componentname *cnp) 1683100979Srwatson{ 1684100979Srwatson int error; 1685100979Srwatson 1686100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1687100979Srwatson 1688100979Srwatson if (!mac_enforce_fs) 1689100979Srwatson return (0); 1690100979Srwatson 1691100979Srwatson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1692100979Srwatson return (error); 1693100979Srwatson} 1694100979Srwatson 1695104546Srwatsonint 1696104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1697100979Srwatson{ 1698104546Srwatson int error; 1699100979Srwatson 1700104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1701103514Srwatson 1702104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1703104546Srwatson return (0); 1704104546Srwatson 1705104546Srwatson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1706104546Srwatson return (error); 1707100979Srwatson} 1708100979Srwatson 1709104546Srwatsonvoid 1710104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1711104546Srwatson{ 1712104546Srwatson int result = *prot; 1713104546Srwatson 1714104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1715104546Srwatson 1716104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1717104546Srwatson return; 1718104546Srwatson 1719104546Srwatson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1720104546Srwatson &result); 1721104546Srwatson 1722104546Srwatson *prot = result; 1723104546Srwatson} 1724104546Srwatson 1725100979Srwatsonint 1726104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1727104546Srwatson{ 1728104546Srwatson int error; 1729104546Srwatson 1730104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1731104546Srwatson 1732104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1733104546Srwatson return (0); 1734104546Srwatson 1735104546Srwatson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1736104546Srwatson return (error); 1737104546Srwatson} 1738104546Srwatson 1739104546Srwatsonint 1740106212Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1741100979Srwatson{ 1742100979Srwatson int error; 1743100979Srwatson 1744102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1745102112Srwatson 1746100979Srwatson if (!mac_enforce_fs) 1747100979Srwatson return (0); 1748100979Srwatson 1749102112Srwatson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1750102112Srwatson return (error); 1751102112Srwatson} 1752102112Srwatson 1753102112Srwatsonint 1754102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1755102129Srwatson struct vnode *vp) 1756102112Srwatson{ 1757102112Srwatson int error; 1758102112Srwatson 1759102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1760102112Srwatson 1761102112Srwatson if (!mac_enforce_fs) 1762102112Srwatson return (0); 1763102112Srwatson 1764102129Srwatson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1765102129Srwatson &vp->v_label); 1766100979Srwatson 1767100979Srwatson return (error); 1768100979Srwatson} 1769100979Srwatson 1770100979Srwatsonint 1771102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1772102129Srwatson struct vnode *vp) 1773100979Srwatson{ 1774100979Srwatson int error; 1775100979Srwatson 1776102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1777100979Srwatson 1778100979Srwatson if (!mac_enforce_fs) 1779100979Srwatson return (0); 1780100979Srwatson 1781102129Srwatson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1782102129Srwatson &vp->v_label); 1783102112Srwatson 1784100979Srwatson return (error); 1785100979Srwatson} 1786100979Srwatson 1787100979Srwatsonint 1788100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1789100979Srwatson{ 1790100979Srwatson int error; 1791100979Srwatson 1792100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1793100979Srwatson 1794100979Srwatson if (!mac_enforce_fs) 1795100979Srwatson return (0); 1796100979Srwatson 1797100979Srwatson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1798100979Srwatson return (error); 1799100979Srwatson} 1800100979Srwatson 1801100979Srwatsonint 1802100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1803100979Srwatson{ 1804100979Srwatson int error; 1805100979Srwatson 1806100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1807100979Srwatson 1808100979Srwatson if (!mac_enforce_fs) 1809100979Srwatson return (0); 1810100979Srwatson 1811100979Srwatson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1812100979Srwatson return (error); 1813100979Srwatson} 1814100979Srwatson 1815100979Srwatsonstatic int 1816100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1817100979Srwatson struct label *newlabel) 1818100979Srwatson{ 1819100979Srwatson int error; 1820100979Srwatson 1821100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1822100979Srwatson 1823100979Srwatson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1824100979Srwatson 1825100979Srwatson return (error); 1826100979Srwatson} 1827100979Srwatson 1828100979Srwatsonint 1829100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1830100979Srwatson struct vnode *vp, struct componentname *cnp) 1831100979Srwatson{ 1832100979Srwatson int error; 1833100979Srwatson 1834100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1835100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1836100979Srwatson 1837100979Srwatson if (!mac_enforce_fs) 1838100979Srwatson return (0); 1839100979Srwatson 1840100979Srwatson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1841100979Srwatson &vp->v_label, cnp); 1842100979Srwatson return (error); 1843100979Srwatson} 1844100979Srwatson 1845100979Srwatsonint 1846100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1847100979Srwatson struct vnode *vp, int samedir, struct componentname *cnp) 1848100979Srwatson{ 1849100979Srwatson int error; 1850100979Srwatson 1851100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1852100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1853100979Srwatson 1854100979Srwatson if (!mac_enforce_fs) 1855100979Srwatson return (0); 1856100979Srwatson 1857100979Srwatson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1858100979Srwatson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1859100979Srwatson return (error); 1860100979Srwatson} 1861100979Srwatson 1862100979Srwatsonint 1863100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1864100979Srwatson{ 1865100979Srwatson int error; 1866100979Srwatson 1867100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1868100979Srwatson 1869100979Srwatson if (!mac_enforce_fs) 1870100979Srwatson return (0); 1871100979Srwatson 1872100979Srwatson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1873100979Srwatson return (error); 1874100979Srwatson} 1875100979Srwatson 1876100979Srwatsonint 1877100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1878100979Srwatson struct acl *acl) 1879100979Srwatson{ 1880100979Srwatson int error; 1881100979Srwatson 1882100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1883100979Srwatson 1884100979Srwatson if (!mac_enforce_fs) 1885100979Srwatson return (0); 1886100979Srwatson 1887100979Srwatson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1888100979Srwatson return (error); 1889100979Srwatson} 1890100979Srwatson 1891100979Srwatsonint 1892100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1893100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1894100979Srwatson{ 1895100979Srwatson int error; 1896100979Srwatson 1897100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1898100979Srwatson 1899100979Srwatson if (!mac_enforce_fs) 1900100979Srwatson return (0); 1901100979Srwatson 1902100979Srwatson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1903100979Srwatson attrnamespace, name, uio); 1904100979Srwatson return (error); 1905100979Srwatson} 1906100979Srwatson 1907100979Srwatsonint 1908100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1909100979Srwatson{ 1910100979Srwatson int error; 1911100979Srwatson 1912100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1913100979Srwatson 1914100979Srwatson if (!mac_enforce_fs) 1915100979Srwatson return (0); 1916100979Srwatson 1917100979Srwatson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1918100979Srwatson return (error); 1919100979Srwatson} 1920100979Srwatson 1921100979Srwatsonint 1922100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1923100979Srwatson{ 1924100979Srwatson int error; 1925100979Srwatson 1926100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1927100979Srwatson 1928100979Srwatson if (!mac_enforce_fs) 1929100979Srwatson return (0); 1930100979Srwatson 1931100979Srwatson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1932100979Srwatson return (error); 1933100979Srwatson} 1934100979Srwatson 1935100979Srwatsonint 1936100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1937100979Srwatson gid_t gid) 1938100979Srwatson{ 1939100979Srwatson int error; 1940100979Srwatson 1941100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1942100979Srwatson 1943100979Srwatson if (!mac_enforce_fs) 1944100979Srwatson return (0); 1945100979Srwatson 1946100979Srwatson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1947100979Srwatson return (error); 1948100979Srwatson} 1949100979Srwatson 1950100979Srwatsonint 1951100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1952100979Srwatson struct timespec atime, struct timespec mtime) 1953100979Srwatson{ 1954100979Srwatson int error; 1955100979Srwatson 1956100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1957100979Srwatson 1958100979Srwatson if (!mac_enforce_fs) 1959100979Srwatson return (0); 1960100979Srwatson 1961100979Srwatson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1962100979Srwatson mtime); 1963100979Srwatson return (error); 1964100979Srwatson} 1965100979Srwatson 1966100979Srwatsonint 1967102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1968102129Srwatson struct vnode *vp) 1969100979Srwatson{ 1970100979Srwatson int error; 1971100979Srwatson 1972100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 1973100979Srwatson 1974100979Srwatson if (!mac_enforce_fs) 1975100979Srwatson return (0); 1976100979Srwatson 1977102129Srwatson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 1978102129Srwatson &vp->v_label); 1979100979Srwatson return (error); 1980100979Srwatson} 1981100979Srwatson 1982102112Srwatsonint 1983102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1984102129Srwatson struct vnode *vp) 1985102112Srwatson{ 1986102112Srwatson int error; 1987102112Srwatson 1988102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 1989102112Srwatson 1990102112Srwatson if (!mac_enforce_fs) 1991102112Srwatson return (0); 1992102112Srwatson 1993102129Srwatson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 1994102129Srwatson &vp->v_label); 1995102112Srwatson 1996102112Srwatson return (error); 1997102112Srwatson} 1998102112Srwatson 1999100979Srwatson/* 2000100979Srwatson * When relabeling a process, call out to the policies for the maximum 2001100979Srwatson * permission allowed for each object type we know about in its 2002100979Srwatson * memory space, and revoke access (in the least surprising ways we 2003100979Srwatson * know) when necessary. The process lock is not held here. 2004100979Srwatson */ 2005107271Srwatsonvoid 2006100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2007100979Srwatson{ 2008100979Srwatson 2009100979Srwatson /* XXX freeze all other threads */ 2010100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2011100979Srwatson &td->td_proc->p_vmspace->vm_map); 2012100979Srwatson /* XXX allow other threads to continue */ 2013100979Srwatson} 2014100979Srwatson 2015100979Srwatsonstatic __inline const char * 2016100979Srwatsonprot2str(vm_prot_t prot) 2017100979Srwatson{ 2018100979Srwatson 2019100979Srwatson switch (prot & VM_PROT_ALL) { 2020100979Srwatson case VM_PROT_READ: 2021100979Srwatson return ("r--"); 2022100979Srwatson case VM_PROT_READ | VM_PROT_WRITE: 2023100979Srwatson return ("rw-"); 2024100979Srwatson case VM_PROT_READ | VM_PROT_EXECUTE: 2025100979Srwatson return ("r-x"); 2026100979Srwatson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2027100979Srwatson return ("rwx"); 2028100979Srwatson case VM_PROT_WRITE: 2029100979Srwatson return ("-w-"); 2030100979Srwatson case VM_PROT_EXECUTE: 2031100979Srwatson return ("--x"); 2032100979Srwatson case VM_PROT_WRITE | VM_PROT_EXECUTE: 2033100979Srwatson return ("-wx"); 2034100979Srwatson default: 2035100979Srwatson return ("---"); 2036100979Srwatson } 2037100979Srwatson} 2038100979Srwatson 2039100979Srwatsonstatic void 2040100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2041100979Srwatson struct vm_map *map) 2042100979Srwatson{ 2043100979Srwatson struct vm_map_entry *vme; 2044104546Srwatson int result; 2045104546Srwatson vm_prot_t revokeperms; 2046100979Srwatson vm_object_t object; 2047100979Srwatson vm_ooffset_t offset; 2048100979Srwatson struct vnode *vp; 2049100979Srwatson 2050103136Srwatson if (!mac_mmap_revocation) 2051103136Srwatson return; 2052103136Srwatson 2053100979Srwatson vm_map_lock_read(map); 2054100979Srwatson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2055100979Srwatson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2056100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2057100979Srwatson vme->object.sub_map); 2058100979Srwatson continue; 2059100979Srwatson } 2060100979Srwatson /* 2061100979Srwatson * Skip over entries that obviously are not shared. 2062100979Srwatson */ 2063100979Srwatson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2064100979Srwatson !vme->max_protection) 2065100979Srwatson continue; 2066100979Srwatson /* 2067100979Srwatson * Drill down to the deepest backing object. 2068100979Srwatson */ 2069100979Srwatson offset = vme->offset; 2070100979Srwatson object = vme->object.vm_object; 2071100979Srwatson if (object == NULL) 2072100979Srwatson continue; 2073100979Srwatson while (object->backing_object != NULL) { 2074100979Srwatson object = object->backing_object; 2075100979Srwatson offset += object->backing_object_offset; 2076100979Srwatson } 2077100979Srwatson /* 2078100979Srwatson * At the moment, vm_maps and objects aren't considered 2079100979Srwatson * by the MAC system, so only things with backing by a 2080100979Srwatson * normal object (read: vnodes) are checked. 2081100979Srwatson */ 2082100979Srwatson if (object->type != OBJT_VNODE) 2083100979Srwatson continue; 2084100979Srwatson vp = (struct vnode *)object->handle; 2085100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2086104546Srwatson result = vme->max_protection; 2087104546Srwatson mac_check_vnode_mmap_downgrade(cred, vp, &result); 2088100979Srwatson VOP_UNLOCK(vp, 0, td); 2089100979Srwatson /* 2090100979Srwatson * Find out what maximum protection we may be allowing 2091100979Srwatson * now but a policy needs to get removed. 2092100979Srwatson */ 2093100979Srwatson revokeperms = vme->max_protection & ~result; 2094100979Srwatson if (!revokeperms) 2095100979Srwatson continue; 2096102949Sbde printf("pid %ld: revoking %s perms from %#lx:%ld " 2097102949Sbde "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2098102949Sbde prot2str(revokeperms), (u_long)vme->start, 2099102949Sbde (long)(vme->end - vme->start), 2100100979Srwatson prot2str(vme->max_protection), prot2str(vme->protection)); 2101100979Srwatson vm_map_lock_upgrade(map); 2102100979Srwatson /* 2103100979Srwatson * This is the really simple case: if a map has more 2104100979Srwatson * max_protection than is allowed, but it's not being 2105100979Srwatson * actually used (that is, the current protection is 2106100979Srwatson * still allowed), we can just wipe it out and do 2107100979Srwatson * nothing more. 2108100979Srwatson */ 2109100979Srwatson if ((vme->protection & revokeperms) == 0) { 2110100979Srwatson vme->max_protection -= revokeperms; 2111100979Srwatson } else { 2112100979Srwatson if (revokeperms & VM_PROT_WRITE) { 2113100979Srwatson /* 2114100979Srwatson * In the more complicated case, flush out all 2115100979Srwatson * pending changes to the object then turn it 2116100979Srwatson * copy-on-write. 2117100979Srwatson */ 2118100979Srwatson vm_object_reference(object); 2119100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2120113955Salc VM_OBJECT_LOCK(object); 2121100979Srwatson vm_object_page_clean(object, 2122100979Srwatson OFF_TO_IDX(offset), 2123100979Srwatson OFF_TO_IDX(offset + vme->end - vme->start + 2124100979Srwatson PAGE_MASK), 2125100979Srwatson OBJPC_SYNC); 2126113955Salc VM_OBJECT_UNLOCK(object); 2127100979Srwatson VOP_UNLOCK(vp, 0, td); 2128100979Srwatson vm_object_deallocate(object); 2129100979Srwatson /* 2130100979Srwatson * Why bother if there's no read permissions 2131100979Srwatson * anymore? For the rest, we need to leave 2132100979Srwatson * the write permissions on for COW, or 2133100979Srwatson * remove them entirely if configured to. 2134100979Srwatson */ 2135100979Srwatson if (!mac_mmap_revocation_via_cow) { 2136100979Srwatson vme->max_protection &= ~VM_PROT_WRITE; 2137100979Srwatson vme->protection &= ~VM_PROT_WRITE; 2138100979Srwatson } if ((revokeperms & VM_PROT_READ) == 0) 2139100979Srwatson vme->eflags |= MAP_ENTRY_COW | 2140100979Srwatson MAP_ENTRY_NEEDS_COPY; 2141100979Srwatson } 2142100979Srwatson if (revokeperms & VM_PROT_EXECUTE) { 2143100979Srwatson vme->max_protection &= ~VM_PROT_EXECUTE; 2144100979Srwatson vme->protection &= ~VM_PROT_EXECUTE; 2145100979Srwatson } 2146100979Srwatson if (revokeperms & VM_PROT_READ) { 2147100979Srwatson vme->max_protection = 0; 2148100979Srwatson vme->protection = 0; 2149100979Srwatson } 2150100979Srwatson pmap_protect(map->pmap, vme->start, vme->end, 2151100979Srwatson vme->protection & ~revokeperms); 2152100979Srwatson vm_map_simplify_entry(map, vme); 2153100979Srwatson } 2154100979Srwatson vm_map_lock_downgrade(map); 2155100979Srwatson } 2156100979Srwatson vm_map_unlock_read(map); 2157100979Srwatson} 2158100979Srwatson 2159100979Srwatson/* 2160100979Srwatson * When the subject's label changes, it may require revocation of privilege 2161100979Srwatson * to mapped objects. This can't be done on-the-fly later with a unified 2162100979Srwatson * buffer cache. 2163100979Srwatson */ 2164100979Srwatsonstatic void 2165100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel) 2166100979Srwatson{ 2167100979Srwatson 2168100979Srwatson MAC_PERFORM(relabel_cred, cred, newlabel); 2169100979Srwatson} 2170100979Srwatson 2171100979Srwatsonvoid 2172100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2173100979Srwatson{ 2174100979Srwatson 2175100979Srwatson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2176100979Srwatson} 2177100979Srwatson 2178100979Srwatsonvoid 2179100979Srwatsonmac_create_ifnet(struct ifnet *ifnet) 2180100979Srwatson{ 2181100979Srwatson 2182100979Srwatson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2183100979Srwatson} 2184100979Srwatson 2185100979Srwatsonvoid 2186100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2187100979Srwatson{ 2188100979Srwatson 2189100979Srwatson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2190100979Srwatson} 2191100979Srwatson 2192100979Srwatsonvoid 2193100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket) 2194100979Srwatson{ 2195100979Srwatson 2196100979Srwatson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2197100979Srwatson} 2198100979Srwatson 2199100979Srwatsonvoid 2200100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe) 2201100979Srwatson{ 2202100979Srwatson 2203100979Srwatson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2204100979Srwatson} 2205100979Srwatson 2206100979Srwatsonvoid 2207100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket, 2208100979Srwatson struct socket *newsocket) 2209100979Srwatson{ 2210100979Srwatson 2211100979Srwatson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2212100979Srwatson newsocket, &newsocket->so_label); 2213100979Srwatson} 2214100979Srwatson 2215100979Srwatsonstatic void 2216100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket, 2217100979Srwatson struct label *newlabel) 2218100979Srwatson{ 2219100979Srwatson 2220100979Srwatson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2221100979Srwatson} 2222100979Srwatson 2223100979Srwatsonstatic void 2224100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2225100979Srwatson{ 2226100979Srwatson 2227100979Srwatson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2228100979Srwatson} 2229100979Srwatson 2230100979Srwatsonvoid 2231100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2232100979Srwatson{ 2233113482Srwatson struct label *label; 2234100979Srwatson 2235113482Srwatson label = mbuf_to_label(mbuf); 2236113482Srwatson 2237113482Srwatson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 2238113482Srwatson &socket->so_peerlabel); 2239100979Srwatson} 2240100979Srwatson 2241100979Srwatsonvoid 2242100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket, 2243100979Srwatson struct socket *newsocket) 2244100979Srwatson{ 2245100979Srwatson 2246100979Srwatson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2247100979Srwatson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2248100979Srwatson} 2249100979Srwatson 2250100979Srwatsonvoid 2251100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2252100979Srwatson{ 2253113482Srwatson struct label *label; 2254100979Srwatson 2255113482Srwatson label = mbuf_to_label(datagram); 2256113482Srwatson 2257100979Srwatson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2258113482Srwatson datagram, label); 2259100979Srwatson} 2260100979Srwatson 2261100979Srwatsonvoid 2262100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2263100979Srwatson{ 2264113482Srwatson struct label *datagramlabel, *fragmentlabel; 2265100979Srwatson 2266113482Srwatson datagramlabel = mbuf_to_label(datagram); 2267113482Srwatson fragmentlabel = mbuf_to_label(fragment); 2268113482Srwatson 2269113482Srwatson MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 2270113482Srwatson fragmentlabel); 2271100979Srwatson} 2272100979Srwatson 2273100979Srwatsonvoid 2274100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2275100979Srwatson{ 2276113482Srwatson struct label *label; 2277100979Srwatson 2278113482Srwatson label = mbuf_to_label(fragment); 2279113482Srwatson 2280113482Srwatson MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label); 2281100979Srwatson} 2282100979Srwatson 2283100979Srwatsonvoid 2284100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2285100979Srwatson{ 2286113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2287100979Srwatson 2288113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2289113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2290113482Srwatson 2291113482Srwatson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 2292113482Srwatson newmbuflabel); 2293100979Srwatson} 2294100979Srwatson 2295100979Srwatsonvoid 2296100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2297100979Srwatson{ 2298113482Srwatson struct label *label; 2299100979Srwatson 2300113482Srwatson label = mbuf_to_label(mbuf); 2301113482Srwatson 2302100979Srwatson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2303113482Srwatson label); 2304100979Srwatson} 2305100979Srwatson 2306100979Srwatsonvoid 2307100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2308100979Srwatson{ 2309113482Srwatson struct label *label; 2310100979Srwatson 2311113482Srwatson label = mbuf_to_label(mbuf); 2312113482Srwatson 2313100979Srwatson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2314113482Srwatson label); 2315100979Srwatson} 2316100979Srwatson 2317100979Srwatsonvoid 2318100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2319100979Srwatson{ 2320113482Srwatson struct label *label; 2321100979Srwatson 2322113482Srwatson label = mbuf_to_label(mbuf); 2323113482Srwatson 2324100979Srwatson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2325113482Srwatson label); 2326100979Srwatson} 2327100979Srwatson 2328100979Srwatsonvoid 2329100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2330100979Srwatson struct mbuf *newmbuf) 2331100979Srwatson{ 2332113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2333100979Srwatson 2334113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2335113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2336113482Srwatson 2337113482Srwatson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 2338113482Srwatson ifnet, &ifnet->if_label, newmbuf, newmbuflabel); 2339100979Srwatson} 2340100979Srwatson 2341100979Srwatsonvoid 2342100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2343100979Srwatson{ 2344113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2345100979Srwatson 2346113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2347113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2348113482Srwatson 2349113482Srwatson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 2350113482Srwatson newmbuflabel); 2351100979Srwatson} 2352100979Srwatson 2353100979Srwatsonint 2354100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2355100979Srwatson{ 2356113482Srwatson struct label *label; 2357100979Srwatson int result; 2358100979Srwatson 2359113482Srwatson label = mbuf_to_label(fragment); 2360113482Srwatson 2361100979Srwatson result = 1; 2362113482Srwatson MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 2363113482Srwatson &ipq->ipq_label); 2364100979Srwatson 2365100979Srwatson return (result); 2366100979Srwatson} 2367100979Srwatson 2368100979Srwatsonvoid 2369100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2370100979Srwatson{ 2371113482Srwatson struct label *label; 2372100979Srwatson 2373113482Srwatson label = mbuf_to_label(fragment); 2374113482Srwatson 2375113482Srwatson MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label); 2376100979Srwatson} 2377100979Srwatson 2378100979Srwatsonvoid 2379100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2380100979Srwatson{ 2381113482Srwatson struct label *label; 2382100979Srwatson 2383113482Srwatson label = mbuf_to_label(mbuf); 2384113482Srwatson 2385100979Srwatson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2386113482Srwatson label); 2387100979Srwatson} 2388100979Srwatson 2389100979Srwatsonvoid 2390100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp) 2391100979Srwatson{ 2392100979Srwatson 2393100979Srwatson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2394100979Srwatson &mp->mnt_fslabel); 2395100979Srwatson} 2396100979Srwatson 2397100979Srwatsonvoid 2398100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp) 2399100979Srwatson{ 2400100979Srwatson 2401100979Srwatson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2402100979Srwatson &mp->mnt_fslabel); 2403100979Srwatson} 2404100979Srwatson 2405100979Srwatsonint 2406100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2407100979Srwatson{ 2408100979Srwatson int error; 2409100979Srwatson 2410100979Srwatson if (!mac_enforce_network) 2411100979Srwatson return (0); 2412100979Srwatson 2413100979Srwatson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2414100979Srwatson &ifnet->if_label); 2415100979Srwatson 2416100979Srwatson return (error); 2417100979Srwatson} 2418100979Srwatson 2419100979Srwatsonstatic int 2420100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2421100979Srwatson{ 2422100979Srwatson int error; 2423100979Srwatson 2424100979Srwatson MAC_CHECK(check_cred_relabel, cred, newlabel); 2425100979Srwatson 2426100979Srwatson return (error); 2427100979Srwatson} 2428100979Srwatson 2429100979Srwatsonint 2430100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2431100979Srwatson{ 2432100979Srwatson int error; 2433100979Srwatson 2434100979Srwatson if (!mac_enforce_process) 2435100979Srwatson return (0); 2436100979Srwatson 2437100979Srwatson MAC_CHECK(check_cred_visible, u1, u2); 2438100979Srwatson 2439100979Srwatson return (error); 2440100979Srwatson} 2441100979Srwatson 2442100979Srwatsonint 2443100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2444100979Srwatson{ 2445113482Srwatson struct label *label; 2446100979Srwatson int error; 2447100979Srwatson 2448113487Srwatson M_ASSERTPKTHDR(mbuf); 2449113487Srwatson 2450100979Srwatson if (!mac_enforce_network) 2451100979Srwatson return (0); 2452100979Srwatson 2453113482Srwatson label = mbuf_to_label(mbuf); 2454100979Srwatson 2455100979Srwatson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2456113482Srwatson label); 2457100979Srwatson 2458100979Srwatson return (error); 2459100979Srwatson} 2460100979Srwatson 2461100979Srwatsonint 2462106308Srwatsonmac_check_kenv_dump(struct ucred *cred) 2463106308Srwatson{ 2464106308Srwatson int error; 2465106308Srwatson 2466106308Srwatson if (!mac_enforce_system) 2467106308Srwatson return (0); 2468106308Srwatson 2469106308Srwatson MAC_CHECK(check_kenv_dump, cred); 2470106308Srwatson 2471106308Srwatson return (error); 2472106308Srwatson} 2473106308Srwatson 2474106308Srwatsonint 2475106308Srwatsonmac_check_kenv_get(struct ucred *cred, char *name) 2476106308Srwatson{ 2477106308Srwatson int error; 2478106308Srwatson 2479106308Srwatson if (!mac_enforce_system) 2480106308Srwatson return (0); 2481106308Srwatson 2482106308Srwatson MAC_CHECK(check_kenv_get, cred, name); 2483106308Srwatson 2484106308Srwatson return (error); 2485106308Srwatson} 2486106308Srwatson 2487106308Srwatsonint 2488106308Srwatsonmac_check_kenv_set(struct ucred *cred, char *name, char *value) 2489106308Srwatson{ 2490106308Srwatson int error; 2491106308Srwatson 2492106308Srwatson if (!mac_enforce_system) 2493106308Srwatson return (0); 2494106308Srwatson 2495106308Srwatson MAC_CHECK(check_kenv_set, cred, name, value); 2496106308Srwatson 2497106308Srwatson return (error); 2498106308Srwatson} 2499106308Srwatson 2500106308Srwatsonint 2501106308Srwatsonmac_check_kenv_unset(struct ucred *cred, char *name) 2502106308Srwatson{ 2503106308Srwatson int error; 2504106308Srwatson 2505106308Srwatson if (!mac_enforce_system) 2506106308Srwatson return (0); 2507106308Srwatson 2508106308Srwatson MAC_CHECK(check_kenv_unset, cred, name); 2509106308Srwatson 2510106308Srwatson return (error); 2511106308Srwatson} 2512106308Srwatson 2513106308Srwatsonint 2514107089Srwatsonmac_check_kld_load(struct ucred *cred, struct vnode *vp) 2515107089Srwatson{ 2516107089Srwatson int error; 2517107089Srwatson 2518107089Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2519107089Srwatson 2520107089Srwatson if (!mac_enforce_kld) 2521107089Srwatson return (0); 2522107089Srwatson 2523107089Srwatson MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2524107089Srwatson 2525107089Srwatson return (error); 2526107089Srwatson} 2527107089Srwatson 2528107089Srwatsonint 2529107089Srwatsonmac_check_kld_stat(struct ucred *cred) 2530107089Srwatson{ 2531107089Srwatson int error; 2532107089Srwatson 2533107089Srwatson if (!mac_enforce_kld) 2534107089Srwatson return (0); 2535107089Srwatson 2536107089Srwatson MAC_CHECK(check_kld_stat, cred); 2537107089Srwatson 2538107089Srwatson return (error); 2539107089Srwatson} 2540107089Srwatson 2541107089Srwatsonint 2542107089Srwatsonmac_check_kld_unload(struct ucred *cred) 2543107089Srwatson{ 2544107089Srwatson int error; 2545107089Srwatson 2546107089Srwatson if (!mac_enforce_kld) 2547107089Srwatson return (0); 2548107089Srwatson 2549107089Srwatson MAC_CHECK(check_kld_unload, cred); 2550107089Srwatson 2551107089Srwatson return (error); 2552107089Srwatson} 2553107089Srwatson 2554107089Srwatsonint 2555100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount) 2556100979Srwatson{ 2557100979Srwatson int error; 2558100979Srwatson 2559100979Srwatson if (!mac_enforce_fs) 2560100979Srwatson return (0); 2561100979Srwatson 2562100979Srwatson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2563100979Srwatson 2564100979Srwatson return (error); 2565100979Srwatson} 2566100979Srwatson 2567100979Srwatsonint 2568100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2569100979Srwatson void *data) 2570100979Srwatson{ 2571100979Srwatson int error; 2572100979Srwatson 2573104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2574104269Srwatson 2575104269Srwatson if (!mac_enforce_pipe) 2576104269Srwatson return (0); 2577104269Srwatson 2578100979Srwatson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2579100979Srwatson 2580100979Srwatson return (error); 2581100979Srwatson} 2582100979Srwatson 2583100979Srwatsonint 2584102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2585100979Srwatson{ 2586100979Srwatson int error; 2587100979Srwatson 2588104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2589104269Srwatson 2590104269Srwatson if (!mac_enforce_pipe) 2591104269Srwatson return (0); 2592104269Srwatson 2593102115Srwatson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2594100979Srwatson 2595100979Srwatson return (error); 2596100979Srwatson} 2597100979Srwatson 2598102115Srwatsonint 2599102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2600102115Srwatson{ 2601102115Srwatson int error; 2602102115Srwatson 2603104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2604104269Srwatson 2605104269Srwatson if (!mac_enforce_pipe) 2606104269Srwatson return (0); 2607104269Srwatson 2608102115Srwatson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2609102115Srwatson 2610102115Srwatson return (error); 2611102115Srwatson} 2612102115Srwatson 2613100979Srwatsonstatic int 2614100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2615100979Srwatson struct label *newlabel) 2616100979Srwatson{ 2617100979Srwatson int error; 2618100979Srwatson 2619104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2620104269Srwatson 2621104269Srwatson if (!mac_enforce_pipe) 2622104269Srwatson return (0); 2623104269Srwatson 2624100979Srwatson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2625100979Srwatson 2626100979Srwatson return (error); 2627100979Srwatson} 2628100979Srwatson 2629100979Srwatsonint 2630102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2631102115Srwatson{ 2632102115Srwatson int error; 2633102115Srwatson 2634104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2635104269Srwatson 2636104269Srwatson if (!mac_enforce_pipe) 2637104269Srwatson return (0); 2638104269Srwatson 2639102115Srwatson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2640102115Srwatson 2641102115Srwatson return (error); 2642102115Srwatson} 2643102115Srwatson 2644102115Srwatsonint 2645102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2646102115Srwatson{ 2647102115Srwatson int error; 2648102115Srwatson 2649104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2650104269Srwatson 2651104269Srwatson if (!mac_enforce_pipe) 2652104269Srwatson return (0); 2653104269Srwatson 2654102115Srwatson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2655102115Srwatson 2656102115Srwatson return (error); 2657102115Srwatson} 2658102115Srwatson 2659102115Srwatsonint 2660100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc) 2661100979Srwatson{ 2662100979Srwatson int error; 2663100979Srwatson 2664102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2665102103Srwatson 2666100979Srwatson if (!mac_enforce_process) 2667100979Srwatson return (0); 2668100979Srwatson 2669100979Srwatson MAC_CHECK(check_proc_debug, cred, proc); 2670100979Srwatson 2671100979Srwatson return (error); 2672100979Srwatson} 2673100979Srwatson 2674100979Srwatsonint 2675100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc) 2676100979Srwatson{ 2677100979Srwatson int error; 2678100979Srwatson 2679102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2680102103Srwatson 2681100979Srwatson if (!mac_enforce_process) 2682100979Srwatson return (0); 2683100979Srwatson 2684100979Srwatson MAC_CHECK(check_proc_sched, cred, proc); 2685100979Srwatson 2686100979Srwatson return (error); 2687100979Srwatson} 2688100979Srwatson 2689100979Srwatsonint 2690100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2691100979Srwatson{ 2692100979Srwatson int error; 2693100979Srwatson 2694102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2695102103Srwatson 2696100979Srwatson if (!mac_enforce_process) 2697100979Srwatson return (0); 2698100979Srwatson 2699100979Srwatson MAC_CHECK(check_proc_signal, cred, proc, signum); 2700100979Srwatson 2701100979Srwatson return (error); 2702100979Srwatson} 2703100979Srwatson 2704100979Srwatsonint 2705100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2706100979Srwatson struct sockaddr *sockaddr) 2707100979Srwatson{ 2708100979Srwatson int error; 2709100979Srwatson 2710100979Srwatson if (!mac_enforce_socket) 2711100979Srwatson return (0); 2712100979Srwatson 2713100979Srwatson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2714100979Srwatson sockaddr); 2715100979Srwatson 2716100979Srwatson return (error); 2717100979Srwatson} 2718100979Srwatson 2719100979Srwatsonint 2720100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket, 2721100979Srwatson struct sockaddr *sockaddr) 2722100979Srwatson{ 2723100979Srwatson int error; 2724100979Srwatson 2725100979Srwatson if (!mac_enforce_socket) 2726100979Srwatson return (0); 2727100979Srwatson 2728100979Srwatson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2729100979Srwatson sockaddr); 2730100979Srwatson 2731100979Srwatson return (error); 2732100979Srwatson} 2733100979Srwatson 2734100979Srwatsonint 2735101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2736100979Srwatson{ 2737113482Srwatson struct label *label; 2738100979Srwatson int error; 2739100979Srwatson 2740100979Srwatson if (!mac_enforce_socket) 2741100979Srwatson return (0); 2742100979Srwatson 2743113482Srwatson label = mbuf_to_label(mbuf); 2744113482Srwatson 2745101933Srwatson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2746113482Srwatson label); 2747101933Srwatson 2748100979Srwatson return (error); 2749100979Srwatson} 2750100979Srwatson 2751100979Srwatsonint 2752101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket) 2753100979Srwatson{ 2754100979Srwatson int error; 2755100979Srwatson 2756100979Srwatson if (!mac_enforce_socket) 2757100979Srwatson return (0); 2758100979Srwatson 2759101933Srwatson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2760100979Srwatson return (error); 2761100979Srwatson} 2762100979Srwatson 2763104571Srwatsonint 2764104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so) 2765104571Srwatson{ 2766104571Srwatson int error; 2767104571Srwatson 2768104571Srwatson if (!mac_enforce_socket) 2769104571Srwatson return (0); 2770104571Srwatson 2771104571Srwatson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2772104571Srwatson 2773104571Srwatson return (error); 2774104571Srwatson} 2775104571Srwatson 2776100979Srwatsonstatic int 2777100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2778100979Srwatson struct label *newlabel) 2779100979Srwatson{ 2780100979Srwatson int error; 2781100979Srwatson 2782100979Srwatson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2783100979Srwatson newlabel); 2784100979Srwatson 2785100979Srwatson return (error); 2786100979Srwatson} 2787100979Srwatson 2788100979Srwatsonint 2789104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so) 2790104571Srwatson{ 2791104571Srwatson int error; 2792104571Srwatson 2793104571Srwatson if (!mac_enforce_socket) 2794104571Srwatson return (0); 2795104571Srwatson 2796104571Srwatson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2797104571Srwatson 2798104571Srwatson return (error); 2799104571Srwatson} 2800104571Srwatson 2801104571Srwatsonint 2802100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket) 2803100979Srwatson{ 2804100979Srwatson int error; 2805100979Srwatson 2806100979Srwatson if (!mac_enforce_socket) 2807100979Srwatson return (0); 2808105694Srwatson 2809100979Srwatson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2810105694Srwatson 2811100979Srwatson return (error); 2812100979Srwatson} 2813100979Srwatson 2814100979Srwatsonint 2815111939Srwatsonmac_check_sysarch_ioperm(struct ucred *cred) 2816111939Srwatson{ 2817111939Srwatson int error; 2818111939Srwatson 2819111939Srwatson if (!mac_enforce_system) 2820111939Srwatson return (0); 2821111939Srwatson 2822111939Srwatson MAC_CHECK(check_sysarch_ioperm, cred); 2823111939Srwatson return (error); 2824111939Srwatson} 2825111939Srwatson 2826111939Srwatsonint 2827106412Srwatsonmac_check_system_acct(struct ucred *cred, struct vnode *vp) 2828106412Srwatson{ 2829106412Srwatson int error; 2830106412Srwatson 2831106412Srwatson if (vp != NULL) { 2832106412Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2833106412Srwatson } 2834106412Srwatson 2835106412Srwatson if (!mac_enforce_system) 2836106412Srwatson return (0); 2837106412Srwatson 2838106412Srwatson MAC_CHECK(check_system_acct, cred, vp, 2839106412Srwatson vp != NULL ? &vp->v_label : NULL); 2840106412Srwatson 2841106412Srwatson return (error); 2842106412Srwatson} 2843106412Srwatson 2844106412Srwatsonint 2845106412Srwatsonmac_check_system_nfsd(struct ucred *cred) 2846106412Srwatson{ 2847106412Srwatson int error; 2848106412Srwatson 2849106412Srwatson if (!mac_enforce_system) 2850106412Srwatson return (0); 2851106412Srwatson 2852106412Srwatson MAC_CHECK(check_system_nfsd, cred); 2853106412Srwatson 2854106412Srwatson return (error); 2855106412Srwatson} 2856106412Srwatson 2857106412Srwatsonint 2858106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto) 2859106024Srwatson{ 2860106024Srwatson int error; 2861106024Srwatson 2862106045Srwatson if (!mac_enforce_system) 2863106024Srwatson return (0); 2864106024Srwatson 2865106024Srwatson MAC_CHECK(check_system_reboot, cred, howto); 2866106045Srwatson 2867106024Srwatson return (error); 2868106024Srwatson} 2869106024Srwatson 2870106024Srwatsonint 2871106369Srwatsonmac_check_system_settime(struct ucred *cred) 2872106369Srwatson{ 2873106369Srwatson int error; 2874106369Srwatson 2875106369Srwatson if (!mac_enforce_system) 2876106369Srwatson return (0); 2877106369Srwatson 2878106369Srwatson MAC_CHECK(check_system_settime, cred); 2879106369Srwatson 2880106369Srwatson return (error); 2881106369Srwatson} 2882106369Srwatson 2883106369Srwatsonint 2884106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2885106023Srwatson{ 2886106023Srwatson int error; 2887106023Srwatson 2888106023Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2889106023Srwatson 2890106045Srwatson if (!mac_enforce_system) 2891106023Srwatson return (0); 2892106023Srwatson 2893106023Srwatson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2894106023Srwatson return (error); 2895106023Srwatson} 2896106023Srwatson 2897106023Srwatsonint 2898111936Srwatsonmac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2899111936Srwatson{ 2900111936Srwatson int error; 2901111936Srwatson 2902111936Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2903111936Srwatson 2904111936Srwatson if (!mac_enforce_system) 2905111936Srwatson return (0); 2906111936Srwatson 2907111936Srwatson MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2908111936Srwatson return (error); 2909111936Srwatson} 2910111936Srwatson 2911111936Srwatsonint 2912106025Srwatsonmac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2913106025Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2914106025Srwatson{ 2915106025Srwatson int error; 2916106025Srwatson 2917106025Srwatson /* 2918106025Srwatson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2919106025Srwatson * but since it's not exported from kern_sysctl.c, we can't. 2920106025Srwatson */ 2921106045Srwatson if (!mac_enforce_system) 2922106025Srwatson return (0); 2923106025Srwatson 2924106025Srwatson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2925106025Srwatson inkernel, new, newlen); 2926106025Srwatson 2927106025Srwatson return (error); 2928106025Srwatson} 2929106025Srwatson 2930106025Srwatsonint 2931100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2932100979Srwatson struct ifnet *ifnet) 2933100979Srwatson{ 2934105694Srwatson char *elements, *buffer; 2935105694Srwatson struct mac mac; 2936100979Srwatson int error; 2937100979Srwatson 2938105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2939100979Srwatson if (error) 2940100979Srwatson return (error); 2941100979Srwatson 2942105694Srwatson error = mac_check_structmac_consistent(&mac); 2943105694Srwatson if (error) 2944105694Srwatson return (error); 2945105694Srwatson 2946111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2947105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2948105694Srwatson if (error) { 2949105694Srwatson free(elements, M_MACTEMP); 2950105694Srwatson return (error); 2951105694Srwatson } 2952105694Srwatson 2953111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2954105694Srwatson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 2955111119Simp buffer, mac.m_buflen, M_WAITOK); 2956105694Srwatson if (error == 0) 2957105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2958105694Srwatson 2959105694Srwatson free(buffer, M_MACTEMP); 2960105694Srwatson free(elements, M_MACTEMP); 2961105694Srwatson 2962105694Srwatson return (error); 2963100979Srwatson} 2964100979Srwatson 2965100979Srwatsonint 2966100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2967100979Srwatson struct ifnet *ifnet) 2968100979Srwatson{ 2969100979Srwatson struct label intlabel; 2970105694Srwatson struct mac mac; 2971105694Srwatson char *buffer; 2972100979Srwatson int error; 2973100979Srwatson 2974105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2975100979Srwatson if (error) 2976100979Srwatson return (error); 2977100979Srwatson 2978105694Srwatson error = mac_check_structmac_consistent(&mac); 2979100979Srwatson if (error) 2980100979Srwatson return (error); 2981100979Srwatson 2982111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2983105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2984105694Srwatson if (error) { 2985105694Srwatson free(buffer, M_MACTEMP); 2986105694Srwatson return (error); 2987105694Srwatson } 2988105694Srwatson 2989105694Srwatson mac_init_ifnet_label(&intlabel); 2990105694Srwatson error = mac_internalize_ifnet_label(&intlabel, buffer); 2991105694Srwatson free(buffer, M_MACTEMP); 2992105694Srwatson if (error) { 2993105694Srwatson mac_destroy_ifnet_label(&intlabel); 2994105694Srwatson return (error); 2995105694Srwatson } 2996105694Srwatson 2997100979Srwatson /* 2998100979Srwatson * XXX: Note that this is a redundant privilege check, since 2999100979Srwatson * policies impose this check themselves if required by the 3000100979Srwatson * policy. Eventually, this should go away. 3001100979Srwatson */ 3002100979Srwatson error = suser_cred(cred, 0); 3003105694Srwatson if (error) { 3004105694Srwatson mac_destroy_ifnet_label(&intlabel); 3005105694Srwatson return (error); 3006105694Srwatson } 3007100979Srwatson 3008100979Srwatson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 3009100979Srwatson &intlabel); 3010105694Srwatson if (error) { 3011105694Srwatson mac_destroy_ifnet_label(&intlabel); 3012105694Srwatson return (error); 3013105694Srwatson } 3014100979Srwatson 3015100979Srwatson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 3016100979Srwatson 3017105694Srwatson mac_destroy_ifnet_label(&intlabel); 3018105694Srwatson return (0); 3019100979Srwatson} 3020100979Srwatson 3021100979Srwatsonvoid 3022107698Srwatsonmac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de) 3023100979Srwatson{ 3024100979Srwatson 3025107698Srwatson MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label); 3026100979Srwatson} 3027100979Srwatson 3028104533Srwatsonvoid 3029107698Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 3030107698Srwatson struct devfs_dirent *dd, struct devfs_dirent *de) 3031104533Srwatson{ 3032104533Srwatson 3033107698Srwatson MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de, 3034104533Srwatson &de->de_label); 3035104533Srwatson} 3036104533Srwatson 3037100979Srwatsonvoid 3038107698Srwatsonmac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 3039100979Srwatson struct devfs_dirent *de) 3040100979Srwatson{ 3041100979Srwatson 3042107698Srwatson MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 3043100979Srwatson &de->de_label); 3044100979Srwatson} 3045100979Srwatson 3046100979Srwatsonint 3047100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3048105694Srwatson struct mac *mac) 3049100979Srwatson{ 3050100979Srwatson struct label intlabel; 3051105694Srwatson char *buffer; 3052100979Srwatson int error; 3053100979Srwatson 3054105694Srwatson error = mac_check_structmac_consistent(mac); 3055100979Srwatson if (error) 3056100979Srwatson return (error); 3057100979Srwatson 3058111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3059105694Srwatson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3060105694Srwatson if (error) { 3061105694Srwatson free(buffer, M_MACTEMP); 3062105694Srwatson return (error); 3063105694Srwatson } 3064105694Srwatson 3065111119Simp mac_init_socket_label(&intlabel, M_WAITOK); 3066105694Srwatson error = mac_internalize_socket_label(&intlabel, buffer); 3067105694Srwatson free(buffer, M_MACTEMP); 3068105694Srwatson if (error) { 3069105694Srwatson mac_destroy_socket_label(&intlabel); 3070105694Srwatson return (error); 3071105694Srwatson } 3072105694Srwatson 3073100979Srwatson mac_check_socket_relabel(cred, so, &intlabel); 3074100979Srwatson if (error) { 3075105694Srwatson mac_destroy_socket_label(&intlabel); 3076100979Srwatson return (error); 3077100979Srwatson } 3078100979Srwatson 3079100979Srwatson mac_relabel_socket(cred, so, &intlabel); 3080100979Srwatson 3081105694Srwatson mac_destroy_socket_label(&intlabel); 3082100979Srwatson return (0); 3083100979Srwatson} 3084100979Srwatson 3085100979Srwatsonint 3086100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3087100979Srwatson{ 3088100979Srwatson int error; 3089100979Srwatson 3090104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3091104269Srwatson 3092100979Srwatson error = mac_check_pipe_relabel(cred, pipe, label); 3093100979Srwatson if (error) 3094100979Srwatson return (error); 3095100979Srwatson 3096100979Srwatson mac_relabel_pipe(cred, pipe, label); 3097100979Srwatson 3098100979Srwatson return (0); 3099100979Srwatson} 3100100979Srwatson 3101100979Srwatsonint 3102100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3103105694Srwatson struct mac *mac) 3104100979Srwatson{ 3105105694Srwatson char *buffer, *elements; 3106105694Srwatson int error; 3107100979Srwatson 3108105694Srwatson error = mac_check_structmac_consistent(mac); 3109105694Srwatson if (error) 3110105694Srwatson return (error); 3111105694Srwatson 3112111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3113105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3114105694Srwatson if (error) { 3115105694Srwatson free(elements, M_MACTEMP); 3116105694Srwatson return (error); 3117105694Srwatson } 3118105694Srwatson 3119111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3120105694Srwatson error = mac_externalize_socket_label(&so->so_label, elements, 3121111119Simp buffer, mac->m_buflen, M_WAITOK); 3122105694Srwatson if (error == 0) 3123105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3124105694Srwatson 3125105694Srwatson free(buffer, M_MACTEMP); 3126105694Srwatson free(elements, M_MACTEMP); 3127105694Srwatson 3128105694Srwatson return (error); 3129100979Srwatson} 3130100979Srwatson 3131100979Srwatsonint 3132100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3133105694Srwatson struct mac *mac) 3134100979Srwatson{ 3135105694Srwatson char *elements, *buffer; 3136105694Srwatson int error; 3137100979Srwatson 3138105694Srwatson error = mac_check_structmac_consistent(mac); 3139105694Srwatson if (error) 3140105694Srwatson return (error); 3141105694Srwatson 3142111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3143105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3144105694Srwatson if (error) { 3145105694Srwatson free(elements, M_MACTEMP); 3146105694Srwatson return (error); 3147105694Srwatson } 3148105694Srwatson 3149111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3150105694Srwatson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3151111119Simp elements, buffer, mac->m_buflen, M_WAITOK); 3152105694Srwatson if (error == 0) 3153105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3154105694Srwatson 3155105694Srwatson free(buffer, M_MACTEMP); 3156105694Srwatson free(elements, M_MACTEMP); 3157105694Srwatson 3158105694Srwatson return (error); 3159100979Srwatson} 3160100979Srwatson 3161100979Srwatson/* 3162100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes 3163100979Srwatson * to store label data. Can be referenced by filesystems supporting 3164100979Srwatson * extended attributes. 3165100979Srwatson */ 3166100979Srwatsonint 3167100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3168100979Srwatson{ 3169100979Srwatson struct vnode *vp = ap->a_vp; 3170100979Srwatson struct label *intlabel = ap->a_label; 3171100979Srwatson int error; 3172100979Srwatson 3173100979Srwatson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3174100979Srwatson 3175105988Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3176105988Srwatson return (EOPNOTSUPP); 3177100979Srwatson 3178105988Srwatson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3179100979Srwatson if (error) 3180100979Srwatson return (error); 3181100979Srwatson 3182100979Srwatson mac_relabel_vnode(ap->a_cred, vp, intlabel); 3183100979Srwatson 3184100979Srwatson return (0); 3185100979Srwatson} 3186100979Srwatson 3187100979Srwatsonstatic int 3188100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3189100979Srwatson{ 3190100979Srwatson int error; 3191100979Srwatson 3192100979Srwatson if (vp->v_mount == NULL) { 3193100979Srwatson /* printf("vn_setlabel: null v_mount\n"); */ 3194103314Snjl if (vp->v_type != VNON) 3195103314Snjl printf("vn_setlabel: null v_mount with non-VNON\n"); 3196100979Srwatson return (EBADF); 3197100979Srwatson } 3198100979Srwatson 3199100979Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3200100979Srwatson return (EOPNOTSUPP); 3201100979Srwatson 3202100979Srwatson /* 3203100979Srwatson * Multi-phase commit. First check the policies to confirm the 3204100979Srwatson * change is OK. Then commit via the filesystem. Finally, 3205100979Srwatson * update the actual vnode label. Question: maybe the filesystem 3206100979Srwatson * should update the vnode at the end as part of VOP_SETLABEL()? 3207100979Srwatson */ 3208100979Srwatson error = mac_check_vnode_relabel(cred, vp, intlabel); 3209100979Srwatson if (error) 3210100979Srwatson return (error); 3211100979Srwatson 3212100979Srwatson /* 3213100979Srwatson * VADMIN provides the opportunity for the filesystem to make 3214100979Srwatson * decisions about who is and is not able to modify labels 3215100979Srwatson * and protections on files. This might not be right. We can't 3216100979Srwatson * assume VOP_SETLABEL() will do it, because we might implement 3217100979Srwatson * that as part of vop_stdsetlabel_ea(). 3218100979Srwatson */ 3219100979Srwatson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3220100979Srwatson if (error) 3221100979Srwatson return (error); 3222100979Srwatson 3223100979Srwatson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3224100979Srwatson if (error) 3225100979Srwatson return (error); 3226100979Srwatson 3227100979Srwatson return (0); 3228100979Srwatson} 3229100979Srwatson 3230105694Srwatsonint 3231105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3232105694Srwatson{ 3233105694Srwatson char *elements, *buffer; 3234105694Srwatson struct mac mac; 3235105694Srwatson struct proc *tproc; 3236105694Srwatson struct ucred *tcred; 3237105694Srwatson int error; 3238105694Srwatson 3239107849Salfred error = copyin(uap->mac_p, &mac, sizeof(mac)); 3240105694Srwatson if (error) 3241105694Srwatson return (error); 3242105694Srwatson 3243105694Srwatson error = mac_check_structmac_consistent(&mac); 3244105694Srwatson if (error) 3245105694Srwatson return (error); 3246105694Srwatson 3247105694Srwatson tproc = pfind(uap->pid); 3248105694Srwatson if (tproc == NULL) 3249105694Srwatson return (ESRCH); 3250105694Srwatson 3251105694Srwatson tcred = NULL; /* Satisfy gcc. */ 3252105694Srwatson error = p_cansee(td, tproc); 3253105694Srwatson if (error == 0) 3254105694Srwatson tcred = crhold(tproc->p_ucred); 3255105694Srwatson PROC_UNLOCK(tproc); 3256105694Srwatson if (error) 3257105694Srwatson return (error); 3258105694Srwatson 3259111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3260105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3261105694Srwatson if (error) { 3262105694Srwatson free(elements, M_MACTEMP); 3263105694Srwatson crfree(tcred); 3264105694Srwatson return (error); 3265105694Srwatson } 3266105694Srwatson 3267111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3268105694Srwatson error = mac_externalize_cred_label(&tcred->cr_label, elements, 3269111119Simp buffer, mac.m_buflen, M_WAITOK); 3270105694Srwatson if (error == 0) 3271105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3272105694Srwatson 3273105694Srwatson free(buffer, M_MACTEMP); 3274105694Srwatson free(elements, M_MACTEMP); 3275105694Srwatson crfree(tcred); 3276105694Srwatson return (error); 3277105694Srwatson} 3278105694Srwatson 3279100979Srwatson/* 3280100979Srwatson * MPSAFE 3281100979Srwatson */ 3282100979Srwatsonint 3283100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3284100894Srwatson{ 3285105694Srwatson char *elements, *buffer; 3286105694Srwatson struct mac mac; 3287100979Srwatson int error; 3288100894Srwatson 3289105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3290105694Srwatson if (error) 3291105694Srwatson return (error); 3292105694Srwatson 3293105694Srwatson error = mac_check_structmac_consistent(&mac); 3294105694Srwatson if (error) 3295105694Srwatson return (error); 3296105694Srwatson 3297111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3298105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3299105694Srwatson if (error) { 3300105694Srwatson free(elements, M_MACTEMP); 3301105694Srwatson return (error); 3302105694Srwatson } 3303105694Srwatson 3304111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3305105694Srwatson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3306111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3307100979Srwatson if (error == 0) 3308105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3309100979Srwatson 3310105694Srwatson free(buffer, M_MACTEMP); 3311105694Srwatson free(elements, M_MACTEMP); 3312100979Srwatson return (error); 3313100979Srwatson} 3314100979Srwatson 3315100979Srwatson/* 3316100979Srwatson * MPSAFE 3317100979Srwatson */ 3318100979Srwatsonint 3319100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3320100979Srwatson{ 3321100979Srwatson struct ucred *newcred, *oldcred; 3322105694Srwatson struct label intlabel; 3323100979Srwatson struct proc *p; 3324105694Srwatson struct mac mac; 3325105694Srwatson char *buffer; 3326100979Srwatson int error; 3327100979Srwatson 3328105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3329100979Srwatson if (error) 3330100979Srwatson return (error); 3331100979Srwatson 3332105694Srwatson error = mac_check_structmac_consistent(&mac); 3333100979Srwatson if (error) 3334100979Srwatson return (error); 3335100979Srwatson 3336111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3337105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3338105694Srwatson if (error) { 3339105694Srwatson free(buffer, M_MACTEMP); 3340105694Srwatson return (error); 3341105694Srwatson } 3342105694Srwatson 3343105694Srwatson mac_init_cred_label(&intlabel); 3344105694Srwatson error = mac_internalize_cred_label(&intlabel, buffer); 3345105694Srwatson free(buffer, M_MACTEMP); 3346105694Srwatson if (error) { 3347105694Srwatson mac_destroy_cred_label(&intlabel); 3348105694Srwatson return (error); 3349105694Srwatson } 3350105694Srwatson 3351100979Srwatson newcred = crget(); 3352100979Srwatson 3353100979Srwatson p = td->td_proc; 3354100979Srwatson PROC_LOCK(p); 3355100979Srwatson oldcred = p->p_ucred; 3356100979Srwatson 3357100979Srwatson error = mac_check_cred_relabel(oldcred, &intlabel); 3358100979Srwatson if (error) { 3359100979Srwatson PROC_UNLOCK(p); 3360100979Srwatson crfree(newcred); 3361105694Srwatson goto out; 3362100979Srwatson } 3363100979Srwatson 3364100979Srwatson setsugid(p); 3365100979Srwatson crcopy(newcred, oldcred); 3366100979Srwatson mac_relabel_cred(newcred, &intlabel); 3367102136Srwatson p->p_ucred = newcred; 3368100979Srwatson 3369102136Srwatson /* 3370102136Srwatson * Grab additional reference for use while revoking mmaps, prior 3371102136Srwatson * to releasing the proc lock and sharing the cred. 3372102136Srwatson */ 3373102136Srwatson crhold(newcred); 3374100979Srwatson PROC_UNLOCK(p); 3375102136Srwatson 3376105694Srwatson if (mac_enforce_vm) { 3377105694Srwatson mtx_lock(&Giant); 3378105694Srwatson mac_cred_mmapped_drop_perms(td, newcred); 3379105694Srwatson mtx_unlock(&Giant); 3380105694Srwatson } 3381102136Srwatson 3382102136Srwatson crfree(newcred); /* Free revocation reference. */ 3383100979Srwatson crfree(oldcred); 3384105694Srwatson 3385105694Srwatsonout: 3386105694Srwatson mac_destroy_cred_label(&intlabel); 3387105694Srwatson return (error); 3388100979Srwatson} 3389100979Srwatson 3390100979Srwatson/* 3391100979Srwatson * MPSAFE 3392100979Srwatson */ 3393100979Srwatsonint 3394100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3395100979Srwatson{ 3396105694Srwatson char *elements, *buffer; 3397105694Srwatson struct label intlabel; 3398100979Srwatson struct file *fp; 3399105694Srwatson struct mac mac; 3400100979Srwatson struct vnode *vp; 3401100979Srwatson struct pipe *pipe; 3402105694Srwatson short label_type; 3403100979Srwatson int error; 3404100979Srwatson 3405105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3406105694Srwatson if (error) 3407105694Srwatson return (error); 3408100979Srwatson 3409105694Srwatson error = mac_check_structmac_consistent(&mac); 3410105694Srwatson if (error) 3411105694Srwatson return (error); 3412105694Srwatson 3413111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3414105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3415105694Srwatson if (error) { 3416105694Srwatson free(elements, M_MACTEMP); 3417105694Srwatson return (error); 3418105694Srwatson } 3419105694Srwatson 3420111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3421105694Srwatson mtx_lock(&Giant); /* VFS */ 3422107849Salfred error = fget(td, uap->fd, &fp); 3423100979Srwatson if (error) 3424100979Srwatson goto out; 3425100979Srwatson 3426105694Srwatson label_type = fp->f_type; 3427100979Srwatson switch (fp->f_type) { 3428100979Srwatson case DTYPE_FIFO: 3429100979Srwatson case DTYPE_VNODE: 3430116678Sphk vp = fp->f_vnode; 3431100979Srwatson 3432105694Srwatson mac_init_vnode_label(&intlabel); 3433105694Srwatson 3434100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3435105988Srwatson mac_copy_vnode_label(&vp->v_label, &intlabel); 3436100979Srwatson VOP_UNLOCK(vp, 0, td); 3437105694Srwatson 3438100979Srwatson break; 3439100979Srwatson case DTYPE_PIPE: 3440109153Sdillon pipe = fp->f_data; 3441105694Srwatson 3442105694Srwatson mac_init_pipe_label(&intlabel); 3443105694Srwatson 3444105694Srwatson PIPE_LOCK(pipe); 3445105694Srwatson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3446105694Srwatson PIPE_UNLOCK(pipe); 3447100979Srwatson break; 3448100979Srwatson default: 3449100979Srwatson error = EINVAL; 3450105694Srwatson fdrop(fp, td); 3451105694Srwatson goto out; 3452100979Srwatson } 3453105694Srwatson fdrop(fp, td); 3454100979Srwatson 3455105694Srwatson switch (label_type) { 3456105694Srwatson case DTYPE_FIFO: 3457105694Srwatson case DTYPE_VNODE: 3458105694Srwatson if (error == 0) 3459105694Srwatson error = mac_externalize_vnode_label(&intlabel, 3460111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3461105694Srwatson mac_destroy_vnode_label(&intlabel); 3462105694Srwatson break; 3463105694Srwatson case DTYPE_PIPE: 3464105694Srwatson error = mac_externalize_pipe_label(&intlabel, elements, 3465111119Simp buffer, mac.m_buflen, M_WAITOK); 3466105694Srwatson mac_destroy_pipe_label(&intlabel); 3467105694Srwatson break; 3468105694Srwatson default: 3469105694Srwatson panic("__mac_get_fd: corrupted label_type"); 3470105694Srwatson } 3471105694Srwatson 3472100979Srwatson if (error == 0) 3473105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3474100979Srwatson 3475105694Srwatsonout: 3476105694Srwatson mtx_unlock(&Giant); /* VFS */ 3477105694Srwatson free(buffer, M_MACTEMP); 3478105694Srwatson free(elements, M_MACTEMP); 3479100979Srwatson 3480100979Srwatson return (error); 3481100979Srwatson} 3482100979Srwatson 3483100979Srwatson/* 3484100979Srwatson * MPSAFE 3485100979Srwatson */ 3486100979Srwatsonint 3487100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3488100979Srwatson{ 3489105694Srwatson char *elements, *buffer; 3490100979Srwatson struct nameidata nd; 3491105694Srwatson struct label intlabel; 3492105694Srwatson struct mac mac; 3493100979Srwatson int error; 3494100979Srwatson 3495105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3496105694Srwatson if (error) 3497105694Srwatson return (error); 3498105694Srwatson 3499105694Srwatson error = mac_check_structmac_consistent(&mac); 3500105694Srwatson if (error) 3501105694Srwatson return (error); 3502105694Srwatson 3503111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3504105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3505105694Srwatson if (error) { 3506105694Srwatson free(elements, M_MACTEMP); 3507105694Srwatson return (error); 3508105694Srwatson } 3509105694Srwatson 3510111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3511105694Srwatson mtx_lock(&Giant); /* VFS */ 3512105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3513105694Srwatson td); 3514100979Srwatson error = namei(&nd); 3515100979Srwatson if (error) 3516100979Srwatson goto out; 3517100979Srwatson 3518105694Srwatson mac_init_vnode_label(&intlabel); 3519105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3520105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3521111119Simp mac.m_buflen, M_WAITOK); 3522105694Srwatson 3523100979Srwatson NDFREE(&nd, 0); 3524105694Srwatson mac_destroy_vnode_label(&intlabel); 3525105694Srwatson 3526105694Srwatson if (error == 0) 3527105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3528105694Srwatson 3529105694Srwatsonout: 3530105694Srwatson mtx_unlock(&Giant); /* VFS */ 3531105694Srwatson 3532105694Srwatson free(buffer, M_MACTEMP); 3533105694Srwatson free(elements, M_MACTEMP); 3534105694Srwatson 3535105694Srwatson return (error); 3536105694Srwatson} 3537105694Srwatson 3538105694Srwatson/* 3539105694Srwatson * MPSAFE 3540105694Srwatson */ 3541105694Srwatsonint 3542105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3543105694Srwatson{ 3544105694Srwatson char *elements, *buffer; 3545105694Srwatson struct nameidata nd; 3546105694Srwatson struct label intlabel; 3547105694Srwatson struct mac mac; 3548105694Srwatson int error; 3549105694Srwatson 3550105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3551100979Srwatson if (error) 3552105694Srwatson return (error); 3553105694Srwatson 3554105694Srwatson error = mac_check_structmac_consistent(&mac); 3555105694Srwatson if (error) 3556105694Srwatson return (error); 3557105694Srwatson 3558111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3559105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3560105694Srwatson if (error) { 3561105694Srwatson free(elements, M_MACTEMP); 3562105694Srwatson return (error); 3563105694Srwatson } 3564105694Srwatson 3565111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3566105694Srwatson mtx_lock(&Giant); /* VFS */ 3567105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3568105694Srwatson td); 3569105694Srwatson error = namei(&nd); 3570105694Srwatson if (error) 3571100979Srwatson goto out; 3572100979Srwatson 3573105694Srwatson mac_init_vnode_label(&intlabel); 3574105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3575105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3576111119Simp mac.m_buflen, M_WAITOK); 3577105694Srwatson NDFREE(&nd, 0); 3578105694Srwatson mac_destroy_vnode_label(&intlabel); 3579100979Srwatson 3580105694Srwatson if (error == 0) 3581105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3582105694Srwatson 3583100979Srwatsonout: 3584105694Srwatson mtx_unlock(&Giant); /* VFS */ 3585105694Srwatson 3586105694Srwatson free(buffer, M_MACTEMP); 3587105694Srwatson free(elements, M_MACTEMP); 3588105694Srwatson 3589100979Srwatson return (error); 3590100979Srwatson} 3591100979Srwatson 3592100979Srwatson/* 3593100979Srwatson * MPSAFE 3594100979Srwatson */ 3595100979Srwatsonint 3596100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3597100979Srwatson{ 3598105694Srwatson struct label intlabel; 3599105694Srwatson struct pipe *pipe; 3600100979Srwatson struct file *fp; 3601100979Srwatson struct mount *mp; 3602100979Srwatson struct vnode *vp; 3603105694Srwatson struct mac mac; 3604105694Srwatson char *buffer; 3605100979Srwatson int error; 3606100979Srwatson 3607105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3608100979Srwatson if (error) 3609105694Srwatson return (error); 3610100979Srwatson 3611105694Srwatson error = mac_check_structmac_consistent(&mac); 3612100979Srwatson if (error) 3613105694Srwatson return (error); 3614100979Srwatson 3615111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3616105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3617105694Srwatson if (error) { 3618105694Srwatson free(buffer, M_MACTEMP); 3619105694Srwatson return (error); 3620105694Srwatson } 3621105694Srwatson 3622105694Srwatson mtx_lock(&Giant); /* VFS */ 3623105694Srwatson 3624107849Salfred error = fget(td, uap->fd, &fp); 3625100979Srwatson if (error) 3626105694Srwatson goto out; 3627100979Srwatson 3628100979Srwatson switch (fp->f_type) { 3629100979Srwatson case DTYPE_FIFO: 3630100979Srwatson case DTYPE_VNODE: 3631105694Srwatson mac_init_vnode_label(&intlabel); 3632105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3633105694Srwatson if (error) { 3634105694Srwatson mac_destroy_vnode_label(&intlabel); 3635105694Srwatson break; 3636105694Srwatson } 3637105694Srwatson 3638116678Sphk vp = fp->f_vnode; 3639100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3640105694Srwatson if (error != 0) { 3641105694Srwatson mac_destroy_vnode_label(&intlabel); 3642100979Srwatson break; 3643105694Srwatson } 3644100979Srwatson 3645100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3646100979Srwatson error = vn_setlabel(vp, &intlabel, td->td_ucred); 3647100979Srwatson VOP_UNLOCK(vp, 0, td); 3648100979Srwatson vn_finished_write(mp); 3649105694Srwatson 3650105694Srwatson mac_destroy_vnode_label(&intlabel); 3651100979Srwatson break; 3652105694Srwatson 3653100979Srwatson case DTYPE_PIPE: 3654105694Srwatson mac_init_pipe_label(&intlabel); 3655105694Srwatson error = mac_internalize_pipe_label(&intlabel, buffer); 3656105694Srwatson if (error == 0) { 3657109153Sdillon pipe = fp->f_data; 3658105694Srwatson PIPE_LOCK(pipe); 3659105694Srwatson error = mac_pipe_label_set(td->td_ucred, pipe, 3660105694Srwatson &intlabel); 3661105694Srwatson PIPE_UNLOCK(pipe); 3662105694Srwatson } 3663105694Srwatson 3664105694Srwatson mac_destroy_pipe_label(&intlabel); 3665100979Srwatson break; 3666105694Srwatson 3667100979Srwatson default: 3668100979Srwatson error = EINVAL; 3669100979Srwatson } 3670100979Srwatson 3671100979Srwatson fdrop(fp, td); 3672105694Srwatsonout: 3673105694Srwatson mtx_unlock(&Giant); /* VFS */ 3674105694Srwatson 3675105694Srwatson free(buffer, M_MACTEMP); 3676105694Srwatson 3677100979Srwatson return (error); 3678100979Srwatson} 3679100979Srwatson 3680100979Srwatson/* 3681100979Srwatson * MPSAFE 3682100979Srwatson */ 3683100979Srwatsonint 3684100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3685100979Srwatson{ 3686105694Srwatson struct label intlabel; 3687100979Srwatson struct nameidata nd; 3688100979Srwatson struct mount *mp; 3689105694Srwatson struct mac mac; 3690105694Srwatson char *buffer; 3691100979Srwatson int error; 3692100979Srwatson 3693105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3694100979Srwatson if (error) 3695105694Srwatson return (error); 3696100979Srwatson 3697105694Srwatson error = mac_check_structmac_consistent(&mac); 3698100979Srwatson if (error) 3699105694Srwatson return (error); 3700100979Srwatson 3701111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3702105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3703105694Srwatson if (error) { 3704105694Srwatson free(buffer, M_MACTEMP); 3705105694Srwatson return (error); 3706105694Srwatson } 3707105694Srwatson 3708105694Srwatson mac_init_vnode_label(&intlabel); 3709105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3710105694Srwatson free(buffer, M_MACTEMP); 3711105694Srwatson if (error) { 3712105694Srwatson mac_destroy_vnode_label(&intlabel); 3713105694Srwatson return (error); 3714105694Srwatson } 3715105694Srwatson 3716105694Srwatson mtx_lock(&Giant); /* VFS */ 3717105694Srwatson 3718105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3719105694Srwatson td); 3720100979Srwatson error = namei(&nd); 3721105694Srwatson if (error == 0) { 3722105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3723105694Srwatson if (error == 0) 3724105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3725105694Srwatson td->td_ucred); 3726105694Srwatson vn_finished_write(mp); 3727105694Srwatson } 3728105694Srwatson 3729105694Srwatson NDFREE(&nd, 0); 3730105694Srwatson mtx_unlock(&Giant); /* VFS */ 3731105694Srwatson mac_destroy_vnode_label(&intlabel); 3732105694Srwatson 3733105694Srwatson return (error); 3734105694Srwatson} 3735105694Srwatson 3736105694Srwatson/* 3737105694Srwatson * MPSAFE 3738105694Srwatson */ 3739105694Srwatsonint 3740105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3741105694Srwatson{ 3742105694Srwatson struct label intlabel; 3743105694Srwatson struct nameidata nd; 3744105694Srwatson struct mount *mp; 3745105694Srwatson struct mac mac; 3746105694Srwatson char *buffer; 3747105694Srwatson int error; 3748105694Srwatson 3749105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3750100979Srwatson if (error) 3751105694Srwatson return (error); 3752105694Srwatson 3753105694Srwatson error = mac_check_structmac_consistent(&mac); 3754100979Srwatson if (error) 3755105694Srwatson return (error); 3756100979Srwatson 3757111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3758105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3759105694Srwatson if (error) { 3760105694Srwatson free(buffer, M_MACTEMP); 3761105694Srwatson return (error); 3762105694Srwatson } 3763105694Srwatson 3764105694Srwatson mac_init_vnode_label(&intlabel); 3765105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3766105694Srwatson free(buffer, M_MACTEMP); 3767105694Srwatson if (error) { 3768105694Srwatson mac_destroy_vnode_label(&intlabel); 3769105694Srwatson return (error); 3770105694Srwatson } 3771105694Srwatson 3772105694Srwatson mtx_lock(&Giant); /* VFS */ 3773105694Srwatson 3774105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3775105694Srwatson td); 3776105694Srwatson error = namei(&nd); 3777105694Srwatson if (error == 0) { 3778105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3779105694Srwatson if (error == 0) 3780105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3781105694Srwatson td->td_ucred); 3782105694Srwatson vn_finished_write(mp); 3783105694Srwatson } 3784105694Srwatson 3785100979Srwatson NDFREE(&nd, 0); 3786105694Srwatson mtx_unlock(&Giant); /* VFS */ 3787105694Srwatson mac_destroy_vnode_label(&intlabel); 3788105694Srwatson 3789100979Srwatson return (error); 3790100979Srwatson} 3791100979Srwatson 3792105694Srwatson/* 3793105694Srwatson * MPSAFE 3794105694Srwatson */ 3795102123Srwatsonint 3796102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3797102123Srwatson{ 3798102123Srwatson struct mac_policy_conf *mpc; 3799102123Srwatson char target[MAC_MAX_POLICY_NAME]; 3800114806Srwatson int entrycount, error; 3801102123Srwatson 3802107849Salfred error = copyinstr(uap->policy, target, sizeof(target), NULL); 3803102123Srwatson if (error) 3804102123Srwatson return (error); 3805102123Srwatson 3806102123Srwatson error = ENOSYS; 3807102123Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3808102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3809102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3810102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3811107849Salfred uap->call, uap->arg); 3812102123Srwatson goto out; 3813102123Srwatson } 3814102123Srwatson } 3815102123Srwatson 3816114806Srwatson if ((entrycount = mac_policy_list_conditional_busy()) != 0) { 3817114806Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3818114806Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3819114806Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3820114806Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3821114806Srwatson uap->call, uap->arg); 3822114806Srwatson break; 3823114806Srwatson } 3824114806Srwatson } 3825114806Srwatson mac_policy_list_unbusy(); 3826114806Srwatson } 3827102123Srwatsonout: 3828102123Srwatson return (error); 3829102123Srwatson} 3830102123Srwatson 3831100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3832100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3833100979Srwatson 3834100979Srwatson#else /* !MAC */ 3835100979Srwatson 3836100979Srwatsonint 3837105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3838105694Srwatson{ 3839105694Srwatson 3840105694Srwatson return (ENOSYS); 3841105694Srwatson} 3842105694Srwatson 3843105694Srwatsonint 3844100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3845100979Srwatson{ 3846100979Srwatson 3847100894Srwatson return (ENOSYS); 3848100894Srwatson} 3849100894Srwatson 3850100894Srwatsonint 3851100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3852100894Srwatson{ 3853100894Srwatson 3854100894Srwatson return (ENOSYS); 3855100894Srwatson} 3856100894Srwatson 3857100894Srwatsonint 3858100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3859100894Srwatson{ 3860100894Srwatson 3861100894Srwatson return (ENOSYS); 3862100894Srwatson} 3863100894Srwatson 3864100894Srwatsonint 3865100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3866100894Srwatson{ 3867100894Srwatson 3868100894Srwatson return (ENOSYS); 3869100894Srwatson} 3870100894Srwatson 3871100894Srwatsonint 3872105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3873105694Srwatson{ 3874105694Srwatson 3875105694Srwatson return (ENOSYS); 3876105694Srwatson} 3877105694Srwatson 3878105694Srwatsonint 3879100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3880100894Srwatson{ 3881100894Srwatson 3882100894Srwatson return (ENOSYS); 3883100894Srwatson} 3884100894Srwatson 3885100894Srwatsonint 3886100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3887100894Srwatson{ 3888100894Srwatson 3889100894Srwatson return (ENOSYS); 3890100894Srwatson} 3891100979Srwatson 3892102123Srwatsonint 3893105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3894105694Srwatson{ 3895105694Srwatson 3896105694Srwatson return (ENOSYS); 3897105694Srwatson} 3898105694Srwatson 3899105694Srwatsonint 3900102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3901102123Srwatson{ 3902102123Srwatson 3903102123Srwatson return (ENOSYS); 3904102123Srwatson} 3905102123Srwatson 3906105694Srwatson#endif 3907