mac_cred.c revision 106856
1100894Srwatson/*- 2100894Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3100894Srwatson * Copyright (c) 2001 Ilmar S. Habibulin 4100894Srwatson * Copyright (c) 2001, 2002 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 106856 2002-11-13 15:47:09Z rwatson $ 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 123100979Srwatsonstatic int mac_enforce_fs = 1; 124100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 125100979Srwatson &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 126100979SrwatsonTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 127100979Srwatson 128100979Srwatsonstatic int mac_enforce_network = 1; 129100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 130100979Srwatson &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 131100979SrwatsonTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 132100979Srwatson 133103513Srwatsonstatic int mac_enforce_pipe = 1; 134103513SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 135103513Srwatson &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 136104236SrwatsonTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 137103513Srwatson 138100979Srwatsonstatic int mac_enforce_process = 1; 139100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 140100979Srwatson &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 141100979SrwatsonTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 142100979Srwatson 143100979Srwatsonstatic int mac_enforce_socket = 1; 144100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 145100979Srwatson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 146100979SrwatsonTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 147100979Srwatson 148106045Srwatsonstatic int mac_enforce_system = 1; 149106045SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 150106045Srwatson &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 151106045SrwatsonTUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 152106025Srwatson 153106045Srwatsonstatic int mac_enforce_vm = 1; 154103514SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 155103514Srwatson &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 156104236SrwatsonTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 157103514Srwatson 158103136Srwatsonstatic int mac_mmap_revocation = 1; 159103136SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 160103136Srwatson &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 161103136Srwatson "relabel"); 162101892Srwatsonstatic int mac_mmap_revocation_via_cow = 0; 163100979SrwatsonSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 164100979Srwatson &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 165100979Srwatson "copy-on-write semantics, or by removing all write access"); 166100979Srwatson 167101988Srwatson#ifdef MAC_DEBUG 168104268SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 169104268Srwatson "TrustedBSD MAC debug info"); 170104268Srwatson 171104268Srwatsonstatic int mac_debug_label_fallback = 0; 172104268SrwatsonSYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 173104268Srwatson &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 174104268Srwatson "when label is corrupted."); 175104268SrwatsonTUNABLE_INT("security.mac.debug_label_fallback", 176104268Srwatson &mac_debug_label_fallback); 177104268Srwatson 178104517SrwatsonSYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 179104517Srwatson "TrustedBSD MAC object counters"); 180104517Srwatson 181100979Srwatsonstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 182100979Srwatson nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 183100979Srwatson nmacipqs, nmacpipes; 184104517Srwatson 185104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 186100979Srwatson &nmacmbufs, 0, "number of mbufs in use"); 187104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 188100979Srwatson &nmaccreds, 0, "number of ucreds in use"); 189104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 190100979Srwatson &nmacifnets, 0, "number of ifnets in use"); 191104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 192100979Srwatson &nmacipqs, 0, "number of ipqs in use"); 193104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 194100979Srwatson &nmacbpfdescs, 0, "number of bpfdescs in use"); 195104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 196100979Srwatson &nmacsockets, 0, "number of sockets in use"); 197104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 198100979Srwatson &nmacpipes, 0, "number of pipes in use"); 199104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 200100979Srwatson &nmacmounts, 0, "number of mounts in use"); 201104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 202100979Srwatson &nmactemp, 0, "number of temporary labels in use"); 203104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 204100979Srwatson &nmacvnodes, 0, "number of vnodes in use"); 205104517SrwatsonSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 206100979Srwatson &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 207101988Srwatson#endif 208100979Srwatson 209100979Srwatsonstatic int error_select(int error1, int error2); 210100979Srwatsonstatic int mac_policy_register(struct mac_policy_conf *mpc); 211100979Srwatsonstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 212100979Srwatson 213104546Srwatsonstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 214104546Srwatson struct vnode *vp, int *prot); 215100979Srwatsonstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 216100979Srwatson struct ucred *cred, struct vm_map *map); 217100979Srwatson 218104541Srwatsonstatic void mac_destroy_socket_label(struct label *label); 219104541Srwatson 220105988Srwatsonstatic int mac_setlabel_vnode_extattr(struct ucred *cred, 221105988Srwatson struct vnode *vp, struct label *intlabel); 222105988Srwatson 223100979SrwatsonMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 224105694SrwatsonMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 225100979Srwatson 226100979Srwatson/* 227106856Srwatson * mac_policy_list stores the list of active policies. A busy count is 228106856Srwatson * maintained for the list, stored in mac_policy_busy. The busy count 229106856Srwatson * is protected by mac_policy_list_lock; the list may be modified only 230106856Srwatson * while the busy count is 0, requiring that the lock be held to 231106856Srwatson * prevent new references to the list from being acquired. For almost 232106856Srwatson * all operations, incrementing the busy count is sufficient to 233106856Srwatson * guarantee consistency, as the list cannot be modified while the 234106856Srwatson * busy count is elevated. For a few special operations involving a 235106856Srwatson * change to the list of active policies, the lock itself must be held. 236106856Srwatson * A condition variable, mac_policy_list_not_busy, is used to signal 237106856Srwatson * potential exclusive consumers that they should try to acquire the 238106856Srwatson * lock if a first attempt at exclusive access fails. 239100979Srwatson */ 240100979Srwatsonstatic struct mtx mac_policy_list_lock; 241106856Srwatsonstatic struct cv mac_policy_list_not_busy; 242100979Srwatsonstatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 243100979Srwatsonstatic int mac_policy_list_busy; 244100979Srwatson 245106856Srwatson#define MAC_POLICY_LIST_LOCKINIT() do { \ 246106856Srwatson mtx_init(&mac_policy_list_lock, "mac_policy_list_lock", NULL, \ 247106856Srwatson MTX_DEF); \ 248106856Srwatson cv_init(&mac_policy_list_not_busy, "mac_policy_list_not_busy"); \ 249106856Srwatson} while (0) 250106856Srwatson 251106856Srwatson#define MAC_POLICY_LIST_LOCK() do { \ 252106856Srwatson mtx_lock(&mac_policy_list_lock); \ 253106856Srwatson} while (0) 254106856Srwatson 255106856Srwatson#define MAC_POLICY_LIST_UNLOCK() do { \ 256106856Srwatson mtx_unlock(&mac_policy_list_lock); \ 257106856Srwatson} while (0) 258106856Srwatson 259106856Srwatson/* 260106856Srwatson * We manually invoke WITNESS_SLEEP() to allow Witness to generate 261106856Srwatson * warnings even if we don't end up ever triggering the wait at 262106856Srwatson * run-time. The consumer of the exclusive interface must not hold 263106856Srwatson * any locks (other than potentially Giant) since we may sleep for 264106856Srwatson * long (potentially indefinite) periods of time waiting for the 265106856Srwatson * framework to become quiescent so that a policy list change may 266106856Srwatson * be made. 267106856Srwatson */ 268106856Srwatson#define MAC_POLICY_LIST_EXCLUSIVE() do { \ 269106856Srwatson WITNESS_SLEEP(1, NULL); \ 270106856Srwatson mtx_lock(&mac_policy_list_lock); \ 271106856Srwatson while (mac_policy_list_busy != 0) \ 272106856Srwatson cv_wait(&mac_policy_list_not_busy, \ 273106856Srwatson &mac_policy_list_lock); \ 274106856Srwatson} while (0) 275106856Srwatson 276100979Srwatson#define MAC_POLICY_LIST_BUSY() do { \ 277100979Srwatson MAC_POLICY_LIST_LOCK(); \ 278100979Srwatson mac_policy_list_busy++; \ 279100979Srwatson MAC_POLICY_LIST_UNLOCK(); \ 280100979Srwatson} while (0) 281100979Srwatson 282100979Srwatson#define MAC_POLICY_LIST_UNBUSY() do { \ 283100979Srwatson MAC_POLICY_LIST_LOCK(); \ 284100979Srwatson mac_policy_list_busy--; \ 285106856Srwatson KASSERT(mac_policy_list_busy >= 0, ("MAC_POLICY_LIST_LOCK")); \ 286106856Srwatson if (mac_policy_list_busy == 0) \ 287106856Srwatson cv_signal(&mac_policy_list_not_busy); \ 288100979Srwatson MAC_POLICY_LIST_UNLOCK(); \ 289100979Srwatson} while (0) 290100979Srwatson 291100979Srwatson/* 292100979Srwatson * MAC_CHECK performs the designated check by walking the policy 293100979Srwatson * module list and checking with each as to how it feels about the 294100979Srwatson * request. Note that it returns its value via 'error' in the scope 295100979Srwatson * of the caller. 296100979Srwatson */ 297100979Srwatson#define MAC_CHECK(check, args...) do { \ 298100979Srwatson struct mac_policy_conf *mpc; \ 299100979Srwatson \ 300100979Srwatson error = 0; \ 301100979Srwatson MAC_POLICY_LIST_BUSY(); \ 302100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 303100979Srwatson if (mpc->mpc_ops->mpo_ ## check != NULL) \ 304100979Srwatson error = error_select( \ 305100979Srwatson mpc->mpc_ops->mpo_ ## check (args), \ 306100979Srwatson error); \ 307100979Srwatson } \ 308100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 309100979Srwatson} while (0) 310100979Srwatson 311100979Srwatson/* 312100979Srwatson * MAC_BOOLEAN performs the designated boolean composition by walking 313100979Srwatson * the module list, invoking each instance of the operation, and 314100979Srwatson * combining the results using the passed C operator. Note that it 315100979Srwatson * returns its value via 'result' in the scope of the caller, which 316100979Srwatson * should be initialized by the caller in a meaningful way to get 317100979Srwatson * a meaningful result. 318100979Srwatson */ 319100979Srwatson#define MAC_BOOLEAN(operation, composition, args...) do { \ 320100979Srwatson struct mac_policy_conf *mpc; \ 321100979Srwatson \ 322100979Srwatson MAC_POLICY_LIST_BUSY(); \ 323100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 324100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 325100979Srwatson result = result composition \ 326100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 327100979Srwatson } \ 328100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 329100979Srwatson} while (0) 330100979Srwatson 331105694Srwatson#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 332105694Srwatson outbuflen) do { \ 333105694Srwatson char *curptr, *curptr_start, *element_name, *element_temp; \ 334105694Srwatson size_t left, left_start, len; \ 335105694Srwatson int claimed, first, first_start, ignorenotfound; \ 336105694Srwatson \ 337105694Srwatson error = 0; \ 338105694Srwatson element_temp = elementlist; \ 339105694Srwatson curptr = outbuf; \ 340105694Srwatson curptr[0] = '\0'; \ 341105694Srwatson left = outbuflen; \ 342105694Srwatson first = 1; \ 343105694Srwatson while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 344105694Srwatson curptr_start = curptr; \ 345105694Srwatson left_start = left; \ 346105694Srwatson first_start = first; \ 347105694Srwatson if (element_name[0] == '?') { \ 348105694Srwatson element_name++; \ 349105694Srwatson ignorenotfound = 1; \ 350105694Srwatson } else \ 351105694Srwatson ignorenotfound = 0; \ 352105694Srwatson claimed = 0; \ 353105694Srwatson if (first) { \ 354105694Srwatson len = snprintf(curptr, left, "%s/", \ 355105694Srwatson element_name); \ 356105694Srwatson first = 0; \ 357105694Srwatson } else \ 358105694Srwatson len = snprintf(curptr, left, ",%s/", \ 359105694Srwatson element_name); \ 360105694Srwatson if (len >= left) { \ 361105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 362105694Srwatson break; \ 363105694Srwatson } \ 364105694Srwatson curptr += len; \ 365105694Srwatson left -= len; \ 366105694Srwatson \ 367105694Srwatson MAC_CHECK(externalize_ ## type, label, element_name, \ 368105694Srwatson curptr, left, &len, &claimed); \ 369105694Srwatson if (error) \ 370105694Srwatson break; \ 371105694Srwatson if (claimed == 1) { \ 372105694Srwatson if (len >= outbuflen) { \ 373105694Srwatson error = EINVAL; /* XXXMAC: E2BIG */ \ 374105694Srwatson break; \ 375105694Srwatson } \ 376105694Srwatson curptr += len; \ 377105694Srwatson left -= len; \ 378105694Srwatson } else if (claimed == 0 && ignorenotfound) { \ 379105694Srwatson /* \ 380105694Srwatson * Revert addition of the label element \ 381105694Srwatson * name. \ 382105694Srwatson */ \ 383105694Srwatson curptr = curptr_start; \ 384105694Srwatson *curptr = '\0'; \ 385105694Srwatson left = left_start; \ 386105694Srwatson first = first_start; \ 387105694Srwatson } else { \ 388105694Srwatson error = EINVAL; /* XXXMAC: ENOLABEL */ \ 389105694Srwatson break; \ 390105694Srwatson } \ 391105694Srwatson } \ 392105694Srwatson} while (0) 393105694Srwatson 394105694Srwatson#define MAC_INTERNALIZE(type, label, instring) do { \ 395105694Srwatson char *element, *element_name, *element_data; \ 396105694Srwatson int claimed; \ 397105694Srwatson \ 398105694Srwatson error = 0; \ 399105694Srwatson element = instring; \ 400105694Srwatson while ((element_name = strsep(&element, ",")) != NULL) { \ 401105694Srwatson element_data = element_name; \ 402105694Srwatson element_name = strsep(&element_data, "/"); \ 403105694Srwatson if (element_data == NULL) { \ 404105694Srwatson error = EINVAL; \ 405105694Srwatson break; \ 406105694Srwatson } \ 407105694Srwatson claimed = 0; \ 408105694Srwatson MAC_CHECK(internalize_ ## type, label, element_name, \ 409105694Srwatson element_data, &claimed); \ 410105694Srwatson if (error) \ 411105694Srwatson break; \ 412105694Srwatson if (claimed != 1) { \ 413105694Srwatson /* XXXMAC: Another error here? */ \ 414105694Srwatson error = EINVAL; \ 415105694Srwatson break; \ 416105694Srwatson } \ 417105694Srwatson } \ 418105694Srwatson} while (0) 419105694Srwatson 420100979Srwatson/* 421100979Srwatson * MAC_PERFORM performs the designated operation by walking the policy 422100979Srwatson * module list and invoking that operation for each policy. 423100979Srwatson */ 424100979Srwatson#define MAC_PERFORM(operation, args...) do { \ 425100979Srwatson struct mac_policy_conf *mpc; \ 426100979Srwatson \ 427100979Srwatson MAC_POLICY_LIST_BUSY(); \ 428100979Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 429100979Srwatson if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 430100979Srwatson mpc->mpc_ops->mpo_ ## operation (args); \ 431100979Srwatson } \ 432100979Srwatson MAC_POLICY_LIST_UNBUSY(); \ 433100979Srwatson} while (0) 434100979Srwatson 435100979Srwatson/* 436100979Srwatson * Initialize the MAC subsystem, including appropriate SMP locks. 437100979Srwatson */ 438100979Srwatsonstatic void 439100979Srwatsonmac_init(void) 440100979Srwatson{ 441100979Srwatson 442100979Srwatson LIST_INIT(&mac_policy_list); 443100979Srwatson MAC_POLICY_LIST_LOCKINIT(); 444100979Srwatson} 445100979Srwatson 446100979Srwatson/* 447100979Srwatson * For the purposes of modules that want to know if they were loaded 448100979Srwatson * "early", set the mac_late flag once we've processed modules either 449100979Srwatson * linked into the kernel, or loaded before the kernel startup. 450100979Srwatson */ 451100979Srwatsonstatic void 452100979Srwatsonmac_late_init(void) 453100979Srwatson{ 454100979Srwatson 455100979Srwatson mac_late = 1; 456100979Srwatson} 457100979Srwatson 458100979Srwatson/* 459100979Srwatson * Allow MAC policy modules to register during boot, etc. 460100979Srwatson */ 461100894Srwatsonint 462100979Srwatsonmac_policy_modevent(module_t mod, int type, void *data) 463100979Srwatson{ 464100979Srwatson struct mac_policy_conf *mpc; 465100979Srwatson int error; 466100979Srwatson 467100979Srwatson error = 0; 468100979Srwatson mpc = (struct mac_policy_conf *) data; 469100979Srwatson 470100979Srwatson switch (type) { 471100979Srwatson case MOD_LOAD: 472100979Srwatson if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 473100979Srwatson mac_late) { 474100979Srwatson printf("mac_policy_modevent: can't load %s policy " 475100979Srwatson "after booting\n", mpc->mpc_name); 476100979Srwatson error = EBUSY; 477100979Srwatson break; 478100979Srwatson } 479100979Srwatson error = mac_policy_register(mpc); 480100979Srwatson break; 481100979Srwatson case MOD_UNLOAD: 482100979Srwatson /* Don't unregister the module if it was never registered. */ 483100979Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 484100979Srwatson != 0) 485100979Srwatson error = mac_policy_unregister(mpc); 486100979Srwatson else 487100979Srwatson error = 0; 488100979Srwatson break; 489100979Srwatson default: 490100979Srwatson break; 491100979Srwatson } 492100979Srwatson 493100979Srwatson return (error); 494100979Srwatson} 495100979Srwatson 496100979Srwatsonstatic int 497100979Srwatsonmac_policy_register(struct mac_policy_conf *mpc) 498100979Srwatson{ 499100979Srwatson struct mac_policy_conf *tmpc; 500100979Srwatson int slot; 501100979Srwatson 502106856Srwatson MAC_POLICY_LIST_EXCLUSIVE(); 503100979Srwatson LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 504100979Srwatson if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 505100979Srwatson MAC_POLICY_LIST_UNLOCK(); 506100979Srwatson return (EEXIST); 507100979Srwatson } 508100979Srwatson } 509100979Srwatson if (mpc->mpc_field_off != NULL) { 510100979Srwatson slot = ffs(mac_policy_offsets_free); 511100979Srwatson if (slot == 0) { 512100979Srwatson MAC_POLICY_LIST_UNLOCK(); 513100979Srwatson return (ENOMEM); 514100979Srwatson } 515100979Srwatson slot--; 516100979Srwatson mac_policy_offsets_free &= ~(1 << slot); 517100979Srwatson *mpc->mpc_field_off = slot; 518100979Srwatson } 519100979Srwatson mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 520100979Srwatson LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 521100979Srwatson 522100979Srwatson /* Per-policy initialization. */ 523100979Srwatson if (mpc->mpc_ops->mpo_init != NULL) 524100979Srwatson (*(mpc->mpc_ops->mpo_init))(mpc); 525100979Srwatson MAC_POLICY_LIST_UNLOCK(); 526100979Srwatson 527100979Srwatson printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 528100979Srwatson mpc->mpc_name); 529100979Srwatson 530100979Srwatson return (0); 531100979Srwatson} 532100979Srwatson 533100979Srwatsonstatic int 534100979Srwatsonmac_policy_unregister(struct mac_policy_conf *mpc) 535100979Srwatson{ 536100979Srwatson 537104520Srwatson /* 538104520Srwatson * If we fail the load, we may get a request to unload. Check 539104520Srwatson * to see if we did the run-time registration, and if not, 540104520Srwatson * silently succeed. 541104520Srwatson */ 542106856Srwatson MAC_POLICY_LIST_EXCLUSIVE(); 543104520Srwatson if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 544104520Srwatson MAC_POLICY_LIST_UNLOCK(); 545104520Srwatson return (0); 546104520Srwatson } 547100979Srwatson#if 0 548100979Srwatson /* 549100979Srwatson * Don't allow unloading modules with private data. 550100979Srwatson */ 551104520Srwatson if (mpc->mpc_field_off != NULL) { 552104520Srwatson MAC_POLICY_LIST_UNLOCK(); 553100979Srwatson return (EBUSY); 554104520Srwatson } 555100979Srwatson#endif 556104520Srwatson /* 557104520Srwatson * Only allow the unload to proceed if the module is unloadable 558104520Srwatson * by its own definition. 559104520Srwatson */ 560104520Srwatson if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 561104520Srwatson MAC_POLICY_LIST_UNLOCK(); 562100979Srwatson return (EBUSY); 563104520Srwatson } 564100979Srwatson if (mpc->mpc_ops->mpo_destroy != NULL) 565100979Srwatson (*(mpc->mpc_ops->mpo_destroy))(mpc); 566100979Srwatson 567100979Srwatson LIST_REMOVE(mpc, mpc_list); 568106856Srwatson mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 569106856Srwatson 570100979Srwatson MAC_POLICY_LIST_UNLOCK(); 571100979Srwatson 572100979Srwatson printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 573100979Srwatson mpc->mpc_name); 574100979Srwatson 575100979Srwatson return (0); 576100979Srwatson} 577100979Srwatson 578100979Srwatson/* 579100979Srwatson * Define an error value precedence, and given two arguments, selects the 580100979Srwatson * value with the higher precedence. 581100979Srwatson */ 582100979Srwatsonstatic int 583100979Srwatsonerror_select(int error1, int error2) 584100979Srwatson{ 585100979Srwatson 586100979Srwatson /* Certain decision-making errors take top priority. */ 587100979Srwatson if (error1 == EDEADLK || error2 == EDEADLK) 588100979Srwatson return (EDEADLK); 589100979Srwatson 590100979Srwatson /* Invalid arguments should be reported where possible. */ 591100979Srwatson if (error1 == EINVAL || error2 == EINVAL) 592100979Srwatson return (EINVAL); 593100979Srwatson 594100979Srwatson /* Precedence goes to "visibility", with both process and file. */ 595100979Srwatson if (error1 == ESRCH || error2 == ESRCH) 596100979Srwatson return (ESRCH); 597100979Srwatson 598100979Srwatson if (error1 == ENOENT || error2 == ENOENT) 599100979Srwatson return (ENOENT); 600100979Srwatson 601100979Srwatson /* Precedence goes to DAC/MAC protections. */ 602100979Srwatson if (error1 == EACCES || error2 == EACCES) 603100979Srwatson return (EACCES); 604100979Srwatson 605100979Srwatson /* Precedence goes to privilege. */ 606100979Srwatson if (error1 == EPERM || error2 == EPERM) 607100979Srwatson return (EPERM); 608100979Srwatson 609100979Srwatson /* Precedence goes to error over success; otherwise, arbitrary. */ 610100979Srwatson if (error1 != 0) 611100979Srwatson return (error1); 612100979Srwatson return (error2); 613100979Srwatson} 614100979Srwatson 615104521Srwatsonstatic void 616104521Srwatsonmac_init_label(struct label *label) 617104521Srwatson{ 618104521Srwatson 619104521Srwatson bzero(label, sizeof(*label)); 620104521Srwatson label->l_flags = MAC_FLAG_INITIALIZED; 621104521Srwatson} 622104521Srwatson 623104521Srwatsonstatic void 624104521Srwatsonmac_destroy_label(struct label *label) 625104521Srwatson{ 626104521Srwatson 627104521Srwatson KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 628104521Srwatson ("destroying uninitialized label")); 629104521Srwatson 630104521Srwatson bzero(label, sizeof(*label)); 631104521Srwatson /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 632104521Srwatson} 633104521Srwatson 634100979Srwatsonvoid 635104527Srwatsonmac_init_bpfdesc(struct bpf_d *bpf_d) 636104521Srwatson{ 637104521Srwatson 638104527Srwatson mac_init_label(&bpf_d->bd_label); 639104527Srwatson MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 640104521Srwatson#ifdef MAC_DEBUG 641104527Srwatson atomic_add_int(&nmacbpfdescs, 1); 642104521Srwatson#endif 643104521Srwatson} 644104521Srwatson 645105694Srwatsonstatic void 646105694Srwatsonmac_init_cred_label(struct label *label) 647104521Srwatson{ 648104521Srwatson 649105694Srwatson mac_init_label(label); 650105694Srwatson MAC_PERFORM(init_cred_label, label); 651104521Srwatson#ifdef MAC_DEBUG 652104521Srwatson atomic_add_int(&nmaccreds, 1); 653104521Srwatson#endif 654104521Srwatson} 655104521Srwatson 656104521Srwatsonvoid 657105694Srwatsonmac_init_cred(struct ucred *cred) 658105694Srwatson{ 659105694Srwatson 660105694Srwatson mac_init_cred_label(&cred->cr_label); 661105694Srwatson} 662105694Srwatson 663105694Srwatsonvoid 664104527Srwatsonmac_init_devfsdirent(struct devfs_dirent *de) 665104521Srwatson{ 666104521Srwatson 667104527Srwatson mac_init_label(&de->de_label); 668104527Srwatson MAC_PERFORM(init_devfsdirent_label, &de->de_label); 669104521Srwatson#ifdef MAC_DEBUG 670104527Srwatson atomic_add_int(&nmacdevfsdirents, 1); 671104521Srwatson#endif 672104521Srwatson} 673104521Srwatson 674105694Srwatsonstatic void 675105694Srwatsonmac_init_ifnet_label(struct label *label) 676104521Srwatson{ 677104521Srwatson 678105694Srwatson mac_init_label(label); 679105694Srwatson MAC_PERFORM(init_ifnet_label, label); 680104521Srwatson#ifdef MAC_DEBUG 681104521Srwatson atomic_add_int(&nmacifnets, 1); 682104521Srwatson#endif 683104521Srwatson} 684104521Srwatson 685104521Srwatsonvoid 686105694Srwatsonmac_init_ifnet(struct ifnet *ifp) 687105694Srwatson{ 688105694Srwatson 689105694Srwatson mac_init_ifnet_label(&ifp->if_label); 690105694Srwatson} 691105694Srwatson 692105694Srwatsonvoid 693104527Srwatsonmac_init_ipq(struct ipq *ipq) 694104521Srwatson{ 695104521Srwatson 696104527Srwatson mac_init_label(&ipq->ipq_label); 697104527Srwatson MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 698104521Srwatson#ifdef MAC_DEBUG 699104527Srwatson atomic_add_int(&nmacipqs, 1); 700104521Srwatson#endif 701104521Srwatson} 702104521Srwatson 703104527Srwatsonint 704104527Srwatsonmac_init_mbuf(struct mbuf *m, int flag) 705104527Srwatson{ 706104528Srwatson int error; 707104528Srwatson 708104527Srwatson KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 709104527Srwatson 710104527Srwatson mac_init_label(&m->m_pkthdr.label); 711104527Srwatson 712104528Srwatson MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 713104528Srwatson if (error) { 714104528Srwatson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 715104528Srwatson mac_destroy_label(&m->m_pkthdr.label); 716104528Srwatson } 717104528Srwatson 718104527Srwatson#ifdef MAC_DEBUG 719104528Srwatson if (error == 0) 720104528Srwatson atomic_add_int(&nmacmbufs, 1); 721104527Srwatson#endif 722104528Srwatson return (error); 723104527Srwatson} 724104527Srwatson 725104521Srwatsonvoid 726104527Srwatsonmac_init_mount(struct mount *mp) 727104521Srwatson{ 728104521Srwatson 729104527Srwatson mac_init_label(&mp->mnt_mntlabel); 730104527Srwatson mac_init_label(&mp->mnt_fslabel); 731104527Srwatson MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 732104527Srwatson MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 733104521Srwatson#ifdef MAC_DEBUG 734104527Srwatson atomic_add_int(&nmacmounts, 1); 735104521Srwatson#endif 736104521Srwatson} 737104521Srwatson 738105694Srwatsonstatic void 739105694Srwatsonmac_init_pipe_label(struct label *label) 740105694Srwatson{ 741105694Srwatson 742105694Srwatson mac_init_label(label); 743105694Srwatson MAC_PERFORM(init_pipe_label, label); 744105694Srwatson#ifdef MAC_DEBUG 745105694Srwatson atomic_add_int(&nmacpipes, 1); 746105694Srwatson#endif 747105694Srwatson} 748105694Srwatson 749104521Srwatsonvoid 750104527Srwatsonmac_init_pipe(struct pipe *pipe) 751104521Srwatson{ 752104527Srwatson struct label *label; 753104521Srwatson 754104527Srwatson label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 755104527Srwatson pipe->pipe_label = label; 756104527Srwatson pipe->pipe_peer->pipe_label = label; 757105694Srwatson mac_init_pipe_label(label); 758104521Srwatson} 759104521Srwatson 760104541Srwatsonstatic int 761104541Srwatsonmac_init_socket_label(struct label *label, int flag) 762104521Srwatson{ 763104541Srwatson int error; 764104521Srwatson 765104541Srwatson mac_init_label(label); 766104541Srwatson 767104541Srwatson MAC_CHECK(init_socket_label, label, flag); 768104541Srwatson if (error) { 769104541Srwatson MAC_PERFORM(destroy_socket_label, label); 770104541Srwatson mac_destroy_label(label); 771104541Srwatson } 772104541Srwatson 773104521Srwatson#ifdef MAC_DEBUG 774104541Srwatson if (error == 0) 775104541Srwatson atomic_add_int(&nmacsockets, 1); 776104521Srwatson#endif 777104541Srwatson 778104541Srwatson return (error); 779104521Srwatson} 780104521Srwatson 781104541Srwatsonstatic int 782104541Srwatsonmac_init_socket_peer_label(struct label *label, int flag) 783104541Srwatson{ 784104541Srwatson int error; 785104541Srwatson 786104541Srwatson mac_init_label(label); 787104541Srwatson 788104541Srwatson MAC_CHECK(init_socket_peer_label, label, flag); 789104541Srwatson if (error) { 790104541Srwatson MAC_PERFORM(destroy_socket_label, label); 791104541Srwatson mac_destroy_label(label); 792104541Srwatson } 793104541Srwatson 794104541Srwatson return (error); 795104541Srwatson} 796104541Srwatson 797104541Srwatsonint 798104541Srwatsonmac_init_socket(struct socket *socket, int flag) 799104541Srwatson{ 800104541Srwatson int error; 801104541Srwatson 802104541Srwatson error = mac_init_socket_label(&socket->so_label, flag); 803104541Srwatson if (error) 804104541Srwatson return (error); 805104541Srwatson 806104541Srwatson error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 807104541Srwatson if (error) 808104541Srwatson mac_destroy_socket_label(&socket->so_label); 809104541Srwatson 810104541Srwatson return (error); 811104541Srwatson} 812104541Srwatson 813105988Srwatsonvoid 814105694Srwatsonmac_init_vnode_label(struct label *label) 815104521Srwatson{ 816104521Srwatson 817104527Srwatson mac_init_label(label); 818105694Srwatson MAC_PERFORM(init_vnode_label, label); 819104521Srwatson#ifdef MAC_DEBUG 820105694Srwatson atomic_add_int(&nmacvnodes, 1); 821104521Srwatson#endif 822104521Srwatson} 823104521Srwatson 824104521Srwatsonvoid 825104527Srwatsonmac_init_vnode(struct vnode *vp) 826104521Srwatson{ 827104521Srwatson 828105694Srwatson mac_init_vnode_label(&vp->v_label); 829104521Srwatson} 830104521Srwatson 831104521Srwatsonvoid 832104527Srwatsonmac_destroy_bpfdesc(struct bpf_d *bpf_d) 833104521Srwatson{ 834104521Srwatson 835104527Srwatson MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 836104527Srwatson mac_destroy_label(&bpf_d->bd_label); 837104521Srwatson#ifdef MAC_DEBUG 838104527Srwatson atomic_subtract_int(&nmacbpfdescs, 1); 839104521Srwatson#endif 840104521Srwatson} 841104521Srwatson 842105694Srwatsonstatic void 843105694Srwatsonmac_destroy_cred_label(struct label *label) 844104521Srwatson{ 845104521Srwatson 846105694Srwatson MAC_PERFORM(destroy_cred_label, label); 847105694Srwatson mac_destroy_label(label); 848104521Srwatson#ifdef MAC_DEBUG 849104527Srwatson atomic_subtract_int(&nmaccreds, 1); 850104521Srwatson#endif 851104521Srwatson} 852104521Srwatson 853104521Srwatsonvoid 854105694Srwatsonmac_destroy_cred(struct ucred *cred) 855105694Srwatson{ 856105694Srwatson 857105694Srwatson mac_destroy_cred_label(&cred->cr_label); 858105694Srwatson} 859105694Srwatson 860105694Srwatsonvoid 861104527Srwatsonmac_destroy_devfsdirent(struct devfs_dirent *de) 862104521Srwatson{ 863104521Srwatson 864104527Srwatson MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 865104527Srwatson mac_destroy_label(&de->de_label); 866104521Srwatson#ifdef MAC_DEBUG 867104527Srwatson atomic_subtract_int(&nmacdevfsdirents, 1); 868104521Srwatson#endif 869104521Srwatson} 870104521Srwatson 871105694Srwatsonstatic void 872105694Srwatsonmac_destroy_ifnet_label(struct label *label) 873104521Srwatson{ 874104521Srwatson 875105694Srwatson MAC_PERFORM(destroy_ifnet_label, label); 876105694Srwatson mac_destroy_label(label); 877104521Srwatson#ifdef MAC_DEBUG 878104527Srwatson atomic_subtract_int(&nmacifnets, 1); 879104521Srwatson#endif 880104521Srwatson} 881104521Srwatson 882104521Srwatsonvoid 883105694Srwatsonmac_destroy_ifnet(struct ifnet *ifp) 884105694Srwatson{ 885105694Srwatson 886105694Srwatson mac_destroy_ifnet_label(&ifp->if_label); 887105694Srwatson} 888105694Srwatson 889105694Srwatsonvoid 890104527Srwatsonmac_destroy_ipq(struct ipq *ipq) 891104521Srwatson{ 892104521Srwatson 893104527Srwatson MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 894104527Srwatson mac_destroy_label(&ipq->ipq_label); 895104521Srwatson#ifdef MAC_DEBUG 896104527Srwatson atomic_subtract_int(&nmacipqs, 1); 897104521Srwatson#endif 898104521Srwatson} 899104521Srwatson 900104527Srwatsonvoid 901104527Srwatsonmac_destroy_mbuf(struct mbuf *m) 902104521Srwatson{ 903104521Srwatson 904104527Srwatson MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 905104527Srwatson mac_destroy_label(&m->m_pkthdr.label); 906104521Srwatson#ifdef MAC_DEBUG 907104527Srwatson atomic_subtract_int(&nmacmbufs, 1); 908104521Srwatson#endif 909104521Srwatson} 910104521Srwatson 911104527Srwatsonvoid 912104527Srwatsonmac_destroy_mount(struct mount *mp) 913104521Srwatson{ 914104521Srwatson 915104527Srwatson MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 916104527Srwatson MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 917104527Srwatson mac_destroy_label(&mp->mnt_fslabel); 918104527Srwatson mac_destroy_label(&mp->mnt_mntlabel); 919104521Srwatson#ifdef MAC_DEBUG 920104527Srwatson atomic_subtract_int(&nmacmounts, 1); 921104521Srwatson#endif 922104521Srwatson} 923104521Srwatson 924105694Srwatsonstatic void 925105694Srwatsonmac_destroy_pipe_label(struct label *label) 926104521Srwatson{ 927104521Srwatson 928105694Srwatson MAC_PERFORM(destroy_pipe_label, label); 929105694Srwatson mac_destroy_label(label); 930104521Srwatson#ifdef MAC_DEBUG 931104527Srwatson atomic_subtract_int(&nmacpipes, 1); 932104521Srwatson#endif 933104521Srwatson} 934104521Srwatson 935105694Srwatsonvoid 936105694Srwatsonmac_destroy_pipe(struct pipe *pipe) 937105694Srwatson{ 938105694Srwatson 939105694Srwatson mac_destroy_pipe_label(pipe->pipe_label); 940105694Srwatson free(pipe->pipe_label, M_MACPIPELABEL); 941105694Srwatson} 942105694Srwatson 943104541Srwatsonstatic void 944104541Srwatsonmac_destroy_socket_label(struct label *label) 945104521Srwatson{ 946104521Srwatson 947104541Srwatson MAC_PERFORM(destroy_socket_label, label); 948104541Srwatson mac_destroy_label(label); 949104521Srwatson#ifdef MAC_DEBUG 950104527Srwatson atomic_subtract_int(&nmacsockets, 1); 951104521Srwatson#endif 952104521Srwatson} 953104521Srwatson 954104527Srwatsonstatic void 955104541Srwatsonmac_destroy_socket_peer_label(struct label *label) 956104541Srwatson{ 957104541Srwatson 958104541Srwatson MAC_PERFORM(destroy_socket_peer_label, label); 959104541Srwatson mac_destroy_label(label); 960104541Srwatson} 961104541Srwatson 962104541Srwatsonvoid 963104541Srwatsonmac_destroy_socket(struct socket *socket) 964104541Srwatson{ 965104541Srwatson 966104541Srwatson mac_destroy_socket_label(&socket->so_label); 967104541Srwatson mac_destroy_socket_peer_label(&socket->so_peerlabel); 968104541Srwatson} 969104541Srwatson 970105988Srwatsonvoid 971105694Srwatsonmac_destroy_vnode_label(struct label *label) 972104521Srwatson{ 973104521Srwatson 974105694Srwatson MAC_PERFORM(destroy_vnode_label, label); 975104527Srwatson mac_destroy_label(label); 976104521Srwatson#ifdef MAC_DEBUG 977105694Srwatson atomic_subtract_int(&nmacvnodes, 1); 978104521Srwatson#endif 979104521Srwatson} 980104521Srwatson 981104521Srwatsonvoid 982104527Srwatsonmac_destroy_vnode(struct vnode *vp) 983104521Srwatson{ 984104521Srwatson 985105694Srwatson mac_destroy_vnode_label(&vp->v_label); 986104521Srwatson} 987104521Srwatson 988105694Srwatsonstatic void 989105694Srwatsonmac_copy_pipe_label(struct label *src, struct label *dest) 990105694Srwatson{ 991105694Srwatson 992105694Srwatson MAC_PERFORM(copy_pipe_label, src, dest); 993105694Srwatson} 994105694Srwatson 995105988Srwatsonvoid 996105694Srwatsonmac_copy_vnode_label(struct label *src, struct label *dest) 997105694Srwatson{ 998105694Srwatson 999105694Srwatson MAC_PERFORM(copy_vnode_label, src, dest); 1000105694Srwatson} 1001105694Srwatson 1002104522Srwatsonstatic int 1003105694Srwatsonmac_check_structmac_consistent(struct mac *mac) 1004104522Srwatson{ 1005105694Srwatson 1006105694Srwatson if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1007105694Srwatson return (EINVAL); 1008105694Srwatson 1009105694Srwatson return (0); 1010105694Srwatson} 1011105694Srwatson 1012105694Srwatsonstatic int 1013105694Srwatsonmac_externalize_cred_label(struct label *label, char *elements, 1014105694Srwatson char *outbuf, size_t outbuflen, int flags) 1015105694Srwatson{ 1016104522Srwatson int error; 1017104522Srwatson 1018105694Srwatson MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1019104522Srwatson 1020104522Srwatson return (error); 1021104522Srwatson} 1022104522Srwatson 1023104522Srwatsonstatic int 1024105694Srwatsonmac_externalize_ifnet_label(struct label *label, char *elements, 1025105694Srwatson char *outbuf, size_t outbuflen, int flags) 1026104522Srwatson{ 1027104522Srwatson int error; 1028104522Srwatson 1029105694Srwatson MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1030104522Srwatson 1031104522Srwatson return (error); 1032104522Srwatson} 1033104522Srwatson 1034105694Srwatsonstatic int 1035105694Srwatsonmac_externalize_pipe_label(struct label *label, char *elements, 1036105694Srwatson char *outbuf, size_t outbuflen, int flags) 1037105694Srwatson{ 1038105694Srwatson int error; 1039105694Srwatson 1040105694Srwatson MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1041105694Srwatson 1042105694Srwatson return (error); 1043105694Srwatson} 1044105694Srwatson 1045105694Srwatsonstatic int 1046105694Srwatsonmac_externalize_socket_label(struct label *label, char *elements, 1047105694Srwatson char *outbuf, size_t outbuflen, int flags) 1048105694Srwatson{ 1049105694Srwatson int error; 1050105694Srwatson 1051105694Srwatson MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1052105694Srwatson 1053105694Srwatson return (error); 1054105694Srwatson} 1055105694Srwatson 1056105694Srwatsonstatic int 1057105694Srwatsonmac_externalize_socket_peer_label(struct label *label, char *elements, 1058105694Srwatson char *outbuf, size_t outbuflen, int flags) 1059105694Srwatson{ 1060105694Srwatson int error; 1061105694Srwatson 1062105694Srwatson MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1063105694Srwatson 1064105694Srwatson return (error); 1065105694Srwatson} 1066105694Srwatson 1067105694Srwatsonstatic int 1068105694Srwatsonmac_externalize_vnode_label(struct label *label, char *elements, 1069105694Srwatson char *outbuf, size_t outbuflen, int flags) 1070105694Srwatson{ 1071105694Srwatson int error; 1072105694Srwatson 1073105694Srwatson MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1074105694Srwatson 1075105694Srwatson return (error); 1076105694Srwatson} 1077105694Srwatson 1078105694Srwatsonstatic int 1079105694Srwatsonmac_internalize_cred_label(struct label *label, char *string) 1080105694Srwatson{ 1081105694Srwatson int error; 1082105694Srwatson 1083105694Srwatson MAC_INTERNALIZE(cred_label, label, string); 1084105694Srwatson 1085105694Srwatson return (error); 1086105694Srwatson} 1087105694Srwatson 1088105694Srwatsonstatic int 1089105694Srwatsonmac_internalize_ifnet_label(struct label *label, char *string) 1090105694Srwatson{ 1091105694Srwatson int error; 1092105694Srwatson 1093105694Srwatson MAC_INTERNALIZE(ifnet_label, label, string); 1094105694Srwatson 1095105694Srwatson return (error); 1096105694Srwatson} 1097105694Srwatson 1098105694Srwatsonstatic int 1099105694Srwatsonmac_internalize_pipe_label(struct label *label, char *string) 1100105694Srwatson{ 1101105694Srwatson int error; 1102105694Srwatson 1103105694Srwatson MAC_INTERNALIZE(pipe_label, label, string); 1104105694Srwatson 1105105694Srwatson return (error); 1106105694Srwatson} 1107105694Srwatson 1108105694Srwatsonstatic int 1109105694Srwatsonmac_internalize_socket_label(struct label *label, char *string) 1110105694Srwatson{ 1111105694Srwatson int error; 1112105694Srwatson 1113105694Srwatson MAC_INTERNALIZE(socket_label, label, string); 1114105694Srwatson 1115105694Srwatson return (error); 1116105694Srwatson} 1117105694Srwatson 1118105694Srwatsonstatic int 1119105694Srwatsonmac_internalize_vnode_label(struct label *label, char *string) 1120105694Srwatson{ 1121105694Srwatson int error; 1122105694Srwatson 1123105694Srwatson MAC_INTERNALIZE(vnode_label, label, string); 1124105694Srwatson 1125105694Srwatson return (error); 1126105694Srwatson} 1127105694Srwatson 1128104522Srwatson/* 1129104522Srwatson * Initialize MAC label for the first kernel process, from which other 1130104522Srwatson * kernel processes and threads are spawned. 1131104522Srwatson */ 1132104521Srwatsonvoid 1133104522Srwatsonmac_create_proc0(struct ucred *cred) 1134104522Srwatson{ 1135104522Srwatson 1136104522Srwatson MAC_PERFORM(create_proc0, cred); 1137104522Srwatson} 1138104522Srwatson 1139104522Srwatson/* 1140104522Srwatson * Initialize MAC label for the first userland process, from which other 1141104522Srwatson * userland processes and threads are spawned. 1142104522Srwatson */ 1143104522Srwatsonvoid 1144104522Srwatsonmac_create_proc1(struct ucred *cred) 1145104522Srwatson{ 1146104522Srwatson 1147104522Srwatson MAC_PERFORM(create_proc1, cred); 1148104522Srwatson} 1149104522Srwatson 1150104522Srwatsonvoid 1151104522Srwatsonmac_thread_userret(struct thread *td) 1152104522Srwatson{ 1153104522Srwatson 1154104522Srwatson MAC_PERFORM(thread_userret, td); 1155104522Srwatson} 1156104522Srwatson 1157104522Srwatson/* 1158104522Srwatson * When a new process is created, its label must be initialized. Generally, 1159104522Srwatson * this involves inheritence from the parent process, modulo possible 1160104522Srwatson * deltas. This function allows that processing to take place. 1161104522Srwatson */ 1162104522Srwatsonvoid 1163104522Srwatsonmac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1164104522Srwatson{ 1165104522Srwatson 1166104522Srwatson MAC_PERFORM(create_cred, parent_cred, child_cred); 1167104522Srwatson} 1168104522Srwatson 1169104522Srwatsonvoid 1170100979Srwatsonmac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 1171100979Srwatson{ 1172100979Srwatson 1173100979Srwatson MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 1174100979Srwatson} 1175100979Srwatson 1176100979Srwatsonvoid 1177105988Srwatsonmac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1178105988Srwatson struct vnode *vp) 1179100979Srwatson{ 1180100979Srwatson 1181105988Srwatson MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1182105988Srwatson &de->de_label, vp, &vp->v_label); 1183100979Srwatson} 1184100979Srwatson 1185105988Srwatsonint 1186105988Srwatsonmac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1187100979Srwatson{ 1188100979Srwatson int error; 1189100979Srwatson 1190105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1191100979Srwatson 1192105988Srwatson MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1193105988Srwatson &vp->v_label); 1194100979Srwatson 1195100979Srwatson return (error); 1196100979Srwatson} 1197100979Srwatson 1198100979Srwatsonvoid 1199105988Srwatsonmac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1200100979Srwatson{ 1201100979Srwatson 1202105988Srwatson MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1203105988Srwatson &vp->v_label); 1204100979Srwatson} 1205100979Srwatson 1206100979Srwatsonint 1207105988Srwatsonmac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1208105988Srwatson struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1209100979Srwatson{ 1210105988Srwatson int error; 1211100979Srwatson 1212105988Srwatson ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1213105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1214100979Srwatson 1215105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1216105988Srwatson if (error == EOPNOTSUPP) { 1217105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1218105988Srwatson if (ea_warn_once == 0) { 1219105988Srwatson printf("Warning: transactions not supported " 1220105988Srwatson "in EA write.\n"); 1221105988Srwatson ea_warn_once = 1; 1222105988Srwatson } 1223105988Srwatson } else if (error) 1224100979Srwatson return (error); 1225100979Srwatson 1226105988Srwatson MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1227105988Srwatson dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1228100979Srwatson 1229105988Srwatson if (error) { 1230105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1231100979Srwatson return (error); 1232100979Srwatson } 1233100979Srwatson 1234105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1235100979Srwatson 1236105988Srwatson if (error == EOPNOTSUPP) 1237105988Srwatson error = 0; /* XXX */ 1238100979Srwatson 1239100979Srwatson return (error); 1240100979Srwatson} 1241100979Srwatson 1242100979Srwatsonstatic int 1243105988Srwatsonmac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1244105988Srwatson struct label *intlabel) 1245100979Srwatson{ 1246100979Srwatson int error; 1247100979Srwatson 1248105988Srwatson ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1249100979Srwatson 1250105988Srwatson error = VOP_OPENEXTATTR(vp, cred, curthread); 1251105988Srwatson if (error == EOPNOTSUPP) { 1252105988Srwatson /* XXX: Optionally abort if transactions not supported. */ 1253105988Srwatson if (ea_warn_once == 0) { 1254105988Srwatson printf("Warning: transactions not supported " 1255105988Srwatson "in EA write.\n"); 1256105988Srwatson ea_warn_once = 1; 1257105988Srwatson } 1258105988Srwatson } else if (error) 1259105988Srwatson return (error); 1260100979Srwatson 1261105988Srwatson MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1262100979Srwatson 1263105988Srwatson if (error) { 1264105988Srwatson VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1265100979Srwatson return (error); 1266100979Srwatson } 1267100979Srwatson 1268105988Srwatson error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1269100979Srwatson 1270105988Srwatson if (error == EOPNOTSUPP) 1271105988Srwatson error = 0; /* XXX */ 1272100979Srwatson 1273105988Srwatson return (error); 1274100979Srwatson} 1275100979Srwatson 1276106468Srwatsonint 1277106468Srwatsonmac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1278106468Srwatson struct label *execlabelstorage) 1279106468Srwatson{ 1280106468Srwatson struct mac mac; 1281106468Srwatson char *buffer; 1282106468Srwatson int error; 1283106468Srwatson 1284106468Srwatson if (mac_p == NULL) 1285106468Srwatson return (0); 1286106468Srwatson 1287106468Srwatson error = copyin(mac_p, &mac, sizeof(mac)); 1288106468Srwatson if (error) 1289106468Srwatson return (error); 1290106468Srwatson 1291106468Srwatson error = mac_check_structmac_consistent(&mac); 1292106468Srwatson if (error) 1293106468Srwatson return (error); 1294106468Srwatson 1295106468Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1296106468Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1297106468Srwatson if (error) { 1298106468Srwatson free(buffer, M_MACTEMP); 1299106468Srwatson return (error); 1300106468Srwatson } 1301106468Srwatson 1302106468Srwatson mac_init_cred_label(execlabelstorage); 1303106468Srwatson error = mac_internalize_cred_label(execlabelstorage, buffer); 1304106468Srwatson free(buffer, M_MACTEMP); 1305106468Srwatson if (error) { 1306106468Srwatson mac_destroy_cred_label(execlabelstorage); 1307106468Srwatson return (error); 1308106468Srwatson } 1309106468Srwatson imgp->execlabel = execlabelstorage; 1310106468Srwatson return (0); 1311106468Srwatson} 1312106468Srwatson 1313100979Srwatsonvoid 1314106468Srwatsonmac_execve_exit(struct image_params *imgp) 1315100979Srwatson{ 1316106468Srwatson if (imgp->execlabel != NULL) 1317106468Srwatson mac_destroy_cred_label(imgp->execlabel); 1318106468Srwatson} 1319100979Srwatson 1320106468Srwatsonvoid 1321106468Srwatsonmac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1322106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1323106468Srwatson{ 1324106468Srwatson 1325100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1326100979Srwatson 1327106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1328106460Srwatson return; 1329106460Srwatson 1330106468Srwatson MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1331106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1332100979Srwatson} 1333100979Srwatson 1334100979Srwatsonint 1335106468Srwatsonmac_execve_will_transition(struct ucred *old, struct vnode *vp, 1336106468Srwatson struct label *interpvnodelabel, struct image_params *imgp) 1337100979Srwatson{ 1338105988Srwatson int result; 1339100979Srwatson 1340106460Srwatson ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1341106460Srwatson 1342106460Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1343106460Srwatson return (0); 1344106460Srwatson 1345100979Srwatson result = 0; 1346106468Srwatson MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1347106647Srwatson interpvnodelabel, imgp, imgp->execlabel); 1348100979Srwatson 1349100979Srwatson return (result); 1350100979Srwatson} 1351100979Srwatson 1352100979Srwatsonint 1353106212Srwatsonmac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1354100979Srwatson{ 1355100979Srwatson int error; 1356100979Srwatson 1357100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1358100979Srwatson 1359100979Srwatson if (!mac_enforce_fs) 1360100979Srwatson return (0); 1361100979Srwatson 1362106212Srwatson MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1363100979Srwatson return (error); 1364100979Srwatson} 1365100979Srwatson 1366100979Srwatsonint 1367100979Srwatsonmac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1368100979Srwatson{ 1369100979Srwatson int error; 1370100979Srwatson 1371100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1372100979Srwatson 1373100979Srwatson if (!mac_enforce_fs) 1374100979Srwatson return (0); 1375100979Srwatson 1376100979Srwatson MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1377100979Srwatson return (error); 1378100979Srwatson} 1379100979Srwatson 1380100979Srwatsonint 1381100979Srwatsonmac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1382100979Srwatson{ 1383100979Srwatson int error; 1384100979Srwatson 1385100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1386100979Srwatson 1387100979Srwatson if (!mac_enforce_fs) 1388100979Srwatson return (0); 1389100979Srwatson 1390100979Srwatson MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1391100979Srwatson return (error); 1392100979Srwatson} 1393100979Srwatson 1394100979Srwatsonint 1395100979Srwatsonmac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1396100979Srwatson struct componentname *cnp, struct vattr *vap) 1397100979Srwatson{ 1398100979Srwatson int error; 1399100979Srwatson 1400100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1401100979Srwatson 1402100979Srwatson if (!mac_enforce_fs) 1403100979Srwatson return (0); 1404100979Srwatson 1405100979Srwatson MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1406100979Srwatson return (error); 1407100979Srwatson} 1408100979Srwatson 1409100979Srwatsonint 1410100979Srwatsonmac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1411100979Srwatson struct componentname *cnp) 1412100979Srwatson{ 1413100979Srwatson int error; 1414100979Srwatson 1415100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1416100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1417100979Srwatson 1418100979Srwatson if (!mac_enforce_fs) 1419100979Srwatson return (0); 1420100979Srwatson 1421100979Srwatson MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1422100979Srwatson &vp->v_label, cnp); 1423100979Srwatson return (error); 1424100979Srwatson} 1425100979Srwatson 1426100979Srwatsonint 1427100979Srwatsonmac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1428100979Srwatson acl_type_t type) 1429100979Srwatson{ 1430100979Srwatson int error; 1431100979Srwatson 1432100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1433100979Srwatson 1434100979Srwatson if (!mac_enforce_fs) 1435100979Srwatson return (0); 1436100979Srwatson 1437100979Srwatson MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1438100979Srwatson return (error); 1439100979Srwatson} 1440100979Srwatson 1441100979Srwatsonint 1442106468Srwatsonmac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1443106468Srwatson struct image_params *imgp) 1444100979Srwatson{ 1445100979Srwatson int error; 1446100979Srwatson 1447102102Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1448102102Srwatson 1449100979Srwatson if (!mac_enforce_process && !mac_enforce_fs) 1450100979Srwatson return (0); 1451100979Srwatson 1452106647Srwatson MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1453106647Srwatson imgp->execlabel); 1454100979Srwatson 1455100979Srwatson return (error); 1456100979Srwatson} 1457100979Srwatson 1458100979Srwatsonint 1459100979Srwatsonmac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1460100979Srwatson{ 1461100979Srwatson int error; 1462100979Srwatson 1463100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1464100979Srwatson 1465100979Srwatson if (!mac_enforce_fs) 1466100979Srwatson return (0); 1467100979Srwatson 1468100979Srwatson MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1469100979Srwatson return (error); 1470100979Srwatson} 1471100979Srwatson 1472100979Srwatsonint 1473100979Srwatsonmac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1474100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1475100979Srwatson{ 1476100979Srwatson int error; 1477100979Srwatson 1478100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1479100979Srwatson 1480100979Srwatson if (!mac_enforce_fs) 1481100979Srwatson return (0); 1482100979Srwatson 1483100979Srwatson MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1484100979Srwatson attrnamespace, name, uio); 1485100979Srwatson return (error); 1486100979Srwatson} 1487100979Srwatson 1488100979Srwatsonint 1489104529Srwatsonmac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1490104529Srwatson struct vnode *vp, struct componentname *cnp) 1491104529Srwatson{ 1492104529Srwatson int error; 1493104529Srwatson 1494104529Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1495104529Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1496104529Srwatson 1497104529Srwatson if (!mac_enforce_fs) 1498104529Srwatson return (0); 1499104529Srwatson 1500104529Srwatson MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1501104529Srwatson &vp->v_label, cnp); 1502104529Srwatson return (error); 1503104529Srwatson} 1504104529Srwatson 1505104529Srwatsonint 1506100979Srwatsonmac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1507100979Srwatson struct componentname *cnp) 1508100979Srwatson{ 1509100979Srwatson int error; 1510100979Srwatson 1511100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1512100979Srwatson 1513100979Srwatson if (!mac_enforce_fs) 1514100979Srwatson return (0); 1515100979Srwatson 1516100979Srwatson MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1517100979Srwatson return (error); 1518100979Srwatson} 1519100979Srwatson 1520104546Srwatsonint 1521104546Srwatsonmac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1522100979Srwatson{ 1523104546Srwatson int error; 1524100979Srwatson 1525104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1526103514Srwatson 1527104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1528104546Srwatson return (0); 1529104546Srwatson 1530104546Srwatson MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1531104546Srwatson return (error); 1532100979Srwatson} 1533100979Srwatson 1534104546Srwatsonvoid 1535104546Srwatsonmac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1536104546Srwatson{ 1537104546Srwatson int result = *prot; 1538104546Srwatson 1539104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1540104546Srwatson 1541104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1542104546Srwatson return; 1543104546Srwatson 1544104546Srwatson MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1545104546Srwatson &result); 1546104546Srwatson 1547104546Srwatson *prot = result; 1548104546Srwatson} 1549104546Srwatson 1550100979Srwatsonint 1551104546Srwatsonmac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1552104546Srwatson{ 1553104546Srwatson int error; 1554104546Srwatson 1555104546Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1556104546Srwatson 1557104546Srwatson if (!mac_enforce_fs || !mac_enforce_vm) 1558104546Srwatson return (0); 1559104546Srwatson 1560104546Srwatson MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1561104546Srwatson return (error); 1562104546Srwatson} 1563104546Srwatson 1564104546Srwatsonint 1565106212Srwatsonmac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1566100979Srwatson{ 1567100979Srwatson int error; 1568100979Srwatson 1569102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1570102112Srwatson 1571100979Srwatson if (!mac_enforce_fs) 1572100979Srwatson return (0); 1573100979Srwatson 1574102112Srwatson MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1575102112Srwatson return (error); 1576102112Srwatson} 1577102112Srwatson 1578102112Srwatsonint 1579102129Srwatsonmac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1580102129Srwatson struct vnode *vp) 1581102112Srwatson{ 1582102112Srwatson int error; 1583102112Srwatson 1584102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1585102112Srwatson 1586102112Srwatson if (!mac_enforce_fs) 1587102112Srwatson return (0); 1588102112Srwatson 1589102129Srwatson MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1590102129Srwatson &vp->v_label); 1591100979Srwatson 1592100979Srwatson return (error); 1593100979Srwatson} 1594100979Srwatson 1595100979Srwatsonint 1596102129Srwatsonmac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1597102129Srwatson struct vnode *vp) 1598100979Srwatson{ 1599100979Srwatson int error; 1600100979Srwatson 1601102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1602100979Srwatson 1603100979Srwatson if (!mac_enforce_fs) 1604100979Srwatson return (0); 1605100979Srwatson 1606102129Srwatson MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1607102129Srwatson &vp->v_label); 1608102112Srwatson 1609100979Srwatson return (error); 1610100979Srwatson} 1611100979Srwatson 1612100979Srwatsonint 1613100979Srwatsonmac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1614100979Srwatson{ 1615100979Srwatson int error; 1616100979Srwatson 1617100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1618100979Srwatson 1619100979Srwatson if (!mac_enforce_fs) 1620100979Srwatson return (0); 1621100979Srwatson 1622100979Srwatson MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1623100979Srwatson return (error); 1624100979Srwatson} 1625100979Srwatson 1626100979Srwatsonint 1627100979Srwatsonmac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1628100979Srwatson{ 1629100979Srwatson int error; 1630100979Srwatson 1631100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1632100979Srwatson 1633100979Srwatson if (!mac_enforce_fs) 1634100979Srwatson return (0); 1635100979Srwatson 1636100979Srwatson MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1637100979Srwatson return (error); 1638100979Srwatson} 1639100979Srwatson 1640100979Srwatsonstatic int 1641100979Srwatsonmac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1642100979Srwatson struct label *newlabel) 1643100979Srwatson{ 1644100979Srwatson int error; 1645100979Srwatson 1646100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1647100979Srwatson 1648100979Srwatson MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1649100979Srwatson 1650100979Srwatson return (error); 1651100979Srwatson} 1652100979Srwatson 1653100979Srwatsonint 1654100979Srwatsonmac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1655100979Srwatson struct vnode *vp, struct componentname *cnp) 1656100979Srwatson{ 1657100979Srwatson int error; 1658100979Srwatson 1659100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1660100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1661100979Srwatson 1662100979Srwatson if (!mac_enforce_fs) 1663100979Srwatson return (0); 1664100979Srwatson 1665100979Srwatson MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1666100979Srwatson &vp->v_label, cnp); 1667100979Srwatson return (error); 1668100979Srwatson} 1669100979Srwatson 1670100979Srwatsonint 1671100979Srwatsonmac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1672100979Srwatson struct vnode *vp, int samedir, struct componentname *cnp) 1673100979Srwatson{ 1674100979Srwatson int error; 1675100979Srwatson 1676100979Srwatson ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1677100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1678100979Srwatson 1679100979Srwatson if (!mac_enforce_fs) 1680100979Srwatson return (0); 1681100979Srwatson 1682100979Srwatson MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1683100979Srwatson vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1684100979Srwatson return (error); 1685100979Srwatson} 1686100979Srwatson 1687100979Srwatsonint 1688100979Srwatsonmac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1689100979Srwatson{ 1690100979Srwatson int error; 1691100979Srwatson 1692100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1693100979Srwatson 1694100979Srwatson if (!mac_enforce_fs) 1695100979Srwatson return (0); 1696100979Srwatson 1697100979Srwatson MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1698100979Srwatson return (error); 1699100979Srwatson} 1700100979Srwatson 1701100979Srwatsonint 1702100979Srwatsonmac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1703100979Srwatson struct acl *acl) 1704100979Srwatson{ 1705100979Srwatson int error; 1706100979Srwatson 1707100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1708100979Srwatson 1709100979Srwatson if (!mac_enforce_fs) 1710100979Srwatson return (0); 1711100979Srwatson 1712100979Srwatson MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1713100979Srwatson return (error); 1714100979Srwatson} 1715100979Srwatson 1716100979Srwatsonint 1717100979Srwatsonmac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1718100979Srwatson int attrnamespace, const char *name, struct uio *uio) 1719100979Srwatson{ 1720100979Srwatson int error; 1721100979Srwatson 1722100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1723100979Srwatson 1724100979Srwatson if (!mac_enforce_fs) 1725100979Srwatson return (0); 1726100979Srwatson 1727100979Srwatson MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1728100979Srwatson attrnamespace, name, uio); 1729100979Srwatson return (error); 1730100979Srwatson} 1731100979Srwatson 1732100979Srwatsonint 1733100979Srwatsonmac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1734100979Srwatson{ 1735100979Srwatson int error; 1736100979Srwatson 1737100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1738100979Srwatson 1739100979Srwatson if (!mac_enforce_fs) 1740100979Srwatson return (0); 1741100979Srwatson 1742100979Srwatson MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1743100979Srwatson return (error); 1744100979Srwatson} 1745100979Srwatson 1746100979Srwatsonint 1747100979Srwatsonmac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1748100979Srwatson{ 1749100979Srwatson int error; 1750100979Srwatson 1751100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1752100979Srwatson 1753100979Srwatson if (!mac_enforce_fs) 1754100979Srwatson return (0); 1755100979Srwatson 1756100979Srwatson MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1757100979Srwatson return (error); 1758100979Srwatson} 1759100979Srwatson 1760100979Srwatsonint 1761100979Srwatsonmac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1762100979Srwatson gid_t gid) 1763100979Srwatson{ 1764100979Srwatson int error; 1765100979Srwatson 1766100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1767100979Srwatson 1768100979Srwatson if (!mac_enforce_fs) 1769100979Srwatson return (0); 1770100979Srwatson 1771100979Srwatson MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1772100979Srwatson return (error); 1773100979Srwatson} 1774100979Srwatson 1775100979Srwatsonint 1776100979Srwatsonmac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1777100979Srwatson struct timespec atime, struct timespec mtime) 1778100979Srwatson{ 1779100979Srwatson int error; 1780100979Srwatson 1781100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1782100979Srwatson 1783100979Srwatson if (!mac_enforce_fs) 1784100979Srwatson return (0); 1785100979Srwatson 1786100979Srwatson MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1787100979Srwatson mtime); 1788100979Srwatson return (error); 1789100979Srwatson} 1790100979Srwatson 1791100979Srwatsonint 1792102129Srwatsonmac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1793102129Srwatson struct vnode *vp) 1794100979Srwatson{ 1795100979Srwatson int error; 1796100979Srwatson 1797100979Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 1798100979Srwatson 1799100979Srwatson if (!mac_enforce_fs) 1800100979Srwatson return (0); 1801100979Srwatson 1802102129Srwatson MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 1803102129Srwatson &vp->v_label); 1804100979Srwatson return (error); 1805100979Srwatson} 1806100979Srwatson 1807102112Srwatsonint 1808102129Srwatsonmac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1809102129Srwatson struct vnode *vp) 1810102112Srwatson{ 1811102112Srwatson int error; 1812102112Srwatson 1813102112Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 1814102112Srwatson 1815102112Srwatson if (!mac_enforce_fs) 1816102112Srwatson return (0); 1817102112Srwatson 1818102129Srwatson MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 1819102129Srwatson &vp->v_label); 1820102112Srwatson 1821102112Srwatson return (error); 1822102112Srwatson} 1823102112Srwatson 1824100979Srwatson/* 1825100979Srwatson * When relabeling a process, call out to the policies for the maximum 1826100979Srwatson * permission allowed for each object type we know about in its 1827100979Srwatson * memory space, and revoke access (in the least surprising ways we 1828100979Srwatson * know) when necessary. The process lock is not held here. 1829100979Srwatson */ 1830100979Srwatsonstatic void 1831100979Srwatsonmac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 1832100979Srwatson{ 1833100979Srwatson 1834100979Srwatson /* XXX freeze all other threads */ 1835100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 1836100979Srwatson &td->td_proc->p_vmspace->vm_map); 1837100979Srwatson /* XXX allow other threads to continue */ 1838100979Srwatson} 1839100979Srwatson 1840100979Srwatsonstatic __inline const char * 1841100979Srwatsonprot2str(vm_prot_t prot) 1842100979Srwatson{ 1843100979Srwatson 1844100979Srwatson switch (prot & VM_PROT_ALL) { 1845100979Srwatson case VM_PROT_READ: 1846100979Srwatson return ("r--"); 1847100979Srwatson case VM_PROT_READ | VM_PROT_WRITE: 1848100979Srwatson return ("rw-"); 1849100979Srwatson case VM_PROT_READ | VM_PROT_EXECUTE: 1850100979Srwatson return ("r-x"); 1851100979Srwatson case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 1852100979Srwatson return ("rwx"); 1853100979Srwatson case VM_PROT_WRITE: 1854100979Srwatson return ("-w-"); 1855100979Srwatson case VM_PROT_EXECUTE: 1856100979Srwatson return ("--x"); 1857100979Srwatson case VM_PROT_WRITE | VM_PROT_EXECUTE: 1858100979Srwatson return ("-wx"); 1859100979Srwatson default: 1860100979Srwatson return ("---"); 1861100979Srwatson } 1862100979Srwatson} 1863100979Srwatson 1864100979Srwatsonstatic void 1865100979Srwatsonmac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 1866100979Srwatson struct vm_map *map) 1867100979Srwatson{ 1868100979Srwatson struct vm_map_entry *vme; 1869104546Srwatson int result; 1870104546Srwatson vm_prot_t revokeperms; 1871100979Srwatson vm_object_t object; 1872100979Srwatson vm_ooffset_t offset; 1873100979Srwatson struct vnode *vp; 1874100979Srwatson 1875103136Srwatson if (!mac_mmap_revocation) 1876103136Srwatson return; 1877103136Srwatson 1878100979Srwatson vm_map_lock_read(map); 1879100979Srwatson for (vme = map->header.next; vme != &map->header; vme = vme->next) { 1880100979Srwatson if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 1881100979Srwatson mac_cred_mmapped_drop_perms_recurse(td, cred, 1882100979Srwatson vme->object.sub_map); 1883100979Srwatson continue; 1884100979Srwatson } 1885100979Srwatson /* 1886100979Srwatson * Skip over entries that obviously are not shared. 1887100979Srwatson */ 1888100979Srwatson if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 1889100979Srwatson !vme->max_protection) 1890100979Srwatson continue; 1891100979Srwatson /* 1892100979Srwatson * Drill down to the deepest backing object. 1893100979Srwatson */ 1894100979Srwatson offset = vme->offset; 1895100979Srwatson object = vme->object.vm_object; 1896100979Srwatson if (object == NULL) 1897100979Srwatson continue; 1898100979Srwatson while (object->backing_object != NULL) { 1899100979Srwatson object = object->backing_object; 1900100979Srwatson offset += object->backing_object_offset; 1901100979Srwatson } 1902100979Srwatson /* 1903100979Srwatson * At the moment, vm_maps and objects aren't considered 1904100979Srwatson * by the MAC system, so only things with backing by a 1905100979Srwatson * normal object (read: vnodes) are checked. 1906100979Srwatson */ 1907100979Srwatson if (object->type != OBJT_VNODE) 1908100979Srwatson continue; 1909100979Srwatson vp = (struct vnode *)object->handle; 1910100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1911104546Srwatson result = vme->max_protection; 1912104546Srwatson mac_check_vnode_mmap_downgrade(cred, vp, &result); 1913100979Srwatson VOP_UNLOCK(vp, 0, td); 1914100979Srwatson /* 1915100979Srwatson * Find out what maximum protection we may be allowing 1916100979Srwatson * now but a policy needs to get removed. 1917100979Srwatson */ 1918100979Srwatson revokeperms = vme->max_protection & ~result; 1919100979Srwatson if (!revokeperms) 1920100979Srwatson continue; 1921102949Sbde printf("pid %ld: revoking %s perms from %#lx:%ld " 1922102949Sbde "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 1923102949Sbde prot2str(revokeperms), (u_long)vme->start, 1924102949Sbde (long)(vme->end - vme->start), 1925100979Srwatson prot2str(vme->max_protection), prot2str(vme->protection)); 1926100979Srwatson vm_map_lock_upgrade(map); 1927100979Srwatson /* 1928100979Srwatson * This is the really simple case: if a map has more 1929100979Srwatson * max_protection than is allowed, but it's not being 1930100979Srwatson * actually used (that is, the current protection is 1931100979Srwatson * still allowed), we can just wipe it out and do 1932100979Srwatson * nothing more. 1933100979Srwatson */ 1934100979Srwatson if ((vme->protection & revokeperms) == 0) { 1935100979Srwatson vme->max_protection -= revokeperms; 1936100979Srwatson } else { 1937100979Srwatson if (revokeperms & VM_PROT_WRITE) { 1938100979Srwatson /* 1939100979Srwatson * In the more complicated case, flush out all 1940100979Srwatson * pending changes to the object then turn it 1941100979Srwatson * copy-on-write. 1942100979Srwatson */ 1943100979Srwatson vm_object_reference(object); 1944100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1945100979Srwatson vm_object_page_clean(object, 1946100979Srwatson OFF_TO_IDX(offset), 1947100979Srwatson OFF_TO_IDX(offset + vme->end - vme->start + 1948100979Srwatson PAGE_MASK), 1949100979Srwatson OBJPC_SYNC); 1950100979Srwatson VOP_UNLOCK(vp, 0, td); 1951100979Srwatson vm_object_deallocate(object); 1952100979Srwatson /* 1953100979Srwatson * Why bother if there's no read permissions 1954100979Srwatson * anymore? For the rest, we need to leave 1955100979Srwatson * the write permissions on for COW, or 1956100979Srwatson * remove them entirely if configured to. 1957100979Srwatson */ 1958100979Srwatson if (!mac_mmap_revocation_via_cow) { 1959100979Srwatson vme->max_protection &= ~VM_PROT_WRITE; 1960100979Srwatson vme->protection &= ~VM_PROT_WRITE; 1961100979Srwatson } if ((revokeperms & VM_PROT_READ) == 0) 1962100979Srwatson vme->eflags |= MAP_ENTRY_COW | 1963100979Srwatson MAP_ENTRY_NEEDS_COPY; 1964100979Srwatson } 1965100979Srwatson if (revokeperms & VM_PROT_EXECUTE) { 1966100979Srwatson vme->max_protection &= ~VM_PROT_EXECUTE; 1967100979Srwatson vme->protection &= ~VM_PROT_EXECUTE; 1968100979Srwatson } 1969100979Srwatson if (revokeperms & VM_PROT_READ) { 1970100979Srwatson vme->max_protection = 0; 1971100979Srwatson vme->protection = 0; 1972100979Srwatson } 1973100979Srwatson pmap_protect(map->pmap, vme->start, vme->end, 1974100979Srwatson vme->protection & ~revokeperms); 1975100979Srwatson vm_map_simplify_entry(map, vme); 1976100979Srwatson } 1977100979Srwatson vm_map_lock_downgrade(map); 1978100979Srwatson } 1979100979Srwatson vm_map_unlock_read(map); 1980100979Srwatson} 1981100979Srwatson 1982100979Srwatson/* 1983100979Srwatson * When the subject's label changes, it may require revocation of privilege 1984100979Srwatson * to mapped objects. This can't be done on-the-fly later with a unified 1985100979Srwatson * buffer cache. 1986100979Srwatson */ 1987100979Srwatsonstatic void 1988100979Srwatsonmac_relabel_cred(struct ucred *cred, struct label *newlabel) 1989100979Srwatson{ 1990100979Srwatson 1991100979Srwatson MAC_PERFORM(relabel_cred, cred, newlabel); 1992100979Srwatson} 1993100979Srwatson 1994100979Srwatsonvoid 1995100979Srwatsonmac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 1996100979Srwatson{ 1997100979Srwatson 1998100979Srwatson MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 1999100979Srwatson} 2000100979Srwatson 2001100979Srwatsonvoid 2002100979Srwatsonmac_create_ifnet(struct ifnet *ifnet) 2003100979Srwatson{ 2004100979Srwatson 2005100979Srwatson MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2006100979Srwatson} 2007100979Srwatson 2008100979Srwatsonvoid 2009100979Srwatsonmac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2010100979Srwatson{ 2011100979Srwatson 2012100979Srwatson MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2013100979Srwatson} 2014100979Srwatson 2015100979Srwatsonvoid 2016100979Srwatsonmac_create_socket(struct ucred *cred, struct socket *socket) 2017100979Srwatson{ 2018100979Srwatson 2019100979Srwatson MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2020100979Srwatson} 2021100979Srwatson 2022100979Srwatsonvoid 2023100979Srwatsonmac_create_pipe(struct ucred *cred, struct pipe *pipe) 2024100979Srwatson{ 2025100979Srwatson 2026100979Srwatson MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2027100979Srwatson} 2028100979Srwatson 2029100979Srwatsonvoid 2030100979Srwatsonmac_create_socket_from_socket(struct socket *oldsocket, 2031100979Srwatson struct socket *newsocket) 2032100979Srwatson{ 2033100979Srwatson 2034100979Srwatson MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2035100979Srwatson newsocket, &newsocket->so_label); 2036100979Srwatson} 2037100979Srwatson 2038100979Srwatsonstatic void 2039100979Srwatsonmac_relabel_socket(struct ucred *cred, struct socket *socket, 2040100979Srwatson struct label *newlabel) 2041100979Srwatson{ 2042100979Srwatson 2043100979Srwatson MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2044100979Srwatson} 2045100979Srwatson 2046100979Srwatsonstatic void 2047100979Srwatsonmac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2048100979Srwatson{ 2049100979Srwatson 2050100979Srwatson MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2051100979Srwatson} 2052100979Srwatson 2053100979Srwatsonvoid 2054100979Srwatsonmac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2055100979Srwatson{ 2056100979Srwatson 2057100979Srwatson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2058100979Srwatson socket, &socket->so_peerlabel); 2059100979Srwatson} 2060100979Srwatson 2061100979Srwatsonvoid 2062100979Srwatsonmac_set_socket_peer_from_socket(struct socket *oldsocket, 2063100979Srwatson struct socket *newsocket) 2064100979Srwatson{ 2065100979Srwatson 2066100979Srwatson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2067100979Srwatson &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2068100979Srwatson} 2069100979Srwatson 2070100979Srwatsonvoid 2071100979Srwatsonmac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2072100979Srwatson{ 2073100979Srwatson 2074100979Srwatson MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2075100979Srwatson datagram, &datagram->m_pkthdr.label); 2076100979Srwatson} 2077100979Srwatson 2078100979Srwatsonvoid 2079100979Srwatsonmac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2080100979Srwatson{ 2081100979Srwatson 2082100979Srwatson MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2083100979Srwatson fragment, &fragment->m_pkthdr.label); 2084100979Srwatson} 2085100979Srwatson 2086100979Srwatsonvoid 2087100979Srwatsonmac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2088100979Srwatson{ 2089100979Srwatson 2090100979Srwatson MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2091100979Srwatson &ipq->ipq_label); 2092100979Srwatson} 2093100979Srwatson 2094100979Srwatsonvoid 2095100979Srwatsonmac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2096100979Srwatson{ 2097100979Srwatson 2098100979Srwatson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2099100979Srwatson newmbuf, &newmbuf->m_pkthdr.label); 2100100979Srwatson} 2101100979Srwatson 2102100979Srwatsonvoid 2103100979Srwatsonmac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2104100979Srwatson{ 2105100979Srwatson 2106100979Srwatson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2107100979Srwatson &mbuf->m_pkthdr.label); 2108100979Srwatson} 2109100979Srwatson 2110100979Srwatsonvoid 2111100979Srwatsonmac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2112100979Srwatson{ 2113100979Srwatson 2114100979Srwatson MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2115100979Srwatson &mbuf->m_pkthdr.label); 2116100979Srwatson} 2117100979Srwatson 2118100979Srwatsonvoid 2119100979Srwatsonmac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2120100979Srwatson{ 2121100979Srwatson 2122100979Srwatson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2123100979Srwatson &mbuf->m_pkthdr.label); 2124100979Srwatson} 2125100979Srwatson 2126100979Srwatsonvoid 2127100979Srwatsonmac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2128100979Srwatson struct mbuf *newmbuf) 2129100979Srwatson{ 2130100979Srwatson 2131100979Srwatson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2132100979Srwatson &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2133100979Srwatson &newmbuf->m_pkthdr.label); 2134100979Srwatson} 2135100979Srwatson 2136100979Srwatsonvoid 2137100979Srwatsonmac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2138100979Srwatson{ 2139100979Srwatson 2140100979Srwatson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2141100979Srwatson newmbuf, &newmbuf->m_pkthdr.label); 2142100979Srwatson} 2143100979Srwatson 2144100979Srwatsonint 2145100979Srwatsonmac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2146100979Srwatson{ 2147100979Srwatson int result; 2148100979Srwatson 2149100979Srwatson result = 1; 2150100979Srwatson MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2151100979Srwatson ipq, &ipq->ipq_label); 2152100979Srwatson 2153100979Srwatson return (result); 2154100979Srwatson} 2155100979Srwatson 2156100979Srwatsonvoid 2157100979Srwatsonmac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2158100979Srwatson{ 2159100979Srwatson 2160100979Srwatson MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2161100979Srwatson &ipq->ipq_label); 2162100979Srwatson} 2163100979Srwatson 2164100979Srwatsonvoid 2165100979Srwatsonmac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2166100979Srwatson{ 2167100979Srwatson 2168100979Srwatson MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2169100979Srwatson &mbuf->m_pkthdr.label); 2170100979Srwatson} 2171100979Srwatson 2172100979Srwatsonvoid 2173100979Srwatsonmac_create_mount(struct ucred *cred, struct mount *mp) 2174100979Srwatson{ 2175100979Srwatson 2176100979Srwatson MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2177100979Srwatson &mp->mnt_fslabel); 2178100979Srwatson} 2179100979Srwatson 2180100979Srwatsonvoid 2181100979Srwatsonmac_create_root_mount(struct ucred *cred, struct mount *mp) 2182100979Srwatson{ 2183100979Srwatson 2184100979Srwatson MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2185100979Srwatson &mp->mnt_fslabel); 2186100979Srwatson} 2187100979Srwatson 2188100979Srwatsonint 2189100979Srwatsonmac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2190100979Srwatson{ 2191100979Srwatson int error; 2192100979Srwatson 2193100979Srwatson if (!mac_enforce_network) 2194100979Srwatson return (0); 2195100979Srwatson 2196100979Srwatson MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2197100979Srwatson &ifnet->if_label); 2198100979Srwatson 2199100979Srwatson return (error); 2200100979Srwatson} 2201100979Srwatson 2202100979Srwatsonstatic int 2203100979Srwatsonmac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2204100979Srwatson{ 2205100979Srwatson int error; 2206100979Srwatson 2207100979Srwatson MAC_CHECK(check_cred_relabel, cred, newlabel); 2208100979Srwatson 2209100979Srwatson return (error); 2210100979Srwatson} 2211100979Srwatson 2212100979Srwatsonint 2213100979Srwatsonmac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2214100979Srwatson{ 2215100979Srwatson int error; 2216100979Srwatson 2217100979Srwatson if (!mac_enforce_process) 2218100979Srwatson return (0); 2219100979Srwatson 2220100979Srwatson MAC_CHECK(check_cred_visible, u1, u2); 2221100979Srwatson 2222100979Srwatson return (error); 2223100979Srwatson} 2224100979Srwatson 2225100979Srwatsonint 2226100979Srwatsonmac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2227100979Srwatson{ 2228100979Srwatson int error; 2229100979Srwatson 2230100979Srwatson if (!mac_enforce_network) 2231100979Srwatson return (0); 2232100979Srwatson 2233100979Srwatson KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2234100979Srwatson if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2235105598Sbrooks if_printf(ifnet, "not initialized\n"); 2236100979Srwatson 2237100979Srwatson MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2238100979Srwatson &mbuf->m_pkthdr.label); 2239100979Srwatson 2240100979Srwatson return (error); 2241100979Srwatson} 2242100979Srwatson 2243100979Srwatsonint 2244106308Srwatsonmac_check_kenv_dump(struct ucred *cred) 2245106308Srwatson{ 2246106308Srwatson int error; 2247106308Srwatson 2248106308Srwatson if (!mac_enforce_system) 2249106308Srwatson return (0); 2250106308Srwatson 2251106308Srwatson MAC_CHECK(check_kenv_dump, cred); 2252106308Srwatson 2253106308Srwatson return (error); 2254106308Srwatson} 2255106308Srwatson 2256106308Srwatsonint 2257106308Srwatsonmac_check_kenv_get(struct ucred *cred, char *name) 2258106308Srwatson{ 2259106308Srwatson int error; 2260106308Srwatson 2261106308Srwatson if (!mac_enforce_system) 2262106308Srwatson return (0); 2263106308Srwatson 2264106308Srwatson MAC_CHECK(check_kenv_get, cred, name); 2265106308Srwatson 2266106308Srwatson return (error); 2267106308Srwatson} 2268106308Srwatson 2269106308Srwatsonint 2270106308Srwatsonmac_check_kenv_set(struct ucred *cred, char *name, char *value) 2271106308Srwatson{ 2272106308Srwatson int error; 2273106308Srwatson 2274106308Srwatson if (!mac_enforce_system) 2275106308Srwatson return (0); 2276106308Srwatson 2277106308Srwatson MAC_CHECK(check_kenv_set, cred, name, value); 2278106308Srwatson 2279106308Srwatson return (error); 2280106308Srwatson} 2281106308Srwatson 2282106308Srwatsonint 2283106308Srwatsonmac_check_kenv_unset(struct ucred *cred, char *name) 2284106308Srwatson{ 2285106308Srwatson int error; 2286106308Srwatson 2287106308Srwatson if (!mac_enforce_system) 2288106308Srwatson return (0); 2289106308Srwatson 2290106308Srwatson MAC_CHECK(check_kenv_unset, cred, name); 2291106308Srwatson 2292106308Srwatson return (error); 2293106308Srwatson} 2294106308Srwatson 2295106308Srwatsonint 2296100979Srwatsonmac_check_mount_stat(struct ucred *cred, struct mount *mount) 2297100979Srwatson{ 2298100979Srwatson int error; 2299100979Srwatson 2300100979Srwatson if (!mac_enforce_fs) 2301100979Srwatson return (0); 2302100979Srwatson 2303100979Srwatson MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2304100979Srwatson 2305100979Srwatson return (error); 2306100979Srwatson} 2307100979Srwatson 2308100979Srwatsonint 2309100979Srwatsonmac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2310100979Srwatson void *data) 2311100979Srwatson{ 2312100979Srwatson int error; 2313100979Srwatson 2314104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2315104269Srwatson 2316104269Srwatson if (!mac_enforce_pipe) 2317104269Srwatson return (0); 2318104269Srwatson 2319100979Srwatson MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2320100979Srwatson 2321100979Srwatson return (error); 2322100979Srwatson} 2323100979Srwatson 2324100979Srwatsonint 2325102115Srwatsonmac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2326100979Srwatson{ 2327100979Srwatson int error; 2328100979Srwatson 2329104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2330104269Srwatson 2331104269Srwatson if (!mac_enforce_pipe) 2332104269Srwatson return (0); 2333104269Srwatson 2334102115Srwatson MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2335100979Srwatson 2336100979Srwatson return (error); 2337100979Srwatson} 2338100979Srwatson 2339102115Srwatsonint 2340102115Srwatsonmac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2341102115Srwatson{ 2342102115Srwatson int error; 2343102115Srwatson 2344104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2345104269Srwatson 2346104269Srwatson if (!mac_enforce_pipe) 2347104269Srwatson return (0); 2348104269Srwatson 2349102115Srwatson MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2350102115Srwatson 2351102115Srwatson return (error); 2352102115Srwatson} 2353102115Srwatson 2354100979Srwatsonstatic int 2355100979Srwatsonmac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2356100979Srwatson struct label *newlabel) 2357100979Srwatson{ 2358100979Srwatson int error; 2359100979Srwatson 2360104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2361104269Srwatson 2362104269Srwatson if (!mac_enforce_pipe) 2363104269Srwatson return (0); 2364104269Srwatson 2365100979Srwatson MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2366100979Srwatson 2367100979Srwatson return (error); 2368100979Srwatson} 2369100979Srwatson 2370100979Srwatsonint 2371102115Srwatsonmac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2372102115Srwatson{ 2373102115Srwatson int error; 2374102115Srwatson 2375104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2376104269Srwatson 2377104269Srwatson if (!mac_enforce_pipe) 2378104269Srwatson return (0); 2379104269Srwatson 2380102115Srwatson MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2381102115Srwatson 2382102115Srwatson return (error); 2383102115Srwatson} 2384102115Srwatson 2385102115Srwatsonint 2386102115Srwatsonmac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2387102115Srwatson{ 2388102115Srwatson int error; 2389102115Srwatson 2390104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2391104269Srwatson 2392104269Srwatson if (!mac_enforce_pipe) 2393104269Srwatson return (0); 2394104269Srwatson 2395102115Srwatson MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2396102115Srwatson 2397102115Srwatson return (error); 2398102115Srwatson} 2399102115Srwatson 2400102115Srwatsonint 2401100979Srwatsonmac_check_proc_debug(struct ucred *cred, struct proc *proc) 2402100979Srwatson{ 2403100979Srwatson int error; 2404100979Srwatson 2405102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2406102103Srwatson 2407100979Srwatson if (!mac_enforce_process) 2408100979Srwatson return (0); 2409100979Srwatson 2410100979Srwatson MAC_CHECK(check_proc_debug, cred, proc); 2411100979Srwatson 2412100979Srwatson return (error); 2413100979Srwatson} 2414100979Srwatson 2415100979Srwatsonint 2416100979Srwatsonmac_check_proc_sched(struct ucred *cred, struct proc *proc) 2417100979Srwatson{ 2418100979Srwatson int error; 2419100979Srwatson 2420102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2421102103Srwatson 2422100979Srwatson if (!mac_enforce_process) 2423100979Srwatson return (0); 2424100979Srwatson 2425100979Srwatson MAC_CHECK(check_proc_sched, cred, proc); 2426100979Srwatson 2427100979Srwatson return (error); 2428100979Srwatson} 2429100979Srwatson 2430100979Srwatsonint 2431100979Srwatsonmac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2432100979Srwatson{ 2433100979Srwatson int error; 2434100979Srwatson 2435102103Srwatson PROC_LOCK_ASSERT(proc, MA_OWNED); 2436102103Srwatson 2437100979Srwatson if (!mac_enforce_process) 2438100979Srwatson return (0); 2439100979Srwatson 2440100979Srwatson MAC_CHECK(check_proc_signal, cred, proc, signum); 2441100979Srwatson 2442100979Srwatson return (error); 2443100979Srwatson} 2444100979Srwatson 2445100979Srwatsonint 2446100979Srwatsonmac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2447100979Srwatson struct sockaddr *sockaddr) 2448100979Srwatson{ 2449100979Srwatson int error; 2450100979Srwatson 2451100979Srwatson if (!mac_enforce_socket) 2452100979Srwatson return (0); 2453100979Srwatson 2454100979Srwatson MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2455100979Srwatson sockaddr); 2456100979Srwatson 2457100979Srwatson return (error); 2458100979Srwatson} 2459100979Srwatson 2460100979Srwatsonint 2461100979Srwatsonmac_check_socket_connect(struct ucred *cred, struct socket *socket, 2462100979Srwatson struct sockaddr *sockaddr) 2463100979Srwatson{ 2464100979Srwatson int error; 2465100979Srwatson 2466100979Srwatson if (!mac_enforce_socket) 2467100979Srwatson return (0); 2468100979Srwatson 2469100979Srwatson MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2470100979Srwatson sockaddr); 2471100979Srwatson 2472100979Srwatson return (error); 2473100979Srwatson} 2474100979Srwatson 2475100979Srwatsonint 2476101933Srwatsonmac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2477100979Srwatson{ 2478100979Srwatson int error; 2479100979Srwatson 2480100979Srwatson if (!mac_enforce_socket) 2481100979Srwatson return (0); 2482100979Srwatson 2483101933Srwatson MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2484101933Srwatson &mbuf->m_pkthdr.label); 2485101933Srwatson 2486100979Srwatson return (error); 2487100979Srwatson} 2488100979Srwatson 2489100979Srwatsonint 2490101933Srwatsonmac_check_socket_listen(struct ucred *cred, struct socket *socket) 2491100979Srwatson{ 2492100979Srwatson int error; 2493100979Srwatson 2494100979Srwatson if (!mac_enforce_socket) 2495100979Srwatson return (0); 2496100979Srwatson 2497101933Srwatson MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2498100979Srwatson return (error); 2499100979Srwatson} 2500100979Srwatson 2501104571Srwatsonint 2502104571Srwatsonmac_check_socket_receive(struct ucred *cred, struct socket *so) 2503104571Srwatson{ 2504104571Srwatson int error; 2505104571Srwatson 2506104571Srwatson if (!mac_enforce_socket) 2507104571Srwatson return (0); 2508104571Srwatson 2509104571Srwatson MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2510104571Srwatson 2511104571Srwatson return (error); 2512104571Srwatson} 2513104571Srwatson 2514100979Srwatsonstatic int 2515100979Srwatsonmac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2516100979Srwatson struct label *newlabel) 2517100979Srwatson{ 2518100979Srwatson int error; 2519100979Srwatson 2520100979Srwatson MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2521100979Srwatson newlabel); 2522100979Srwatson 2523100979Srwatson return (error); 2524100979Srwatson} 2525100979Srwatson 2526100979Srwatsonint 2527104571Srwatsonmac_check_socket_send(struct ucred *cred, struct socket *so) 2528104571Srwatson{ 2529104571Srwatson int error; 2530104571Srwatson 2531104571Srwatson if (!mac_enforce_socket) 2532104571Srwatson return (0); 2533104571Srwatson 2534104571Srwatson MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2535104571Srwatson 2536104571Srwatson return (error); 2537104571Srwatson} 2538104571Srwatson 2539104571Srwatsonint 2540100979Srwatsonmac_check_socket_visible(struct ucred *cred, struct socket *socket) 2541100979Srwatson{ 2542100979Srwatson int error; 2543100979Srwatson 2544100979Srwatson if (!mac_enforce_socket) 2545100979Srwatson return (0); 2546105694Srwatson 2547100979Srwatson MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2548105694Srwatson 2549100979Srwatson return (error); 2550100979Srwatson} 2551100979Srwatson 2552100979Srwatsonint 2553106412Srwatsonmac_check_system_acct(struct ucred *cred, struct vnode *vp) 2554106412Srwatson{ 2555106412Srwatson int error; 2556106412Srwatson 2557106412Srwatson if (vp != NULL) { 2558106412Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2559106412Srwatson } 2560106412Srwatson 2561106412Srwatson if (!mac_enforce_system) 2562106412Srwatson return (0); 2563106412Srwatson 2564106412Srwatson MAC_CHECK(check_system_acct, cred, vp, 2565106412Srwatson vp != NULL ? &vp->v_label : NULL); 2566106412Srwatson 2567106412Srwatson return (error); 2568106412Srwatson} 2569106412Srwatson 2570106412Srwatsonint 2571106412Srwatsonmac_check_system_nfsd(struct ucred *cred) 2572106412Srwatson{ 2573106412Srwatson int error; 2574106412Srwatson 2575106412Srwatson if (!mac_enforce_system) 2576106412Srwatson return (0); 2577106412Srwatson 2578106412Srwatson MAC_CHECK(check_system_nfsd, cred); 2579106412Srwatson 2580106412Srwatson return (error); 2581106412Srwatson} 2582106412Srwatson 2583106412Srwatsonint 2584106024Srwatsonmac_check_system_reboot(struct ucred *cred, int howto) 2585106024Srwatson{ 2586106024Srwatson int error; 2587106024Srwatson 2588106045Srwatson if (!mac_enforce_system) 2589106024Srwatson return (0); 2590106024Srwatson 2591106024Srwatson MAC_CHECK(check_system_reboot, cred, howto); 2592106045Srwatson 2593106024Srwatson return (error); 2594106024Srwatson} 2595106024Srwatson 2596106024Srwatsonint 2597106369Srwatsonmac_check_system_settime(struct ucred *cred) 2598106369Srwatson{ 2599106369Srwatson int error; 2600106369Srwatson 2601106369Srwatson if (!mac_enforce_system) 2602106369Srwatson return (0); 2603106369Srwatson 2604106369Srwatson MAC_CHECK(check_system_settime, cred); 2605106369Srwatson 2606106369Srwatson return (error); 2607106369Srwatson} 2608106369Srwatson 2609106369Srwatsonint 2610106023Srwatsonmac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2611106023Srwatson{ 2612106023Srwatson int error; 2613106023Srwatson 2614106023Srwatson ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2615106023Srwatson 2616106045Srwatson if (!mac_enforce_system) 2617106023Srwatson return (0); 2618106023Srwatson 2619106023Srwatson MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2620106023Srwatson return (error); 2621106023Srwatson} 2622106023Srwatson 2623106023Srwatsonint 2624106025Srwatsonmac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2625106025Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2626106025Srwatson{ 2627106025Srwatson int error; 2628106025Srwatson 2629106025Srwatson /* 2630106025Srwatson * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2631106025Srwatson * but since it's not exported from kern_sysctl.c, we can't. 2632106025Srwatson */ 2633106045Srwatson if (!mac_enforce_system) 2634106025Srwatson return (0); 2635106025Srwatson 2636106025Srwatson MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2637106025Srwatson inkernel, new, newlen); 2638106025Srwatson 2639106025Srwatson return (error); 2640106025Srwatson} 2641106025Srwatson 2642106025Srwatsonint 2643100979Srwatsonmac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2644100979Srwatson struct ifnet *ifnet) 2645100979Srwatson{ 2646105694Srwatson char *elements, *buffer; 2647105694Srwatson struct mac mac; 2648100979Srwatson int error; 2649100979Srwatson 2650105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2651100979Srwatson if (error) 2652100979Srwatson return (error); 2653100979Srwatson 2654105694Srwatson error = mac_check_structmac_consistent(&mac); 2655105694Srwatson if (error) 2656105694Srwatson return (error); 2657105694Srwatson 2658105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2659105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2660105694Srwatson if (error) { 2661105694Srwatson free(elements, M_MACTEMP); 2662105694Srwatson return (error); 2663105694Srwatson } 2664105694Srwatson 2665105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2666105694Srwatson error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 2667105694Srwatson buffer, mac.m_buflen, M_WAITOK); 2668105694Srwatson if (error == 0) 2669105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2670105694Srwatson 2671105694Srwatson free(buffer, M_MACTEMP); 2672105694Srwatson free(elements, M_MACTEMP); 2673105694Srwatson 2674105694Srwatson return (error); 2675100979Srwatson} 2676100979Srwatson 2677100979Srwatsonint 2678100979Srwatsonmac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2679100979Srwatson struct ifnet *ifnet) 2680100979Srwatson{ 2681100979Srwatson struct label intlabel; 2682105694Srwatson struct mac mac; 2683105694Srwatson char *buffer; 2684100979Srwatson int error; 2685100979Srwatson 2686105694Srwatson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2687100979Srwatson if (error) 2688100979Srwatson return (error); 2689100979Srwatson 2690105694Srwatson error = mac_check_structmac_consistent(&mac); 2691100979Srwatson if (error) 2692100979Srwatson return (error); 2693100979Srwatson 2694105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2695105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2696105694Srwatson if (error) { 2697105694Srwatson free(buffer, M_MACTEMP); 2698105694Srwatson return (error); 2699105694Srwatson } 2700105694Srwatson 2701105694Srwatson mac_init_ifnet_label(&intlabel); 2702105694Srwatson error = mac_internalize_ifnet_label(&intlabel, buffer); 2703105694Srwatson free(buffer, M_MACTEMP); 2704105694Srwatson if (error) { 2705105694Srwatson mac_destroy_ifnet_label(&intlabel); 2706105694Srwatson return (error); 2707105694Srwatson } 2708105694Srwatson 2709100979Srwatson /* 2710100979Srwatson * XXX: Note that this is a redundant privilege check, since 2711100979Srwatson * policies impose this check themselves if required by the 2712100979Srwatson * policy. Eventually, this should go away. 2713100979Srwatson */ 2714100979Srwatson error = suser_cred(cred, 0); 2715105694Srwatson if (error) { 2716105694Srwatson mac_destroy_ifnet_label(&intlabel); 2717105694Srwatson return (error); 2718105694Srwatson } 2719100979Srwatson 2720100979Srwatson MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2721100979Srwatson &intlabel); 2722105694Srwatson if (error) { 2723105694Srwatson mac_destroy_ifnet_label(&intlabel); 2724105694Srwatson return (error); 2725105694Srwatson } 2726100979Srwatson 2727100979Srwatson MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2728100979Srwatson 2729105694Srwatson mac_destroy_ifnet_label(&intlabel); 2730105694Srwatson return (0); 2731100979Srwatson} 2732100979Srwatson 2733100979Srwatsonvoid 2734100979Srwatsonmac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 2735100979Srwatson{ 2736100979Srwatson 2737100979Srwatson MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 2738100979Srwatson} 2739100979Srwatson 2740104533Srwatsonvoid 2741104533Srwatsonmac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 2742104533Srwatson struct devfs_dirent *de) 2743104533Srwatson{ 2744104533Srwatson 2745104533Srwatson MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de, 2746104533Srwatson &de->de_label); 2747104533Srwatson} 2748104533Srwatson 2749100979Srwatsonvoid 2750100979Srwatsonmac_create_devfs_directory(char *dirname, int dirnamelen, 2751100979Srwatson struct devfs_dirent *de) 2752100979Srwatson{ 2753100979Srwatson 2754100979Srwatson MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 2755100979Srwatson &de->de_label); 2756100979Srwatson} 2757100979Srwatson 2758100979Srwatsonint 2759100979Srwatsonmac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2760105694Srwatson struct mac *mac) 2761100979Srwatson{ 2762100979Srwatson struct label intlabel; 2763105694Srwatson char *buffer; 2764100979Srwatson int error; 2765100979Srwatson 2766105694Srwatson error = mac_check_structmac_consistent(mac); 2767100979Srwatson if (error) 2768100979Srwatson return (error); 2769100979Srwatson 2770105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2771105694Srwatson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 2772105694Srwatson if (error) { 2773105694Srwatson free(buffer, M_MACTEMP); 2774105694Srwatson return (error); 2775105694Srwatson } 2776105694Srwatson 2777105694Srwatson mac_init_socket_label(&intlabel, M_WAITOK); 2778105694Srwatson error = mac_internalize_socket_label(&intlabel, buffer); 2779105694Srwatson free(buffer, M_MACTEMP); 2780105694Srwatson if (error) { 2781105694Srwatson mac_destroy_socket_label(&intlabel); 2782105694Srwatson return (error); 2783105694Srwatson } 2784105694Srwatson 2785100979Srwatson mac_check_socket_relabel(cred, so, &intlabel); 2786100979Srwatson if (error) { 2787105694Srwatson mac_destroy_socket_label(&intlabel); 2788100979Srwatson return (error); 2789100979Srwatson } 2790100979Srwatson 2791100979Srwatson mac_relabel_socket(cred, so, &intlabel); 2792100979Srwatson 2793105694Srwatson mac_destroy_socket_label(&intlabel); 2794100979Srwatson return (0); 2795100979Srwatson} 2796100979Srwatson 2797100979Srwatsonint 2798100979Srwatsonmac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 2799100979Srwatson{ 2800100979Srwatson int error; 2801100979Srwatson 2802104269Srwatson PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2803104269Srwatson 2804100979Srwatson error = mac_check_pipe_relabel(cred, pipe, label); 2805100979Srwatson if (error) 2806100979Srwatson return (error); 2807100979Srwatson 2808100979Srwatson mac_relabel_pipe(cred, pipe, label); 2809100979Srwatson 2810100979Srwatson return (0); 2811100979Srwatson} 2812100979Srwatson 2813100979Srwatsonint 2814100979Srwatsonmac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2815105694Srwatson struct mac *mac) 2816100979Srwatson{ 2817105694Srwatson char *buffer, *elements; 2818105694Srwatson int error; 2819100979Srwatson 2820105694Srwatson error = mac_check_structmac_consistent(mac); 2821105694Srwatson if (error) 2822105694Srwatson return (error); 2823105694Srwatson 2824105694Srwatson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2825105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2826105694Srwatson if (error) { 2827105694Srwatson free(elements, M_MACTEMP); 2828105694Srwatson return (error); 2829105694Srwatson } 2830105694Srwatson 2831105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2832105694Srwatson error = mac_externalize_socket_label(&so->so_label, elements, 2833105694Srwatson buffer, mac->m_buflen, M_WAITOK); 2834105694Srwatson if (error == 0) 2835105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2836105694Srwatson 2837105694Srwatson free(buffer, M_MACTEMP); 2838105694Srwatson free(elements, M_MACTEMP); 2839105694Srwatson 2840105694Srwatson return (error); 2841100979Srwatson} 2842100979Srwatson 2843100979Srwatsonint 2844100979Srwatsonmac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2845105694Srwatson struct mac *mac) 2846100979Srwatson{ 2847105694Srwatson char *elements, *buffer; 2848105694Srwatson int error; 2849100979Srwatson 2850105694Srwatson error = mac_check_structmac_consistent(mac); 2851105694Srwatson if (error) 2852105694Srwatson return (error); 2853105694Srwatson 2854105694Srwatson elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2855105694Srwatson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2856105694Srwatson if (error) { 2857105694Srwatson free(elements, M_MACTEMP); 2858105694Srwatson return (error); 2859105694Srwatson } 2860105694Srwatson 2861105694Srwatson buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2862105694Srwatson error = mac_externalize_socket_peer_label(&so->so_peerlabel, 2863105694Srwatson elements, buffer, mac->m_buflen, M_WAITOK); 2864105694Srwatson if (error == 0) 2865105694Srwatson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2866105694Srwatson 2867105694Srwatson free(buffer, M_MACTEMP); 2868105694Srwatson free(elements, M_MACTEMP); 2869105694Srwatson 2870105694Srwatson return (error); 2871100979Srwatson} 2872100979Srwatson 2873100979Srwatson/* 2874100979Srwatson * Implementation of VOP_SETLABEL() that relies on extended attributes 2875100979Srwatson * to store label data. Can be referenced by filesystems supporting 2876100979Srwatson * extended attributes. 2877100979Srwatson */ 2878100979Srwatsonint 2879100979Srwatsonvop_stdsetlabel_ea(struct vop_setlabel_args *ap) 2880100979Srwatson{ 2881100979Srwatson struct vnode *vp = ap->a_vp; 2882100979Srwatson struct label *intlabel = ap->a_label; 2883100979Srwatson int error; 2884100979Srwatson 2885100979Srwatson ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 2886100979Srwatson 2887105988Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2888105988Srwatson return (EOPNOTSUPP); 2889100979Srwatson 2890105988Srwatson error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 2891100979Srwatson if (error) 2892100979Srwatson return (error); 2893100979Srwatson 2894100979Srwatson mac_relabel_vnode(ap->a_cred, vp, intlabel); 2895100979Srwatson 2896100979Srwatson return (0); 2897100979Srwatson} 2898100979Srwatson 2899100979Srwatsonstatic int 2900100979Srwatsonvn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 2901100979Srwatson{ 2902100979Srwatson int error; 2903100979Srwatson 2904100979Srwatson if (vp->v_mount == NULL) { 2905100979Srwatson /* printf("vn_setlabel: null v_mount\n"); */ 2906103314Snjl if (vp->v_type != VNON) 2907103314Snjl printf("vn_setlabel: null v_mount with non-VNON\n"); 2908100979Srwatson return (EBADF); 2909100979Srwatson } 2910100979Srwatson 2911100979Srwatson if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2912100979Srwatson return (EOPNOTSUPP); 2913100979Srwatson 2914100979Srwatson /* 2915100979Srwatson * Multi-phase commit. First check the policies to confirm the 2916100979Srwatson * change is OK. Then commit via the filesystem. Finally, 2917100979Srwatson * update the actual vnode label. Question: maybe the filesystem 2918100979Srwatson * should update the vnode at the end as part of VOP_SETLABEL()? 2919100979Srwatson */ 2920100979Srwatson error = mac_check_vnode_relabel(cred, vp, intlabel); 2921100979Srwatson if (error) 2922100979Srwatson return (error); 2923100979Srwatson 2924100979Srwatson /* 2925100979Srwatson * VADMIN provides the opportunity for the filesystem to make 2926100979Srwatson * decisions about who is and is not able to modify labels 2927100979Srwatson * and protections on files. This might not be right. We can't 2928100979Srwatson * assume VOP_SETLABEL() will do it, because we might implement 2929100979Srwatson * that as part of vop_stdsetlabel_ea(). 2930100979Srwatson */ 2931100979Srwatson error = VOP_ACCESS(vp, VADMIN, cred, curthread); 2932100979Srwatson if (error) 2933100979Srwatson return (error); 2934100979Srwatson 2935100979Srwatson error = VOP_SETLABEL(vp, intlabel, cred, curthread); 2936100979Srwatson if (error) 2937100979Srwatson return (error); 2938100979Srwatson 2939100979Srwatson return (0); 2940100979Srwatson} 2941100979Srwatson 2942105694Srwatsonint 2943105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 2944105694Srwatson{ 2945105694Srwatson char *elements, *buffer; 2946105694Srwatson struct mac mac; 2947105694Srwatson struct proc *tproc; 2948105694Srwatson struct ucred *tcred; 2949105694Srwatson int error; 2950105694Srwatson 2951105694Srwatson error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac)); 2952105694Srwatson if (error) 2953105694Srwatson return (error); 2954105694Srwatson 2955105694Srwatson error = mac_check_structmac_consistent(&mac); 2956105694Srwatson if (error) 2957105694Srwatson return (error); 2958105694Srwatson 2959105694Srwatson tproc = pfind(uap->pid); 2960105694Srwatson if (tproc == NULL) 2961105694Srwatson return (ESRCH); 2962105694Srwatson 2963105694Srwatson tcred = NULL; /* Satisfy gcc. */ 2964105694Srwatson error = p_cansee(td, tproc); 2965105694Srwatson if (error == 0) 2966105694Srwatson tcred = crhold(tproc->p_ucred); 2967105694Srwatson PROC_UNLOCK(tproc); 2968105694Srwatson if (error) 2969105694Srwatson return (error); 2970105694Srwatson 2971105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2972105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2973105694Srwatson if (error) { 2974105694Srwatson free(elements, M_MACTEMP); 2975105694Srwatson crfree(tcred); 2976105694Srwatson return (error); 2977105694Srwatson } 2978105694Srwatson 2979105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2980105694Srwatson error = mac_externalize_cred_label(&tcred->cr_label, elements, 2981105694Srwatson buffer, mac.m_buflen, M_WAITOK); 2982105694Srwatson if (error == 0) 2983105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2984105694Srwatson 2985105694Srwatson free(buffer, M_MACTEMP); 2986105694Srwatson free(elements, M_MACTEMP); 2987105694Srwatson crfree(tcred); 2988105694Srwatson return (error); 2989105694Srwatson} 2990105694Srwatson 2991100979Srwatson/* 2992100979Srwatson * MPSAFE 2993100979Srwatson */ 2994100979Srwatsonint 2995100894Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 2996100894Srwatson{ 2997105694Srwatson char *elements, *buffer; 2998105694Srwatson struct mac mac; 2999100979Srwatson int error; 3000100894Srwatson 3001105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3002105694Srwatson if (error) 3003105694Srwatson return (error); 3004105694Srwatson 3005105694Srwatson error = mac_check_structmac_consistent(&mac); 3006105694Srwatson if (error) 3007105694Srwatson return (error); 3008105694Srwatson 3009105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3010105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3011105694Srwatson if (error) { 3012105694Srwatson free(elements, M_MACTEMP); 3013105694Srwatson return (error); 3014105694Srwatson } 3015105694Srwatson 3016105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3017105694Srwatson error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3018105694Srwatson elements, buffer, mac.m_buflen, M_WAITOK); 3019100979Srwatson if (error == 0) 3020105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3021100979Srwatson 3022105694Srwatson free(buffer, M_MACTEMP); 3023105694Srwatson free(elements, M_MACTEMP); 3024100979Srwatson return (error); 3025100979Srwatson} 3026100979Srwatson 3027100979Srwatson/* 3028100979Srwatson * MPSAFE 3029100979Srwatson */ 3030100979Srwatsonint 3031100979Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3032100979Srwatson{ 3033100979Srwatson struct ucred *newcred, *oldcred; 3034105694Srwatson struct label intlabel; 3035100979Srwatson struct proc *p; 3036105694Srwatson struct mac mac; 3037105694Srwatson char *buffer; 3038100979Srwatson int error; 3039100979Srwatson 3040105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3041100979Srwatson if (error) 3042100979Srwatson return (error); 3043100979Srwatson 3044105694Srwatson error = mac_check_structmac_consistent(&mac); 3045100979Srwatson if (error) 3046100979Srwatson return (error); 3047100979Srwatson 3048105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3049105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3050105694Srwatson if (error) { 3051105694Srwatson free(buffer, M_MACTEMP); 3052105694Srwatson return (error); 3053105694Srwatson } 3054105694Srwatson 3055105694Srwatson mac_init_cred_label(&intlabel); 3056105694Srwatson error = mac_internalize_cred_label(&intlabel, buffer); 3057105694Srwatson free(buffer, M_MACTEMP); 3058105694Srwatson if (error) { 3059105694Srwatson mac_destroy_cred_label(&intlabel); 3060105694Srwatson return (error); 3061105694Srwatson } 3062105694Srwatson 3063100979Srwatson newcred = crget(); 3064100979Srwatson 3065100979Srwatson p = td->td_proc; 3066100979Srwatson PROC_LOCK(p); 3067100979Srwatson oldcred = p->p_ucred; 3068100979Srwatson 3069100979Srwatson error = mac_check_cred_relabel(oldcred, &intlabel); 3070100979Srwatson if (error) { 3071100979Srwatson PROC_UNLOCK(p); 3072100979Srwatson crfree(newcred); 3073105694Srwatson goto out; 3074100979Srwatson } 3075100979Srwatson 3076100979Srwatson setsugid(p); 3077100979Srwatson crcopy(newcred, oldcred); 3078100979Srwatson mac_relabel_cred(newcred, &intlabel); 3079102136Srwatson p->p_ucred = newcred; 3080100979Srwatson 3081102136Srwatson /* 3082102136Srwatson * Grab additional reference for use while revoking mmaps, prior 3083102136Srwatson * to releasing the proc lock and sharing the cred. 3084102136Srwatson */ 3085102136Srwatson crhold(newcred); 3086100979Srwatson PROC_UNLOCK(p); 3087102136Srwatson 3088105694Srwatson if (mac_enforce_vm) { 3089105694Srwatson mtx_lock(&Giant); 3090105694Srwatson mac_cred_mmapped_drop_perms(td, newcred); 3091105694Srwatson mtx_unlock(&Giant); 3092105694Srwatson } 3093102136Srwatson 3094102136Srwatson crfree(newcred); /* Free revocation reference. */ 3095100979Srwatson crfree(oldcred); 3096105694Srwatson 3097105694Srwatsonout: 3098105694Srwatson mac_destroy_cred_label(&intlabel); 3099105694Srwatson return (error); 3100100979Srwatson} 3101100979Srwatson 3102100979Srwatson/* 3103100979Srwatson * MPSAFE 3104100979Srwatson */ 3105100979Srwatsonint 3106100979Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3107100979Srwatson{ 3108105694Srwatson char *elements, *buffer; 3109105694Srwatson struct label intlabel; 3110100979Srwatson struct file *fp; 3111105694Srwatson struct mac mac; 3112100979Srwatson struct vnode *vp; 3113100979Srwatson struct pipe *pipe; 3114105694Srwatson short label_type; 3115100979Srwatson int error; 3116100979Srwatson 3117105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3118105694Srwatson if (error) 3119105694Srwatson return (error); 3120100979Srwatson 3121105694Srwatson error = mac_check_structmac_consistent(&mac); 3122105694Srwatson if (error) 3123105694Srwatson return (error); 3124105694Srwatson 3125105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3126105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3127105694Srwatson if (error) { 3128105694Srwatson free(elements, M_MACTEMP); 3129105694Srwatson return (error); 3130105694Srwatson } 3131105694Srwatson 3132105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3133105694Srwatson mtx_lock(&Giant); /* VFS */ 3134100979Srwatson error = fget(td, SCARG(uap, fd), &fp); 3135100979Srwatson if (error) 3136100979Srwatson goto out; 3137100979Srwatson 3138105694Srwatson label_type = fp->f_type; 3139100979Srwatson switch (fp->f_type) { 3140100979Srwatson case DTYPE_FIFO: 3141100979Srwatson case DTYPE_VNODE: 3142100979Srwatson vp = (struct vnode *)fp->f_data; 3143100979Srwatson 3144105694Srwatson mac_init_vnode_label(&intlabel); 3145105694Srwatson 3146100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3147105988Srwatson mac_copy_vnode_label(&vp->v_label, &intlabel); 3148100979Srwatson VOP_UNLOCK(vp, 0, td); 3149105694Srwatson 3150100979Srwatson break; 3151100979Srwatson case DTYPE_PIPE: 3152100979Srwatson pipe = (struct pipe *)fp->f_data; 3153105694Srwatson 3154105694Srwatson mac_init_pipe_label(&intlabel); 3155105694Srwatson 3156105694Srwatson PIPE_LOCK(pipe); 3157105694Srwatson mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3158105694Srwatson PIPE_UNLOCK(pipe); 3159100979Srwatson break; 3160100979Srwatson default: 3161100979Srwatson error = EINVAL; 3162105694Srwatson fdrop(fp, td); 3163105694Srwatson goto out; 3164100979Srwatson } 3165105694Srwatson fdrop(fp, td); 3166100979Srwatson 3167105694Srwatson switch (label_type) { 3168105694Srwatson case DTYPE_FIFO: 3169105694Srwatson case DTYPE_VNODE: 3170105694Srwatson if (error == 0) 3171105694Srwatson error = mac_externalize_vnode_label(&intlabel, 3172105694Srwatson elements, buffer, mac.m_buflen, M_WAITOK); 3173105694Srwatson mac_destroy_vnode_label(&intlabel); 3174105694Srwatson break; 3175105694Srwatson case DTYPE_PIPE: 3176105694Srwatson error = mac_externalize_pipe_label(&intlabel, elements, 3177105694Srwatson buffer, mac.m_buflen, M_WAITOK); 3178105694Srwatson mac_destroy_pipe_label(&intlabel); 3179105694Srwatson break; 3180105694Srwatson default: 3181105694Srwatson panic("__mac_get_fd: corrupted label_type"); 3182105694Srwatson } 3183105694Srwatson 3184100979Srwatson if (error == 0) 3185105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3186100979Srwatson 3187105694Srwatsonout: 3188105694Srwatson mtx_unlock(&Giant); /* VFS */ 3189105694Srwatson free(buffer, M_MACTEMP); 3190105694Srwatson free(elements, M_MACTEMP); 3191100979Srwatson 3192100979Srwatson return (error); 3193100979Srwatson} 3194100979Srwatson 3195100979Srwatson/* 3196100979Srwatson * MPSAFE 3197100979Srwatson */ 3198100979Srwatsonint 3199100979Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3200100979Srwatson{ 3201105694Srwatson char *elements, *buffer; 3202100979Srwatson struct nameidata nd; 3203105694Srwatson struct label intlabel; 3204105694Srwatson struct mac mac; 3205100979Srwatson int error; 3206100979Srwatson 3207105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3208105694Srwatson if (error) 3209105694Srwatson return (error); 3210105694Srwatson 3211105694Srwatson error = mac_check_structmac_consistent(&mac); 3212105694Srwatson if (error) 3213105694Srwatson return (error); 3214105694Srwatson 3215105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3216105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3217105694Srwatson if (error) { 3218105694Srwatson free(elements, M_MACTEMP); 3219105694Srwatson return (error); 3220105694Srwatson } 3221105694Srwatson 3222105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3223105694Srwatson mtx_lock(&Giant); /* VFS */ 3224105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3225105694Srwatson td); 3226100979Srwatson error = namei(&nd); 3227100979Srwatson if (error) 3228100979Srwatson goto out; 3229100979Srwatson 3230105694Srwatson mac_init_vnode_label(&intlabel); 3231105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3232105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3233105988Srwatson mac.m_buflen, M_WAITOK); 3234105694Srwatson 3235100979Srwatson NDFREE(&nd, 0); 3236105694Srwatson mac_destroy_vnode_label(&intlabel); 3237105694Srwatson 3238105694Srwatson if (error == 0) 3239105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3240105694Srwatson 3241105694Srwatsonout: 3242105694Srwatson mtx_unlock(&Giant); /* VFS */ 3243105694Srwatson 3244105694Srwatson free(buffer, M_MACTEMP); 3245105694Srwatson free(elements, M_MACTEMP); 3246105694Srwatson 3247105694Srwatson return (error); 3248105694Srwatson} 3249105694Srwatson 3250105694Srwatson/* 3251105694Srwatson * MPSAFE 3252105694Srwatson */ 3253105694Srwatsonint 3254105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3255105694Srwatson{ 3256105694Srwatson char *elements, *buffer; 3257105694Srwatson struct nameidata nd; 3258105694Srwatson struct label intlabel; 3259105694Srwatson struct mac mac; 3260105694Srwatson int error; 3261105694Srwatson 3262105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3263100979Srwatson if (error) 3264105694Srwatson return (error); 3265105694Srwatson 3266105694Srwatson error = mac_check_structmac_consistent(&mac); 3267105694Srwatson if (error) 3268105694Srwatson return (error); 3269105694Srwatson 3270105694Srwatson elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3271105694Srwatson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3272105694Srwatson if (error) { 3273105694Srwatson free(elements, M_MACTEMP); 3274105694Srwatson return (error); 3275105694Srwatson } 3276105694Srwatson 3277105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3278105694Srwatson mtx_lock(&Giant); /* VFS */ 3279105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3280105694Srwatson td); 3281105694Srwatson error = namei(&nd); 3282105694Srwatson if (error) 3283100979Srwatson goto out; 3284100979Srwatson 3285105694Srwatson mac_init_vnode_label(&intlabel); 3286105988Srwatson mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3287105988Srwatson error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3288105988Srwatson mac.m_buflen, M_WAITOK); 3289105694Srwatson NDFREE(&nd, 0); 3290105694Srwatson mac_destroy_vnode_label(&intlabel); 3291100979Srwatson 3292105694Srwatson if (error == 0) 3293105694Srwatson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3294105694Srwatson 3295100979Srwatsonout: 3296105694Srwatson mtx_unlock(&Giant); /* VFS */ 3297105694Srwatson 3298105694Srwatson free(buffer, M_MACTEMP); 3299105694Srwatson free(elements, M_MACTEMP); 3300105694Srwatson 3301100979Srwatson return (error); 3302100979Srwatson} 3303100979Srwatson 3304100979Srwatson/* 3305100979Srwatson * MPSAFE 3306100979Srwatson */ 3307100979Srwatsonint 3308100979Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3309100979Srwatson{ 3310105694Srwatson struct label intlabel; 3311105694Srwatson struct pipe *pipe; 3312100979Srwatson struct file *fp; 3313100979Srwatson struct mount *mp; 3314100979Srwatson struct vnode *vp; 3315105694Srwatson struct mac mac; 3316105694Srwatson char *buffer; 3317100979Srwatson int error; 3318100979Srwatson 3319105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3320100979Srwatson if (error) 3321105694Srwatson return (error); 3322100979Srwatson 3323105694Srwatson error = mac_check_structmac_consistent(&mac); 3324100979Srwatson if (error) 3325105694Srwatson return (error); 3326100979Srwatson 3327105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3328105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3329105694Srwatson if (error) { 3330105694Srwatson free(buffer, M_MACTEMP); 3331105694Srwatson return (error); 3332105694Srwatson } 3333105694Srwatson 3334105694Srwatson mtx_lock(&Giant); /* VFS */ 3335105694Srwatson 3336105694Srwatson error = fget(td, SCARG(uap, fd), &fp); 3337100979Srwatson if (error) 3338105694Srwatson goto out; 3339100979Srwatson 3340100979Srwatson switch (fp->f_type) { 3341100979Srwatson case DTYPE_FIFO: 3342100979Srwatson case DTYPE_VNODE: 3343105694Srwatson mac_init_vnode_label(&intlabel); 3344105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3345105694Srwatson if (error) { 3346105694Srwatson mac_destroy_vnode_label(&intlabel); 3347105694Srwatson break; 3348105694Srwatson } 3349105694Srwatson 3350100979Srwatson vp = (struct vnode *)fp->f_data; 3351100979Srwatson error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3352105694Srwatson if (error != 0) { 3353105694Srwatson mac_destroy_vnode_label(&intlabel); 3354100979Srwatson break; 3355105694Srwatson } 3356100979Srwatson 3357100979Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3358100979Srwatson error = vn_setlabel(vp, &intlabel, td->td_ucred); 3359100979Srwatson VOP_UNLOCK(vp, 0, td); 3360100979Srwatson vn_finished_write(mp); 3361105694Srwatson 3362105694Srwatson mac_destroy_vnode_label(&intlabel); 3363100979Srwatson break; 3364105694Srwatson 3365100979Srwatson case DTYPE_PIPE: 3366105694Srwatson mac_init_pipe_label(&intlabel); 3367105694Srwatson error = mac_internalize_pipe_label(&intlabel, buffer); 3368105694Srwatson if (error == 0) { 3369105694Srwatson pipe = (struct pipe *)fp->f_data; 3370105694Srwatson PIPE_LOCK(pipe); 3371105694Srwatson error = mac_pipe_label_set(td->td_ucred, pipe, 3372105694Srwatson &intlabel); 3373105694Srwatson PIPE_UNLOCK(pipe); 3374105694Srwatson } 3375105694Srwatson 3376105694Srwatson mac_destroy_pipe_label(&intlabel); 3377100979Srwatson break; 3378105694Srwatson 3379100979Srwatson default: 3380100979Srwatson error = EINVAL; 3381100979Srwatson } 3382100979Srwatson 3383100979Srwatson fdrop(fp, td); 3384105694Srwatsonout: 3385105694Srwatson mtx_unlock(&Giant); /* VFS */ 3386105694Srwatson 3387105694Srwatson free(buffer, M_MACTEMP); 3388105694Srwatson 3389100979Srwatson return (error); 3390100979Srwatson} 3391100979Srwatson 3392100979Srwatson/* 3393100979Srwatson * MPSAFE 3394100979Srwatson */ 3395100979Srwatsonint 3396100979Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3397100979Srwatson{ 3398105694Srwatson struct label intlabel; 3399100979Srwatson struct nameidata nd; 3400100979Srwatson struct mount *mp; 3401105694Srwatson struct mac mac; 3402105694Srwatson char *buffer; 3403100979Srwatson int error; 3404100979Srwatson 3405105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3406100979Srwatson if (error) 3407105694Srwatson return (error); 3408100979Srwatson 3409105694Srwatson error = mac_check_structmac_consistent(&mac); 3410100979Srwatson if (error) 3411105694Srwatson return (error); 3412100979Srwatson 3413105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3414105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3415105694Srwatson if (error) { 3416105694Srwatson free(buffer, M_MACTEMP); 3417105694Srwatson return (error); 3418105694Srwatson } 3419105694Srwatson 3420105694Srwatson mac_init_vnode_label(&intlabel); 3421105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3422105694Srwatson free(buffer, M_MACTEMP); 3423105694Srwatson if (error) { 3424105694Srwatson mac_destroy_vnode_label(&intlabel); 3425105694Srwatson return (error); 3426105694Srwatson } 3427105694Srwatson 3428105694Srwatson mtx_lock(&Giant); /* VFS */ 3429105694Srwatson 3430105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3431105694Srwatson td); 3432100979Srwatson error = namei(&nd); 3433105694Srwatson if (error == 0) { 3434105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3435105694Srwatson if (error == 0) 3436105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3437105694Srwatson td->td_ucred); 3438105694Srwatson vn_finished_write(mp); 3439105694Srwatson } 3440105694Srwatson 3441105694Srwatson NDFREE(&nd, 0); 3442105694Srwatson mtx_unlock(&Giant); /* VFS */ 3443105694Srwatson mac_destroy_vnode_label(&intlabel); 3444105694Srwatson 3445105694Srwatson return (error); 3446105694Srwatson} 3447105694Srwatson 3448105694Srwatson/* 3449105694Srwatson * MPSAFE 3450105694Srwatson */ 3451105694Srwatsonint 3452105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3453105694Srwatson{ 3454105694Srwatson struct label intlabel; 3455105694Srwatson struct nameidata nd; 3456105694Srwatson struct mount *mp; 3457105694Srwatson struct mac mac; 3458105694Srwatson char *buffer; 3459105694Srwatson int error; 3460105694Srwatson 3461105694Srwatson error = copyin(uap->mac_p, &mac, sizeof(mac)); 3462100979Srwatson if (error) 3463105694Srwatson return (error); 3464105694Srwatson 3465105694Srwatson error = mac_check_structmac_consistent(&mac); 3466100979Srwatson if (error) 3467105694Srwatson return (error); 3468100979Srwatson 3469105694Srwatson buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3470105694Srwatson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3471105694Srwatson if (error) { 3472105694Srwatson free(buffer, M_MACTEMP); 3473105694Srwatson return (error); 3474105694Srwatson } 3475105694Srwatson 3476105694Srwatson mac_init_vnode_label(&intlabel); 3477105694Srwatson error = mac_internalize_vnode_label(&intlabel, buffer); 3478105694Srwatson free(buffer, M_MACTEMP); 3479105694Srwatson if (error) { 3480105694Srwatson mac_destroy_vnode_label(&intlabel); 3481105694Srwatson return (error); 3482105694Srwatson } 3483105694Srwatson 3484105694Srwatson mtx_lock(&Giant); /* VFS */ 3485105694Srwatson 3486105694Srwatson NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3487105694Srwatson td); 3488105694Srwatson error = namei(&nd); 3489105694Srwatson if (error == 0) { 3490105694Srwatson error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3491105694Srwatson if (error == 0) 3492105694Srwatson error = vn_setlabel(nd.ni_vp, &intlabel, 3493105694Srwatson td->td_ucred); 3494105694Srwatson vn_finished_write(mp); 3495105694Srwatson } 3496105694Srwatson 3497100979Srwatson NDFREE(&nd, 0); 3498105694Srwatson mtx_unlock(&Giant); /* VFS */ 3499105694Srwatson mac_destroy_vnode_label(&intlabel); 3500105694Srwatson 3501100979Srwatson return (error); 3502100979Srwatson} 3503100979Srwatson 3504105694Srwatson/* 3505105694Srwatson * MPSAFE 3506105694Srwatson */ 3507102123Srwatsonint 3508102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3509102123Srwatson{ 3510102123Srwatson struct mac_policy_conf *mpc; 3511102123Srwatson char target[MAC_MAX_POLICY_NAME]; 3512102123Srwatson int error; 3513102123Srwatson 3514102123Srwatson error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3515102123Srwatson if (error) 3516102123Srwatson return (error); 3517102123Srwatson 3518102123Srwatson error = ENOSYS; 3519102123Srwatson MAC_POLICY_LIST_BUSY(); 3520102123Srwatson LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3521102123Srwatson if (strcmp(mpc->mpc_name, target) == 0 && 3522102123Srwatson mpc->mpc_ops->mpo_syscall != NULL) { 3523102123Srwatson error = mpc->mpc_ops->mpo_syscall(td, 3524102123Srwatson SCARG(uap, call), SCARG(uap, arg)); 3525102123Srwatson goto out; 3526102123Srwatson } 3527102123Srwatson } 3528102123Srwatson 3529102123Srwatsonout: 3530102123Srwatson MAC_POLICY_LIST_UNBUSY(); 3531102123Srwatson return (error); 3532102123Srwatson} 3533102123Srwatson 3534100979SrwatsonSYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3535100979SrwatsonSYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3536100979Srwatson 3537100979Srwatson#else /* !MAC */ 3538100979Srwatson 3539100979Srwatsonint 3540105694Srwatson__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3541105694Srwatson{ 3542105694Srwatson 3543105694Srwatson return (ENOSYS); 3544105694Srwatson} 3545105694Srwatson 3546105694Srwatsonint 3547100979Srwatson__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3548100979Srwatson{ 3549100979Srwatson 3550100894Srwatson return (ENOSYS); 3551100894Srwatson} 3552100894Srwatson 3553100894Srwatsonint 3554100894Srwatson__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3555100894Srwatson{ 3556100894Srwatson 3557100894Srwatson return (ENOSYS); 3558100894Srwatson} 3559100894Srwatson 3560100894Srwatsonint 3561100894Srwatson__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3562100894Srwatson{ 3563100894Srwatson 3564100894Srwatson return (ENOSYS); 3565100894Srwatson} 3566100894Srwatson 3567100894Srwatsonint 3568100894Srwatson__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3569100894Srwatson{ 3570100894Srwatson 3571100894Srwatson return (ENOSYS); 3572100894Srwatson} 3573100894Srwatson 3574100894Srwatsonint 3575105694Srwatson__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3576105694Srwatson{ 3577105694Srwatson 3578105694Srwatson return (ENOSYS); 3579105694Srwatson} 3580105694Srwatson 3581105694Srwatsonint 3582100894Srwatson__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3583100894Srwatson{ 3584100894Srwatson 3585100894Srwatson return (ENOSYS); 3586100894Srwatson} 3587100894Srwatson 3588100894Srwatsonint 3589100894Srwatson__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3590100894Srwatson{ 3591100894Srwatson 3592100894Srwatson return (ENOSYS); 3593100894Srwatson} 3594100979Srwatson 3595102123Srwatsonint 3596105694Srwatson__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3597105694Srwatson{ 3598105694Srwatson 3599105694Srwatson return (ENOSYS); 3600105694Srwatson} 3601105694Srwatson 3602105694Srwatsonint 3603102123Srwatsonmac_syscall(struct thread *td, struct mac_syscall_args *uap) 3604102123Srwatson{ 3605102123Srwatson 3606102123Srwatson return (ENOSYS); 3607102123Srwatson} 3608102123Srwatson 3609105694Srwatson#endif 3610