mac_process.c revision 113955
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 * 36100894Srwatson * $FreeBSD: head/sys/security/mac/mac_process.c 113955 2003-04-24 04:31:25Z alc $ 37100894Srwatson */ 38100894Srwatson/* 39100894Srwatson * Developed by the TrustedBSD Project. 40100894Srwatson * 41100894Srwatson * Framework for extensible kernel access control. Kernel and userland 42100894Srwatson * interface to the framework, policy registration and composition. 43100894Srwatson */ 44100894Srwatson 45100894Srwatson#include "opt_mac.h" 46104300Sphk#include "opt_devfs.h" 47101173Srwatson 48100894Srwatson#include <sys/param.h> 49106856Srwatson#include <sys/condvar.h> 50100979Srwatson#include <sys/extattr.h> 51106468Srwatson#include <sys/imgact.h> 52100979Srwatson#include <sys/kernel.h> 53100979Srwatson#include <sys/lock.h> 54102949Sbde#include <sys/malloc.h> 55100979Srwatson#include <sys/mutex.h> 56100979Srwatson#include <sys/mac.h> 57101712Srwatson#include <sys/module.h> 58100979Srwatson#include <sys/proc.h> 59100979Srwatson#include <sys/systm.h> 60100894Srwatson#include <sys/sysproto.h> 61100894Srwatson#include <sys/sysent.h> 62100979Srwatson#include <sys/vnode.h> 63100979Srwatson#include <sys/mount.h> 64100979Srwatson#include <sys/file.h> 65100979Srwatson#include <sys/namei.h> 66100979Srwatson#include <sys/socket.h> 67100979Srwatson#include <sys/pipe.h> 68100979Srwatson#include <sys/socketvar.h> 69100979Srwatson#include <sys/sysctl.h> 70100894Srwatson 71100979Srwatson#include <vm/vm.h> 72100979Srwatson#include <vm/pmap.h> 73100979Srwatson#include <vm/vm_map.h> 74100979Srwatson#include <vm/vm_object.h> 75100979Srwatson 76100979Srwatson#include <sys/mac_policy.h> 77100979Srwatson 78100979Srwatson#include <fs/devfs/devfs.h> 79100979Srwatson 80100979Srwatson#include <net/bpfdesc.h> 81100979Srwatson#include <net/if.h> 82100979Srwatson#include <net/if_var.h> 83100979Srwatson 84100979Srwatson#include <netinet/in.h> 85100979Srwatson#include <netinet/ip_var.h> 86100979Srwatson 87100979Srwatson#ifdef MAC 88100979Srwatson 89101712Srwatson/* 90101712Srwatson * Declare that the kernel provides MAC support, version 1. This permits 91101712Srwatson * modules to refuse to be loaded if the necessary support isn't present, 92101712Srwatson * even if it's pre-boot. 93101712Srwatson */ 94101712SrwatsonMODULE_VERSION(kernel_mac_support, 1); 95101712Srwatson 96100979SrwatsonSYSCTL_DECL(_security); 97100979Srwatson 98100979SrwatsonSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 99100979Srwatson "TrustedBSD MAC policy controls"); 100104517Srwatson 101100979Srwatson#if MAC_MAX_POLICIES > 32 102100979Srwatson#error "MAC_MAX_POLICIES too large" 103100979Srwatson#endif 104105497Srwatson 105100979Srwatsonstatic unsigned int mac_max_policies = MAC_MAX_POLICIES; 106100979Srwatsonstatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 107100979SrwatsonSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 108100979Srwatson &mac_max_policies, 0, ""); 109100979Srwatson 110105959Srwatson/* 111105959Srwatson * Has the kernel started generating labeled objects yet? All read/write 112105959Srwatson * access to this variable is serialized during the boot process. Following 113105959Srwatson * the end of serialization, we don't update this flag; no locking. 114105959Srwatson */ 115100979Srwatsonstatic int mac_late = 0; 116100979Srwatson 117105988Srwatson/* 118105988Srwatson * Warn about EA transactions only the first time they happen. 119105988Srwatson * Weak coherency, no locking. 120105988Srwatson */ 121105988Srwatsonstatic int ea_warn_once = 0; 122105988Srwatson 123113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 124113487Srwatson/* 125113487Srwatson * Flag to indicate whether or not we should allocate label storage for 126113487Srwatson * new mbufs. Since most dynamic policies we currently work with don't 127113487Srwatson * rely on mbuf labeling, try to avoid paying the cost of mtag allocation 128113487Srwatson * unless specifically notified of interest. One result of this is 129113487Srwatson * that if a dynamically loaded policy requests mbuf labels, it must 130113487Srwatson * be able to deal with a NULL label being returned on any mbufs that 131113487Srwatson * were already in flight when the policy was loaded. Since the policy 132113487Srwatson * already has to deal with uninitialized labels, this probably won't 133113487Srwatson * be a problem. Note: currently no locking. Will this be a problem? 134113487Srwatson */ 135113487Srwatsonstatic int mac_labelmbufs = 0; 136113487Srwatson#endif 137113487Srwatson 138100979Srwatsonstatic int mac_enforce_fs = 1; 139100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 140100979Srwatson &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 141100979SrwatsonTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 142100979Srwatson 143107089Srwatsonstatic int mac_enforce_kld = 1; 144107089SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW, 145107089Srwatson &mac_enforce_kld, 0, "Enforce MAC policy on kld operations"); 146107089SrwatsonTUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld); 147107089Srwatson 148100979Srwatsonstatic int mac_enforce_network = 1; 149100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 150100979Srwatson &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 151100979SrwatsonTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 152100979Srwatson 153103513Srwatsonstatic int mac_enforce_pipe = 1; 154103513SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 155103513Srwatson &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 156104236SrwatsonTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 157103513Srwatson 158100979Srwatsonstatic int mac_enforce_process = 1; 159100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 160100979Srwatson &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 161100979SrwatsonTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 162100979Srwatson 163100979Srwatsonstatic int mac_enforce_socket = 1; 164100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 165100979Srwatson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 166100979SrwatsonTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 167100979Srwatson 168106045Srwatsonstatic int mac_enforce_system = 1; 169106045SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 170106045Srwatson &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 171106045SrwatsonTUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 172106025Srwatson 173106045Srwatsonstatic int mac_enforce_vm = 1; 174103514SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 175103514Srwatson &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 176104236SrwatsonTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 177103514Srwatson 178103136Srwatsonstatic int mac_mmap_revocation = 1; 179103136SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 180103136Srwatson &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 181103136Srwatson "relabel"); 182101892Srwatsonstatic int mac_mmap_revocation_via_cow = 0; 183100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 184100979Srwatson &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 185100979Srwatson "copy-on-write semantics, or by removing all write access"); 186100979Srwatson 187101988Srwatson#ifdef MAC_DEBUG 188104268SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 189104268Srwatson "TrustedBSD MAC debug info"); 190104268Srwatson 191104268Srwatsonstatic int mac_debug_label_fallback = 0; 192104268SrwatsonSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 193104268Srwatson &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 194104268Srwatson "when label is corrupted."); 195104268SrwatsonTUNABLE_INT("security.mac.debug_label_fallback", 196104268Srwatson &mac_debug_label_fallback); 197104268Srwatson 198104517SrwatsonSYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 199104517Srwatson "TrustedBSD MAC object counters"); 200104517Srwatson 201100979Srwatsonstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 202100979Srwatson nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 203107105Srwatson nmacipqs, nmacpipes, nmacprocs; 204104517Srwatson 205104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 206100979Srwatson &nmacmbufs, 0, "number of mbufs in use"); 207104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 208100979Srwatson &nmaccreds, 0, "number of ucreds in use"); 209104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 210100979Srwatson &nmacifnets, 0, "number of ifnets in use"); 211104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 212100979Srwatson &nmacipqs, 0, "number of ipqs in use"); 213104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 214100979Srwatson &nmacbpfdescs, 0, "number of bpfdescs in use"); 215104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 216100979Srwatson &nmacsockets, 0, "number of sockets in use"); 217104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 218100979Srwatson &nmacpipes, 0, "number of pipes in use"); 219107105SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, procs, CTLFLAG_RD, 220107105Srwatson &nmacprocs, 0, "number of procs in use"); 221104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 222100979Srwatson &nmacmounts, 0, "number of mounts in use"); 223104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 224100979Srwatson &nmactemp, 0, "number of temporary labels in use"); 225104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 226100979Srwatson &nmacvnodes, 0, "number of vnodes in use"); 227104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 228100979Srwatson &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 229101988Srwatson#endif 230100979Srwatson 231100979Srwatsonstatic int error_select(int error1, int error2); 232100979Srwatsonstatic int mac_policy_register(struct mac_policy_conf *mpc); 233100979Srwatsonstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 234100979Srwatson 235104546Srwatsonstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 236104546Srwatson struct vnode *vp, int *prot); 237100979Srwatsonstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 238100979Srwatson struct ucred *cred, struct vm_map *map); 239100979Srwatson 240104541Srwatsonstatic void mac_destroy_socket_label(struct label *label); 241104541Srwatson 242105988Srwatsonstatic int mac_setlabel_vnode_extattr(struct ucred *cred, 243105988Srwatson struct vnode *vp, struct label *intlabel); 244105988Srwatson 245100979SrwatsonMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 246105694SrwatsonMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 247100979Srwatson 248100979Srwatson/* 249106856Srwatson * mac_policy_list stores the list of active policies. A busy count is 250106856Srwatson * maintained for the list, stored in mac_policy_busy. The busy count 251106856Srwatson * is protected by mac_policy_list_lock; the list may be modified only 252106856Srwatson * while the busy count is 0, requiring that the lock be held to 253106856Srwatson * prevent new references to the list from being acquired. For almost 254106856Srwatson * all operations, incrementing the busy count is sufficient to 255106856Srwatson * guarantee consistency, as the list cannot be modified while the 256106856Srwatson * busy count is elevated. For a few special operations involving a 257106856Srwatson * change to the list of active policies, the lock itself must be held. 258106856Srwatson * A condition variable, mac_policy_list_not_busy, is used to signal 259106856Srwatson * potential exclusive consumers that they should try to acquire the 260106856Srwatson * lock if a first attempt at exclusive access fails. 261100979Srwatson */ 262100979Srwatsonstatic struct mtx mac_policy_list_lock; 263106856Srwatsonstatic struct cv mac_policy_list_not_busy; 264100979Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 265100979Srwatsonstatic int mac_policy_list_busy; 266100979Srwatson 267106856Srwatson#define MAC_POLICY_LIST_LOCKINIT() do { \ 268106856Srwatson mtx_init(&mac_policy_list_lock, "mac_policy_list_lock", NULL, \ 269106856Srwatson MTX_DEF); \ 270106856Srwatson cv_init(&mac_policy_list_not_busy, "mac_policy_list_not_busy"); \ 271106856Srwatson} while (0) 272106856Srwatson 273106856Srwatson#define MAC_POLICY_LIST_LOCK() do { \ 274106856Srwatson mtx_lock(&mac_policy_list_lock); \ 275106856Srwatson} while (0) 276106856Srwatson 277106856Srwatson#define MAC_POLICY_LIST_UNLOCK() do { \ 278106856Srwatson mtx_unlock(&mac_policy_list_lock); \ 279106856Srwatson} while (0) 280106856Srwatson 281106856Srwatson/* 282111883Sjhb * We manually invoke WITNESS_WARN() to allow Witness to generate 283106856Srwatson * warnings even if we don't end up ever triggering the wait at 284106856Srwatson * run-time. The consumer of the exclusive interface must not hold 285106856Srwatson * any locks (other than potentially Giant) since we may sleep for 286106856Srwatson * long (potentially indefinite) periods of time waiting for the 287106856Srwatson * framework to become quiescent so that a policy list change may 288106856Srwatson * be made. 289106856Srwatson */ 290106856Srwatson#define MAC_POLICY_LIST_EXCLUSIVE() do { \ 291111883Sjhb WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, \ 292111883Sjhb "mac_policy_list_exclusive() at %s:%d", __FILE__, __LINE__);\ 293106856Srwatson mtx_lock(&mac_policy_list_lock); \ 294106856Srwatson while (mac_policy_list_busy != 0) \ 295106856Srwatson cv_wait(&mac_policy_list_not_busy, \ 296106856Srwatson &mac_policy_list_lock); \ 297106856Srwatson} while (0) 298106856Srwatson 299113487Srwatson#define MAC_POLICY_LIST_ASSERT_EXCLUSIVE() do { \ 300113487Srwatson mtx_assert(&mac_policy_list_lock, MA_OWNED); \ 301113487Srwatson KASSERT(mac_policy_list_busy == 0, \ 302113487Srwatson ("MAC_POLICY_LIST_ASSERT_EXCLUSIVE()")); \ 303113487Srwatson} while (0) 304113487Srwatson 305100979Srwatson#define MAC_POLICY_LIST_BUSY() do { \ 306100979Srwatson MAC_POLICY_LIST_LOCK(); \ 307100979Srwatson mac_policy_list_busy++; \ 308100979Srwatson MAC_POLICY_LIST_UNLOCK(); \ 309100979Srwatson} while (0) 310100979Srwatson 311100979Srwatson#define MAC_POLICY_LIST_UNBUSY() do { \ 312100979Srwatson MAC_POLICY_LIST_LOCK(); \ 313100979Srwatson mac_policy_list_busy--; \ 314106856Srwatson KASSERT(mac_policy_list_busy >= 0, ("MAC_POLICY_LIST_LOCK")); \ 315106856Srwatson if (mac_policy_list_busy == 0) \ 316106856Srwatson cv_signal(&mac_policy_list_not_busy); \ 317100979Srwatson MAC_POLICY_LIST_UNLOCK(); \ 318100979Srwatson} while (0) 319100979Srwatson 320100979Srwatson/* 321100979Srwatson * MAC_CHECK performs the designated check by walking the policy 322100979Srwatson * module list and checking with each as to how it feels about the 323100979Srwatson * request. Note that it returns its value via 'error' in the scope 324100979Srwatson * of the caller. 325100979Srwatson */ 326100979Srwatson#define MAC_CHECK(check, args...) do { \ 327100979Srwatson struct mac_policy_conf *mpc; \ 328100979Srwatson \ 329100979Srwatson error = 0; \ 330100979Srwatson MAC_POLICY_LIST_BUSY(); \ 331100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 332100979Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 333100979Srwatson error = error_select( \ 334100979Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 335100979Srwatson error); \ 336100979Srwatson } \ 337100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 338100979Srwatson} while (0) 339100979Srwatson 340100979Srwatson/* 341100979Srwatson * MAC_BOOLEAN performs the designated boolean composition by walking 342100979Srwatson * the module list, invoking each instance of the operation, and 343100979Srwatson * combining the results using the passed C operator. Note that it 344100979Srwatson * returns its value via 'result' in the scope of the caller, which 345100979Srwatson * should be initialized by the caller in a meaningful way to get 346100979Srwatson * a meaningful result. 347100979Srwatson */ 348100979Srwatson#define MAC_BOOLEAN(operation, composition, args...) do { \ 349100979Srwatson struct mac_policy_conf *mpc; \ 350100979Srwatson \ 351100979Srwatson MAC_POLICY_LIST_BUSY(); \ 352100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 353100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 354100979Srwatson result = result composition \ 355100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 356100979Srwatson } \ 357100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 358100979Srwatson} while (0) 359100979Srwatson 360105694Srwatson#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 361105694Srwatson outbuflen) do { \ 362105694Srwatson char *curptr, *curptr_start, *element_name, *element_temp; \ 363105694Srwatson size_t left, left_start, len; \ 364105694Srwatson int claimed, first, first_start, ignorenotfound; \ 365105694Srwatson \ 366105694Srwatson error = 0; \ 367105694Srwatson element_temp = elementlist; \ 368105694Srwatson curptr = outbuf; \ 369105694Srwatson curptr[0] = '\0'; \ 370105694Srwatson left = outbuflen; \ 371105694Srwatson first = 1; \ 372105694Srwatson while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 373105694Srwatson curptr_start = curptr; \ 374105694Srwatson left_start = left; \ 375105694Srwatson first_start = first; \ 376105694Srwatson if (element_name[0] == '?') { \ 377105694Srwatson element_name++; \ 378105694Srwatson ignorenotfound = 1; \ 379105694Srwatson } else \ 380105694Srwatson ignorenotfound = 0; \ 381105694Srwatson claimed = 0; \ 382105694Srwatson if (first) { \ 383105694Srwatson len = snprintf(curptr, left, "%s/", \ 384105694Srwatson element_name); \ 385105694Srwatson first = 0; \ 386105694Srwatson } else \ 387105694Srwatson len = snprintf(curptr, left, ",%s/", \ 388105694Srwatson element_name); \ 389105694Srwatson if (len >= left) { \ 390105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 391105694Srwatson break; \ 392105694Srwatson } \ 393105694Srwatson curptr += len; \ 394105694Srwatson left -= len; \ 395105694Srwatson \ 396105694Srwatson MAC_CHECK(externalize_ ## type, label, element_name, \ 397105694Srwatson curptr, left, &len, &claimed); \ 398105694Srwatson if (error) \ 399105694Srwatson break; \ 400105694Srwatson if (claimed == 1) { \ 401105694Srwatson if (len >= outbuflen) { \ 402105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 403105694Srwatson break; \ 404105694Srwatson } \ 405105694Srwatson curptr += len; \ 406105694Srwatson left -= len; \ 407105694Srwatson } else if (claimed == 0 && ignorenotfound) { \ 408105694Srwatson /* \ 409105694Srwatson * Revert addition of the label element \ 410105694Srwatson * name. \ 411105694Srwatson */ \ 412105694Srwatson curptr = curptr_start; \ 413105694Srwatson *curptr = '\0'; \ 414105694Srwatson left = left_start; \ 415105694Srwatson first = first_start; \ 416105694Srwatson } else { \ 417105694Srwatson error = EINVAL; /* XXXMAC: ENOLABEL */ \ 418105694Srwatson break; \ 419105694Srwatson } \ 420105694Srwatson } \ 421105694Srwatson} while (0) 422105694Srwatson 423105694Srwatson#define MAC_INTERNALIZE(type, label, instring) do { \ 424105694Srwatson char *element, *element_name, *element_data; \ 425105694Srwatson int claimed; \ 426105694Srwatson \ 427105694Srwatson error = 0; \ 428105694Srwatson element = instring; \ 429105694Srwatson while ((element_name = strsep(&element, ",")) != NULL) { \ 430105694Srwatson element_data = element_name; \ 431105694Srwatson element_name = strsep(&element_data, "/"); \ 432105694Srwatson if (element_data == NULL) { \ 433105694Srwatson error = EINVAL; \ 434105694Srwatson break; \ 435105694Srwatson } \ 436105694Srwatson claimed = 0; \ 437105694Srwatson MAC_CHECK(internalize_ ## type, label, element_name, \ 438105694Srwatson element_data, &claimed); \ 439105694Srwatson if (error) \ 440105694Srwatson break; \ 441105694Srwatson if (claimed != 1) { \ 442105694Srwatson /* XXXMAC: Another error here? */ \ 443105694Srwatson error = EINVAL; \ 444105694Srwatson break; \ 445105694Srwatson } \ 446105694Srwatson } \ 447105694Srwatson} while (0) 448105694Srwatson 449100979Srwatson/* 450100979Srwatson * MAC_PERFORM performs the designated operation by walking the policy 451100979Srwatson * module list and invoking that operation for each policy. 452100979Srwatson */ 453100979Srwatson#define MAC_PERFORM(operation, args...) do { \ 454100979Srwatson struct mac_policy_conf *mpc; \ 455100979Srwatson \ 456100979Srwatson MAC_POLICY_LIST_BUSY(); \ 457100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 458100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 459100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 460100979Srwatson } \ 461100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 462100979Srwatson} while (0) 463100979Srwatson 464100979Srwatson/* 465100979Srwatson * Initialize the MAC subsystem, including appropriate SMP locks. 466100979Srwatson */ 467100979Srwatsonstatic void 468100979Srwatsonmac_init(void) 469100979Srwatson{ 470100979Srwatson 471100979Srwatson LIST_INIT(&mac_policy_list); 472100979Srwatson MAC_POLICY_LIST_LOCKINIT(); 473100979Srwatson} 474100979Srwatson 475100979Srwatson/* 476100979Srwatson * For the purposes of modules that want to know if they were loaded 477100979Srwatson * "early", set the mac_late flag once we've processed modules either 478100979Srwatson * linked into the kernel, or loaded before the kernel startup. 479100979Srwatson */ 480100979Srwatsonstatic void 481100979Srwatsonmac_late_init(void) 482100979Srwatson{ 483100979Srwatson 484100979Srwatson mac_late = 1; 485100979Srwatson} 486100979Srwatson 487100979Srwatson/* 488113487Srwatson * After the policy list has changed, walk the list to update any global 489113487Srwatson * flags. 490113487Srwatson */ 491113487Srwatsonstatic void 492113487Srwatsonmac_policy_updateflags(void) 493113487Srwatson{ 494113487Srwatson struct mac_policy_conf *tmpc; 495113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 496113487Srwatson int labelmbufs; 497113487Srwatson#endif 498113487Srwatson 499113487Srwatson MAC_POLICY_LIST_ASSERT_EXCLUSIVE(); 500113487Srwatson 501113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 502113487Srwatson labelmbufs = 0; 503113487Srwatson#endif 504113487Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 505113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 506113487Srwatson if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) 507113487Srwatson labelmbufs++; 508113487Srwatson#endif 509113487Srwatson } 510113487Srwatson 511113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 512113487Srwatson mac_labelmbufs = (labelmbufs != 0); 513113487Srwatson#endif 514113487Srwatson} 515113487Srwatson 516113487Srwatson/* 517100979Srwatson * Allow MAC policy modules to register during boot, etc. 518100979Srwatson */ 519100894Srwatsonint 520100979Srwatsonmac_policy_modevent(module_t mod, int type, void *data) 521100979Srwatson{ 522100979Srwatson struct mac_policy_conf *mpc; 523100979Srwatson int error; 524100979Srwatson 525100979Srwatson error = 0; 526100979Srwatson mpc = (struct mac_policy_conf *) data; 527100979Srwatson 528100979Srwatson switch (type) { 529100979Srwatson case MOD_LOAD: 530100979Srwatson if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 531100979Srwatson mac_late) { 532100979Srwatson printf("mac_policy_modevent: can't load %s policy " 533100979Srwatson "after booting\n", mpc->mpc_name); 534100979Srwatson error = EBUSY; 535100979Srwatson break; 536100979Srwatson } 537100979Srwatson error = mac_policy_register(mpc); 538100979Srwatson break; 539100979Srwatson case MOD_UNLOAD: 540100979Srwatson /* Don't unregister the module if it was never registered. */ 541100979Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 542100979Srwatson != 0) 543100979Srwatson error = mac_policy_unregister(mpc); 544100979Srwatson else 545100979Srwatson error = 0; 546100979Srwatson break; 547100979Srwatson default: 548100979Srwatson break; 549100979Srwatson } 550100979Srwatson 551100979Srwatson return (error); 552100979Srwatson} 553100979Srwatson 554100979Srwatsonstatic int 555100979Srwatsonmac_policy_register(struct mac_policy_conf *mpc) 556100979Srwatson{ 557100979Srwatson struct mac_policy_conf *tmpc; 558100979Srwatson int slot; 559100979Srwatson 560106856Srwatson MAC_POLICY_LIST_EXCLUSIVE(); 561100979Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 562100979Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 563100979Srwatson MAC_POLICY_LIST_UNLOCK(); 564100979Srwatson return (EEXIST); 565100979Srwatson } 566100979Srwatson } 567100979Srwatson if (mpc->mpc_field_off != NULL) { 568100979Srwatson slot = ffs(mac_policy_offsets_free); 569100979Srwatson if (slot == 0) { 570100979Srwatson MAC_POLICY_LIST_UNLOCK(); 571100979Srwatson return (ENOMEM); 572100979Srwatson } 573100979Srwatson slot--; 574100979Srwatson mac_policy_offsets_free &= ~(1 << slot); 575100979Srwatson *mpc->mpc_field_off = slot; 576100979Srwatson } 577100979Srwatson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 578100979Srwatson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 579100979Srwatson 580100979Srwatson /* Per-policy initialization. */ 581100979Srwatson if (mpc->mpc_ops->mpo_init != NULL) 582100979Srwatson (*(mpc->mpc_ops->mpo_init))(mpc); 583113487Srwatson mac_policy_updateflags(); 584100979Srwatson MAC_POLICY_LIST_UNLOCK(); 585100979Srwatson 586100979Srwatson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 587100979Srwatson mpc->mpc_name); 588100979Srwatson 589100979Srwatson return (0); 590100979Srwatson} 591100979Srwatson 592100979Srwatsonstatic int 593100979Srwatsonmac_policy_unregister(struct mac_policy_conf *mpc) 594100979Srwatson{ 595100979Srwatson 596104520Srwatson /* 597104520Srwatson * If we fail the load, we may get a request to unload. Check 598104520Srwatson * to see if we did the run-time registration, and if not, 599104520Srwatson * silently succeed. 600104520Srwatson */ 601106856Srwatson MAC_POLICY_LIST_EXCLUSIVE(); 602104520Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 603104520Srwatson MAC_POLICY_LIST_UNLOCK(); 604104520Srwatson return (0); 605104520Srwatson } 606100979Srwatson#if 0 607100979Srwatson /* 608100979Srwatson * Don't allow unloading modules with private data. 609100979Srwatson */ 610104520Srwatson if (mpc->mpc_field_off != NULL) { 611104520Srwatson MAC_POLICY_LIST_UNLOCK(); 612100979Srwatson return (EBUSY); 613104520Srwatson } 614100979Srwatson#endif 615104520Srwatson /* 616104520Srwatson * Only allow the unload to proceed if the module is unloadable 617104520Srwatson * by its own definition. 618104520Srwatson */ 619104520Srwatson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 620104520Srwatson MAC_POLICY_LIST_UNLOCK(); 621100979Srwatson return (EBUSY); 622104520Srwatson } 623100979Srwatson if (mpc->mpc_ops->mpo_destroy != NULL) 624100979Srwatson (*(mpc->mpc_ops->mpo_destroy))(mpc); 625100979Srwatson 626100979Srwatson LIST_REMOVE(mpc, mpc_list); 627106856Srwatson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 628113487Srwatson mac_policy_updateflags(); 629100979Srwatson MAC_POLICY_LIST_UNLOCK(); 630100979Srwatson 631100979Srwatson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 632100979Srwatson mpc->mpc_name); 633100979Srwatson 634100979Srwatson return (0); 635100979Srwatson} 636100979Srwatson 637100979Srwatson/* 638100979Srwatson * Define an error value precedence, and given two arguments, selects the 639100979Srwatson * value with the higher precedence. 640100979Srwatson */ 641100979Srwatsonstatic int 642100979Srwatsonerror_select(int error1, int error2) 643100979Srwatson{ 644100979Srwatson 645100979Srwatson /* Certain decision-making errors take top priority. */ 646100979Srwatson if (error1 == EDEADLK || error2 == EDEADLK) 647100979Srwatson return (EDEADLK); 648100979Srwatson 649100979Srwatson /* Invalid arguments should be reported where possible. */ 650100979Srwatson if (error1 == EINVAL || error2 == EINVAL) 651100979Srwatson return (EINVAL); 652100979Srwatson 653100979Srwatson /* Precedence goes to "visibility", with both process and file. */ 654100979Srwatson if (error1 == ESRCH || error2 == ESRCH) 655100979Srwatson return (ESRCH); 656100979Srwatson 657100979Srwatson if (error1 == ENOENT || error2 == ENOENT) 658100979Srwatson return (ENOENT); 659100979Srwatson 660100979Srwatson /* Precedence goes to DAC/MAC protections. */ 661100979Srwatson if (error1 == EACCES || error2 == EACCES) 662100979Srwatson return (EACCES); 663100979Srwatson 664100979Srwatson /* Precedence goes to privilege. */ 665100979Srwatson if (error1 == EPERM || error2 == EPERM) 666100979Srwatson return (EPERM); 667100979Srwatson 668100979Srwatson /* Precedence goes to error over success; otherwise, arbitrary. */ 669100979Srwatson if (error1 != 0) 670100979Srwatson return (error1); 671100979Srwatson return (error2); 672100979Srwatson} 673100979Srwatson 674113482Srwatsonstatic struct label * 675113482Srwatsonmbuf_to_label(struct mbuf *mbuf) 676113482Srwatson{ 677113487Srwatson struct m_tag *tag; 678113482Srwatson struct label *label; 679113482Srwatson 680113487Srwatson tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL); 681113487Srwatson label = (struct label *)(tag+1); 682113482Srwatson 683113482Srwatson return (label); 684113482Srwatson} 685113482Srwatson 686104521Srwatsonstatic void 687104521Srwatsonmac_init_label(struct label *label) 688104521Srwatson{ 689104521Srwatson 690104521Srwatson bzero(label, sizeof(*label)); 691104521Srwatson label->l_flags = MAC_FLAG_INITIALIZED; 692104521Srwatson} 693104521Srwatson 694104521Srwatsonstatic void 695104521Srwatsonmac_destroy_label(struct label *label) 696104521Srwatson{ 697104521Srwatson 698104521Srwatson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 699104521Srwatson ("destroying uninitialized label")); 700104521Srwatson 701104521Srwatson bzero(label, sizeof(*label)); 702104521Srwatson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 703104521Srwatson} 704104521Srwatson 705100979Srwatsonvoid 706104527Srwatsonmac_init_bpfdesc(struct bpf_d *bpf_d) 707104521Srwatson{ 708104521Srwatson 709104527Srwatson mac_init_label(&bpf_d->bd_label); 710104527Srwatson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 711104521Srwatson#ifdef MAC_DEBUG 712104527Srwatson atomic_add_int(&nmacbpfdescs, 1); 713104521Srwatson#endif 714104521Srwatson} 715104521Srwatson 716105694Srwatsonstatic void 717105694Srwatsonmac_init_cred_label(struct label *label) 718104521Srwatson{ 719104521Srwatson 720105694Srwatson mac_init_label(label); 721105694Srwatson MAC_PERFORM(init_cred_label, label); 722104521Srwatson#ifdef MAC_DEBUG 723104521Srwatson atomic_add_int(&nmaccreds, 1); 724104521Srwatson#endif 725104521Srwatson} 726104521Srwatson 727104521Srwatsonvoid 728105694Srwatsonmac_init_cred(struct ucred *cred) 729105694Srwatson{ 730105694Srwatson 731105694Srwatson mac_init_cred_label(&cred->cr_label); 732105694Srwatson} 733105694Srwatson 734105694Srwatsonvoid 735104527Srwatsonmac_init_devfsdirent(struct devfs_dirent *de) 736104521Srwatson{ 737104521Srwatson 738104527Srwatson mac_init_label(&de->de_label); 739104527Srwatson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 740104521Srwatson#ifdef MAC_DEBUG 741104527Srwatson atomic_add_int(&nmacdevfsdirents, 1); 742104521Srwatson#endif 743104521Srwatson} 744104521Srwatson 745105694Srwatsonstatic void 746105694Srwatsonmac_init_ifnet_label(struct label *label) 747104521Srwatson{ 748104521Srwatson 749105694Srwatson mac_init_label(label); 750105694Srwatson MAC_PERFORM(init_ifnet_label, label); 751104521Srwatson#ifdef MAC_DEBUG 752104521Srwatson atomic_add_int(&nmacifnets, 1); 753104521Srwatson#endif 754104521Srwatson} 755104521Srwatson 756104521Srwatsonvoid 757105694Srwatsonmac_init_ifnet(struct ifnet *ifp) 758105694Srwatson{ 759105694Srwatson 760105694Srwatson mac_init_ifnet_label(&ifp->if_label); 761105694Srwatson} 762105694Srwatson 763112675Srwatsonint 764112675Srwatsonmac_init_ipq(struct ipq *ipq, int flag) 765104521Srwatson{ 766112675Srwatson int error; 767104521Srwatson 768104527Srwatson mac_init_label(&ipq->ipq_label); 769112675Srwatson 770112675Srwatson MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag); 771112675Srwatson if (error) { 772112675Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 773112675Srwatson mac_destroy_label(&ipq->ipq_label); 774112675Srwatson } 775104521Srwatson#ifdef MAC_DEBUG 776112675Srwatson if (error == 0) 777112675Srwatson atomic_add_int(&nmacipqs, 1); 778104521Srwatson#endif 779112675Srwatson return (error); 780104521Srwatson} 781104521Srwatson 782104527Srwatsonint 783113487Srwatsonmac_init_mbuf_tag(struct m_tag *tag, int flag) 784104527Srwatson{ 785113487Srwatson struct label *label; 786113526Srwatson int error; 787104528Srwatson 788113487Srwatson label = (struct label *) (tag + 1); 789113487Srwatson mac_init_label(label); 790104527Srwatson 791113526Srwatson MAC_CHECK(init_mbuf_label, label, flag); 792104528Srwatson if (error) { 793113487Srwatson MAC_PERFORM(destroy_mbuf_label, label); 794113487Srwatson mac_destroy_label(label); 795104528Srwatson } 796104527Srwatson#ifdef MAC_DEBUG 797104528Srwatson if (error == 0) 798104528Srwatson atomic_add_int(&nmacmbufs, 1); 799104527Srwatson#endif 800104528Srwatson return (error); 801104527Srwatson} 802104527Srwatson 803113487Srwatsonint 804113487Srwatsonmac_init_mbuf(struct mbuf *m, int flag) 805113487Srwatson{ 806113487Srwatson struct m_tag *tag; 807113487Srwatson int error; 808113487Srwatson 809113487Srwatson M_ASSERTPKTHDR(m); 810113487Srwatson 811113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 812113487Srwatson /* 813113487Srwatson * Don't reserve space for labels on mbufs unless we have a policy 814113487Srwatson * that uses the labels. 815113487Srwatson */ 816113487Srwatson if (mac_labelmbufs) { 817113487Srwatson#endif 818113487Srwatson tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 819113487Srwatson flag); 820113487Srwatson if (tag == NULL) 821113487Srwatson return (ENOMEM); 822113487Srwatson error = mac_init_mbuf_tag(tag, flag); 823113487Srwatson if (error) { 824113487Srwatson m_tag_free(tag); 825113487Srwatson return (error); 826113487Srwatson } 827113487Srwatson m_tag_prepend(m, tag); 828113487Srwatson#ifndef MAC_ALWAYS_LABEL_MBUF 829113487Srwatson } 830113487Srwatson#endif 831113487Srwatson return (0); 832113487Srwatson} 833113487Srwatson 834104521Srwatsonvoid 835104527Srwatsonmac_init_mount(struct mount *mp) 836104521Srwatson{ 837104521Srwatson 838104527Srwatson mac_init_label(&mp->mnt_mntlabel); 839104527Srwatson mac_init_label(&mp->mnt_fslabel); 840104527Srwatson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 841104527Srwatson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 842104521Srwatson#ifdef MAC_DEBUG 843104527Srwatson atomic_add_int(&nmacmounts, 1); 844104521Srwatson#endif 845104521Srwatson} 846104521Srwatson 847105694Srwatsonstatic void 848105694Srwatsonmac_init_pipe_label(struct label *label) 849105694Srwatson{ 850105694Srwatson 851105694Srwatson mac_init_label(label); 852105694Srwatson MAC_PERFORM(init_pipe_label, label); 853105694Srwatson#ifdef MAC_DEBUG 854105694Srwatson atomic_add_int(&nmacpipes, 1); 855105694Srwatson#endif 856105694Srwatson} 857105694Srwatson 858104521Srwatsonvoid 859104527Srwatsonmac_init_pipe(struct pipe *pipe) 860104521Srwatson{ 861104527Srwatson struct label *label; 862104521Srwatson 863111119Simp label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 864104527Srwatson pipe->pipe_label = label; 865104527Srwatson pipe->pipe_peer->pipe_label = label; 866105694Srwatson mac_init_pipe_label(label); 867104521Srwatson} 868104521Srwatson 869107105Srwatsonvoid 870107105Srwatsonmac_init_proc(struct proc *p) 871107105Srwatson{ 872107105Srwatson 873107105Srwatson mac_init_label(&p->p_label); 874107105Srwatson MAC_PERFORM(init_proc_label, &p->p_label); 875107105Srwatson#ifdef MAC_DEBUG 876107105Srwatson atomic_add_int(&nmacprocs, 1); 877107105Srwatson#endif 878107105Srwatson} 879107105Srwatson 880104541Srwatsonstatic int 881104541Srwatsonmac_init_socket_label(struct label *label, int flag) 882104521Srwatson{ 883104541Srwatson int error; 884104521Srwatson 885104541Srwatson mac_init_label(label); 886104541Srwatson 887104541Srwatson MAC_CHECK(init_socket_label, label, flag); 888104541Srwatson if (error) { 889104541Srwatson MAC_PERFORM(destroy_socket_label, label); 890104541Srwatson mac_destroy_label(label); 891104541Srwatson } 892104541Srwatson 893104521Srwatson#ifdef MAC_DEBUG 894104541Srwatson if (error == 0) 895104541Srwatson atomic_add_int(&nmacsockets, 1); 896104521Srwatson#endif 897104541Srwatson 898104541Srwatson return (error); 899104521Srwatson} 900104521Srwatson 901104541Srwatsonstatic int 902104541Srwatsonmac_init_socket_peer_label(struct label *label, int flag) 903104541Srwatson{ 904104541Srwatson int error; 905104541Srwatson 906104541Srwatson mac_init_label(label); 907104541Srwatson 908104541Srwatson MAC_CHECK(init_socket_peer_label, label, flag); 909104541Srwatson if (error) { 910104541Srwatson MAC_PERFORM(destroy_socket_label, label); 911104541Srwatson mac_destroy_label(label); 912104541Srwatson } 913104541Srwatson 914104541Srwatson return (error); 915104541Srwatson} 916104541Srwatson 917104541Srwatsonint 918104541Srwatsonmac_init_socket(struct socket *socket, int flag) 919104541Srwatson{ 920104541Srwatson int error; 921104541Srwatson 922104541Srwatson error = mac_init_socket_label(&socket->so_label, flag); 923104541Srwatson if (error) 924104541Srwatson return (error); 925104541Srwatson 926104541Srwatson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 927104541Srwatson if (error) 928104541Srwatson mac_destroy_socket_label(&socket->so_label); 929104541Srwatson 930104541Srwatson return (error); 931104541Srwatson} 932104541Srwatson 933105988Srwatsonvoid 934105694Srwatsonmac_init_vnode_label(struct label *label) 935104521Srwatson{ 936104521Srwatson 937104527Srwatson mac_init_label(label); 938105694Srwatson MAC_PERFORM(init_vnode_label, label); 939104521Srwatson#ifdef MAC_DEBUG 940105694Srwatson atomic_add_int(&nmacvnodes, 1); 941104521Srwatson#endif 942104521Srwatson} 943104521Srwatson 944104521Srwatsonvoid 945104527Srwatsonmac_init_vnode(struct vnode *vp) 946104521Srwatson{ 947104521Srwatson 948105694Srwatson mac_init_vnode_label(&vp->v_label); 949104521Srwatson} 950104521Srwatson 951104521Srwatsonvoid 952104527Srwatsonmac_destroy_bpfdesc(struct bpf_d *bpf_d) 953104521Srwatson{ 954104521Srwatson 955104527Srwatson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 956104527Srwatson mac_destroy_label(&bpf_d->bd_label); 957104521Srwatson#ifdef MAC_DEBUG 958104527Srwatson atomic_subtract_int(&nmacbpfdescs, 1); 959104521Srwatson#endif 960104521Srwatson} 961104521Srwatson 962105694Srwatsonstatic void 963105694Srwatsonmac_destroy_cred_label(struct label *label) 964104521Srwatson{ 965104521Srwatson 966105694Srwatson MAC_PERFORM(destroy_cred_label, label); 967105694Srwatson mac_destroy_label(label); 968104521Srwatson#ifdef MAC_DEBUG 969104527Srwatson atomic_subtract_int(&nmaccreds, 1); 970104521Srwatson#endif 971104521Srwatson} 972104521Srwatson 973104521Srwatsonvoid 974105694Srwatsonmac_destroy_cred(struct ucred *cred) 975105694Srwatson{ 976105694Srwatson 977105694Srwatson mac_destroy_cred_label(&cred->cr_label); 978105694Srwatson} 979105694Srwatson 980105694Srwatsonvoid 981104527Srwatsonmac_destroy_devfsdirent(struct devfs_dirent *de) 982104521Srwatson{ 983104521Srwatson 984104527Srwatson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 985104527Srwatson mac_destroy_label(&de->de_label); 986104521Srwatson#ifdef MAC_DEBUG 987104527Srwatson atomic_subtract_int(&nmacdevfsdirents, 1); 988104521Srwatson#endif 989104521Srwatson} 990104521Srwatson 991105694Srwatsonstatic void 992105694Srwatsonmac_destroy_ifnet_label(struct label *label) 993104521Srwatson{ 994104521Srwatson 995105694Srwatson MAC_PERFORM(destroy_ifnet_label, label); 996105694Srwatson mac_destroy_label(label); 997104521Srwatson#ifdef MAC_DEBUG 998104527Srwatson atomic_subtract_int(&nmacifnets, 1); 999104521Srwatson#endif 1000104521Srwatson} 1001104521Srwatson 1002104521Srwatsonvoid 1003105694Srwatsonmac_destroy_ifnet(struct ifnet *ifp) 1004105694Srwatson{ 1005105694Srwatson 1006105694Srwatson mac_destroy_ifnet_label(&ifp->if_label); 1007105694Srwatson} 1008105694Srwatson 1009105694Srwatsonvoid 1010104527Srwatsonmac_destroy_ipq(struct ipq *ipq) 1011104521Srwatson{ 1012104521Srwatson 1013104527Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1014104527Srwatson mac_destroy_label(&ipq->ipq_label); 1015104521Srwatson#ifdef MAC_DEBUG 1016104527Srwatson atomic_subtract_int(&nmacipqs, 1); 1017104521Srwatson#endif 1018104521Srwatson} 1019104521Srwatson 1020104527Srwatsonvoid 1021113487Srwatsonmac_destroy_mbuf_tag(struct m_tag *tag) 1022104521Srwatson{ 1023113487Srwatson struct label *label; 1024104521Srwatson 1025113487Srwatson label = (struct label *)(tag+1); 1026113487Srwatson 1027113487Srwatson MAC_PERFORM(destroy_mbuf_label, label); 1028113487Srwatson mac_destroy_label(label); 1029104521Srwatson#ifdef MAC_DEBUG 1030104527Srwatson atomic_subtract_int(&nmacmbufs, 1); 1031104521Srwatson#endif 1032104521Srwatson} 1033104521Srwatson 1034104527Srwatsonvoid 1035104527Srwatsonmac_destroy_mount(struct mount *mp) 1036104521Srwatson{ 1037104521Srwatson 1038104527Srwatson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1039104527Srwatson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1040104527Srwatson mac_destroy_label(&mp->mnt_fslabel); 1041104527Srwatson mac_destroy_label(&mp->mnt_mntlabel); 1042104521Srwatson#ifdef MAC_DEBUG 1043104527Srwatson atomic_subtract_int(&nmacmounts, 1); 1044104521Srwatson#endif 1045104521Srwatson} 1046104521Srwatson 1047105694Srwatsonstatic void 1048105694Srwatsonmac_destroy_pipe_label(struct label *label) 1049104521Srwatson{ 1050104521Srwatson 1051105694Srwatson MAC_PERFORM(destroy_pipe_label, label); 1052105694Srwatson mac_destroy_label(label); 1053104521Srwatson#ifdef MAC_DEBUG 1054104527Srwatson atomic_subtract_int(&nmacpipes, 1); 1055104521Srwatson#endif 1056104521Srwatson} 1057104521Srwatson 1058105694Srwatsonvoid 1059105694Srwatsonmac_destroy_pipe(struct pipe *pipe) 1060105694Srwatson{ 1061105694Srwatson 1062105694Srwatson mac_destroy_pipe_label(pipe->pipe_label); 1063105694Srwatson free(pipe->pipe_label, M_MACPIPELABEL); 1064105694Srwatson} 1065105694Srwatson 1066107105Srwatsonvoid 1067107105Srwatsonmac_destroy_proc(struct proc *p) 1068107105Srwatson{ 1069107105Srwatson 1070107105Srwatson MAC_PERFORM(destroy_proc_label, &p->p_label); 1071107105Srwatson mac_destroy_label(&p->p_label); 1072107105Srwatson#ifdef MAC_DEBUG 1073107105Srwatson atomic_subtract_int(&nmacprocs, 1); 1074107105Srwatson#endif 1075107105Srwatson} 1076107105Srwatson 1077104541Srwatsonstatic void 1078104541Srwatsonmac_destroy_socket_label(struct label *label) 1079104521Srwatson{ 1080104521Srwatson 1081104541Srwatson MAC_PERFORM(destroy_socket_label, label); 1082104541Srwatson mac_destroy_label(label); 1083104521Srwatson#ifdef MAC_DEBUG 1084104527Srwatson atomic_subtract_int(&nmacsockets, 1); 1085104521Srwatson#endif 1086104521Srwatson} 1087104521Srwatson 1088104527Srwatsonstatic void 1089104541Srwatsonmac_destroy_socket_peer_label(struct label *label) 1090104541Srwatson{ 1091104541Srwatson 1092104541Srwatson MAC_PERFORM(destroy_socket_peer_label, label); 1093104541Srwatson mac_destroy_label(label); 1094104541Srwatson} 1095104541Srwatson 1096104541Srwatsonvoid 1097104541Srwatsonmac_destroy_socket(struct socket *socket) 1098104541Srwatson{ 1099104541Srwatson 1100104541Srwatson mac_destroy_socket_label(&socket->so_label); 1101104541Srwatson mac_destroy_socket_peer_label(&socket->so_peerlabel); 1102104541Srwatson} 1103104541Srwatson 1104105988Srwatsonvoid 1105105694Srwatsonmac_destroy_vnode_label(struct label *label) 1106104521Srwatson{ 1107104521Srwatson 1108105694Srwatson MAC_PERFORM(destroy_vnode_label, label); 1109104527Srwatson mac_destroy_label(label); 1110104521Srwatson#ifdef MAC_DEBUG 1111105694Srwatson atomic_subtract_int(&nmacvnodes, 1); 1112104521Srwatson#endif 1113104521Srwatson} 1114104521Srwatson 1115104521Srwatsonvoid 1116104527Srwatsonmac_destroy_vnode(struct vnode *vp) 1117104521Srwatson{ 1118104521Srwatson 1119105694Srwatson mac_destroy_vnode_label(&vp->v_label); 1120104521Srwatson} 1121104521Srwatson 1122113487Srwatsonvoid 1123113487Srwatsonmac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 1124113487Srwatson{ 1125113487Srwatson struct label *src_label, *dest_label; 1126113487Srwatson 1127113487Srwatson src_label = (struct label *)(src+1); 1128113487Srwatson dest_label = (struct label *)(dest+1); 1129113487Srwatson 1130113487Srwatson /* 1131113487Srwatson * mac_init_mbuf_tag() is called on the target tag in 1132113487Srwatson * m_tag_copy(), so we don't need to call it here. 1133113487Srwatson */ 1134113487Srwatson MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 1135113487Srwatson} 1136113487Srwatson 1137105694Srwatsonstatic void 1138105694Srwatsonmac_copy_pipe_label(struct label *src, struct label *dest) 1139105694Srwatson{ 1140105694Srwatson 1141105694Srwatson MAC_PERFORM(copy_pipe_label, src, dest); 1142105694Srwatson} 1143105694Srwatson 1144105988Srwatsonvoid 1145105694Srwatsonmac_copy_vnode_label(struct label *src, struct label *dest) 1146105694Srwatson{ 1147105694Srwatson 1148105694Srwatson MAC_PERFORM(copy_vnode_label, src, dest); 1149105694Srwatson} 1150105694Srwatson 1151104522Srwatsonstatic int 1152105694Srwatsonmac_check_structmac_consistent(struct mac *mac) 1153104522Srwatson{ 1154105694Srwatson 1155105694Srwatson if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1156105694Srwatson return (EINVAL); 1157105694Srwatson 1158105694Srwatson return (0); 1159105694Srwatson} 1160105694Srwatson 1161105694Srwatsonstatic int 1162105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements, 1163105694Srwatson char *outbuf, size_t outbuflen, int flags) 1164105694Srwatson{ 1165104522Srwatson int error; 1166104522Srwatson 1167105694Srwatson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1168104522Srwatson 1169104522Srwatson return (error); 1170104522Srwatson} 1171104522Srwatson 1172104522Srwatsonstatic int 1173105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements, 1174105694Srwatson char *outbuf, size_t outbuflen, int flags) 1175104522Srwatson{ 1176104522Srwatson int error; 1177104522Srwatson 1178105694Srwatson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1179104522Srwatson 1180104522Srwatson return (error); 1181104522Srwatson} 1182104522Srwatson 1183105694Srwatsonstatic int 1184105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements, 1185105694Srwatson char *outbuf, size_t outbuflen, int flags) 1186105694Srwatson{ 1187105694Srwatson int error; 1188105694Srwatson 1189105694Srwatson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1190105694Srwatson 1191105694Srwatson return (error); 1192105694Srwatson} 1193105694Srwatson 1194105694Srwatsonstatic int 1195105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements, 1196105694Srwatson char *outbuf, size_t outbuflen, int flags) 1197105694Srwatson{ 1198105694Srwatson int error; 1199105694Srwatson 1200105694Srwatson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1201105694Srwatson 1202105694Srwatson return (error); 1203105694Srwatson} 1204105694Srwatson 1205105694Srwatsonstatic int 1206105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements, 1207105694Srwatson char *outbuf, size_t outbuflen, int flags) 1208105694Srwatson{ 1209105694Srwatson int error; 1210105694Srwatson 1211105694Srwatson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1212105694Srwatson 1213105694Srwatson return (error); 1214105694Srwatson} 1215105694Srwatson 1216105694Srwatsonstatic int 1217105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements, 1218105694Srwatson char *outbuf, size_t outbuflen, int flags) 1219105694Srwatson{ 1220105694Srwatson int error; 1221105694Srwatson 1222105694Srwatson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1223105694Srwatson 1224105694Srwatson return (error); 1225105694Srwatson} 1226105694Srwatson 1227105694Srwatsonstatic int 1228105694Srwatsonmac_internalize_cred_label(struct label *label, char *string) 1229105694Srwatson{ 1230105694Srwatson int error; 1231105694Srwatson 1232105694Srwatson MAC_INTERNALIZE(cred_label, label, string); 1233105694Srwatson 1234105694Srwatson return (error); 1235105694Srwatson} 1236105694Srwatson 1237105694Srwatsonstatic int 1238105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string) 1239105694Srwatson{ 1240105694Srwatson int error; 1241105694Srwatson 1242105694Srwatson MAC_INTERNALIZE(ifnet_label, label, string); 1243105694Srwatson 1244105694Srwatson return (error); 1245105694Srwatson} 1246105694Srwatson 1247105694Srwatsonstatic int 1248105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string) 1249105694Srwatson{ 1250105694Srwatson int error; 1251105694Srwatson 1252105694Srwatson MAC_INTERNALIZE(pipe_label, label, string); 1253105694Srwatson 1254105694Srwatson return (error); 1255105694Srwatson} 1256105694Srwatson 1257105694Srwatsonstatic int 1258105694Srwatsonmac_internalize_socket_label(struct label *label, char *string) 1259105694Srwatson{ 1260105694Srwatson int error; 1261105694Srwatson 1262105694Srwatson MAC_INTERNALIZE(socket_label, label, string); 1263105694Srwatson 1264105694Srwatson return (error); 1265105694Srwatson} 1266105694Srwatson 1267105694Srwatsonstatic int 1268105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string) 1269105694Srwatson{ 1270105694Srwatson int error; 1271105694Srwatson 1272105694Srwatson MAC_INTERNALIZE(vnode_label, label, string); 1273105694Srwatson 1274105694Srwatson return (error); 1275105694Srwatson} 1276105694Srwatson 1277104522Srwatson/* 1278104522Srwatson * Initialize MAC label for the first kernel process, from which other 1279104522Srwatson * kernel processes and threads are spawned. 1280104522Srwatson */ 1281104521Srwatsonvoid 1282104522Srwatsonmac_create_proc0(struct ucred *cred) 1283104522Srwatson{ 1284104522Srwatson 1285104522Srwatson MAC_PERFORM(create_proc0, cred); 1286104522Srwatson} 1287104522Srwatson 1288104522Srwatson/* 1289104522Srwatson * Initialize MAC label for the first userland process, from which other 1290104522Srwatson * userland processes and threads are spawned. 1291104522Srwatson */ 1292104522Srwatsonvoid 1293104522Srwatsonmac_create_proc1(struct ucred *cred) 1294104522Srwatson{ 1295104522Srwatson 1296104522Srwatson MAC_PERFORM(create_proc1, cred); 1297104522Srwatson} 1298104522Srwatson 1299104522Srwatsonvoid 1300104522Srwatsonmac_thread_userret(struct thread *td) 1301104522Srwatson{ 1302104522Srwatson 1303104522Srwatson MAC_PERFORM(thread_userret, td); 1304104522Srwatson} 1305104522Srwatson 1306104522Srwatson/* 1307104522Srwatson * When a new process is created, its label must be initialized. Generally, 1308104522Srwatson * this involves inheritence from the parent process, modulo possible 1309104522Srwatson * deltas. This function allows that processing to take place. 1310104522Srwatson */ 1311104522Srwatsonvoid 1312104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1313104522Srwatson{ 1314104522Srwatson 1315104522Srwatson MAC_PERFORM(create_cred, parent_cred, child_cred); 1316104522Srwatson} 1317104522Srwatson 1318104522Srwatsonvoid 1319107698Srwatsonmac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 1320107698Srwatson struct vnode *vp) 1321100979Srwatson{ 1322100979Srwatson 1323107698Srwatson MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp, 1324107698Srwatson &vp->v_label); 1325100979Srwatson} 1326100979Srwatson 1327100979Srwatsonvoid 1328105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1329105988Srwatson struct vnode *vp) 1330100979Srwatson{ 1331100979Srwatson 1332105988Srwatson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1333105988Srwatson &de->de_label, vp, &vp->v_label); 1334100979Srwatson} 1335100979Srwatson 1336105988Srwatsonint 1337105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1338100979Srwatson{ 1339100979Srwatson int error; 1340100979Srwatson 1341105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1342100979Srwatson 1343105988Srwatson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1344105988Srwatson &vp->v_label); 1345100979Srwatson 1346100979Srwatson return (error); 1347100979Srwatson} 1348100979Srwatson 1349100979Srwatsonvoid 1350105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1351100979Srwatson{ 1352100979Srwatson 1353105988Srwatson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1354105988Srwatson &vp->v_label); 1355100979Srwatson} 1356100979Srwatson 1357100979Srwatsonint 1358105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1359105988Srwatson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1360100979Srwatson{ 1361105988Srwatson int error; 1362100979Srwatson 1363105988Srwatson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1364105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1365100979Srwatson 1366105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1367105988Srwatson if (error == EOPNOTSUPP) { 1368105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1369105988Srwatson if (ea_warn_once == 0) { 1370105988Srwatson printf("Warning: transactions not supported " 1371105988Srwatson "in EA write.\n"); 1372105988Srwatson ea_warn_once = 1; 1373105988Srwatson } 1374105988Srwatson } else if (error) 1375100979Srwatson return (error); 1376100979Srwatson 1377105988Srwatson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1378105988Srwatson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1379100979Srwatson 1380105988Srwatson if (error) { 1381105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1382100979Srwatson return (error); 1383100979Srwatson } 1384100979Srwatson 1385105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1386100979Srwatson 1387105988Srwatson if (error == EOPNOTSUPP) 1388105988Srwatson error = 0; /* XXX */ 1389100979Srwatson 1390100979Srwatson return (error); 1391100979Srwatson} 1392100979Srwatson 1393100979Srwatsonstatic int 1394105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1395105988Srwatson struct label *intlabel) 1396100979Srwatson{ 1397100979Srwatson int error; 1398100979Srwatson 1399105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1400100979Srwatson 1401105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1402105988Srwatson if (error == EOPNOTSUPP) { 1403105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1404105988Srwatson if (ea_warn_once == 0) { 1405105988Srwatson printf("Warning: transactions not supported " 1406105988Srwatson "in EA write.\n"); 1407105988Srwatson ea_warn_once = 1; 1408105988Srwatson } 1409105988Srwatson } else if (error) 1410105988Srwatson return (error); 1411100979Srwatson 1412105988Srwatson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1413100979Srwatson 1414105988Srwatson if (error) { 1415105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1416100979Srwatson return (error); 1417100979Srwatson } 1418100979Srwatson 1419105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1420100979Srwatson 1421105988Srwatson if (error == EOPNOTSUPP) 1422105988Srwatson error = 0; /* XXX */ 1423100979Srwatson 1424105988Srwatson return (error); 1425100979Srwatson} 1426100979Srwatson 1427106468Srwatsonint 1428106468Srwatsonmac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1429106468Srwatson struct label *execlabelstorage) 1430106468Srwatson{ 1431106468Srwatson struct mac mac; 1432106468Srwatson char *buffer; 1433106468Srwatson int error; 1434106468Srwatson 1435106468Srwatson if (mac_p == NULL) 1436106468Srwatson return (0); 1437106468Srwatson 1438106468Srwatson error = copyin(mac_p, &mac, sizeof(mac)); 1439106468Srwatson if (error) 1440106468Srwatson return (error); 1441106468Srwatson 1442106468Srwatson error = mac_check_structmac_consistent(&mac); 1443106468Srwatson if (error) 1444106468Srwatson return (error); 1445106468Srwatson 1446111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1447106468Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1448106468Srwatson if (error) { 1449106468Srwatson free(buffer, M_MACTEMP); 1450106468Srwatson return (error); 1451106468Srwatson } 1452106468Srwatson 1453106468Srwatson mac_init_cred_label(execlabelstorage); 1454106468Srwatson error = mac_internalize_cred_label(execlabelstorage, buffer); 1455106468Srwatson free(buffer, M_MACTEMP); 1456106468Srwatson if (error) { 1457106468Srwatson mac_destroy_cred_label(execlabelstorage); 1458106468Srwatson return (error); 1459106468Srwatson } 1460106468Srwatson imgp->execlabel = execlabelstorage; 1461106468Srwatson return (0); 1462106468Srwatson} 1463106468Srwatson 1464100979Srwatsonvoid 1465106468Srwatsonmac_execve_exit(struct image_params *imgp) 1466100979Srwatson{ 1467106468Srwatson if (imgp->execlabel != NULL) 1468106468Srwatson mac_destroy_cred_label(imgp->execlabel); 1469106468Srwatson} 1470100979Srwatson 1471106468Srwatsonvoid 1472106468Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1473106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1474106468Srwatson{ 1475106468Srwatson 1476100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1477100979Srwatson 1478106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1479106460Srwatson return; 1480106460Srwatson 1481106468Srwatson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1482106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1483100979Srwatson} 1484100979Srwatson 1485100979Srwatsonint 1486106468Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp, 1487106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1488100979Srwatson{ 1489105988Srwatson int result; 1490100979Srwatson 1491106460Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1492106460Srwatson 1493106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1494106460Srwatson return (0); 1495106460Srwatson 1496100979Srwatson result = 0; 1497106468Srwatson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1498106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1499100979Srwatson 1500100979Srwatson return (result); 1501100979Srwatson} 1502100979Srwatson 1503100979Srwatsonint 1504106212Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1505100979Srwatson{ 1506100979Srwatson int error; 1507100979Srwatson 1508100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1509100979Srwatson 1510100979Srwatson if (!mac_enforce_fs) 1511100979Srwatson return (0); 1512100979Srwatson 1513106212Srwatson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1514100979Srwatson return (error); 1515100979Srwatson} 1516100979Srwatson 1517100979Srwatsonint 1518100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1519100979Srwatson{ 1520100979Srwatson int error; 1521100979Srwatson 1522100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1523100979Srwatson 1524100979Srwatson if (!mac_enforce_fs) 1525100979Srwatson return (0); 1526100979Srwatson 1527100979Srwatson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1528100979Srwatson return (error); 1529100979Srwatson} 1530100979Srwatson 1531100979Srwatsonint 1532100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1533100979Srwatson{ 1534100979Srwatson int error; 1535100979Srwatson 1536100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1537100979Srwatson 1538100979Srwatson if (!mac_enforce_fs) 1539100979Srwatson return (0); 1540100979Srwatson 1541100979Srwatson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1542100979Srwatson return (error); 1543100979Srwatson} 1544100979Srwatson 1545100979Srwatsonint 1546100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1547100979Srwatson struct componentname *cnp, struct vattr *vap) 1548100979Srwatson{ 1549100979Srwatson int error; 1550100979Srwatson 1551100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1552100979Srwatson 1553100979Srwatson if (!mac_enforce_fs) 1554100979Srwatson return (0); 1555100979Srwatson 1556100979Srwatson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1557100979Srwatson return (error); 1558100979Srwatson} 1559100979Srwatson 1560100979Srwatsonint 1561100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1562100979Srwatson struct componentname *cnp) 1563100979Srwatson{ 1564100979Srwatson int error; 1565100979Srwatson 1566100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1567100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1568100979Srwatson 1569100979Srwatson if (!mac_enforce_fs) 1570100979Srwatson return (0); 1571100979Srwatson 1572100979Srwatson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1573100979Srwatson &vp->v_label, cnp); 1574100979Srwatson return (error); 1575100979Srwatson} 1576100979Srwatson 1577100979Srwatsonint 1578100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1579100979Srwatson acl_type_t type) 1580100979Srwatson{ 1581100979Srwatson int error; 1582100979Srwatson 1583100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1584100979Srwatson 1585100979Srwatson if (!mac_enforce_fs) 1586100979Srwatson return (0); 1587100979Srwatson 1588100979Srwatson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1589100979Srwatson return (error); 1590100979Srwatson} 1591100979Srwatson 1592100979Srwatsonint 1593106468Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1594106468Srwatson struct image_params *imgp) 1595100979Srwatson{ 1596100979Srwatson int error; 1597100979Srwatson 1598102102Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1599102102Srwatson 1600100979Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1601100979Srwatson return (0); 1602100979Srwatson 1603106647Srwatson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1604106647Srwatson imgp->execlabel); 1605100979Srwatson 1606100979Srwatson return (error); 1607100979Srwatson} 1608100979Srwatson 1609100979Srwatsonint 1610100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1611100979Srwatson{ 1612100979Srwatson int error; 1613100979Srwatson 1614100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1615100979Srwatson 1616100979Srwatson if (!mac_enforce_fs) 1617100979Srwatson return (0); 1618100979Srwatson 1619100979Srwatson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1620100979Srwatson return (error); 1621100979Srwatson} 1622100979Srwatson 1623100979Srwatsonint 1624100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1625100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1626100979Srwatson{ 1627100979Srwatson int error; 1628100979Srwatson 1629100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1630100979Srwatson 1631100979Srwatson if (!mac_enforce_fs) 1632100979Srwatson return (0); 1633100979Srwatson 1634100979Srwatson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1635100979Srwatson attrnamespace, name, uio); 1636100979Srwatson return (error); 1637100979Srwatson} 1638100979Srwatson 1639100979Srwatsonint 1640104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1641104529Srwatson struct vnode *vp, struct componentname *cnp) 1642104529Srwatson{ 1643104529Srwatson int error; 1644104529Srwatson 1645104529Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1646104529Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1647104529Srwatson 1648104529Srwatson if (!mac_enforce_fs) 1649104529Srwatson return (0); 1650104529Srwatson 1651104529Srwatson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1652104529Srwatson &vp->v_label, cnp); 1653104529Srwatson return (error); 1654104529Srwatson} 1655104529Srwatson 1656104529Srwatsonint 1657100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1658100979Srwatson struct componentname *cnp) 1659100979Srwatson{ 1660100979Srwatson int error; 1661100979Srwatson 1662100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1663100979Srwatson 1664100979Srwatson if (!mac_enforce_fs) 1665100979Srwatson return (0); 1666100979Srwatson 1667100979Srwatson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1668100979Srwatson return (error); 1669100979Srwatson} 1670100979Srwatson 1671104546Srwatsonint 1672104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1673100979Srwatson{ 1674104546Srwatson int error; 1675100979Srwatson 1676104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1677103514Srwatson 1678104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1679104546Srwatson return (0); 1680104546Srwatson 1681104546Srwatson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1682104546Srwatson return (error); 1683100979Srwatson} 1684100979Srwatson 1685104546Srwatsonvoid 1686104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1687104546Srwatson{ 1688104546Srwatson int result = *prot; 1689104546Srwatson 1690104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1691104546Srwatson 1692104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1693104546Srwatson return; 1694104546Srwatson 1695104546Srwatson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1696104546Srwatson &result); 1697104546Srwatson 1698104546Srwatson *prot = result; 1699104546Srwatson} 1700104546Srwatson 1701100979Srwatsonint 1702104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1703104546Srwatson{ 1704104546Srwatson int error; 1705104546Srwatson 1706104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1707104546Srwatson 1708104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1709104546Srwatson return (0); 1710104546Srwatson 1711104546Srwatson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1712104546Srwatson return (error); 1713104546Srwatson} 1714104546Srwatson 1715104546Srwatsonint 1716106212Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1717100979Srwatson{ 1718100979Srwatson int error; 1719100979Srwatson 1720102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1721102112Srwatson 1722100979Srwatson if (!mac_enforce_fs) 1723100979Srwatson return (0); 1724100979Srwatson 1725102112Srwatson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1726102112Srwatson return (error); 1727102112Srwatson} 1728102112Srwatson 1729102112Srwatsonint 1730102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1731102129Srwatson struct vnode *vp) 1732102112Srwatson{ 1733102112Srwatson int error; 1734102112Srwatson 1735102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1736102112Srwatson 1737102112Srwatson if (!mac_enforce_fs) 1738102112Srwatson return (0); 1739102112Srwatson 1740102129Srwatson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1741102129Srwatson &vp->v_label); 1742100979Srwatson 1743100979Srwatson return (error); 1744100979Srwatson} 1745100979Srwatson 1746100979Srwatsonint 1747102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1748102129Srwatson struct vnode *vp) 1749100979Srwatson{ 1750100979Srwatson int error; 1751100979Srwatson 1752102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1753100979Srwatson 1754100979Srwatson if (!mac_enforce_fs) 1755100979Srwatson return (0); 1756100979Srwatson 1757102129Srwatson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1758102129Srwatson &vp->v_label); 1759102112Srwatson 1760100979Srwatson return (error); 1761100979Srwatson} 1762100979Srwatson 1763100979Srwatsonint 1764100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1765100979Srwatson{ 1766100979Srwatson int error; 1767100979Srwatson 1768100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1769100979Srwatson 1770100979Srwatson if (!mac_enforce_fs) 1771100979Srwatson return (0); 1772100979Srwatson 1773100979Srwatson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1774100979Srwatson return (error); 1775100979Srwatson} 1776100979Srwatson 1777100979Srwatsonint 1778100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1779100979Srwatson{ 1780100979Srwatson int error; 1781100979Srwatson 1782100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1783100979Srwatson 1784100979Srwatson if (!mac_enforce_fs) 1785100979Srwatson return (0); 1786100979Srwatson 1787100979Srwatson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1788100979Srwatson return (error); 1789100979Srwatson} 1790100979Srwatson 1791100979Srwatsonstatic int 1792100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1793100979Srwatson struct label *newlabel) 1794100979Srwatson{ 1795100979Srwatson int error; 1796100979Srwatson 1797100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1798100979Srwatson 1799100979Srwatson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1800100979Srwatson 1801100979Srwatson return (error); 1802100979Srwatson} 1803100979Srwatson 1804100979Srwatsonint 1805100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1806100979Srwatson struct vnode *vp, struct componentname *cnp) 1807100979Srwatson{ 1808100979Srwatson int error; 1809100979Srwatson 1810100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1811100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1812100979Srwatson 1813100979Srwatson if (!mac_enforce_fs) 1814100979Srwatson return (0); 1815100979Srwatson 1816100979Srwatson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1817100979Srwatson &vp->v_label, cnp); 1818100979Srwatson return (error); 1819100979Srwatson} 1820100979Srwatson 1821100979Srwatsonint 1822100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1823100979Srwatson struct vnode *vp, int samedir, struct componentname *cnp) 1824100979Srwatson{ 1825100979Srwatson int error; 1826100979Srwatson 1827100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1828100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1829100979Srwatson 1830100979Srwatson if (!mac_enforce_fs) 1831100979Srwatson return (0); 1832100979Srwatson 1833100979Srwatson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1834100979Srwatson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1835100979Srwatson return (error); 1836100979Srwatson} 1837100979Srwatson 1838100979Srwatsonint 1839100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1840100979Srwatson{ 1841100979Srwatson int error; 1842100979Srwatson 1843100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1844100979Srwatson 1845100979Srwatson if (!mac_enforce_fs) 1846100979Srwatson return (0); 1847100979Srwatson 1848100979Srwatson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1849100979Srwatson return (error); 1850100979Srwatson} 1851100979Srwatson 1852100979Srwatsonint 1853100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1854100979Srwatson struct acl *acl) 1855100979Srwatson{ 1856100979Srwatson int error; 1857100979Srwatson 1858100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1859100979Srwatson 1860100979Srwatson if (!mac_enforce_fs) 1861100979Srwatson return (0); 1862100979Srwatson 1863100979Srwatson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1864100979Srwatson return (error); 1865100979Srwatson} 1866100979Srwatson 1867100979Srwatsonint 1868100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1869100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1870100979Srwatson{ 1871100979Srwatson int error; 1872100979Srwatson 1873100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1874100979Srwatson 1875100979Srwatson if (!mac_enforce_fs) 1876100979Srwatson return (0); 1877100979Srwatson 1878100979Srwatson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1879100979Srwatson attrnamespace, name, uio); 1880100979Srwatson return (error); 1881100979Srwatson} 1882100979Srwatson 1883100979Srwatsonint 1884100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1885100979Srwatson{ 1886100979Srwatson int error; 1887100979Srwatson 1888100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1889100979Srwatson 1890100979Srwatson if (!mac_enforce_fs) 1891100979Srwatson return (0); 1892100979Srwatson 1893100979Srwatson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1894100979Srwatson return (error); 1895100979Srwatson} 1896100979Srwatson 1897100979Srwatsonint 1898100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1899100979Srwatson{ 1900100979Srwatson int error; 1901100979Srwatson 1902100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1903100979Srwatson 1904100979Srwatson if (!mac_enforce_fs) 1905100979Srwatson return (0); 1906100979Srwatson 1907100979Srwatson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1908100979Srwatson return (error); 1909100979Srwatson} 1910100979Srwatson 1911100979Srwatsonint 1912100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1913100979Srwatson gid_t gid) 1914100979Srwatson{ 1915100979Srwatson int error; 1916100979Srwatson 1917100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1918100979Srwatson 1919100979Srwatson if (!mac_enforce_fs) 1920100979Srwatson return (0); 1921100979Srwatson 1922100979Srwatson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1923100979Srwatson return (error); 1924100979Srwatson} 1925100979Srwatson 1926100979Srwatsonint 1927100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1928100979Srwatson struct timespec atime, struct timespec mtime) 1929100979Srwatson{ 1930100979Srwatson int error; 1931100979Srwatson 1932100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1933100979Srwatson 1934100979Srwatson if (!mac_enforce_fs) 1935100979Srwatson return (0); 1936100979Srwatson 1937100979Srwatson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1938100979Srwatson mtime); 1939100979Srwatson return (error); 1940100979Srwatson} 1941100979Srwatson 1942100979Srwatsonint 1943102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1944102129Srwatson struct vnode *vp) 1945100979Srwatson{ 1946100979Srwatson int error; 1947100979Srwatson 1948100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 1949100979Srwatson 1950100979Srwatson if (!mac_enforce_fs) 1951100979Srwatson return (0); 1952100979Srwatson 1953102129Srwatson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 1954102129Srwatson &vp->v_label); 1955100979Srwatson return (error); 1956100979Srwatson} 1957100979Srwatson 1958102112Srwatsonint 1959102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1960102129Srwatson struct vnode *vp) 1961102112Srwatson{ 1962102112Srwatson int error; 1963102112Srwatson 1964102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 1965102112Srwatson 1966102112Srwatson if (!mac_enforce_fs) 1967102112Srwatson return (0); 1968102112Srwatson 1969102129Srwatson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 1970102129Srwatson &vp->v_label); 1971102112Srwatson 1972102112Srwatson return (error); 1973102112Srwatson} 1974102112Srwatson 1975100979Srwatson/* 1976100979Srwatson * When relabeling a process, call out to the policies for the maximum 1977100979Srwatson * permission allowed for each object type we know about in its 1978100979Srwatson * memory space, and revoke access (in the least surprising ways we 1979100979Srwatson * know) when necessary. The process lock is not held here. 1980100979Srwatson */ 1981107271Srwatsonvoid 1982100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 1983100979Srwatson{ 1984100979Srwatson 1985100979Srwatson /* XXX freeze all other threads */ 1986100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 1987100979Srwatson &td->td_proc->p_vmspace->vm_map); 1988100979Srwatson /* XXX allow other threads to continue */ 1989100979Srwatson} 1990100979Srwatson 1991100979Srwatsonstatic __inline const char * 1992100979Srwatsonprot2str(vm_prot_t prot) 1993100979Srwatson{ 1994100979Srwatson 1995100979Srwatson switch (prot & VM_PROT_ALL) { 1996100979Srwatson case VM_PROT_READ: 1997100979Srwatson return ("r--"); 1998100979Srwatson case VM_PROT_READ | VM_PROT_WRITE: 1999100979Srwatson return ("rw-"); 2000100979Srwatson case VM_PROT_READ | VM_PROT_EXECUTE: 2001100979Srwatson return ("r-x"); 2002100979Srwatson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2003100979Srwatson return ("rwx"); 2004100979Srwatson case VM_PROT_WRITE: 2005100979Srwatson return ("-w-"); 2006100979Srwatson case VM_PROT_EXECUTE: 2007100979Srwatson return ("--x"); 2008100979Srwatson case VM_PROT_WRITE | VM_PROT_EXECUTE: 2009100979Srwatson return ("-wx"); 2010100979Srwatson default: 2011100979Srwatson return ("---"); 2012100979Srwatson } 2013100979Srwatson} 2014100979Srwatson 2015100979Srwatsonstatic void 2016100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2017100979Srwatson struct vm_map *map) 2018100979Srwatson{ 2019100979Srwatson struct vm_map_entry *vme; 2020104546Srwatson int result; 2021104546Srwatson vm_prot_t revokeperms; 2022100979Srwatson vm_object_t object; 2023100979Srwatson vm_ooffset_t offset; 2024100979Srwatson struct vnode *vp; 2025100979Srwatson 2026103136Srwatson if (!mac_mmap_revocation) 2027103136Srwatson return; 2028103136Srwatson 2029100979Srwatson vm_map_lock_read(map); 2030100979Srwatson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2031100979Srwatson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2032100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 2033100979Srwatson vme->object.sub_map); 2034100979Srwatson continue; 2035100979Srwatson } 2036100979Srwatson /* 2037100979Srwatson * Skip over entries that obviously are not shared. 2038100979Srwatson */ 2039100979Srwatson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2040100979Srwatson !vme->max_protection) 2041100979Srwatson continue; 2042100979Srwatson /* 2043100979Srwatson * Drill down to the deepest backing object. 2044100979Srwatson */ 2045100979Srwatson offset = vme->offset; 2046100979Srwatson object = vme->object.vm_object; 2047100979Srwatson if (object == NULL) 2048100979Srwatson continue; 2049100979Srwatson while (object->backing_object != NULL) { 2050100979Srwatson object = object->backing_object; 2051100979Srwatson offset += object->backing_object_offset; 2052100979Srwatson } 2053100979Srwatson /* 2054100979Srwatson * At the moment, vm_maps and objects aren't considered 2055100979Srwatson * by the MAC system, so only things with backing by a 2056100979Srwatson * normal object (read: vnodes) are checked. 2057100979Srwatson */ 2058100979Srwatson if (object->type != OBJT_VNODE) 2059100979Srwatson continue; 2060100979Srwatson vp = (struct vnode *)object->handle; 2061100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2062104546Srwatson result = vme->max_protection; 2063104546Srwatson mac_check_vnode_mmap_downgrade(cred, vp, &result); 2064100979Srwatson VOP_UNLOCK(vp, 0, td); 2065100979Srwatson /* 2066100979Srwatson * Find out what maximum protection we may be allowing 2067100979Srwatson * now but a policy needs to get removed. 2068100979Srwatson */ 2069100979Srwatson revokeperms = vme->max_protection & ~result; 2070100979Srwatson if (!revokeperms) 2071100979Srwatson continue; 2072102949Sbde printf("pid %ld: revoking %s perms from %#lx:%ld " 2073102949Sbde "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2074102949Sbde prot2str(revokeperms), (u_long)vme->start, 2075102949Sbde (long)(vme->end - vme->start), 2076100979Srwatson prot2str(vme->max_protection), prot2str(vme->protection)); 2077100979Srwatson vm_map_lock_upgrade(map); 2078100979Srwatson /* 2079100979Srwatson * This is the really simple case: if a map has more 2080100979Srwatson * max_protection than is allowed, but it's not being 2081100979Srwatson * actually used (that is, the current protection is 2082100979Srwatson * still allowed), we can just wipe it out and do 2083100979Srwatson * nothing more. 2084100979Srwatson */ 2085100979Srwatson if ((vme->protection & revokeperms) == 0) { 2086100979Srwatson vme->max_protection -= revokeperms; 2087100979Srwatson } else { 2088100979Srwatson if (revokeperms & VM_PROT_WRITE) { 2089100979Srwatson /* 2090100979Srwatson * In the more complicated case, flush out all 2091100979Srwatson * pending changes to the object then turn it 2092100979Srwatson * copy-on-write. 2093100979Srwatson */ 2094100979Srwatson vm_object_reference(object); 2095100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2096113955Salc VM_OBJECT_LOCK(object); 2097100979Srwatson vm_object_page_clean(object, 2098100979Srwatson OFF_TO_IDX(offset), 2099100979Srwatson OFF_TO_IDX(offset + vme->end - vme->start + 2100100979Srwatson PAGE_MASK), 2101100979Srwatson OBJPC_SYNC); 2102113955Salc VM_OBJECT_UNLOCK(object); 2103100979Srwatson VOP_UNLOCK(vp, 0, td); 2104100979Srwatson vm_object_deallocate(object); 2105100979Srwatson /* 2106100979Srwatson * Why bother if there's no read permissions 2107100979Srwatson * anymore? For the rest, we need to leave 2108100979Srwatson * the write permissions on for COW, or 2109100979Srwatson * remove them entirely if configured to. 2110100979Srwatson */ 2111100979Srwatson if (!mac_mmap_revocation_via_cow) { 2112100979Srwatson vme->max_protection &= ~VM_PROT_WRITE; 2113100979Srwatson vme->protection &= ~VM_PROT_WRITE; 2114100979Srwatson } if ((revokeperms & VM_PROT_READ) == 0) 2115100979Srwatson vme->eflags |= MAP_ENTRY_COW | 2116100979Srwatson MAP_ENTRY_NEEDS_COPY; 2117100979Srwatson } 2118100979Srwatson if (revokeperms & VM_PROT_EXECUTE) { 2119100979Srwatson vme->max_protection &= ~VM_PROT_EXECUTE; 2120100979Srwatson vme->protection &= ~VM_PROT_EXECUTE; 2121100979Srwatson } 2122100979Srwatson if (revokeperms & VM_PROT_READ) { 2123100979Srwatson vme->max_protection = 0; 2124100979Srwatson vme->protection = 0; 2125100979Srwatson } 2126100979Srwatson pmap_protect(map->pmap, vme->start, vme->end, 2127100979Srwatson vme->protection & ~revokeperms); 2128100979Srwatson vm_map_simplify_entry(map, vme); 2129100979Srwatson } 2130100979Srwatson vm_map_lock_downgrade(map); 2131100979Srwatson } 2132100979Srwatson vm_map_unlock_read(map); 2133100979Srwatson} 2134100979Srwatson 2135100979Srwatson/* 2136100979Srwatson * When the subject's label changes, it may require revocation of privilege 2137100979Srwatson * to mapped objects. This can't be done on-the-fly later with a unified 2138100979Srwatson * buffer cache. 2139100979Srwatson */ 2140100979Srwatsonstatic void 2141100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel) 2142100979Srwatson{ 2143100979Srwatson 2144100979Srwatson MAC_PERFORM(relabel_cred, cred, newlabel); 2145100979Srwatson} 2146100979Srwatson 2147100979Srwatsonvoid 2148100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2149100979Srwatson{ 2150100979Srwatson 2151100979Srwatson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2152100979Srwatson} 2153100979Srwatson 2154100979Srwatsonvoid 2155100979Srwatsonmac_create_ifnet(struct ifnet *ifnet) 2156100979Srwatson{ 2157100979Srwatson 2158100979Srwatson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2159100979Srwatson} 2160100979Srwatson 2161100979Srwatsonvoid 2162100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2163100979Srwatson{ 2164100979Srwatson 2165100979Srwatson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2166100979Srwatson} 2167100979Srwatson 2168100979Srwatsonvoid 2169100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket) 2170100979Srwatson{ 2171100979Srwatson 2172100979Srwatson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2173100979Srwatson} 2174100979Srwatson 2175100979Srwatsonvoid 2176100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe) 2177100979Srwatson{ 2178100979Srwatson 2179100979Srwatson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2180100979Srwatson} 2181100979Srwatson 2182100979Srwatsonvoid 2183100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket, 2184100979Srwatson struct socket *newsocket) 2185100979Srwatson{ 2186100979Srwatson 2187100979Srwatson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2188100979Srwatson newsocket, &newsocket->so_label); 2189100979Srwatson} 2190100979Srwatson 2191100979Srwatsonstatic void 2192100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket, 2193100979Srwatson struct label *newlabel) 2194100979Srwatson{ 2195100979Srwatson 2196100979Srwatson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2197100979Srwatson} 2198100979Srwatson 2199100979Srwatsonstatic void 2200100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2201100979Srwatson{ 2202100979Srwatson 2203100979Srwatson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2204100979Srwatson} 2205100979Srwatson 2206100979Srwatsonvoid 2207100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2208100979Srwatson{ 2209113482Srwatson struct label *label; 2210100979Srwatson 2211113482Srwatson label = mbuf_to_label(mbuf); 2212113482Srwatson 2213113482Srwatson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 2214113482Srwatson &socket->so_peerlabel); 2215100979Srwatson} 2216100979Srwatson 2217100979Srwatsonvoid 2218100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket, 2219100979Srwatson struct socket *newsocket) 2220100979Srwatson{ 2221100979Srwatson 2222100979Srwatson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2223100979Srwatson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2224100979Srwatson} 2225100979Srwatson 2226100979Srwatsonvoid 2227100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2228100979Srwatson{ 2229113482Srwatson struct label *label; 2230100979Srwatson 2231113482Srwatson label = mbuf_to_label(datagram); 2232113482Srwatson 2233100979Srwatson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2234113482Srwatson datagram, label); 2235100979Srwatson} 2236100979Srwatson 2237100979Srwatsonvoid 2238100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2239100979Srwatson{ 2240113482Srwatson struct label *datagramlabel, *fragmentlabel; 2241100979Srwatson 2242113482Srwatson datagramlabel = mbuf_to_label(datagram); 2243113482Srwatson fragmentlabel = mbuf_to_label(fragment); 2244113482Srwatson 2245113482Srwatson MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 2246113482Srwatson fragmentlabel); 2247100979Srwatson} 2248100979Srwatson 2249100979Srwatsonvoid 2250100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2251100979Srwatson{ 2252113482Srwatson struct label *label; 2253100979Srwatson 2254113482Srwatson label = mbuf_to_label(fragment); 2255113482Srwatson 2256113482Srwatson MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label); 2257100979Srwatson} 2258100979Srwatson 2259100979Srwatsonvoid 2260100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2261100979Srwatson{ 2262113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2263100979Srwatson 2264113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2265113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2266113482Srwatson 2267113482Srwatson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 2268113482Srwatson newmbuflabel); 2269100979Srwatson} 2270100979Srwatson 2271100979Srwatsonvoid 2272100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2273100979Srwatson{ 2274113482Srwatson struct label *label; 2275100979Srwatson 2276113482Srwatson label = mbuf_to_label(mbuf); 2277113482Srwatson 2278100979Srwatson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2279113482Srwatson label); 2280100979Srwatson} 2281100979Srwatson 2282100979Srwatsonvoid 2283100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2284100979Srwatson{ 2285113482Srwatson struct label *label; 2286100979Srwatson 2287113482Srwatson label = mbuf_to_label(mbuf); 2288113482Srwatson 2289100979Srwatson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2290113482Srwatson label); 2291100979Srwatson} 2292100979Srwatson 2293100979Srwatsonvoid 2294100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2295100979Srwatson{ 2296113482Srwatson struct label *label; 2297100979Srwatson 2298113482Srwatson label = mbuf_to_label(mbuf); 2299113482Srwatson 2300100979Srwatson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2301113482Srwatson label); 2302100979Srwatson} 2303100979Srwatson 2304100979Srwatsonvoid 2305100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2306100979Srwatson struct mbuf *newmbuf) 2307100979Srwatson{ 2308113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2309100979Srwatson 2310113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2311113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2312113482Srwatson 2313113482Srwatson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 2314113482Srwatson ifnet, &ifnet->if_label, newmbuf, newmbuflabel); 2315100979Srwatson} 2316100979Srwatson 2317100979Srwatsonvoid 2318100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2319100979Srwatson{ 2320113482Srwatson struct label *oldmbuflabel, *newmbuflabel; 2321100979Srwatson 2322113482Srwatson oldmbuflabel = mbuf_to_label(oldmbuf); 2323113482Srwatson newmbuflabel = mbuf_to_label(newmbuf); 2324113482Srwatson 2325113482Srwatson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 2326113482Srwatson newmbuflabel); 2327100979Srwatson} 2328100979Srwatson 2329100979Srwatsonint 2330100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2331100979Srwatson{ 2332113482Srwatson struct label *label; 2333100979Srwatson int result; 2334100979Srwatson 2335113482Srwatson label = mbuf_to_label(fragment); 2336113482Srwatson 2337100979Srwatson result = 1; 2338113482Srwatson MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 2339113482Srwatson &ipq->ipq_label); 2340100979Srwatson 2341100979Srwatson return (result); 2342100979Srwatson} 2343100979Srwatson 2344100979Srwatsonvoid 2345100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2346100979Srwatson{ 2347113482Srwatson struct label *label; 2348100979Srwatson 2349113482Srwatson label = mbuf_to_label(fragment); 2350113482Srwatson 2351113482Srwatson MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label); 2352100979Srwatson} 2353100979Srwatson 2354100979Srwatsonvoid 2355100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2356100979Srwatson{ 2357113482Srwatson struct label *label; 2358100979Srwatson 2359113482Srwatson label = mbuf_to_label(mbuf); 2360113482Srwatson 2361100979Srwatson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2362113482Srwatson label); 2363100979Srwatson} 2364100979Srwatson 2365100979Srwatsonvoid 2366100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp) 2367100979Srwatson{ 2368100979Srwatson 2369100979Srwatson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2370100979Srwatson &mp->mnt_fslabel); 2371100979Srwatson} 2372100979Srwatson 2373100979Srwatsonvoid 2374100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp) 2375100979Srwatson{ 2376100979Srwatson 2377100979Srwatson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2378100979Srwatson &mp->mnt_fslabel); 2379100979Srwatson} 2380100979Srwatson 2381100979Srwatsonint 2382100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2383100979Srwatson{ 2384100979Srwatson int error; 2385100979Srwatson 2386100979Srwatson if (!mac_enforce_network) 2387100979Srwatson return (0); 2388100979Srwatson 2389100979Srwatson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2390100979Srwatson &ifnet->if_label); 2391100979Srwatson 2392100979Srwatson return (error); 2393100979Srwatson} 2394100979Srwatson 2395100979Srwatsonstatic int 2396100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2397100979Srwatson{ 2398100979Srwatson int error; 2399100979Srwatson 2400100979Srwatson MAC_CHECK(check_cred_relabel, cred, newlabel); 2401100979Srwatson 2402100979Srwatson return (error); 2403100979Srwatson} 2404100979Srwatson 2405100979Srwatsonint 2406100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2407100979Srwatson{ 2408100979Srwatson int error; 2409100979Srwatson 2410100979Srwatson if (!mac_enforce_process) 2411100979Srwatson return (0); 2412100979Srwatson 2413100979Srwatson MAC_CHECK(check_cred_visible, u1, u2); 2414100979Srwatson 2415100979Srwatson return (error); 2416100979Srwatson} 2417100979Srwatson 2418100979Srwatsonint 2419100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2420100979Srwatson{ 2421113482Srwatson struct label *label; 2422100979Srwatson int error; 2423100979Srwatson 2424113487Srwatson M_ASSERTPKTHDR(mbuf); 2425113487Srwatson 2426100979Srwatson if (!mac_enforce_network) 2427100979Srwatson return (0); 2428100979Srwatson 2429113482Srwatson label = mbuf_to_label(mbuf); 2430100979Srwatson 2431100979Srwatson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2432113482Srwatson label); 2433100979Srwatson 2434100979Srwatson return (error); 2435100979Srwatson} 2436100979Srwatson 2437100979Srwatsonint 2438106308Srwatsonmac_check_kenv_dump(struct ucred *cred) 2439106308Srwatson{ 2440106308Srwatson int error; 2441106308Srwatson 2442106308Srwatson if (!mac_enforce_system) 2443106308Srwatson return (0); 2444106308Srwatson 2445106308Srwatson MAC_CHECK(check_kenv_dump, cred); 2446106308Srwatson 2447106308Srwatson return (error); 2448106308Srwatson} 2449106308Srwatson 2450106308Srwatsonint 2451106308Srwatsonmac_check_kenv_get(struct ucred *cred, char *name) 2452106308Srwatson{ 2453106308Srwatson int error; 2454106308Srwatson 2455106308Srwatson if (!mac_enforce_system) 2456106308Srwatson return (0); 2457106308Srwatson 2458106308Srwatson MAC_CHECK(check_kenv_get, cred, name); 2459106308Srwatson 2460106308Srwatson return (error); 2461106308Srwatson} 2462106308Srwatson 2463106308Srwatsonint 2464106308Srwatsonmac_check_kenv_set(struct ucred *cred, char *name, char *value) 2465106308Srwatson{ 2466106308Srwatson int error; 2467106308Srwatson 2468106308Srwatson if (!mac_enforce_system) 2469106308Srwatson return (0); 2470106308Srwatson 2471106308Srwatson MAC_CHECK(check_kenv_set, cred, name, value); 2472106308Srwatson 2473106308Srwatson return (error); 2474106308Srwatson} 2475106308Srwatson 2476106308Srwatsonint 2477106308Srwatsonmac_check_kenv_unset(struct ucred *cred, char *name) 2478106308Srwatson{ 2479106308Srwatson int error; 2480106308Srwatson 2481106308Srwatson if (!mac_enforce_system) 2482106308Srwatson return (0); 2483106308Srwatson 2484106308Srwatson MAC_CHECK(check_kenv_unset, cred, name); 2485106308Srwatson 2486106308Srwatson return (error); 2487106308Srwatson} 2488106308Srwatson 2489106308Srwatsonint 2490107089Srwatsonmac_check_kld_load(struct ucred *cred, struct vnode *vp) 2491107089Srwatson{ 2492107089Srwatson int error; 2493107089Srwatson 2494107089Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2495107089Srwatson 2496107089Srwatson if (!mac_enforce_kld) 2497107089Srwatson return (0); 2498107089Srwatson 2499107089Srwatson MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2500107089Srwatson 2501107089Srwatson return (error); 2502107089Srwatson} 2503107089Srwatson 2504107089Srwatsonint 2505107089Srwatsonmac_check_kld_stat(struct ucred *cred) 2506107089Srwatson{ 2507107089Srwatson int error; 2508107089Srwatson 2509107089Srwatson if (!mac_enforce_kld) 2510107089Srwatson return (0); 2511107089Srwatson 2512107089Srwatson MAC_CHECK(check_kld_stat, cred); 2513107089Srwatson 2514107089Srwatson return (error); 2515107089Srwatson} 2516107089Srwatson 2517107089Srwatsonint 2518107089Srwatsonmac_check_kld_unload(struct ucred *cred) 2519107089Srwatson{ 2520107089Srwatson int error; 2521107089Srwatson 2522107089Srwatson if (!mac_enforce_kld) 2523107089Srwatson return (0); 2524107089Srwatson 2525107089Srwatson MAC_CHECK(check_kld_unload, cred); 2526107089Srwatson 2527107089Srwatson return (error); 2528107089Srwatson} 2529107089Srwatson 2530107089Srwatsonint 2531100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount) 2532100979Srwatson{ 2533100979Srwatson int error; 2534100979Srwatson 2535100979Srwatson if (!mac_enforce_fs) 2536100979Srwatson return (0); 2537100979Srwatson 2538100979Srwatson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2539100979Srwatson 2540100979Srwatson return (error); 2541100979Srwatson} 2542100979Srwatson 2543100979Srwatsonint 2544100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2545100979Srwatson void *data) 2546100979Srwatson{ 2547100979Srwatson int error; 2548100979Srwatson 2549104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2550104269Srwatson 2551104269Srwatson if (!mac_enforce_pipe) 2552104269Srwatson return (0); 2553104269Srwatson 2554100979Srwatson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2555100979Srwatson 2556100979Srwatson return (error); 2557100979Srwatson} 2558100979Srwatson 2559100979Srwatsonint 2560102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2561100979Srwatson{ 2562100979Srwatson int error; 2563100979Srwatson 2564104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2565104269Srwatson 2566104269Srwatson if (!mac_enforce_pipe) 2567104269Srwatson return (0); 2568104269Srwatson 2569102115Srwatson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2570100979Srwatson 2571100979Srwatson return (error); 2572100979Srwatson} 2573100979Srwatson 2574102115Srwatsonint 2575102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2576102115Srwatson{ 2577102115Srwatson int error; 2578102115Srwatson 2579104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2580104269Srwatson 2581104269Srwatson if (!mac_enforce_pipe) 2582104269Srwatson return (0); 2583104269Srwatson 2584102115Srwatson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2585102115Srwatson 2586102115Srwatson return (error); 2587102115Srwatson} 2588102115Srwatson 2589100979Srwatsonstatic int 2590100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2591100979Srwatson struct label *newlabel) 2592100979Srwatson{ 2593100979Srwatson int error; 2594100979Srwatson 2595104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2596104269Srwatson 2597104269Srwatson if (!mac_enforce_pipe) 2598104269Srwatson return (0); 2599104269Srwatson 2600100979Srwatson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2601100979Srwatson 2602100979Srwatson return (error); 2603100979Srwatson} 2604100979Srwatson 2605100979Srwatsonint 2606102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2607102115Srwatson{ 2608102115Srwatson int error; 2609102115Srwatson 2610104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2611104269Srwatson 2612104269Srwatson if (!mac_enforce_pipe) 2613104269Srwatson return (0); 2614104269Srwatson 2615102115Srwatson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2616102115Srwatson 2617102115Srwatson return (error); 2618102115Srwatson} 2619102115Srwatson 2620102115Srwatsonint 2621102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2622102115Srwatson{ 2623102115Srwatson int error; 2624102115Srwatson 2625104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2626104269Srwatson 2627104269Srwatson if (!mac_enforce_pipe) 2628104269Srwatson return (0); 2629104269Srwatson 2630102115Srwatson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2631102115Srwatson 2632102115Srwatson return (error); 2633102115Srwatson} 2634102115Srwatson 2635102115Srwatsonint 2636100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc) 2637100979Srwatson{ 2638100979Srwatson int error; 2639100979Srwatson 2640102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2641102103Srwatson 2642100979Srwatson if (!mac_enforce_process) 2643100979Srwatson return (0); 2644100979Srwatson 2645100979Srwatson MAC_CHECK(check_proc_debug, cred, proc); 2646100979Srwatson 2647100979Srwatson return (error); 2648100979Srwatson} 2649100979Srwatson 2650100979Srwatsonint 2651100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc) 2652100979Srwatson{ 2653100979Srwatson int error; 2654100979Srwatson 2655102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2656102103Srwatson 2657100979Srwatson if (!mac_enforce_process) 2658100979Srwatson return (0); 2659100979Srwatson 2660100979Srwatson MAC_CHECK(check_proc_sched, cred, proc); 2661100979Srwatson 2662100979Srwatson return (error); 2663100979Srwatson} 2664100979Srwatson 2665100979Srwatsonint 2666100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2667100979Srwatson{ 2668100979Srwatson int error; 2669100979Srwatson 2670102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2671102103Srwatson 2672100979Srwatson if (!mac_enforce_process) 2673100979Srwatson return (0); 2674100979Srwatson 2675100979Srwatson MAC_CHECK(check_proc_signal, cred, proc, signum); 2676100979Srwatson 2677100979Srwatson return (error); 2678100979Srwatson} 2679100979Srwatson 2680100979Srwatsonint 2681100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2682100979Srwatson struct sockaddr *sockaddr) 2683100979Srwatson{ 2684100979Srwatson int error; 2685100979Srwatson 2686100979Srwatson if (!mac_enforce_socket) 2687100979Srwatson return (0); 2688100979Srwatson 2689100979Srwatson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2690100979Srwatson sockaddr); 2691100979Srwatson 2692100979Srwatson return (error); 2693100979Srwatson} 2694100979Srwatson 2695100979Srwatsonint 2696100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket, 2697100979Srwatson struct sockaddr *sockaddr) 2698100979Srwatson{ 2699100979Srwatson int error; 2700100979Srwatson 2701100979Srwatson if (!mac_enforce_socket) 2702100979Srwatson return (0); 2703100979Srwatson 2704100979Srwatson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2705100979Srwatson sockaddr); 2706100979Srwatson 2707100979Srwatson return (error); 2708100979Srwatson} 2709100979Srwatson 2710100979Srwatsonint 2711101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2712100979Srwatson{ 2713113482Srwatson struct label *label; 2714100979Srwatson int error; 2715100979Srwatson 2716100979Srwatson if (!mac_enforce_socket) 2717100979Srwatson return (0); 2718100979Srwatson 2719113482Srwatson label = mbuf_to_label(mbuf); 2720113482Srwatson 2721101933Srwatson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2722113482Srwatson label); 2723101933Srwatson 2724100979Srwatson return (error); 2725100979Srwatson} 2726100979Srwatson 2727100979Srwatsonint 2728101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket) 2729100979Srwatson{ 2730100979Srwatson int error; 2731100979Srwatson 2732100979Srwatson if (!mac_enforce_socket) 2733100979Srwatson return (0); 2734100979Srwatson 2735101933Srwatson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2736100979Srwatson return (error); 2737100979Srwatson} 2738100979Srwatson 2739104571Srwatsonint 2740104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so) 2741104571Srwatson{ 2742104571Srwatson int error; 2743104571Srwatson 2744104571Srwatson if (!mac_enforce_socket) 2745104571Srwatson return (0); 2746104571Srwatson 2747104571Srwatson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2748104571Srwatson 2749104571Srwatson return (error); 2750104571Srwatson} 2751104571Srwatson 2752100979Srwatsonstatic int 2753100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2754100979Srwatson struct label *newlabel) 2755100979Srwatson{ 2756100979Srwatson int error; 2757100979Srwatson 2758100979Srwatson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2759100979Srwatson newlabel); 2760100979Srwatson 2761100979Srwatson return (error); 2762100979Srwatson} 2763100979Srwatson 2764100979Srwatsonint 2765104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so) 2766104571Srwatson{ 2767104571Srwatson int error; 2768104571Srwatson 2769104571Srwatson if (!mac_enforce_socket) 2770104571Srwatson return (0); 2771104571Srwatson 2772104571Srwatson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2773104571Srwatson 2774104571Srwatson return (error); 2775104571Srwatson} 2776104571Srwatson 2777104571Srwatsonint 2778100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket) 2779100979Srwatson{ 2780100979Srwatson int error; 2781100979Srwatson 2782100979Srwatson if (!mac_enforce_socket) 2783100979Srwatson return (0); 2784105694Srwatson 2785100979Srwatson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2786105694Srwatson 2787100979Srwatson return (error); 2788100979Srwatson} 2789100979Srwatson 2790100979Srwatsonint 2791111939Srwatsonmac_check_sysarch_ioperm(struct ucred *cred) 2792111939Srwatson{ 2793111939Srwatson int error; 2794111939Srwatson 2795111939Srwatson if (!mac_enforce_system) 2796111939Srwatson return (0); 2797111939Srwatson 2798111939Srwatson MAC_CHECK(check_sysarch_ioperm, cred); 2799111939Srwatson return (error); 2800111939Srwatson} 2801111939Srwatson 2802111939Srwatsonint 2803106412Srwatsonmac_check_system_acct(struct ucred *cred, struct vnode *vp) 2804106412Srwatson{ 2805106412Srwatson int error; 2806106412Srwatson 2807106412Srwatson if (vp != NULL) { 2808106412Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2809106412Srwatson } 2810106412Srwatson 2811106412Srwatson if (!mac_enforce_system) 2812106412Srwatson return (0); 2813106412Srwatson 2814106412Srwatson MAC_CHECK(check_system_acct, cred, vp, 2815106412Srwatson vp != NULL ? &vp->v_label : NULL); 2816106412Srwatson 2817106412Srwatson return (error); 2818106412Srwatson} 2819106412Srwatson 2820106412Srwatsonint 2821106412Srwatsonmac_check_system_nfsd(struct ucred *cred) 2822106412Srwatson{ 2823106412Srwatson int error; 2824106412Srwatson 2825106412Srwatson if (!mac_enforce_system) 2826106412Srwatson return (0); 2827106412Srwatson 2828106412Srwatson MAC_CHECK(check_system_nfsd, cred); 2829106412Srwatson 2830106412Srwatson return (error); 2831106412Srwatson} 2832106412Srwatson 2833106412Srwatsonint 2834106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto) 2835106024Srwatson{ 2836106024Srwatson int error; 2837106024Srwatson 2838106045Srwatson if (!mac_enforce_system) 2839106024Srwatson return (0); 2840106024Srwatson 2841106024Srwatson MAC_CHECK(check_system_reboot, cred, howto); 2842106045Srwatson 2843106024Srwatson return (error); 2844106024Srwatson} 2845106024Srwatson 2846106024Srwatsonint 2847106369Srwatsonmac_check_system_settime(struct ucred *cred) 2848106369Srwatson{ 2849106369Srwatson int error; 2850106369Srwatson 2851106369Srwatson if (!mac_enforce_system) 2852106369Srwatson return (0); 2853106369Srwatson 2854106369Srwatson MAC_CHECK(check_system_settime, cred); 2855106369Srwatson 2856106369Srwatson return (error); 2857106369Srwatson} 2858106369Srwatson 2859106369Srwatsonint 2860106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2861106023Srwatson{ 2862106023Srwatson int error; 2863106023Srwatson 2864106023Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2865106023Srwatson 2866106045Srwatson if (!mac_enforce_system) 2867106023Srwatson return (0); 2868106023Srwatson 2869106023Srwatson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2870106023Srwatson return (error); 2871106023Srwatson} 2872106023Srwatson 2873106023Srwatsonint 2874111936Srwatsonmac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2875111936Srwatson{ 2876111936Srwatson int error; 2877111936Srwatson 2878111936Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2879111936Srwatson 2880111936Srwatson if (!mac_enforce_system) 2881111936Srwatson return (0); 2882111936Srwatson 2883111936Srwatson MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2884111936Srwatson return (error); 2885111936Srwatson} 2886111936Srwatson 2887111936Srwatsonint 2888106025Srwatsonmac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2889106025Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2890106025Srwatson{ 2891106025Srwatson int error; 2892106025Srwatson 2893106025Srwatson /* 2894106025Srwatson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2895106025Srwatson * but since it's not exported from kern_sysctl.c, we can't. 2896106025Srwatson */ 2897106045Srwatson if (!mac_enforce_system) 2898106025Srwatson return (0); 2899106025Srwatson 2900106025Srwatson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2901106025Srwatson inkernel, new, newlen); 2902106025Srwatson 2903106025Srwatson return (error); 2904106025Srwatson} 2905106025Srwatson 2906106025Srwatsonint 2907100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2908100979Srwatson struct ifnet *ifnet) 2909100979Srwatson{ 2910105694Srwatson char *elements, *buffer; 2911105694Srwatson struct mac mac; 2912100979Srwatson int error; 2913100979Srwatson 2914105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2915100979Srwatson if (error) 2916100979Srwatson return (error); 2917100979Srwatson 2918105694Srwatson error = mac_check_structmac_consistent(&mac); 2919105694Srwatson if (error) 2920105694Srwatson return (error); 2921105694Srwatson 2922111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2923105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2924105694Srwatson if (error) { 2925105694Srwatson free(elements, M_MACTEMP); 2926105694Srwatson return (error); 2927105694Srwatson } 2928105694Srwatson 2929111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2930105694Srwatson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 2931111119Simp buffer, mac.m_buflen, M_WAITOK); 2932105694Srwatson if (error == 0) 2933105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2934105694Srwatson 2935105694Srwatson free(buffer, M_MACTEMP); 2936105694Srwatson free(elements, M_MACTEMP); 2937105694Srwatson 2938105694Srwatson return (error); 2939100979Srwatson} 2940100979Srwatson 2941100979Srwatsonint 2942100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2943100979Srwatson struct ifnet *ifnet) 2944100979Srwatson{ 2945100979Srwatson struct label intlabel; 2946105694Srwatson struct mac mac; 2947105694Srwatson char *buffer; 2948100979Srwatson int error; 2949100979Srwatson 2950105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2951100979Srwatson if (error) 2952100979Srwatson return (error); 2953100979Srwatson 2954105694Srwatson error = mac_check_structmac_consistent(&mac); 2955100979Srwatson if (error) 2956100979Srwatson return (error); 2957100979Srwatson 2958111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2959105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2960105694Srwatson if (error) { 2961105694Srwatson free(buffer, M_MACTEMP); 2962105694Srwatson return (error); 2963105694Srwatson } 2964105694Srwatson 2965105694Srwatson mac_init_ifnet_label(&intlabel); 2966105694Srwatson error = mac_internalize_ifnet_label(&intlabel, buffer); 2967105694Srwatson free(buffer, M_MACTEMP); 2968105694Srwatson if (error) { 2969105694Srwatson mac_destroy_ifnet_label(&intlabel); 2970105694Srwatson return (error); 2971105694Srwatson } 2972105694Srwatson 2973100979Srwatson /* 2974100979Srwatson * XXX: Note that this is a redundant privilege check, since 2975100979Srwatson * policies impose this check themselves if required by the 2976100979Srwatson * policy. Eventually, this should go away. 2977100979Srwatson */ 2978100979Srwatson error = suser_cred(cred, 0); 2979105694Srwatson if (error) { 2980105694Srwatson mac_destroy_ifnet_label(&intlabel); 2981105694Srwatson return (error); 2982105694Srwatson } 2983100979Srwatson 2984100979Srwatson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2985100979Srwatson &intlabel); 2986105694Srwatson if (error) { 2987105694Srwatson mac_destroy_ifnet_label(&intlabel); 2988105694Srwatson return (error); 2989105694Srwatson } 2990100979Srwatson 2991100979Srwatson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2992100979Srwatson 2993105694Srwatson mac_destroy_ifnet_label(&intlabel); 2994105694Srwatson return (0); 2995100979Srwatson} 2996100979Srwatson 2997100979Srwatsonvoid 2998107698Srwatsonmac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de) 2999100979Srwatson{ 3000100979Srwatson 3001107698Srwatson MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label); 3002100979Srwatson} 3003100979Srwatson 3004104533Srwatsonvoid 3005107698Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 3006107698Srwatson struct devfs_dirent *dd, struct devfs_dirent *de) 3007104533Srwatson{ 3008104533Srwatson 3009107698Srwatson MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de, 3010104533Srwatson &de->de_label); 3011104533Srwatson} 3012104533Srwatson 3013100979Srwatsonvoid 3014107698Srwatsonmac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 3015100979Srwatson struct devfs_dirent *de) 3016100979Srwatson{ 3017100979Srwatson 3018107698Srwatson MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 3019100979Srwatson &de->de_label); 3020100979Srwatson} 3021100979Srwatson 3022100979Srwatsonint 3023100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3024105694Srwatson struct mac *mac) 3025100979Srwatson{ 3026100979Srwatson struct label intlabel; 3027105694Srwatson char *buffer; 3028100979Srwatson int error; 3029100979Srwatson 3030105694Srwatson error = mac_check_structmac_consistent(mac); 3031100979Srwatson if (error) 3032100979Srwatson return (error); 3033100979Srwatson 3034111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3035105694Srwatson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3036105694Srwatson if (error) { 3037105694Srwatson free(buffer, M_MACTEMP); 3038105694Srwatson return (error); 3039105694Srwatson } 3040105694Srwatson 3041111119Simp mac_init_socket_label(&intlabel, M_WAITOK); 3042105694Srwatson error = mac_internalize_socket_label(&intlabel, buffer); 3043105694Srwatson free(buffer, M_MACTEMP); 3044105694Srwatson if (error) { 3045105694Srwatson mac_destroy_socket_label(&intlabel); 3046105694Srwatson return (error); 3047105694Srwatson } 3048105694Srwatson 3049100979Srwatson mac_check_socket_relabel(cred, so, &intlabel); 3050100979Srwatson if (error) { 3051105694Srwatson mac_destroy_socket_label(&intlabel); 3052100979Srwatson return (error); 3053100979Srwatson } 3054100979Srwatson 3055100979Srwatson mac_relabel_socket(cred, so, &intlabel); 3056100979Srwatson 3057105694Srwatson mac_destroy_socket_label(&intlabel); 3058100979Srwatson return (0); 3059100979Srwatson} 3060100979Srwatson 3061100979Srwatsonint 3062100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3063100979Srwatson{ 3064100979Srwatson int error; 3065100979Srwatson 3066104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3067104269Srwatson 3068100979Srwatson error = mac_check_pipe_relabel(cred, pipe, label); 3069100979Srwatson if (error) 3070100979Srwatson return (error); 3071100979Srwatson 3072100979Srwatson mac_relabel_pipe(cred, pipe, label); 3073100979Srwatson 3074100979Srwatson return (0); 3075100979Srwatson} 3076100979Srwatson 3077100979Srwatsonint 3078100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3079105694Srwatson struct mac *mac) 3080100979Srwatson{ 3081105694Srwatson char *buffer, *elements; 3082105694Srwatson int error; 3083100979Srwatson 3084105694Srwatson error = mac_check_structmac_consistent(mac); 3085105694Srwatson if (error) 3086105694Srwatson return (error); 3087105694Srwatson 3088111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3089105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3090105694Srwatson if (error) { 3091105694Srwatson free(elements, M_MACTEMP); 3092105694Srwatson return (error); 3093105694Srwatson } 3094105694Srwatson 3095111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3096105694Srwatson error = mac_externalize_socket_label(&so->so_label, elements, 3097111119Simp buffer, mac->m_buflen, M_WAITOK); 3098105694Srwatson if (error == 0) 3099105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3100105694Srwatson 3101105694Srwatson free(buffer, M_MACTEMP); 3102105694Srwatson free(elements, M_MACTEMP); 3103105694Srwatson 3104105694Srwatson return (error); 3105100979Srwatson} 3106100979Srwatson 3107100979Srwatsonint 3108100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3109105694Srwatson struct mac *mac) 3110100979Srwatson{ 3111105694Srwatson char *elements, *buffer; 3112105694Srwatson int error; 3113100979Srwatson 3114105694Srwatson error = mac_check_structmac_consistent(mac); 3115105694Srwatson if (error) 3116105694Srwatson return (error); 3117105694Srwatson 3118111119Simp elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3119105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3120105694Srwatson if (error) { 3121105694Srwatson free(elements, M_MACTEMP); 3122105694Srwatson return (error); 3123105694Srwatson } 3124105694Srwatson 3125111119Simp buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3126105694Srwatson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3127111119Simp elements, buffer, mac->m_buflen, M_WAITOK); 3128105694Srwatson if (error == 0) 3129105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3130105694Srwatson 3131105694Srwatson free(buffer, M_MACTEMP); 3132105694Srwatson free(elements, M_MACTEMP); 3133105694Srwatson 3134105694Srwatson return (error); 3135100979Srwatson} 3136100979Srwatson 3137100979Srwatson/* 3138100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes 3139100979Srwatson * to store label data. Can be referenced by filesystems supporting 3140100979Srwatson * extended attributes. 3141100979Srwatson */ 3142100979Srwatsonint 3143100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3144100979Srwatson{ 3145100979Srwatson struct vnode *vp = ap->a_vp; 3146100979Srwatson struct label *intlabel = ap->a_label; 3147100979Srwatson int error; 3148100979Srwatson 3149100979Srwatson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3150100979Srwatson 3151105988Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3152105988Srwatson return (EOPNOTSUPP); 3153100979Srwatson 3154105988Srwatson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3155100979Srwatson if (error) 3156100979Srwatson return (error); 3157100979Srwatson 3158100979Srwatson mac_relabel_vnode(ap->a_cred, vp, intlabel); 3159100979Srwatson 3160100979Srwatson return (0); 3161100979Srwatson} 3162100979Srwatson 3163100979Srwatsonstatic int 3164100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3165100979Srwatson{ 3166100979Srwatson int error; 3167100979Srwatson 3168100979Srwatson if (vp->v_mount == NULL) { 3169100979Srwatson /* printf("vn_setlabel: null v_mount\n"); */ 3170103314Snjl if (vp->v_type != VNON) 3171103314Snjl printf("vn_setlabel: null v_mount with non-VNON\n"); 3172100979Srwatson return (EBADF); 3173100979Srwatson } 3174100979Srwatson 3175100979Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3176100979Srwatson return (EOPNOTSUPP); 3177100979Srwatson 3178100979Srwatson /* 3179100979Srwatson * Multi-phase commit. First check the policies to confirm the 3180100979Srwatson * change is OK. Then commit via the filesystem. Finally, 3181100979Srwatson * update the actual vnode label. Question: maybe the filesystem 3182100979Srwatson * should update the vnode at the end as part of VOP_SETLABEL()? 3183100979Srwatson */ 3184100979Srwatson error = mac_check_vnode_relabel(cred, vp, intlabel); 3185100979Srwatson if (error) 3186100979Srwatson return (error); 3187100979Srwatson 3188100979Srwatson /* 3189100979Srwatson * VADMIN provides the opportunity for the filesystem to make 3190100979Srwatson * decisions about who is and is not able to modify labels 3191100979Srwatson * and protections on files. This might not be right. We can't 3192100979Srwatson * assume VOP_SETLABEL() will do it, because we might implement 3193100979Srwatson * that as part of vop_stdsetlabel_ea(). 3194100979Srwatson */ 3195100979Srwatson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3196100979Srwatson if (error) 3197100979Srwatson return (error); 3198100979Srwatson 3199100979Srwatson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3200100979Srwatson if (error) 3201100979Srwatson return (error); 3202100979Srwatson 3203100979Srwatson return (0); 3204100979Srwatson} 3205100979Srwatson 3206105694Srwatsonint 3207105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3208105694Srwatson{ 3209105694Srwatson char *elements, *buffer; 3210105694Srwatson struct mac mac; 3211105694Srwatson struct proc *tproc; 3212105694Srwatson struct ucred *tcred; 3213105694Srwatson int error; 3214105694Srwatson 3215107849Salfred error = copyin(uap->mac_p, &mac, sizeof(mac)); 3216105694Srwatson if (error) 3217105694Srwatson return (error); 3218105694Srwatson 3219105694Srwatson error = mac_check_structmac_consistent(&mac); 3220105694Srwatson if (error) 3221105694Srwatson return (error); 3222105694Srwatson 3223105694Srwatson tproc = pfind(uap->pid); 3224105694Srwatson if (tproc == NULL) 3225105694Srwatson return (ESRCH); 3226105694Srwatson 3227105694Srwatson tcred = NULL; /* Satisfy gcc. */ 3228105694Srwatson error = p_cansee(td, tproc); 3229105694Srwatson if (error == 0) 3230105694Srwatson tcred = crhold(tproc->p_ucred); 3231105694Srwatson PROC_UNLOCK(tproc); 3232105694Srwatson if (error) 3233105694Srwatson return (error); 3234105694Srwatson 3235111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3236105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3237105694Srwatson if (error) { 3238105694Srwatson free(elements, M_MACTEMP); 3239105694Srwatson crfree(tcred); 3240105694Srwatson return (error); 3241105694Srwatson } 3242105694Srwatson 3243111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3244105694Srwatson error = mac_externalize_cred_label(&tcred->cr_label, elements, 3245111119Simp buffer, mac.m_buflen, M_WAITOK); 3246105694Srwatson if (error == 0) 3247105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3248105694Srwatson 3249105694Srwatson free(buffer, M_MACTEMP); 3250105694Srwatson free(elements, M_MACTEMP); 3251105694Srwatson crfree(tcred); 3252105694Srwatson return (error); 3253105694Srwatson} 3254105694Srwatson 3255100979Srwatson/* 3256100979Srwatson * MPSAFE 3257100979Srwatson */ 3258100979Srwatsonint 3259100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3260100894Srwatson{ 3261105694Srwatson char *elements, *buffer; 3262105694Srwatson struct mac mac; 3263100979Srwatson int error; 3264100894Srwatson 3265105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3266105694Srwatson if (error) 3267105694Srwatson return (error); 3268105694Srwatson 3269105694Srwatson error = mac_check_structmac_consistent(&mac); 3270105694Srwatson if (error) 3271105694Srwatson return (error); 3272105694Srwatson 3273111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3274105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3275105694Srwatson if (error) { 3276105694Srwatson free(elements, M_MACTEMP); 3277105694Srwatson return (error); 3278105694Srwatson } 3279105694Srwatson 3280111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3281105694Srwatson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3282111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3283100979Srwatson if (error == 0) 3284105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3285100979Srwatson 3286105694Srwatson free(buffer, M_MACTEMP); 3287105694Srwatson free(elements, M_MACTEMP); 3288100979Srwatson return (error); 3289100979Srwatson} 3290100979Srwatson 3291100979Srwatson/* 3292100979Srwatson * MPSAFE 3293100979Srwatson */ 3294100979Srwatsonint 3295100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3296100979Srwatson{ 3297100979Srwatson struct ucred *newcred, *oldcred; 3298105694Srwatson struct label intlabel; 3299100979Srwatson struct proc *p; 3300105694Srwatson struct mac mac; 3301105694Srwatson char *buffer; 3302100979Srwatson int error; 3303100979Srwatson 3304105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3305100979Srwatson if (error) 3306100979Srwatson return (error); 3307100979Srwatson 3308105694Srwatson error = mac_check_structmac_consistent(&mac); 3309100979Srwatson if (error) 3310100979Srwatson return (error); 3311100979Srwatson 3312111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3313105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3314105694Srwatson if (error) { 3315105694Srwatson free(buffer, M_MACTEMP); 3316105694Srwatson return (error); 3317105694Srwatson } 3318105694Srwatson 3319105694Srwatson mac_init_cred_label(&intlabel); 3320105694Srwatson error = mac_internalize_cred_label(&intlabel, buffer); 3321105694Srwatson free(buffer, M_MACTEMP); 3322105694Srwatson if (error) { 3323105694Srwatson mac_destroy_cred_label(&intlabel); 3324105694Srwatson return (error); 3325105694Srwatson } 3326105694Srwatson 3327100979Srwatson newcred = crget(); 3328100979Srwatson 3329100979Srwatson p = td->td_proc; 3330100979Srwatson PROC_LOCK(p); 3331100979Srwatson oldcred = p->p_ucred; 3332100979Srwatson 3333100979Srwatson error = mac_check_cred_relabel(oldcred, &intlabel); 3334100979Srwatson if (error) { 3335100979Srwatson PROC_UNLOCK(p); 3336100979Srwatson crfree(newcred); 3337105694Srwatson goto out; 3338100979Srwatson } 3339100979Srwatson 3340100979Srwatson setsugid(p); 3341100979Srwatson crcopy(newcred, oldcred); 3342100979Srwatson mac_relabel_cred(newcred, &intlabel); 3343102136Srwatson p->p_ucred = newcred; 3344100979Srwatson 3345102136Srwatson /* 3346102136Srwatson * Grab additional reference for use while revoking mmaps, prior 3347102136Srwatson * to releasing the proc lock and sharing the cred. 3348102136Srwatson */ 3349102136Srwatson crhold(newcred); 3350100979Srwatson PROC_UNLOCK(p); 3351102136Srwatson 3352105694Srwatson if (mac_enforce_vm) { 3353105694Srwatson mtx_lock(&Giant); 3354105694Srwatson mac_cred_mmapped_drop_perms(td, newcred); 3355105694Srwatson mtx_unlock(&Giant); 3356105694Srwatson } 3357102136Srwatson 3358102136Srwatson crfree(newcred); /* Free revocation reference. */ 3359100979Srwatson crfree(oldcred); 3360105694Srwatson 3361105694Srwatsonout: 3362105694Srwatson mac_destroy_cred_label(&intlabel); 3363105694Srwatson return (error); 3364100979Srwatson} 3365100979Srwatson 3366100979Srwatson/* 3367100979Srwatson * MPSAFE 3368100979Srwatson */ 3369100979Srwatsonint 3370100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3371100979Srwatson{ 3372105694Srwatson char *elements, *buffer; 3373105694Srwatson struct label intlabel; 3374100979Srwatson struct file *fp; 3375105694Srwatson struct mac mac; 3376100979Srwatson struct vnode *vp; 3377100979Srwatson struct pipe *pipe; 3378105694Srwatson short label_type; 3379100979Srwatson int error; 3380100979Srwatson 3381105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3382105694Srwatson if (error) 3383105694Srwatson return (error); 3384100979Srwatson 3385105694Srwatson error = mac_check_structmac_consistent(&mac); 3386105694Srwatson if (error) 3387105694Srwatson return (error); 3388105694Srwatson 3389111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3390105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3391105694Srwatson if (error) { 3392105694Srwatson free(elements, M_MACTEMP); 3393105694Srwatson return (error); 3394105694Srwatson } 3395105694Srwatson 3396111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3397105694Srwatson mtx_lock(&Giant); /* VFS */ 3398107849Salfred error = fget(td, uap->fd, &fp); 3399100979Srwatson if (error) 3400100979Srwatson goto out; 3401100979Srwatson 3402105694Srwatson label_type = fp->f_type; 3403100979Srwatson switch (fp->f_type) { 3404100979Srwatson case DTYPE_FIFO: 3405100979Srwatson case DTYPE_VNODE: 3406109153Sdillon vp = fp->f_data; 3407100979Srwatson 3408105694Srwatson mac_init_vnode_label(&intlabel); 3409105694Srwatson 3410100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3411105988Srwatson mac_copy_vnode_label(&vp->v_label, &intlabel); 3412100979Srwatson VOP_UNLOCK(vp, 0, td); 3413105694Srwatson 3414100979Srwatson break; 3415100979Srwatson case DTYPE_PIPE: 3416109153Sdillon pipe = fp->f_data; 3417105694Srwatson 3418105694Srwatson mac_init_pipe_label(&intlabel); 3419105694Srwatson 3420105694Srwatson PIPE_LOCK(pipe); 3421105694Srwatson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3422105694Srwatson PIPE_UNLOCK(pipe); 3423100979Srwatson break; 3424100979Srwatson default: 3425100979Srwatson error = EINVAL; 3426105694Srwatson fdrop(fp, td); 3427105694Srwatson goto out; 3428100979Srwatson } 3429105694Srwatson fdrop(fp, td); 3430100979Srwatson 3431105694Srwatson switch (label_type) { 3432105694Srwatson case DTYPE_FIFO: 3433105694Srwatson case DTYPE_VNODE: 3434105694Srwatson if (error == 0) 3435105694Srwatson error = mac_externalize_vnode_label(&intlabel, 3436111119Simp elements, buffer, mac.m_buflen, M_WAITOK); 3437105694Srwatson mac_destroy_vnode_label(&intlabel); 3438105694Srwatson break; 3439105694Srwatson case DTYPE_PIPE: 3440105694Srwatson error = mac_externalize_pipe_label(&intlabel, elements, 3441111119Simp buffer, mac.m_buflen, M_WAITOK); 3442105694Srwatson mac_destroy_pipe_label(&intlabel); 3443105694Srwatson break; 3444105694Srwatson default: 3445105694Srwatson panic("__mac_get_fd: corrupted label_type"); 3446105694Srwatson } 3447105694Srwatson 3448100979Srwatson if (error == 0) 3449105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3450100979Srwatson 3451105694Srwatsonout: 3452105694Srwatson mtx_unlock(&Giant); /* VFS */ 3453105694Srwatson free(buffer, M_MACTEMP); 3454105694Srwatson free(elements, M_MACTEMP); 3455100979Srwatson 3456100979Srwatson return (error); 3457100979Srwatson} 3458100979Srwatson 3459100979Srwatson/* 3460100979Srwatson * MPSAFE 3461100979Srwatson */ 3462100979Srwatsonint 3463100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3464100979Srwatson{ 3465105694Srwatson char *elements, *buffer; 3466100979Srwatson struct nameidata nd; 3467105694Srwatson struct label intlabel; 3468105694Srwatson struct mac mac; 3469100979Srwatson int error; 3470100979Srwatson 3471105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3472105694Srwatson if (error) 3473105694Srwatson return (error); 3474105694Srwatson 3475105694Srwatson error = mac_check_structmac_consistent(&mac); 3476105694Srwatson if (error) 3477105694Srwatson return (error); 3478105694Srwatson 3479111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3480105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3481105694Srwatson if (error) { 3482105694Srwatson free(elements, M_MACTEMP); 3483105694Srwatson return (error); 3484105694Srwatson } 3485105694Srwatson 3486111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3487105694Srwatson mtx_lock(&Giant); /* VFS */ 3488105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3489105694Srwatson td); 3490100979Srwatson error = namei(&nd); 3491100979Srwatson if (error) 3492100979Srwatson goto out; 3493100979Srwatson 3494105694Srwatson mac_init_vnode_label(&intlabel); 3495105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3496105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3497111119Simp mac.m_buflen, M_WAITOK); 3498105694Srwatson 3499100979Srwatson NDFREE(&nd, 0); 3500105694Srwatson mac_destroy_vnode_label(&intlabel); 3501105694Srwatson 3502105694Srwatson if (error == 0) 3503105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3504105694Srwatson 3505105694Srwatsonout: 3506105694Srwatson mtx_unlock(&Giant); /* VFS */ 3507105694Srwatson 3508105694Srwatson free(buffer, M_MACTEMP); 3509105694Srwatson free(elements, M_MACTEMP); 3510105694Srwatson 3511105694Srwatson return (error); 3512105694Srwatson} 3513105694Srwatson 3514105694Srwatson/* 3515105694Srwatson * MPSAFE 3516105694Srwatson */ 3517105694Srwatsonint 3518105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3519105694Srwatson{ 3520105694Srwatson char *elements, *buffer; 3521105694Srwatson struct nameidata nd; 3522105694Srwatson struct label intlabel; 3523105694Srwatson struct mac mac; 3524105694Srwatson int error; 3525105694Srwatson 3526105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3527100979Srwatson if (error) 3528105694Srwatson return (error); 3529105694Srwatson 3530105694Srwatson error = mac_check_structmac_consistent(&mac); 3531105694Srwatson if (error) 3532105694Srwatson return (error); 3533105694Srwatson 3534111119Simp elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3535105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3536105694Srwatson if (error) { 3537105694Srwatson free(elements, M_MACTEMP); 3538105694Srwatson return (error); 3539105694Srwatson } 3540105694Srwatson 3541111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3542105694Srwatson mtx_lock(&Giant); /* VFS */ 3543105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3544105694Srwatson td); 3545105694Srwatson error = namei(&nd); 3546105694Srwatson if (error) 3547100979Srwatson goto out; 3548100979Srwatson 3549105694Srwatson mac_init_vnode_label(&intlabel); 3550105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3551105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3552111119Simp mac.m_buflen, M_WAITOK); 3553105694Srwatson NDFREE(&nd, 0); 3554105694Srwatson mac_destroy_vnode_label(&intlabel); 3555100979Srwatson 3556105694Srwatson if (error == 0) 3557105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3558105694Srwatson 3559100979Srwatsonout: 3560105694Srwatson mtx_unlock(&Giant); /* VFS */ 3561105694Srwatson 3562105694Srwatson free(buffer, M_MACTEMP); 3563105694Srwatson free(elements, M_MACTEMP); 3564105694Srwatson 3565100979Srwatson return (error); 3566100979Srwatson} 3567100979Srwatson 3568100979Srwatson/* 3569100979Srwatson * MPSAFE 3570100979Srwatson */ 3571100979Srwatsonint 3572100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3573100979Srwatson{ 3574105694Srwatson struct label intlabel; 3575105694Srwatson struct pipe *pipe; 3576100979Srwatson struct file *fp; 3577100979Srwatson struct mount *mp; 3578100979Srwatson struct vnode *vp; 3579105694Srwatson struct mac mac; 3580105694Srwatson char *buffer; 3581100979Srwatson int error; 3582100979Srwatson 3583105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3584100979Srwatson if (error) 3585105694Srwatson return (error); 3586100979Srwatson 3587105694Srwatson error = mac_check_structmac_consistent(&mac); 3588100979Srwatson if (error) 3589105694Srwatson return (error); 3590100979Srwatson 3591111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3592105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3593105694Srwatson if (error) { 3594105694Srwatson free(buffer, M_MACTEMP); 3595105694Srwatson return (error); 3596105694Srwatson } 3597105694Srwatson 3598105694Srwatson mtx_lock(&Giant); /* VFS */ 3599105694Srwatson 3600107849Salfred error = fget(td, uap->fd, &fp); 3601100979Srwatson if (error) 3602105694Srwatson goto out; 3603100979Srwatson 3604100979Srwatson switch (fp->f_type) { 3605100979Srwatson case DTYPE_FIFO: 3606100979Srwatson case DTYPE_VNODE: 3607105694Srwatson mac_init_vnode_label(&intlabel); 3608105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3609105694Srwatson if (error) { 3610105694Srwatson mac_destroy_vnode_label(&intlabel); 3611105694Srwatson break; 3612105694Srwatson } 3613105694Srwatson 3614109153Sdillon vp = fp->f_data; 3615100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3616105694Srwatson if (error != 0) { 3617105694Srwatson mac_destroy_vnode_label(&intlabel); 3618100979Srwatson break; 3619105694Srwatson } 3620100979Srwatson 3621100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3622100979Srwatson error = vn_setlabel(vp, &intlabel, td->td_ucred); 3623100979Srwatson VOP_UNLOCK(vp, 0, td); 3624100979Srwatson vn_finished_write(mp); 3625105694Srwatson 3626105694Srwatson mac_destroy_vnode_label(&intlabel); 3627100979Srwatson break; 3628105694Srwatson 3629100979Srwatson case DTYPE_PIPE: 3630105694Srwatson mac_init_pipe_label(&intlabel); 3631105694Srwatson error = mac_internalize_pipe_label(&intlabel, buffer); 3632105694Srwatson if (error == 0) { 3633109153Sdillon pipe = fp->f_data; 3634105694Srwatson PIPE_LOCK(pipe); 3635105694Srwatson error = mac_pipe_label_set(td->td_ucred, pipe, 3636105694Srwatson &intlabel); 3637105694Srwatson PIPE_UNLOCK(pipe); 3638105694Srwatson } 3639105694Srwatson 3640105694Srwatson mac_destroy_pipe_label(&intlabel); 3641100979Srwatson break; 3642105694Srwatson 3643100979Srwatson default: 3644100979Srwatson error = EINVAL; 3645100979Srwatson } 3646100979Srwatson 3647100979Srwatson fdrop(fp, td); 3648105694Srwatsonout: 3649105694Srwatson mtx_unlock(&Giant); /* VFS */ 3650105694Srwatson 3651105694Srwatson free(buffer, M_MACTEMP); 3652105694Srwatson 3653100979Srwatson return (error); 3654100979Srwatson} 3655100979Srwatson 3656100979Srwatson/* 3657100979Srwatson * MPSAFE 3658100979Srwatson */ 3659100979Srwatsonint 3660100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3661100979Srwatson{ 3662105694Srwatson struct label intlabel; 3663100979Srwatson struct nameidata nd; 3664100979Srwatson struct mount *mp; 3665105694Srwatson struct mac mac; 3666105694Srwatson char *buffer; 3667100979Srwatson int error; 3668100979Srwatson 3669105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3670100979Srwatson if (error) 3671105694Srwatson return (error); 3672100979Srwatson 3673105694Srwatson error = mac_check_structmac_consistent(&mac); 3674100979Srwatson if (error) 3675105694Srwatson return (error); 3676100979Srwatson 3677111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3678105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3679105694Srwatson if (error) { 3680105694Srwatson free(buffer, M_MACTEMP); 3681105694Srwatson return (error); 3682105694Srwatson } 3683105694Srwatson 3684105694Srwatson mac_init_vnode_label(&intlabel); 3685105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3686105694Srwatson free(buffer, M_MACTEMP); 3687105694Srwatson if (error) { 3688105694Srwatson mac_destroy_vnode_label(&intlabel); 3689105694Srwatson return (error); 3690105694Srwatson } 3691105694Srwatson 3692105694Srwatson mtx_lock(&Giant); /* VFS */ 3693105694Srwatson 3694105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3695105694Srwatson td); 3696100979Srwatson error = namei(&nd); 3697105694Srwatson if (error == 0) { 3698105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3699105694Srwatson if (error == 0) 3700105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3701105694Srwatson td->td_ucred); 3702105694Srwatson vn_finished_write(mp); 3703105694Srwatson } 3704105694Srwatson 3705105694Srwatson NDFREE(&nd, 0); 3706105694Srwatson mtx_unlock(&Giant); /* VFS */ 3707105694Srwatson mac_destroy_vnode_label(&intlabel); 3708105694Srwatson 3709105694Srwatson return (error); 3710105694Srwatson} 3711105694Srwatson 3712105694Srwatson/* 3713105694Srwatson * MPSAFE 3714105694Srwatson */ 3715105694Srwatsonint 3716105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3717105694Srwatson{ 3718105694Srwatson struct label intlabel; 3719105694Srwatson struct nameidata nd; 3720105694Srwatson struct mount *mp; 3721105694Srwatson struct mac mac; 3722105694Srwatson char *buffer; 3723105694Srwatson int error; 3724105694Srwatson 3725105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3726100979Srwatson if (error) 3727105694Srwatson return (error); 3728105694Srwatson 3729105694Srwatson error = mac_check_structmac_consistent(&mac); 3730100979Srwatson if (error) 3731105694Srwatson return (error); 3732100979Srwatson 3733111119Simp buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3734105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3735105694Srwatson if (error) { 3736105694Srwatson free(buffer, M_MACTEMP); 3737105694Srwatson return (error); 3738105694Srwatson } 3739105694Srwatson 3740105694Srwatson mac_init_vnode_label(&intlabel); 3741105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3742105694Srwatson free(buffer, M_MACTEMP); 3743105694Srwatson if (error) { 3744105694Srwatson mac_destroy_vnode_label(&intlabel); 3745105694Srwatson return (error); 3746105694Srwatson } 3747105694Srwatson 3748105694Srwatson mtx_lock(&Giant); /* VFS */ 3749105694Srwatson 3750105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3751105694Srwatson td); 3752105694Srwatson error = namei(&nd); 3753105694Srwatson if (error == 0) { 3754105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3755105694Srwatson if (error == 0) 3756105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3757105694Srwatson td->td_ucred); 3758105694Srwatson vn_finished_write(mp); 3759105694Srwatson } 3760105694Srwatson 3761100979Srwatson NDFREE(&nd, 0); 3762105694Srwatson mtx_unlock(&Giant); /* VFS */ 3763105694Srwatson mac_destroy_vnode_label(&intlabel); 3764105694Srwatson 3765100979Srwatson return (error); 3766100979Srwatson} 3767100979Srwatson 3768105694Srwatson/* 3769105694Srwatson * MPSAFE 3770105694Srwatson */ 3771102123Srwatsonint 3772102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3773102123Srwatson{ 3774102123Srwatson struct mac_policy_conf *mpc; 3775102123Srwatson char target[MAC_MAX_POLICY_NAME]; 3776102123Srwatson int error; 3777102123Srwatson 3778107849Salfred error = copyinstr(uap->policy, target, sizeof(target), NULL); 3779102123Srwatson if (error) 3780102123Srwatson return (error); 3781102123Srwatson 3782102123Srwatson error = ENOSYS; 3783102123Srwatson MAC_POLICY_LIST_BUSY(); 3784102123Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3785102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3786102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3787102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3788107849Salfred uap->call, uap->arg); 3789102123Srwatson goto out; 3790102123Srwatson } 3791102123Srwatson } 3792102123Srwatson 3793102123Srwatsonout: 3794102123Srwatson MAC_POLICY_LIST_UNBUSY(); 3795102123Srwatson return (error); 3796102123Srwatson} 3797102123Srwatson 3798100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3799100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3800100979Srwatson 3801100979Srwatson#else /* !MAC */ 3802100979Srwatson 3803100979Srwatsonint 3804105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3805105694Srwatson{ 3806105694Srwatson 3807105694Srwatson return (ENOSYS); 3808105694Srwatson} 3809105694Srwatson 3810105694Srwatsonint 3811100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3812100979Srwatson{ 3813100979Srwatson 3814100894Srwatson return (ENOSYS); 3815100894Srwatson} 3816100894Srwatson 3817100894Srwatsonint 3818100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3819100894Srwatson{ 3820100894Srwatson 3821100894Srwatson return (ENOSYS); 3822100894Srwatson} 3823100894Srwatson 3824100894Srwatsonint 3825100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3826100894Srwatson{ 3827100894Srwatson 3828100894Srwatson return (ENOSYS); 3829100894Srwatson} 3830100894Srwatson 3831100894Srwatsonint 3832100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3833100894Srwatson{ 3834100894Srwatson 3835100894Srwatson return (ENOSYS); 3836100894Srwatson} 3837100894Srwatson 3838100894Srwatsonint 3839105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3840105694Srwatson{ 3841105694Srwatson 3842105694Srwatson return (ENOSYS); 3843105694Srwatson} 3844105694Srwatson 3845105694Srwatsonint 3846100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3847100894Srwatson{ 3848100894Srwatson 3849100894Srwatson return (ENOSYS); 3850100894Srwatson} 3851100894Srwatson 3852100894Srwatsonint 3853100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3854100894Srwatson{ 3855100894Srwatson 3856100894Srwatson return (ENOSYS); 3857100894Srwatson} 3858100979Srwatson 3859102123Srwatsonint 3860105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3861105694Srwatson{ 3862105694Srwatson 3863105694Srwatson return (ENOSYS); 3864105694Srwatson} 3865105694Srwatson 3866105694Srwatsonint 3867102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3868102123Srwatson{ 3869102123Srwatson 3870102123Srwatson return (ENOSYS); 3871102123Srwatson} 3872102123Srwatson 3873105694Srwatson#endif 3874