mac_internal.h revision 111939
1219820Sjeff/*- 2219820Sjeff * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3219820Sjeff * Copyright (c) 2001 Ilmar S. Habibulin 4219820Sjeff * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 5219820Sjeff * All rights reserved. 6219820Sjeff * 7219820Sjeff * This software was developed by Robert Watson and Ilmar Habibulin for the 8219820Sjeff * TrustedBSD Project. 9219820Sjeff * 10219820Sjeff * This software was developed for the FreeBSD Project in part by Network 11219820Sjeff * Associates Laboratories, the Security Research Division of Network 12219820Sjeff * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 13219820Sjeff * as part of the DARPA CHATS research program. 14219820Sjeff * 15219820Sjeff * Redistribution and use in source and binary forms, with or without 16219820Sjeff * modification, are permitted provided that the following conditions 17219820Sjeff * are met: 18219820Sjeff * 1. Redistributions of source code must retain the above copyright 19219820Sjeff * notice, this list of conditions and the following disclaimer. 20219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 21219820Sjeff * notice, this list of conditions and the following disclaimer in the 22219820Sjeff * documentation and/or other materials provided with the distribution. 23219820Sjeff * 24219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25219820Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26219820Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27219820Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28219820Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33219820Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34219820Sjeff * SUCH DAMAGE. 35219820Sjeff * 36219820Sjeff * $FreeBSD: head/sys/security/mac/mac_internal.h 111939 2003-03-06 04:47:47Z rwatson $ 37272027Shselasky */ 38219820Sjeff/* 39219820Sjeff * Developed by the TrustedBSD Project. 40219820Sjeff * 41219820Sjeff * Framework for extensible kernel access control. Kernel and userland 42219820Sjeff * interface to the framework, policy registration and composition. 43219820Sjeff */ 44219820Sjeff 45219820Sjeff#include "opt_mac.h" 46219820Sjeff#include "opt_devfs.h" 47219820Sjeff 48219820Sjeff#include <sys/param.h> 49219820Sjeff#include <sys/condvar.h> 50219820Sjeff#include <sys/extattr.h> 51219820Sjeff#include <sys/imgact.h> 52219820Sjeff#include <sys/kernel.h> 53219820Sjeff#include <sys/lock.h> 54219820Sjeff#include <sys/malloc.h> 55219820Sjeff#include <sys/mutex.h> 56219820Sjeff#include <sys/mac.h> 57219820Sjeff#include <sys/module.h> 58219820Sjeff#include <sys/proc.h> 59219820Sjeff#include <sys/systm.h> 60219820Sjeff#include <sys/sysproto.h> 61219820Sjeff#include <sys/sysent.h> 62219820Sjeff#include <sys/vnode.h> 63255932Salfred#include <sys/mount.h> 64219820Sjeff#include <sys/file.h> 65219820Sjeff#include <sys/namei.h> 66219820Sjeff#include <sys/socket.h> 67219820Sjeff#include <sys/pipe.h> 68219820Sjeff#include <sys/socketvar.h> 69219820Sjeff#include <sys/sysctl.h> 70255932Salfred 71255932Salfred#include <vm/vm.h> 72255932Salfred#include <vm/pmap.h> 73219820Sjeff#include <vm/vm_map.h> 74219820Sjeff#include <vm/vm_object.h> 75219820Sjeff 76219820Sjeff#include <sys/mac_policy.h> 77219820Sjeff 78219820Sjeff#include <fs/devfs/devfs.h> 79219820Sjeff 80219820Sjeff#include <net/bpfdesc.h> 81219820Sjeff#include <net/if.h> 82219820Sjeff#include <net/if_var.h> 83219820Sjeff 84219820Sjeff#include <netinet/in.h> 85219820Sjeff#include <netinet/ip_var.h> 86219820Sjeff 87219820Sjeff#ifdef MAC 88219820Sjeff 89219820Sjeff/* 90219820Sjeff * Declare that the kernel provides MAC support, version 1. This permits 91219820Sjeff * modules to refuse to be loaded if the necessary support isn't present, 92219820Sjeff * even if it's pre-boot. 93219820Sjeff */ 94219820SjeffMODULE_VERSION(kernel_mac_support, 1); 95219820Sjeff 96219820SjeffSYSCTL_DECL(_security); 97219820Sjeff 98219820SjeffSYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 99219820Sjeff "TrustedBSD MAC policy controls"); 100219820Sjeff 101219820Sjeff#if MAC_MAX_POLICIES > 32 102219820Sjeff#error "MAC_MAX_POLICIES too large" 103219820Sjeff#endif 104219820Sjeff 105219820Sjeffstatic unsigned int mac_max_policies = MAC_MAX_POLICIES; 106219820Sjeffstatic unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 107219820SjeffSYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 108219820Sjeff &mac_max_policies, 0, ""); 109219820Sjeff 110219820Sjeff/* 111219820Sjeff * Has the kernel started generating labeled objects yet? All read/write 112219820Sjeff * access to this variable is serialized during the boot process. Following 113219820Sjeff * the end of serialization, we don't update this flag; no locking. 114219820Sjeff */ 115272027Shselaskystatic int mac_late = 0; 116219820Sjeff 117219820Sjeff/* 118219820Sjeff * Warn about EA transactions only the first time they happen. 119219820Sjeff * Weak coherency, no locking. 120219820Sjeff */ 121219820Sjeffstatic int ea_warn_once = 0; 122219820Sjeff 123219820Sjeffstatic int mac_enforce_fs = 1; 124219820SjeffSYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 125219820Sjeff &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 126219820SjeffTUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 127219820Sjeff 128255932Salfredstatic int mac_enforce_kld = 1; 129255932SalfredSYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW, 130219820Sjeff &mac_enforce_kld, 0, "Enforce MAC policy on kld operations"); 131255932SalfredTUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld); 132255932Salfred 133255932Salfredstatic int mac_enforce_network = 1; 134255932SalfredSYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 135255932Salfred &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 136255932SalfredTUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 137255932Salfred 138255932Salfredstatic int mac_enforce_pipe = 1; 139255932SalfredSYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 140255932Salfred &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 141255932SalfredTUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 142255932Salfred 143255932Salfredstatic int mac_enforce_process = 1; 144255932SalfredSYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 145255932Salfred &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 146255932SalfredTUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 147255932Salfred 148255932Salfredstatic int mac_enforce_socket = 1; 149219820SjeffSYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 150219820Sjeff &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 151219820SjeffTUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 152219820Sjeff 153219820Sjeffstatic int mac_enforce_system = 1; 154219820SjeffSYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 155219820Sjeff &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 156255932SalfredTUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 157255932Salfred 158255932Salfredstatic int mac_enforce_vm = 1; 159255932SalfredSYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 160255932Salfred &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 161219820SjeffTUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 162219820Sjeff 163219820Sjeffstatic int mac_mmap_revocation = 1; 164255932SalfredSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 165255932Salfred &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 166255932Salfred "relabel"); 167219820Sjeffstatic int mac_mmap_revocation_via_cow = 0; 168219820SjeffSYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 169219820Sjeff &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 170255932Salfred "copy-on-write semantics, or by removing all write access"); 171255932Salfred 172219820Sjeff#ifdef MAC_DEBUG 173219820SjeffSYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 174219820Sjeff "TrustedBSD MAC debug info"); 175219820Sjeff 176272027Shselaskystatic int mac_debug_label_fallback = 0; 177272027ShselaskySYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 178272027Shselasky &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 179272027Shselasky "when label is corrupted."); 180272027ShselaskyTUNABLE_INT("security.mac.debug_label_fallback", 181272027Shselasky &mac_debug_label_fallback); 182272027Shselasky 183272027ShselaskySYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 184219820Sjeff "TrustedBSD MAC object counters"); 185219820Sjeff 186255932Salfredstatic unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 187255932Salfred nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 188255932Salfred nmacipqs, nmacpipes, nmacprocs; 189255932Salfred 190255932SalfredSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 191219820Sjeff &nmacmbufs, 0, "number of mbufs in use"); 192219820SjeffSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 193219820Sjeff &nmaccreds, 0, "number of ucreds in use"); 194219820SjeffSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 195219820Sjeff &nmacifnets, 0, "number of ifnets in use"); 196219820SjeffSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 197219820Sjeff &nmacipqs, 0, "number of ipqs in use"); 198219820SjeffSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 199219820Sjeff &nmacbpfdescs, 0, "number of bpfdescs in use"); 200255932SalfredSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 201219820Sjeff &nmacsockets, 0, "number of sockets in use"); 202219820SjeffSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 203219820Sjeff &nmacpipes, 0, "number of pipes in use"); 204255932SalfredSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, procs, CTLFLAG_RD, 205255932Salfred &nmacprocs, 0, "number of procs in use"); 206219820SjeffSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 207219820Sjeff &nmacmounts, 0, "number of mounts in use"); 208255932SalfredSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 209219820Sjeff &nmactemp, 0, "number of temporary labels in use"); 210219820SjeffSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 211219820Sjeff &nmacvnodes, 0, "number of vnodes in use"); 212219820SjeffSYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 213219820Sjeff &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 214255932Salfred#endif 215219820Sjeff 216219820Sjeffstatic int error_select(int error1, int error2); 217255932Salfredstatic int mac_policy_register(struct mac_policy_conf *mpc); 218219820Sjeffstatic int mac_policy_unregister(struct mac_policy_conf *mpc); 219219820Sjeff 220219820Sjeffstatic void mac_check_vnode_mmap_downgrade(struct ucred *cred, 221219820Sjeff struct vnode *vp, int *prot); 222219820Sjeffstatic void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 223219820Sjeff struct ucred *cred, struct vm_map *map); 224219820Sjeff 225219820Sjeffstatic void mac_destroy_socket_label(struct label *label); 226219820Sjeff 227255932Salfredstatic int mac_setlabel_vnode_extattr(struct ucred *cred, 228219820Sjeff struct vnode *vp, struct label *intlabel); 229219820Sjeff 230255932SalfredMALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 231219820SjeffMALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 232219820Sjeff 233219820Sjeff/* 234219820Sjeff * mac_policy_list stores the list of active policies. A busy count is 235219820Sjeff * maintained for the list, stored in mac_policy_busy. The busy count 236255932Salfred * is protected by mac_policy_list_lock; the list may be modified only 237255932Salfred * while the busy count is 0, requiring that the lock be held to 238255932Salfred * prevent new references to the list from being acquired. For almost 239255932Salfred * all operations, incrementing the busy count is sufficient to 240272027Shselasky * guarantee consistency, as the list cannot be modified while the 241272027Shselasky * busy count is elevated. For a few special operations involving a 242272027Shselasky * change to the list of active policies, the lock itself must be held. 243272027Shselasky * A condition variable, mac_policy_list_not_busy, is used to signal 244272027Shselasky * potential exclusive consumers that they should try to acquire the 245272027Shselasky * lock if a first attempt at exclusive access fails. 246272027Shselasky */ 247272027Shselaskystatic struct mtx mac_policy_list_lock; 248255932Salfredstatic struct cv mac_policy_list_not_busy; 249272027Shselaskystatic LIST_HEAD(, mac_policy_conf) mac_policy_list; 250272027Shselaskystatic int mac_policy_list_busy; 251272027Shselasky 252272027Shselasky#define MAC_POLICY_LIST_LOCKINIT() do { \ 253272027Shselasky mtx_init(&mac_policy_list_lock, "mac_policy_list_lock", NULL, \ 254272027Shselasky MTX_DEF); \ 255255932Salfred cv_init(&mac_policy_list_not_busy, "mac_policy_list_not_busy"); \ 256255932Salfred} while (0) 257255932Salfred 258219820Sjeff#define MAC_POLICY_LIST_LOCK() do { \ 259 mtx_lock(&mac_policy_list_lock); \ 260} while (0) 261 262#define MAC_POLICY_LIST_UNLOCK() do { \ 263 mtx_unlock(&mac_policy_list_lock); \ 264} while (0) 265 266/* 267 * We manually invoke WITNESS_WARN() to allow Witness to generate 268 * warnings even if we don't end up ever triggering the wait at 269 * run-time. The consumer of the exclusive interface must not hold 270 * any locks (other than potentially Giant) since we may sleep for 271 * long (potentially indefinite) periods of time waiting for the 272 * framework to become quiescent so that a policy list change may 273 * be made. 274 */ 275#define MAC_POLICY_LIST_EXCLUSIVE() do { \ 276 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, \ 277 "mac_policy_list_exclusive() at %s:%d", __FILE__, __LINE__);\ 278 mtx_lock(&mac_policy_list_lock); \ 279 while (mac_policy_list_busy != 0) \ 280 cv_wait(&mac_policy_list_not_busy, \ 281 &mac_policy_list_lock); \ 282} while (0) 283 284#define MAC_POLICY_LIST_BUSY() do { \ 285 MAC_POLICY_LIST_LOCK(); \ 286 mac_policy_list_busy++; \ 287 MAC_POLICY_LIST_UNLOCK(); \ 288} while (0) 289 290#define MAC_POLICY_LIST_UNBUSY() do { \ 291 MAC_POLICY_LIST_LOCK(); \ 292 mac_policy_list_busy--; \ 293 KASSERT(mac_policy_list_busy >= 0, ("MAC_POLICY_LIST_LOCK")); \ 294 if (mac_policy_list_busy == 0) \ 295 cv_signal(&mac_policy_list_not_busy); \ 296 MAC_POLICY_LIST_UNLOCK(); \ 297} while (0) 298 299/* 300 * MAC_CHECK performs the designated check by walking the policy 301 * module list and checking with each as to how it feels about the 302 * request. Note that it returns its value via 'error' in the scope 303 * of the caller. 304 */ 305#define MAC_CHECK(check, args...) do { \ 306 struct mac_policy_conf *mpc; \ 307 \ 308 error = 0; \ 309 MAC_POLICY_LIST_BUSY(); \ 310 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 311 if (mpc->mpc_ops->mpo_ ## check != NULL) \ 312 error = error_select( \ 313 mpc->mpc_ops->mpo_ ## check (args), \ 314 error); \ 315 } \ 316 MAC_POLICY_LIST_UNBUSY(); \ 317} while (0) 318 319/* 320 * MAC_BOOLEAN performs the designated boolean composition by walking 321 * the module list, invoking each instance of the operation, and 322 * combining the results using the passed C operator. Note that it 323 * returns its value via 'result' in the scope of the caller, which 324 * should be initialized by the caller in a meaningful way to get 325 * a meaningful result. 326 */ 327#define MAC_BOOLEAN(operation, composition, args...) do { \ 328 struct mac_policy_conf *mpc; \ 329 \ 330 MAC_POLICY_LIST_BUSY(); \ 331 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 332 if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 333 result = result composition \ 334 mpc->mpc_ops->mpo_ ## operation (args); \ 335 } \ 336 MAC_POLICY_LIST_UNBUSY(); \ 337} while (0) 338 339#define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 340 outbuflen) do { \ 341 char *curptr, *curptr_start, *element_name, *element_temp; \ 342 size_t left, left_start, len; \ 343 int claimed, first, first_start, ignorenotfound; \ 344 \ 345 error = 0; \ 346 element_temp = elementlist; \ 347 curptr = outbuf; \ 348 curptr[0] = '\0'; \ 349 left = outbuflen; \ 350 first = 1; \ 351 while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 352 curptr_start = curptr; \ 353 left_start = left; \ 354 first_start = first; \ 355 if (element_name[0] == '?') { \ 356 element_name++; \ 357 ignorenotfound = 1; \ 358 } else \ 359 ignorenotfound = 0; \ 360 claimed = 0; \ 361 if (first) { \ 362 len = snprintf(curptr, left, "%s/", \ 363 element_name); \ 364 first = 0; \ 365 } else \ 366 len = snprintf(curptr, left, ",%s/", \ 367 element_name); \ 368 if (len >= left) { \ 369 error = EINVAL; /* XXXMAC: E2BIG */ \ 370 break; \ 371 } \ 372 curptr += len; \ 373 left -= len; \ 374 \ 375 MAC_CHECK(externalize_ ## type, label, element_name, \ 376 curptr, left, &len, &claimed); \ 377 if (error) \ 378 break; \ 379 if (claimed == 1) { \ 380 if (len >= outbuflen) { \ 381 error = EINVAL; /* XXXMAC: E2BIG */ \ 382 break; \ 383 } \ 384 curptr += len; \ 385 left -= len; \ 386 } else if (claimed == 0 && ignorenotfound) { \ 387 /* \ 388 * Revert addition of the label element \ 389 * name. \ 390 */ \ 391 curptr = curptr_start; \ 392 *curptr = '\0'; \ 393 left = left_start; \ 394 first = first_start; \ 395 } else { \ 396 error = EINVAL; /* XXXMAC: ENOLABEL */ \ 397 break; \ 398 } \ 399 } \ 400} while (0) 401 402#define MAC_INTERNALIZE(type, label, instring) do { \ 403 char *element, *element_name, *element_data; \ 404 int claimed; \ 405 \ 406 error = 0; \ 407 element = instring; \ 408 while ((element_name = strsep(&element, ",")) != NULL) { \ 409 element_data = element_name; \ 410 element_name = strsep(&element_data, "/"); \ 411 if (element_data == NULL) { \ 412 error = EINVAL; \ 413 break; \ 414 } \ 415 claimed = 0; \ 416 MAC_CHECK(internalize_ ## type, label, element_name, \ 417 element_data, &claimed); \ 418 if (error) \ 419 break; \ 420 if (claimed != 1) { \ 421 /* XXXMAC: Another error here? */ \ 422 error = EINVAL; \ 423 break; \ 424 } \ 425 } \ 426} while (0) 427 428/* 429 * MAC_PERFORM performs the designated operation by walking the policy 430 * module list and invoking that operation for each policy. 431 */ 432#define MAC_PERFORM(operation, args...) do { \ 433 struct mac_policy_conf *mpc; \ 434 \ 435 MAC_POLICY_LIST_BUSY(); \ 436 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 437 if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 438 mpc->mpc_ops->mpo_ ## operation (args); \ 439 } \ 440 MAC_POLICY_LIST_UNBUSY(); \ 441} while (0) 442 443/* 444 * Initialize the MAC subsystem, including appropriate SMP locks. 445 */ 446static void 447mac_init(void) 448{ 449 450 LIST_INIT(&mac_policy_list); 451 MAC_POLICY_LIST_LOCKINIT(); 452} 453 454/* 455 * For the purposes of modules that want to know if they were loaded 456 * "early", set the mac_late flag once we've processed modules either 457 * linked into the kernel, or loaded before the kernel startup. 458 */ 459static void 460mac_late_init(void) 461{ 462 463 mac_late = 1; 464} 465 466/* 467 * Allow MAC policy modules to register during boot, etc. 468 */ 469int 470mac_policy_modevent(module_t mod, int type, void *data) 471{ 472 struct mac_policy_conf *mpc; 473 int error; 474 475 error = 0; 476 mpc = (struct mac_policy_conf *) data; 477 478 switch (type) { 479 case MOD_LOAD: 480 if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 481 mac_late) { 482 printf("mac_policy_modevent: can't load %s policy " 483 "after booting\n", mpc->mpc_name); 484 error = EBUSY; 485 break; 486 } 487 error = mac_policy_register(mpc); 488 break; 489 case MOD_UNLOAD: 490 /* Don't unregister the module if it was never registered. */ 491 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 492 != 0) 493 error = mac_policy_unregister(mpc); 494 else 495 error = 0; 496 break; 497 default: 498 break; 499 } 500 501 return (error); 502} 503 504static int 505mac_policy_register(struct mac_policy_conf *mpc) 506{ 507 struct mac_policy_conf *tmpc; 508 int slot; 509 510 MAC_POLICY_LIST_EXCLUSIVE(); 511 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 512 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 513 MAC_POLICY_LIST_UNLOCK(); 514 return (EEXIST); 515 } 516 } 517 if (mpc->mpc_field_off != NULL) { 518 slot = ffs(mac_policy_offsets_free); 519 if (slot == 0) { 520 MAC_POLICY_LIST_UNLOCK(); 521 return (ENOMEM); 522 } 523 slot--; 524 mac_policy_offsets_free &= ~(1 << slot); 525 *mpc->mpc_field_off = slot; 526 } 527 mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 528 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 529 530 /* Per-policy initialization. */ 531 if (mpc->mpc_ops->mpo_init != NULL) 532 (*(mpc->mpc_ops->mpo_init))(mpc); 533 MAC_POLICY_LIST_UNLOCK(); 534 535 printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 536 mpc->mpc_name); 537 538 return (0); 539} 540 541static int 542mac_policy_unregister(struct mac_policy_conf *mpc) 543{ 544 545 /* 546 * If we fail the load, we may get a request to unload. Check 547 * to see if we did the run-time registration, and if not, 548 * silently succeed. 549 */ 550 MAC_POLICY_LIST_EXCLUSIVE(); 551 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 552 MAC_POLICY_LIST_UNLOCK(); 553 return (0); 554 } 555#if 0 556 /* 557 * Don't allow unloading modules with private data. 558 */ 559 if (mpc->mpc_field_off != NULL) { 560 MAC_POLICY_LIST_UNLOCK(); 561 return (EBUSY); 562 } 563#endif 564 /* 565 * Only allow the unload to proceed if the module is unloadable 566 * by its own definition. 567 */ 568 if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 569 MAC_POLICY_LIST_UNLOCK(); 570 return (EBUSY); 571 } 572 if (mpc->mpc_ops->mpo_destroy != NULL) 573 (*(mpc->mpc_ops->mpo_destroy))(mpc); 574 575 LIST_REMOVE(mpc, mpc_list); 576 mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 577 578 MAC_POLICY_LIST_UNLOCK(); 579 580 printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 581 mpc->mpc_name); 582 583 return (0); 584} 585 586/* 587 * Define an error value precedence, and given two arguments, selects the 588 * value with the higher precedence. 589 */ 590static int 591error_select(int error1, int error2) 592{ 593 594 /* Certain decision-making errors take top priority. */ 595 if (error1 == EDEADLK || error2 == EDEADLK) 596 return (EDEADLK); 597 598 /* Invalid arguments should be reported where possible. */ 599 if (error1 == EINVAL || error2 == EINVAL) 600 return (EINVAL); 601 602 /* Precedence goes to "visibility", with both process and file. */ 603 if (error1 == ESRCH || error2 == ESRCH) 604 return (ESRCH); 605 606 if (error1 == ENOENT || error2 == ENOENT) 607 return (ENOENT); 608 609 /* Precedence goes to DAC/MAC protections. */ 610 if (error1 == EACCES || error2 == EACCES) 611 return (EACCES); 612 613 /* Precedence goes to privilege. */ 614 if (error1 == EPERM || error2 == EPERM) 615 return (EPERM); 616 617 /* Precedence goes to error over success; otherwise, arbitrary. */ 618 if (error1 != 0) 619 return (error1); 620 return (error2); 621} 622 623static void 624mac_init_label(struct label *label) 625{ 626 627 bzero(label, sizeof(*label)); 628 label->l_flags = MAC_FLAG_INITIALIZED; 629} 630 631static void 632mac_destroy_label(struct label *label) 633{ 634 635 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 636 ("destroying uninitialized label")); 637 638 bzero(label, sizeof(*label)); 639 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 640} 641 642void 643mac_init_bpfdesc(struct bpf_d *bpf_d) 644{ 645 646 mac_init_label(&bpf_d->bd_label); 647 MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 648#ifdef MAC_DEBUG 649 atomic_add_int(&nmacbpfdescs, 1); 650#endif 651} 652 653static void 654mac_init_cred_label(struct label *label) 655{ 656 657 mac_init_label(label); 658 MAC_PERFORM(init_cred_label, label); 659#ifdef MAC_DEBUG 660 atomic_add_int(&nmaccreds, 1); 661#endif 662} 663 664void 665mac_init_cred(struct ucred *cred) 666{ 667 668 mac_init_cred_label(&cred->cr_label); 669} 670 671void 672mac_init_devfsdirent(struct devfs_dirent *de) 673{ 674 675 mac_init_label(&de->de_label); 676 MAC_PERFORM(init_devfsdirent_label, &de->de_label); 677#ifdef MAC_DEBUG 678 atomic_add_int(&nmacdevfsdirents, 1); 679#endif 680} 681 682static void 683mac_init_ifnet_label(struct label *label) 684{ 685 686 mac_init_label(label); 687 MAC_PERFORM(init_ifnet_label, label); 688#ifdef MAC_DEBUG 689 atomic_add_int(&nmacifnets, 1); 690#endif 691} 692 693void 694mac_init_ifnet(struct ifnet *ifp) 695{ 696 697 mac_init_ifnet_label(&ifp->if_label); 698} 699 700void 701mac_init_ipq(struct ipq *ipq) 702{ 703 704 mac_init_label(&ipq->ipq_label); 705 MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 706#ifdef MAC_DEBUG 707 atomic_add_int(&nmacipqs, 1); 708#endif 709} 710 711int 712mac_init_mbuf(struct mbuf *m, int flag) 713{ 714 int error; 715 716 KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 717 718 mac_init_label(&m->m_pkthdr.label); 719 720 MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 721 if (error) { 722 MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 723 mac_destroy_label(&m->m_pkthdr.label); 724 } 725 726#ifdef MAC_DEBUG 727 if (error == 0) 728 atomic_add_int(&nmacmbufs, 1); 729#endif 730 return (error); 731} 732 733void 734mac_init_mount(struct mount *mp) 735{ 736 737 mac_init_label(&mp->mnt_mntlabel); 738 mac_init_label(&mp->mnt_fslabel); 739 MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 740 MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 741#ifdef MAC_DEBUG 742 atomic_add_int(&nmacmounts, 1); 743#endif 744} 745 746static void 747mac_init_pipe_label(struct label *label) 748{ 749 750 mac_init_label(label); 751 MAC_PERFORM(init_pipe_label, label); 752#ifdef MAC_DEBUG 753 atomic_add_int(&nmacpipes, 1); 754#endif 755} 756 757void 758mac_init_pipe(struct pipe *pipe) 759{ 760 struct label *label; 761 762 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 763 pipe->pipe_label = label; 764 pipe->pipe_peer->pipe_label = label; 765 mac_init_pipe_label(label); 766} 767 768void 769mac_init_proc(struct proc *p) 770{ 771 772 mac_init_label(&p->p_label); 773 MAC_PERFORM(init_proc_label, &p->p_label); 774#ifdef MAC_DEBUG 775 atomic_add_int(&nmacprocs, 1); 776#endif 777} 778 779static int 780mac_init_socket_label(struct label *label, int flag) 781{ 782 int error; 783 784 mac_init_label(label); 785 786 MAC_CHECK(init_socket_label, label, flag); 787 if (error) { 788 MAC_PERFORM(destroy_socket_label, label); 789 mac_destroy_label(label); 790 } 791 792#ifdef MAC_DEBUG 793 if (error == 0) 794 atomic_add_int(&nmacsockets, 1); 795#endif 796 797 return (error); 798} 799 800static int 801mac_init_socket_peer_label(struct label *label, int flag) 802{ 803 int error; 804 805 mac_init_label(label); 806 807 MAC_CHECK(init_socket_peer_label, label, flag); 808 if (error) { 809 MAC_PERFORM(destroy_socket_label, label); 810 mac_destroy_label(label); 811 } 812 813 return (error); 814} 815 816int 817mac_init_socket(struct socket *socket, int flag) 818{ 819 int error; 820 821 error = mac_init_socket_label(&socket->so_label, flag); 822 if (error) 823 return (error); 824 825 error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 826 if (error) 827 mac_destroy_socket_label(&socket->so_label); 828 829 return (error); 830} 831 832void 833mac_init_vnode_label(struct label *label) 834{ 835 836 mac_init_label(label); 837 MAC_PERFORM(init_vnode_label, label); 838#ifdef MAC_DEBUG 839 atomic_add_int(&nmacvnodes, 1); 840#endif 841} 842 843void 844mac_init_vnode(struct vnode *vp) 845{ 846 847 mac_init_vnode_label(&vp->v_label); 848} 849 850void 851mac_destroy_bpfdesc(struct bpf_d *bpf_d) 852{ 853 854 MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 855 mac_destroy_label(&bpf_d->bd_label); 856#ifdef MAC_DEBUG 857 atomic_subtract_int(&nmacbpfdescs, 1); 858#endif 859} 860 861static void 862mac_destroy_cred_label(struct label *label) 863{ 864 865 MAC_PERFORM(destroy_cred_label, label); 866 mac_destroy_label(label); 867#ifdef MAC_DEBUG 868 atomic_subtract_int(&nmaccreds, 1); 869#endif 870} 871 872void 873mac_destroy_cred(struct ucred *cred) 874{ 875 876 mac_destroy_cred_label(&cred->cr_label); 877} 878 879void 880mac_destroy_devfsdirent(struct devfs_dirent *de) 881{ 882 883 MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 884 mac_destroy_label(&de->de_label); 885#ifdef MAC_DEBUG 886 atomic_subtract_int(&nmacdevfsdirents, 1); 887#endif 888} 889 890static void 891mac_destroy_ifnet_label(struct label *label) 892{ 893 894 MAC_PERFORM(destroy_ifnet_label, label); 895 mac_destroy_label(label); 896#ifdef MAC_DEBUG 897 atomic_subtract_int(&nmacifnets, 1); 898#endif 899} 900 901void 902mac_destroy_ifnet(struct ifnet *ifp) 903{ 904 905 mac_destroy_ifnet_label(&ifp->if_label); 906} 907 908void 909mac_destroy_ipq(struct ipq *ipq) 910{ 911 912 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 913 mac_destroy_label(&ipq->ipq_label); 914#ifdef MAC_DEBUG 915 atomic_subtract_int(&nmacipqs, 1); 916#endif 917} 918 919void 920mac_destroy_mbuf(struct mbuf *m) 921{ 922 923 MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 924 mac_destroy_label(&m->m_pkthdr.label); 925#ifdef MAC_DEBUG 926 atomic_subtract_int(&nmacmbufs, 1); 927#endif 928} 929 930void 931mac_destroy_mount(struct mount *mp) 932{ 933 934 MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 935 MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 936 mac_destroy_label(&mp->mnt_fslabel); 937 mac_destroy_label(&mp->mnt_mntlabel); 938#ifdef MAC_DEBUG 939 atomic_subtract_int(&nmacmounts, 1); 940#endif 941} 942 943static void 944mac_destroy_pipe_label(struct label *label) 945{ 946 947 MAC_PERFORM(destroy_pipe_label, label); 948 mac_destroy_label(label); 949#ifdef MAC_DEBUG 950 atomic_subtract_int(&nmacpipes, 1); 951#endif 952} 953 954void 955mac_destroy_pipe(struct pipe *pipe) 956{ 957 958 mac_destroy_pipe_label(pipe->pipe_label); 959 free(pipe->pipe_label, M_MACPIPELABEL); 960} 961 962void 963mac_destroy_proc(struct proc *p) 964{ 965 966 MAC_PERFORM(destroy_proc_label, &p->p_label); 967 mac_destroy_label(&p->p_label); 968#ifdef MAC_DEBUG 969 atomic_subtract_int(&nmacprocs, 1); 970#endif 971} 972 973static void 974mac_destroy_socket_label(struct label *label) 975{ 976 977 MAC_PERFORM(destroy_socket_label, label); 978 mac_destroy_label(label); 979#ifdef MAC_DEBUG 980 atomic_subtract_int(&nmacsockets, 1); 981#endif 982} 983 984static void 985mac_destroy_socket_peer_label(struct label *label) 986{ 987 988 MAC_PERFORM(destroy_socket_peer_label, label); 989 mac_destroy_label(label); 990} 991 992void 993mac_destroy_socket(struct socket *socket) 994{ 995 996 mac_destroy_socket_label(&socket->so_label); 997 mac_destroy_socket_peer_label(&socket->so_peerlabel); 998} 999 1000void 1001mac_destroy_vnode_label(struct label *label) 1002{ 1003 1004 MAC_PERFORM(destroy_vnode_label, label); 1005 mac_destroy_label(label); 1006#ifdef MAC_DEBUG 1007 atomic_subtract_int(&nmacvnodes, 1); 1008#endif 1009} 1010 1011void 1012mac_destroy_vnode(struct vnode *vp) 1013{ 1014 1015 mac_destroy_vnode_label(&vp->v_label); 1016} 1017 1018static void 1019mac_copy_pipe_label(struct label *src, struct label *dest) 1020{ 1021 1022 MAC_PERFORM(copy_pipe_label, src, dest); 1023} 1024 1025void 1026mac_copy_vnode_label(struct label *src, struct label *dest) 1027{ 1028 1029 MAC_PERFORM(copy_vnode_label, src, dest); 1030} 1031 1032static int 1033mac_check_structmac_consistent(struct mac *mac) 1034{ 1035 1036 if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1037 return (EINVAL); 1038 1039 return (0); 1040} 1041 1042static int 1043mac_externalize_cred_label(struct label *label, char *elements, 1044 char *outbuf, size_t outbuflen, int flags) 1045{ 1046 int error; 1047 1048 MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1049 1050 return (error); 1051} 1052 1053static int 1054mac_externalize_ifnet_label(struct label *label, char *elements, 1055 char *outbuf, size_t outbuflen, int flags) 1056{ 1057 int error; 1058 1059 MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1060 1061 return (error); 1062} 1063 1064static int 1065mac_externalize_pipe_label(struct label *label, char *elements, 1066 char *outbuf, size_t outbuflen, int flags) 1067{ 1068 int error; 1069 1070 MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1071 1072 return (error); 1073} 1074 1075static int 1076mac_externalize_socket_label(struct label *label, char *elements, 1077 char *outbuf, size_t outbuflen, int flags) 1078{ 1079 int error; 1080 1081 MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1082 1083 return (error); 1084} 1085 1086static int 1087mac_externalize_socket_peer_label(struct label *label, char *elements, 1088 char *outbuf, size_t outbuflen, int flags) 1089{ 1090 int error; 1091 1092 MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1093 1094 return (error); 1095} 1096 1097static int 1098mac_externalize_vnode_label(struct label *label, char *elements, 1099 char *outbuf, size_t outbuflen, int flags) 1100{ 1101 int error; 1102 1103 MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1104 1105 return (error); 1106} 1107 1108static int 1109mac_internalize_cred_label(struct label *label, char *string) 1110{ 1111 int error; 1112 1113 MAC_INTERNALIZE(cred_label, label, string); 1114 1115 return (error); 1116} 1117 1118static int 1119mac_internalize_ifnet_label(struct label *label, char *string) 1120{ 1121 int error; 1122 1123 MAC_INTERNALIZE(ifnet_label, label, string); 1124 1125 return (error); 1126} 1127 1128static int 1129mac_internalize_pipe_label(struct label *label, char *string) 1130{ 1131 int error; 1132 1133 MAC_INTERNALIZE(pipe_label, label, string); 1134 1135 return (error); 1136} 1137 1138static int 1139mac_internalize_socket_label(struct label *label, char *string) 1140{ 1141 int error; 1142 1143 MAC_INTERNALIZE(socket_label, label, string); 1144 1145 return (error); 1146} 1147 1148static int 1149mac_internalize_vnode_label(struct label *label, char *string) 1150{ 1151 int error; 1152 1153 MAC_INTERNALIZE(vnode_label, label, string); 1154 1155 return (error); 1156} 1157 1158/* 1159 * Initialize MAC label for the first kernel process, from which other 1160 * kernel processes and threads are spawned. 1161 */ 1162void 1163mac_create_proc0(struct ucred *cred) 1164{ 1165 1166 MAC_PERFORM(create_proc0, cred); 1167} 1168 1169/* 1170 * Initialize MAC label for the first userland process, from which other 1171 * userland processes and threads are spawned. 1172 */ 1173void 1174mac_create_proc1(struct ucred *cred) 1175{ 1176 1177 MAC_PERFORM(create_proc1, cred); 1178} 1179 1180void 1181mac_thread_userret(struct thread *td) 1182{ 1183 1184 MAC_PERFORM(thread_userret, td); 1185} 1186 1187/* 1188 * When a new process is created, its label must be initialized. Generally, 1189 * this involves inheritence from the parent process, modulo possible 1190 * deltas. This function allows that processing to take place. 1191 */ 1192void 1193mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1194{ 1195 1196 MAC_PERFORM(create_cred, parent_cred, child_cred); 1197} 1198 1199void 1200mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 1201 struct vnode *vp) 1202{ 1203 1204 MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp, 1205 &vp->v_label); 1206} 1207 1208void 1209mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1210 struct vnode *vp) 1211{ 1212 1213 MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1214 &de->de_label, vp, &vp->v_label); 1215} 1216 1217int 1218mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1219{ 1220 int error; 1221 1222 ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1223 1224 MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1225 &vp->v_label); 1226 1227 return (error); 1228} 1229 1230void 1231mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1232{ 1233 1234 MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1235 &vp->v_label); 1236} 1237 1238int 1239mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1240 struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1241{ 1242 int error; 1243 1244 ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1245 ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1246 1247 error = VOP_OPENEXTATTR(vp, cred, curthread); 1248 if (error == EOPNOTSUPP) { 1249 /* XXX: Optionally abort if transactions not supported. */ 1250 if (ea_warn_once == 0) { 1251 printf("Warning: transactions not supported " 1252 "in EA write.\n"); 1253 ea_warn_once = 1; 1254 } 1255 } else if (error) 1256 return (error); 1257 1258 MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1259 dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1260 1261 if (error) { 1262 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1263 return (error); 1264 } 1265 1266 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1267 1268 if (error == EOPNOTSUPP) 1269 error = 0; /* XXX */ 1270 1271 return (error); 1272} 1273 1274static int 1275mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1276 struct label *intlabel) 1277{ 1278 int error; 1279 1280 ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1281 1282 error = VOP_OPENEXTATTR(vp, cred, curthread); 1283 if (error == EOPNOTSUPP) { 1284 /* XXX: Optionally abort if transactions not supported. */ 1285 if (ea_warn_once == 0) { 1286 printf("Warning: transactions not supported " 1287 "in EA write.\n"); 1288 ea_warn_once = 1; 1289 } 1290 } else if (error) 1291 return (error); 1292 1293 MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1294 1295 if (error) { 1296 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1297 return (error); 1298 } 1299 1300 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1301 1302 if (error == EOPNOTSUPP) 1303 error = 0; /* XXX */ 1304 1305 return (error); 1306} 1307 1308int 1309mac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1310 struct label *execlabelstorage) 1311{ 1312 struct mac mac; 1313 char *buffer; 1314 int error; 1315 1316 if (mac_p == NULL) 1317 return (0); 1318 1319 error = copyin(mac_p, &mac, sizeof(mac)); 1320 if (error) 1321 return (error); 1322 1323 error = mac_check_structmac_consistent(&mac); 1324 if (error) 1325 return (error); 1326 1327 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1328 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1329 if (error) { 1330 free(buffer, M_MACTEMP); 1331 return (error); 1332 } 1333 1334 mac_init_cred_label(execlabelstorage); 1335 error = mac_internalize_cred_label(execlabelstorage, buffer); 1336 free(buffer, M_MACTEMP); 1337 if (error) { 1338 mac_destroy_cred_label(execlabelstorage); 1339 return (error); 1340 } 1341 imgp->execlabel = execlabelstorage; 1342 return (0); 1343} 1344 1345void 1346mac_execve_exit(struct image_params *imgp) 1347{ 1348 if (imgp->execlabel != NULL) 1349 mac_destroy_cred_label(imgp->execlabel); 1350} 1351 1352void 1353mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1354 struct label *interpvnodelabel, struct image_params *imgp) 1355{ 1356 1357 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1358 1359 if (!mac_enforce_process && !mac_enforce_fs) 1360 return; 1361 1362 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1363 interpvnodelabel, imgp, imgp->execlabel); 1364} 1365 1366int 1367mac_execve_will_transition(struct ucred *old, struct vnode *vp, 1368 struct label *interpvnodelabel, struct image_params *imgp) 1369{ 1370 int result; 1371 1372 ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1373 1374 if (!mac_enforce_process && !mac_enforce_fs) 1375 return (0); 1376 1377 result = 0; 1378 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1379 interpvnodelabel, imgp, imgp->execlabel); 1380 1381 return (result); 1382} 1383 1384int 1385mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1386{ 1387 int error; 1388 1389 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1390 1391 if (!mac_enforce_fs) 1392 return (0); 1393 1394 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1395 return (error); 1396} 1397 1398int 1399mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1400{ 1401 int error; 1402 1403 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1404 1405 if (!mac_enforce_fs) 1406 return (0); 1407 1408 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1409 return (error); 1410} 1411 1412int 1413mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1414{ 1415 int error; 1416 1417 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1418 1419 if (!mac_enforce_fs) 1420 return (0); 1421 1422 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1423 return (error); 1424} 1425 1426int 1427mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1428 struct componentname *cnp, struct vattr *vap) 1429{ 1430 int error; 1431 1432 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1433 1434 if (!mac_enforce_fs) 1435 return (0); 1436 1437 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1438 return (error); 1439} 1440 1441int 1442mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1443 struct componentname *cnp) 1444{ 1445 int error; 1446 1447 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1448 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1449 1450 if (!mac_enforce_fs) 1451 return (0); 1452 1453 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1454 &vp->v_label, cnp); 1455 return (error); 1456} 1457 1458int 1459mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1460 acl_type_t type) 1461{ 1462 int error; 1463 1464 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1465 1466 if (!mac_enforce_fs) 1467 return (0); 1468 1469 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1470 return (error); 1471} 1472 1473int 1474mac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1475 struct image_params *imgp) 1476{ 1477 int error; 1478 1479 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1480 1481 if (!mac_enforce_process && !mac_enforce_fs) 1482 return (0); 1483 1484 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1485 imgp->execlabel); 1486 1487 return (error); 1488} 1489 1490int 1491mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1492{ 1493 int error; 1494 1495 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1496 1497 if (!mac_enforce_fs) 1498 return (0); 1499 1500 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1501 return (error); 1502} 1503 1504int 1505mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1506 int attrnamespace, const char *name, struct uio *uio) 1507{ 1508 int error; 1509 1510 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1511 1512 if (!mac_enforce_fs) 1513 return (0); 1514 1515 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1516 attrnamespace, name, uio); 1517 return (error); 1518} 1519 1520int 1521mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1522 struct vnode *vp, struct componentname *cnp) 1523{ 1524 int error; 1525 1526 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1527 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1528 1529 if (!mac_enforce_fs) 1530 return (0); 1531 1532 MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1533 &vp->v_label, cnp); 1534 return (error); 1535} 1536 1537int 1538mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1539 struct componentname *cnp) 1540{ 1541 int error; 1542 1543 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1544 1545 if (!mac_enforce_fs) 1546 return (0); 1547 1548 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1549 return (error); 1550} 1551 1552int 1553mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1554{ 1555 int error; 1556 1557 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1558 1559 if (!mac_enforce_fs || !mac_enforce_vm) 1560 return (0); 1561 1562 MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1563 return (error); 1564} 1565 1566void 1567mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1568{ 1569 int result = *prot; 1570 1571 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1572 1573 if (!mac_enforce_fs || !mac_enforce_vm) 1574 return; 1575 1576 MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1577 &result); 1578 1579 *prot = result; 1580} 1581 1582int 1583mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1584{ 1585 int error; 1586 1587 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1588 1589 if (!mac_enforce_fs || !mac_enforce_vm) 1590 return (0); 1591 1592 MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1593 return (error); 1594} 1595 1596int 1597mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1598{ 1599 int error; 1600 1601 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1602 1603 if (!mac_enforce_fs) 1604 return (0); 1605 1606 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1607 return (error); 1608} 1609 1610int 1611mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1612 struct vnode *vp) 1613{ 1614 int error; 1615 1616 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1617 1618 if (!mac_enforce_fs) 1619 return (0); 1620 1621 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1622 &vp->v_label); 1623 1624 return (error); 1625} 1626 1627int 1628mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1629 struct vnode *vp) 1630{ 1631 int error; 1632 1633 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1634 1635 if (!mac_enforce_fs) 1636 return (0); 1637 1638 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1639 &vp->v_label); 1640 1641 return (error); 1642} 1643 1644int 1645mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1646{ 1647 int error; 1648 1649 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1650 1651 if (!mac_enforce_fs) 1652 return (0); 1653 1654 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1655 return (error); 1656} 1657 1658int 1659mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1660{ 1661 int error; 1662 1663 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1664 1665 if (!mac_enforce_fs) 1666 return (0); 1667 1668 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1669 return (error); 1670} 1671 1672static int 1673mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1674 struct label *newlabel) 1675{ 1676 int error; 1677 1678 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1679 1680 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1681 1682 return (error); 1683} 1684 1685int 1686mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1687 struct vnode *vp, struct componentname *cnp) 1688{ 1689 int error; 1690 1691 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1692 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1693 1694 if (!mac_enforce_fs) 1695 return (0); 1696 1697 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1698 &vp->v_label, cnp); 1699 return (error); 1700} 1701 1702int 1703mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1704 struct vnode *vp, int samedir, struct componentname *cnp) 1705{ 1706 int error; 1707 1708 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1709 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1710 1711 if (!mac_enforce_fs) 1712 return (0); 1713 1714 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1715 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1716 return (error); 1717} 1718 1719int 1720mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1721{ 1722 int error; 1723 1724 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1725 1726 if (!mac_enforce_fs) 1727 return (0); 1728 1729 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1730 return (error); 1731} 1732 1733int 1734mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1735 struct acl *acl) 1736{ 1737 int error; 1738 1739 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1740 1741 if (!mac_enforce_fs) 1742 return (0); 1743 1744 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1745 return (error); 1746} 1747 1748int 1749mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1750 int attrnamespace, const char *name, struct uio *uio) 1751{ 1752 int error; 1753 1754 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1755 1756 if (!mac_enforce_fs) 1757 return (0); 1758 1759 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1760 attrnamespace, name, uio); 1761 return (error); 1762} 1763 1764int 1765mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1766{ 1767 int error; 1768 1769 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1770 1771 if (!mac_enforce_fs) 1772 return (0); 1773 1774 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1775 return (error); 1776} 1777 1778int 1779mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1780{ 1781 int error; 1782 1783 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1784 1785 if (!mac_enforce_fs) 1786 return (0); 1787 1788 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1789 return (error); 1790} 1791 1792int 1793mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1794 gid_t gid) 1795{ 1796 int error; 1797 1798 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1799 1800 if (!mac_enforce_fs) 1801 return (0); 1802 1803 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1804 return (error); 1805} 1806 1807int 1808mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1809 struct timespec atime, struct timespec mtime) 1810{ 1811 int error; 1812 1813 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1814 1815 if (!mac_enforce_fs) 1816 return (0); 1817 1818 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1819 mtime); 1820 return (error); 1821} 1822 1823int 1824mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1825 struct vnode *vp) 1826{ 1827 int error; 1828 1829 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 1830 1831 if (!mac_enforce_fs) 1832 return (0); 1833 1834 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 1835 &vp->v_label); 1836 return (error); 1837} 1838 1839int 1840mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1841 struct vnode *vp) 1842{ 1843 int error; 1844 1845 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 1846 1847 if (!mac_enforce_fs) 1848 return (0); 1849 1850 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 1851 &vp->v_label); 1852 1853 return (error); 1854} 1855 1856/* 1857 * When relabeling a process, call out to the policies for the maximum 1858 * permission allowed for each object type we know about in its 1859 * memory space, and revoke access (in the least surprising ways we 1860 * know) when necessary. The process lock is not held here. 1861 */ 1862void 1863mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 1864{ 1865 1866 /* XXX freeze all other threads */ 1867 mac_cred_mmapped_drop_perms_recurse(td, cred, 1868 &td->td_proc->p_vmspace->vm_map); 1869 /* XXX allow other threads to continue */ 1870} 1871 1872static __inline const char * 1873prot2str(vm_prot_t prot) 1874{ 1875 1876 switch (prot & VM_PROT_ALL) { 1877 case VM_PROT_READ: 1878 return ("r--"); 1879 case VM_PROT_READ | VM_PROT_WRITE: 1880 return ("rw-"); 1881 case VM_PROT_READ | VM_PROT_EXECUTE: 1882 return ("r-x"); 1883 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 1884 return ("rwx"); 1885 case VM_PROT_WRITE: 1886 return ("-w-"); 1887 case VM_PROT_EXECUTE: 1888 return ("--x"); 1889 case VM_PROT_WRITE | VM_PROT_EXECUTE: 1890 return ("-wx"); 1891 default: 1892 return ("---"); 1893 } 1894} 1895 1896static void 1897mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 1898 struct vm_map *map) 1899{ 1900 struct vm_map_entry *vme; 1901 int result; 1902 vm_prot_t revokeperms; 1903 vm_object_t object; 1904 vm_ooffset_t offset; 1905 struct vnode *vp; 1906 1907 if (!mac_mmap_revocation) 1908 return; 1909 1910 vm_map_lock_read(map); 1911 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 1912 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 1913 mac_cred_mmapped_drop_perms_recurse(td, cred, 1914 vme->object.sub_map); 1915 continue; 1916 } 1917 /* 1918 * Skip over entries that obviously are not shared. 1919 */ 1920 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 1921 !vme->max_protection) 1922 continue; 1923 /* 1924 * Drill down to the deepest backing object. 1925 */ 1926 offset = vme->offset; 1927 object = vme->object.vm_object; 1928 if (object == NULL) 1929 continue; 1930 while (object->backing_object != NULL) { 1931 object = object->backing_object; 1932 offset += object->backing_object_offset; 1933 } 1934 /* 1935 * At the moment, vm_maps and objects aren't considered 1936 * by the MAC system, so only things with backing by a 1937 * normal object (read: vnodes) are checked. 1938 */ 1939 if (object->type != OBJT_VNODE) 1940 continue; 1941 vp = (struct vnode *)object->handle; 1942 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1943 result = vme->max_protection; 1944 mac_check_vnode_mmap_downgrade(cred, vp, &result); 1945 VOP_UNLOCK(vp, 0, td); 1946 /* 1947 * Find out what maximum protection we may be allowing 1948 * now but a policy needs to get removed. 1949 */ 1950 revokeperms = vme->max_protection & ~result; 1951 if (!revokeperms) 1952 continue; 1953 printf("pid %ld: revoking %s perms from %#lx:%ld " 1954 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 1955 prot2str(revokeperms), (u_long)vme->start, 1956 (long)(vme->end - vme->start), 1957 prot2str(vme->max_protection), prot2str(vme->protection)); 1958 vm_map_lock_upgrade(map); 1959 /* 1960 * This is the really simple case: if a map has more 1961 * max_protection than is allowed, but it's not being 1962 * actually used (that is, the current protection is 1963 * still allowed), we can just wipe it out and do 1964 * nothing more. 1965 */ 1966 if ((vme->protection & revokeperms) == 0) { 1967 vme->max_protection -= revokeperms; 1968 } else { 1969 if (revokeperms & VM_PROT_WRITE) { 1970 /* 1971 * In the more complicated case, flush out all 1972 * pending changes to the object then turn it 1973 * copy-on-write. 1974 */ 1975 vm_object_reference(object); 1976 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1977 vm_object_page_clean(object, 1978 OFF_TO_IDX(offset), 1979 OFF_TO_IDX(offset + vme->end - vme->start + 1980 PAGE_MASK), 1981 OBJPC_SYNC); 1982 VOP_UNLOCK(vp, 0, td); 1983 vm_object_deallocate(object); 1984 /* 1985 * Why bother if there's no read permissions 1986 * anymore? For the rest, we need to leave 1987 * the write permissions on for COW, or 1988 * remove them entirely if configured to. 1989 */ 1990 if (!mac_mmap_revocation_via_cow) { 1991 vme->max_protection &= ~VM_PROT_WRITE; 1992 vme->protection &= ~VM_PROT_WRITE; 1993 } if ((revokeperms & VM_PROT_READ) == 0) 1994 vme->eflags |= MAP_ENTRY_COW | 1995 MAP_ENTRY_NEEDS_COPY; 1996 } 1997 if (revokeperms & VM_PROT_EXECUTE) { 1998 vme->max_protection &= ~VM_PROT_EXECUTE; 1999 vme->protection &= ~VM_PROT_EXECUTE; 2000 } 2001 if (revokeperms & VM_PROT_READ) { 2002 vme->max_protection = 0; 2003 vme->protection = 0; 2004 } 2005 pmap_protect(map->pmap, vme->start, vme->end, 2006 vme->protection & ~revokeperms); 2007 vm_map_simplify_entry(map, vme); 2008 } 2009 vm_map_lock_downgrade(map); 2010 } 2011 vm_map_unlock_read(map); 2012} 2013 2014/* 2015 * When the subject's label changes, it may require revocation of privilege 2016 * to mapped objects. This can't be done on-the-fly later with a unified 2017 * buffer cache. 2018 */ 2019static void 2020mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2021{ 2022 2023 MAC_PERFORM(relabel_cred, cred, newlabel); 2024} 2025 2026void 2027mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2028{ 2029 2030 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2031} 2032 2033void 2034mac_create_ifnet(struct ifnet *ifnet) 2035{ 2036 2037 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2038} 2039 2040void 2041mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2042{ 2043 2044 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2045} 2046 2047void 2048mac_create_socket(struct ucred *cred, struct socket *socket) 2049{ 2050 2051 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2052} 2053 2054void 2055mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2056{ 2057 2058 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2059} 2060 2061void 2062mac_create_socket_from_socket(struct socket *oldsocket, 2063 struct socket *newsocket) 2064{ 2065 2066 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2067 newsocket, &newsocket->so_label); 2068} 2069 2070static void 2071mac_relabel_socket(struct ucred *cred, struct socket *socket, 2072 struct label *newlabel) 2073{ 2074 2075 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2076} 2077 2078static void 2079mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2080{ 2081 2082 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2083} 2084 2085void 2086mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2087{ 2088 2089 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2090 socket, &socket->so_peerlabel); 2091} 2092 2093void 2094mac_set_socket_peer_from_socket(struct socket *oldsocket, 2095 struct socket *newsocket) 2096{ 2097 2098 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2099 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2100} 2101 2102void 2103mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2104{ 2105 2106 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2107 datagram, &datagram->m_pkthdr.label); 2108} 2109 2110void 2111mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2112{ 2113 2114 MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2115 fragment, &fragment->m_pkthdr.label); 2116} 2117 2118void 2119mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2120{ 2121 2122 MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2123 &ipq->ipq_label); 2124} 2125 2126void 2127mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2128{ 2129 2130 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2131 newmbuf, &newmbuf->m_pkthdr.label); 2132} 2133 2134void 2135mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2136{ 2137 2138 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2139 &mbuf->m_pkthdr.label); 2140} 2141 2142void 2143mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2144{ 2145 2146 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2147 &mbuf->m_pkthdr.label); 2148} 2149 2150void 2151mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2152{ 2153 2154 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2155 &mbuf->m_pkthdr.label); 2156} 2157 2158void 2159mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2160 struct mbuf *newmbuf) 2161{ 2162 2163 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2164 &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2165 &newmbuf->m_pkthdr.label); 2166} 2167 2168void 2169mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2170{ 2171 2172 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2173 newmbuf, &newmbuf->m_pkthdr.label); 2174} 2175 2176int 2177mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2178{ 2179 int result; 2180 2181 result = 1; 2182 MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2183 ipq, &ipq->ipq_label); 2184 2185 return (result); 2186} 2187 2188void 2189mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2190{ 2191 2192 MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2193 &ipq->ipq_label); 2194} 2195 2196void 2197mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2198{ 2199 2200 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2201 &mbuf->m_pkthdr.label); 2202} 2203 2204void 2205mac_create_mount(struct ucred *cred, struct mount *mp) 2206{ 2207 2208 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2209 &mp->mnt_fslabel); 2210} 2211 2212void 2213mac_create_root_mount(struct ucred *cred, struct mount *mp) 2214{ 2215 2216 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2217 &mp->mnt_fslabel); 2218} 2219 2220int 2221mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2222{ 2223 int error; 2224 2225 if (!mac_enforce_network) 2226 return (0); 2227 2228 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2229 &ifnet->if_label); 2230 2231 return (error); 2232} 2233 2234static int 2235mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2236{ 2237 int error; 2238 2239 MAC_CHECK(check_cred_relabel, cred, newlabel); 2240 2241 return (error); 2242} 2243 2244int 2245mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2246{ 2247 int error; 2248 2249 if (!mac_enforce_process) 2250 return (0); 2251 2252 MAC_CHECK(check_cred_visible, u1, u2); 2253 2254 return (error); 2255} 2256 2257int 2258mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2259{ 2260 int error; 2261 2262 if (!mac_enforce_network) 2263 return (0); 2264 2265 KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2266 if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2267 if_printf(ifnet, "not initialized\n"); 2268 2269 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2270 &mbuf->m_pkthdr.label); 2271 2272 return (error); 2273} 2274 2275int 2276mac_check_kenv_dump(struct ucred *cred) 2277{ 2278 int error; 2279 2280 if (!mac_enforce_system) 2281 return (0); 2282 2283 MAC_CHECK(check_kenv_dump, cred); 2284 2285 return (error); 2286} 2287 2288int 2289mac_check_kenv_get(struct ucred *cred, char *name) 2290{ 2291 int error; 2292 2293 if (!mac_enforce_system) 2294 return (0); 2295 2296 MAC_CHECK(check_kenv_get, cred, name); 2297 2298 return (error); 2299} 2300 2301int 2302mac_check_kenv_set(struct ucred *cred, char *name, char *value) 2303{ 2304 int error; 2305 2306 if (!mac_enforce_system) 2307 return (0); 2308 2309 MAC_CHECK(check_kenv_set, cred, name, value); 2310 2311 return (error); 2312} 2313 2314int 2315mac_check_kenv_unset(struct ucred *cred, char *name) 2316{ 2317 int error; 2318 2319 if (!mac_enforce_system) 2320 return (0); 2321 2322 MAC_CHECK(check_kenv_unset, cred, name); 2323 2324 return (error); 2325} 2326 2327int 2328mac_check_kld_load(struct ucred *cred, struct vnode *vp) 2329{ 2330 int error; 2331 2332 ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2333 2334 if (!mac_enforce_kld) 2335 return (0); 2336 2337 MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2338 2339 return (error); 2340} 2341 2342int 2343mac_check_kld_stat(struct ucred *cred) 2344{ 2345 int error; 2346 2347 if (!mac_enforce_kld) 2348 return (0); 2349 2350 MAC_CHECK(check_kld_stat, cred); 2351 2352 return (error); 2353} 2354 2355int 2356mac_check_kld_unload(struct ucred *cred) 2357{ 2358 int error; 2359 2360 if (!mac_enforce_kld) 2361 return (0); 2362 2363 MAC_CHECK(check_kld_unload, cred); 2364 2365 return (error); 2366} 2367 2368int 2369mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2370{ 2371 int error; 2372 2373 if (!mac_enforce_fs) 2374 return (0); 2375 2376 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2377 2378 return (error); 2379} 2380 2381int 2382mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2383 void *data) 2384{ 2385 int error; 2386 2387 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2388 2389 if (!mac_enforce_pipe) 2390 return (0); 2391 2392 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2393 2394 return (error); 2395} 2396 2397int 2398mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2399{ 2400 int error; 2401 2402 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2403 2404 if (!mac_enforce_pipe) 2405 return (0); 2406 2407 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2408 2409 return (error); 2410} 2411 2412int 2413mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2414{ 2415 int error; 2416 2417 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2418 2419 if (!mac_enforce_pipe) 2420 return (0); 2421 2422 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2423 2424 return (error); 2425} 2426 2427static int 2428mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2429 struct label *newlabel) 2430{ 2431 int error; 2432 2433 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2434 2435 if (!mac_enforce_pipe) 2436 return (0); 2437 2438 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2439 2440 return (error); 2441} 2442 2443int 2444mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2445{ 2446 int error; 2447 2448 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2449 2450 if (!mac_enforce_pipe) 2451 return (0); 2452 2453 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2454 2455 return (error); 2456} 2457 2458int 2459mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2460{ 2461 int error; 2462 2463 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2464 2465 if (!mac_enforce_pipe) 2466 return (0); 2467 2468 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2469 2470 return (error); 2471} 2472 2473int 2474mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2475{ 2476 int error; 2477 2478 PROC_LOCK_ASSERT(proc, MA_OWNED); 2479 2480 if (!mac_enforce_process) 2481 return (0); 2482 2483 MAC_CHECK(check_proc_debug, cred, proc); 2484 2485 return (error); 2486} 2487 2488int 2489mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2490{ 2491 int error; 2492 2493 PROC_LOCK_ASSERT(proc, MA_OWNED); 2494 2495 if (!mac_enforce_process) 2496 return (0); 2497 2498 MAC_CHECK(check_proc_sched, cred, proc); 2499 2500 return (error); 2501} 2502 2503int 2504mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2505{ 2506 int error; 2507 2508 PROC_LOCK_ASSERT(proc, MA_OWNED); 2509 2510 if (!mac_enforce_process) 2511 return (0); 2512 2513 MAC_CHECK(check_proc_signal, cred, proc, signum); 2514 2515 return (error); 2516} 2517 2518int 2519mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2520 struct sockaddr *sockaddr) 2521{ 2522 int error; 2523 2524 if (!mac_enforce_socket) 2525 return (0); 2526 2527 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2528 sockaddr); 2529 2530 return (error); 2531} 2532 2533int 2534mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2535 struct sockaddr *sockaddr) 2536{ 2537 int error; 2538 2539 if (!mac_enforce_socket) 2540 return (0); 2541 2542 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2543 sockaddr); 2544 2545 return (error); 2546} 2547 2548int 2549mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2550{ 2551 int error; 2552 2553 if (!mac_enforce_socket) 2554 return (0); 2555 2556 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2557 &mbuf->m_pkthdr.label); 2558 2559 return (error); 2560} 2561 2562int 2563mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2564{ 2565 int error; 2566 2567 if (!mac_enforce_socket) 2568 return (0); 2569 2570 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2571 return (error); 2572} 2573 2574int 2575mac_check_socket_receive(struct ucred *cred, struct socket *so) 2576{ 2577 int error; 2578 2579 if (!mac_enforce_socket) 2580 return (0); 2581 2582 MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2583 2584 return (error); 2585} 2586 2587static int 2588mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2589 struct label *newlabel) 2590{ 2591 int error; 2592 2593 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2594 newlabel); 2595 2596 return (error); 2597} 2598 2599int 2600mac_check_socket_send(struct ucred *cred, struct socket *so) 2601{ 2602 int error; 2603 2604 if (!mac_enforce_socket) 2605 return (0); 2606 2607 MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2608 2609 return (error); 2610} 2611 2612int 2613mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2614{ 2615 int error; 2616 2617 if (!mac_enforce_socket) 2618 return (0); 2619 2620 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2621 2622 return (error); 2623} 2624 2625int 2626mac_check_sysarch_ioperm(struct ucred *cred) 2627{ 2628 int error; 2629 2630 if (!mac_enforce_system) 2631 return (0); 2632 2633 MAC_CHECK(check_sysarch_ioperm, cred); 2634 return (error); 2635} 2636 2637int 2638mac_check_system_acct(struct ucred *cred, struct vnode *vp) 2639{ 2640 int error; 2641 2642 if (vp != NULL) { 2643 ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2644 } 2645 2646 if (!mac_enforce_system) 2647 return (0); 2648 2649 MAC_CHECK(check_system_acct, cred, vp, 2650 vp != NULL ? &vp->v_label : NULL); 2651 2652 return (error); 2653} 2654 2655int 2656mac_check_system_nfsd(struct ucred *cred) 2657{ 2658 int error; 2659 2660 if (!mac_enforce_system) 2661 return (0); 2662 2663 MAC_CHECK(check_system_nfsd, cred); 2664 2665 return (error); 2666} 2667 2668int 2669mac_check_system_reboot(struct ucred *cred, int howto) 2670{ 2671 int error; 2672 2673 if (!mac_enforce_system) 2674 return (0); 2675 2676 MAC_CHECK(check_system_reboot, cred, howto); 2677 2678 return (error); 2679} 2680 2681int 2682mac_check_system_settime(struct ucred *cred) 2683{ 2684 int error; 2685 2686 if (!mac_enforce_system) 2687 return (0); 2688 2689 MAC_CHECK(check_system_settime, cred); 2690 2691 return (error); 2692} 2693 2694int 2695mac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2696{ 2697 int error; 2698 2699 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2700 2701 if (!mac_enforce_system) 2702 return (0); 2703 2704 MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2705 return (error); 2706} 2707 2708int 2709mac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2710{ 2711 int error; 2712 2713 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2714 2715 if (!mac_enforce_system) 2716 return (0); 2717 2718 MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2719 return (error); 2720} 2721 2722int 2723mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2724 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2725{ 2726 int error; 2727 2728 /* 2729 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2730 * but since it's not exported from kern_sysctl.c, we can't. 2731 */ 2732 if (!mac_enforce_system) 2733 return (0); 2734 2735 MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2736 inkernel, new, newlen); 2737 2738 return (error); 2739} 2740 2741int 2742mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2743 struct ifnet *ifnet) 2744{ 2745 char *elements, *buffer; 2746 struct mac mac; 2747 int error; 2748 2749 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2750 if (error) 2751 return (error); 2752 2753 error = mac_check_structmac_consistent(&mac); 2754 if (error) 2755 return (error); 2756 2757 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2758 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2759 if (error) { 2760 free(elements, M_MACTEMP); 2761 return (error); 2762 } 2763 2764 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2765 error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 2766 buffer, mac.m_buflen, M_WAITOK); 2767 if (error == 0) 2768 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2769 2770 free(buffer, M_MACTEMP); 2771 free(elements, M_MACTEMP); 2772 2773 return (error); 2774} 2775 2776int 2777mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2778 struct ifnet *ifnet) 2779{ 2780 struct label intlabel; 2781 struct mac mac; 2782 char *buffer; 2783 int error; 2784 2785 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2786 if (error) 2787 return (error); 2788 2789 error = mac_check_structmac_consistent(&mac); 2790 if (error) 2791 return (error); 2792 2793 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2794 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2795 if (error) { 2796 free(buffer, M_MACTEMP); 2797 return (error); 2798 } 2799 2800 mac_init_ifnet_label(&intlabel); 2801 error = mac_internalize_ifnet_label(&intlabel, buffer); 2802 free(buffer, M_MACTEMP); 2803 if (error) { 2804 mac_destroy_ifnet_label(&intlabel); 2805 return (error); 2806 } 2807 2808 /* 2809 * XXX: Note that this is a redundant privilege check, since 2810 * policies impose this check themselves if required by the 2811 * policy. Eventually, this should go away. 2812 */ 2813 error = suser_cred(cred, 0); 2814 if (error) { 2815 mac_destroy_ifnet_label(&intlabel); 2816 return (error); 2817 } 2818 2819 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2820 &intlabel); 2821 if (error) { 2822 mac_destroy_ifnet_label(&intlabel); 2823 return (error); 2824 } 2825 2826 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2827 2828 mac_destroy_ifnet_label(&intlabel); 2829 return (0); 2830} 2831 2832void 2833mac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de) 2834{ 2835 2836 MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label); 2837} 2838 2839void 2840mac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 2841 struct devfs_dirent *dd, struct devfs_dirent *de) 2842{ 2843 2844 MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de, 2845 &de->de_label); 2846} 2847 2848void 2849mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 2850 struct devfs_dirent *de) 2851{ 2852 2853 MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 2854 &de->de_label); 2855} 2856 2857int 2858mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2859 struct mac *mac) 2860{ 2861 struct label intlabel; 2862 char *buffer; 2863 int error; 2864 2865 error = mac_check_structmac_consistent(mac); 2866 if (error) 2867 return (error); 2868 2869 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2870 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 2871 if (error) { 2872 free(buffer, M_MACTEMP); 2873 return (error); 2874 } 2875 2876 mac_init_socket_label(&intlabel, M_WAITOK); 2877 error = mac_internalize_socket_label(&intlabel, buffer); 2878 free(buffer, M_MACTEMP); 2879 if (error) { 2880 mac_destroy_socket_label(&intlabel); 2881 return (error); 2882 } 2883 2884 mac_check_socket_relabel(cred, so, &intlabel); 2885 if (error) { 2886 mac_destroy_socket_label(&intlabel); 2887 return (error); 2888 } 2889 2890 mac_relabel_socket(cred, so, &intlabel); 2891 2892 mac_destroy_socket_label(&intlabel); 2893 return (0); 2894} 2895 2896int 2897mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 2898{ 2899 int error; 2900 2901 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2902 2903 error = mac_check_pipe_relabel(cred, pipe, label); 2904 if (error) 2905 return (error); 2906 2907 mac_relabel_pipe(cred, pipe, label); 2908 2909 return (0); 2910} 2911 2912int 2913mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2914 struct mac *mac) 2915{ 2916 char *buffer, *elements; 2917 int error; 2918 2919 error = mac_check_structmac_consistent(mac); 2920 if (error) 2921 return (error); 2922 2923 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2924 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2925 if (error) { 2926 free(elements, M_MACTEMP); 2927 return (error); 2928 } 2929 2930 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2931 error = mac_externalize_socket_label(&so->so_label, elements, 2932 buffer, mac->m_buflen, M_WAITOK); 2933 if (error == 0) 2934 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2935 2936 free(buffer, M_MACTEMP); 2937 free(elements, M_MACTEMP); 2938 2939 return (error); 2940} 2941 2942int 2943mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2944 struct mac *mac) 2945{ 2946 char *elements, *buffer; 2947 int error; 2948 2949 error = mac_check_structmac_consistent(mac); 2950 if (error) 2951 return (error); 2952 2953 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2954 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2955 if (error) { 2956 free(elements, M_MACTEMP); 2957 return (error); 2958 } 2959 2960 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2961 error = mac_externalize_socket_peer_label(&so->so_peerlabel, 2962 elements, buffer, mac->m_buflen, M_WAITOK); 2963 if (error == 0) 2964 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2965 2966 free(buffer, M_MACTEMP); 2967 free(elements, M_MACTEMP); 2968 2969 return (error); 2970} 2971 2972/* 2973 * Implementation of VOP_SETLABEL() that relies on extended attributes 2974 * to store label data. Can be referenced by filesystems supporting 2975 * extended attributes. 2976 */ 2977int 2978vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 2979{ 2980 struct vnode *vp = ap->a_vp; 2981 struct label *intlabel = ap->a_label; 2982 int error; 2983 2984 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 2985 2986 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2987 return (EOPNOTSUPP); 2988 2989 error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 2990 if (error) 2991 return (error); 2992 2993 mac_relabel_vnode(ap->a_cred, vp, intlabel); 2994 2995 return (0); 2996} 2997 2998static int 2999vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3000{ 3001 int error; 3002 3003 if (vp->v_mount == NULL) { 3004 /* printf("vn_setlabel: null v_mount\n"); */ 3005 if (vp->v_type != VNON) 3006 printf("vn_setlabel: null v_mount with non-VNON\n"); 3007 return (EBADF); 3008 } 3009 3010 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3011 return (EOPNOTSUPP); 3012 3013 /* 3014 * Multi-phase commit. First check the policies to confirm the 3015 * change is OK. Then commit via the filesystem. Finally, 3016 * update the actual vnode label. Question: maybe the filesystem 3017 * should update the vnode at the end as part of VOP_SETLABEL()? 3018 */ 3019 error = mac_check_vnode_relabel(cred, vp, intlabel); 3020 if (error) 3021 return (error); 3022 3023 /* 3024 * VADMIN provides the opportunity for the filesystem to make 3025 * decisions about who is and is not able to modify labels 3026 * and protections on files. This might not be right. We can't 3027 * assume VOP_SETLABEL() will do it, because we might implement 3028 * that as part of vop_stdsetlabel_ea(). 3029 */ 3030 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3031 if (error) 3032 return (error); 3033 3034 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3035 if (error) 3036 return (error); 3037 3038 return (0); 3039} 3040 3041int 3042__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3043{ 3044 char *elements, *buffer; 3045 struct mac mac; 3046 struct proc *tproc; 3047 struct ucred *tcred; 3048 int error; 3049 3050 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3051 if (error) 3052 return (error); 3053 3054 error = mac_check_structmac_consistent(&mac); 3055 if (error) 3056 return (error); 3057 3058 tproc = pfind(uap->pid); 3059 if (tproc == NULL) 3060 return (ESRCH); 3061 3062 tcred = NULL; /* Satisfy gcc. */ 3063 error = p_cansee(td, tproc); 3064 if (error == 0) 3065 tcred = crhold(tproc->p_ucred); 3066 PROC_UNLOCK(tproc); 3067 if (error) 3068 return (error); 3069 3070 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3071 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3072 if (error) { 3073 free(elements, M_MACTEMP); 3074 crfree(tcred); 3075 return (error); 3076 } 3077 3078 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3079 error = mac_externalize_cred_label(&tcred->cr_label, elements, 3080 buffer, mac.m_buflen, M_WAITOK); 3081 if (error == 0) 3082 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3083 3084 free(buffer, M_MACTEMP); 3085 free(elements, M_MACTEMP); 3086 crfree(tcred); 3087 return (error); 3088} 3089 3090/* 3091 * MPSAFE 3092 */ 3093int 3094__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3095{ 3096 char *elements, *buffer; 3097 struct mac mac; 3098 int error; 3099 3100 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3101 if (error) 3102 return (error); 3103 3104 error = mac_check_structmac_consistent(&mac); 3105 if (error) 3106 return (error); 3107 3108 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3109 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3110 if (error) { 3111 free(elements, M_MACTEMP); 3112 return (error); 3113 } 3114 3115 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3116 error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3117 elements, buffer, mac.m_buflen, M_WAITOK); 3118 if (error == 0) 3119 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3120 3121 free(buffer, M_MACTEMP); 3122 free(elements, M_MACTEMP); 3123 return (error); 3124} 3125 3126/* 3127 * MPSAFE 3128 */ 3129int 3130__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3131{ 3132 struct ucred *newcred, *oldcred; 3133 struct label intlabel; 3134 struct proc *p; 3135 struct mac mac; 3136 char *buffer; 3137 int error; 3138 3139 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3140 if (error) 3141 return (error); 3142 3143 error = mac_check_structmac_consistent(&mac); 3144 if (error) 3145 return (error); 3146 3147 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3148 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3149 if (error) { 3150 free(buffer, M_MACTEMP); 3151 return (error); 3152 } 3153 3154 mac_init_cred_label(&intlabel); 3155 error = mac_internalize_cred_label(&intlabel, buffer); 3156 free(buffer, M_MACTEMP); 3157 if (error) { 3158 mac_destroy_cred_label(&intlabel); 3159 return (error); 3160 } 3161 3162 newcred = crget(); 3163 3164 p = td->td_proc; 3165 PROC_LOCK(p); 3166 oldcred = p->p_ucred; 3167 3168 error = mac_check_cred_relabel(oldcred, &intlabel); 3169 if (error) { 3170 PROC_UNLOCK(p); 3171 crfree(newcred); 3172 goto out; 3173 } 3174 3175 setsugid(p); 3176 crcopy(newcred, oldcred); 3177 mac_relabel_cred(newcred, &intlabel); 3178 p->p_ucred = newcred; 3179 3180 /* 3181 * Grab additional reference for use while revoking mmaps, prior 3182 * to releasing the proc lock and sharing the cred. 3183 */ 3184 crhold(newcred); 3185 PROC_UNLOCK(p); 3186 3187 if (mac_enforce_vm) { 3188 mtx_lock(&Giant); 3189 mac_cred_mmapped_drop_perms(td, newcred); 3190 mtx_unlock(&Giant); 3191 } 3192 3193 crfree(newcred); /* Free revocation reference. */ 3194 crfree(oldcred); 3195 3196out: 3197 mac_destroy_cred_label(&intlabel); 3198 return (error); 3199} 3200 3201/* 3202 * MPSAFE 3203 */ 3204int 3205__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3206{ 3207 char *elements, *buffer; 3208 struct label intlabel; 3209 struct file *fp; 3210 struct mac mac; 3211 struct vnode *vp; 3212 struct pipe *pipe; 3213 short label_type; 3214 int error; 3215 3216 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3217 if (error) 3218 return (error); 3219 3220 error = mac_check_structmac_consistent(&mac); 3221 if (error) 3222 return (error); 3223 3224 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3225 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3226 if (error) { 3227 free(elements, M_MACTEMP); 3228 return (error); 3229 } 3230 3231 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3232 mtx_lock(&Giant); /* VFS */ 3233 error = fget(td, uap->fd, &fp); 3234 if (error) 3235 goto out; 3236 3237 label_type = fp->f_type; 3238 switch (fp->f_type) { 3239 case DTYPE_FIFO: 3240 case DTYPE_VNODE: 3241 vp = fp->f_data; 3242 3243 mac_init_vnode_label(&intlabel); 3244 3245 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3246 mac_copy_vnode_label(&vp->v_label, &intlabel); 3247 VOP_UNLOCK(vp, 0, td); 3248 3249 break; 3250 case DTYPE_PIPE: 3251 pipe = fp->f_data; 3252 3253 mac_init_pipe_label(&intlabel); 3254 3255 PIPE_LOCK(pipe); 3256 mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3257 PIPE_UNLOCK(pipe); 3258 break; 3259 default: 3260 error = EINVAL; 3261 fdrop(fp, td); 3262 goto out; 3263 } 3264 fdrop(fp, td); 3265 3266 switch (label_type) { 3267 case DTYPE_FIFO: 3268 case DTYPE_VNODE: 3269 if (error == 0) 3270 error = mac_externalize_vnode_label(&intlabel, 3271 elements, buffer, mac.m_buflen, M_WAITOK); 3272 mac_destroy_vnode_label(&intlabel); 3273 break; 3274 case DTYPE_PIPE: 3275 error = mac_externalize_pipe_label(&intlabel, elements, 3276 buffer, mac.m_buflen, M_WAITOK); 3277 mac_destroy_pipe_label(&intlabel); 3278 break; 3279 default: 3280 panic("__mac_get_fd: corrupted label_type"); 3281 } 3282 3283 if (error == 0) 3284 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3285 3286out: 3287 mtx_unlock(&Giant); /* VFS */ 3288 free(buffer, M_MACTEMP); 3289 free(elements, M_MACTEMP); 3290 3291 return (error); 3292} 3293 3294/* 3295 * MPSAFE 3296 */ 3297int 3298__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3299{ 3300 char *elements, *buffer; 3301 struct nameidata nd; 3302 struct label intlabel; 3303 struct mac mac; 3304 int error; 3305 3306 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3307 if (error) 3308 return (error); 3309 3310 error = mac_check_structmac_consistent(&mac); 3311 if (error) 3312 return (error); 3313 3314 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3315 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3316 if (error) { 3317 free(elements, M_MACTEMP); 3318 return (error); 3319 } 3320 3321 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3322 mtx_lock(&Giant); /* VFS */ 3323 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3324 td); 3325 error = namei(&nd); 3326 if (error) 3327 goto out; 3328 3329 mac_init_vnode_label(&intlabel); 3330 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3331 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3332 mac.m_buflen, M_WAITOK); 3333 3334 NDFREE(&nd, 0); 3335 mac_destroy_vnode_label(&intlabel); 3336 3337 if (error == 0) 3338 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3339 3340out: 3341 mtx_unlock(&Giant); /* VFS */ 3342 3343 free(buffer, M_MACTEMP); 3344 free(elements, M_MACTEMP); 3345 3346 return (error); 3347} 3348 3349/* 3350 * MPSAFE 3351 */ 3352int 3353__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3354{ 3355 char *elements, *buffer; 3356 struct nameidata nd; 3357 struct label intlabel; 3358 struct mac mac; 3359 int error; 3360 3361 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3362 if (error) 3363 return (error); 3364 3365 error = mac_check_structmac_consistent(&mac); 3366 if (error) 3367 return (error); 3368 3369 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3370 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3371 if (error) { 3372 free(elements, M_MACTEMP); 3373 return (error); 3374 } 3375 3376 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3377 mtx_lock(&Giant); /* VFS */ 3378 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3379 td); 3380 error = namei(&nd); 3381 if (error) 3382 goto out; 3383 3384 mac_init_vnode_label(&intlabel); 3385 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3386 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3387 mac.m_buflen, M_WAITOK); 3388 NDFREE(&nd, 0); 3389 mac_destroy_vnode_label(&intlabel); 3390 3391 if (error == 0) 3392 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3393 3394out: 3395 mtx_unlock(&Giant); /* VFS */ 3396 3397 free(buffer, M_MACTEMP); 3398 free(elements, M_MACTEMP); 3399 3400 return (error); 3401} 3402 3403/* 3404 * MPSAFE 3405 */ 3406int 3407__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3408{ 3409 struct label intlabel; 3410 struct pipe *pipe; 3411 struct file *fp; 3412 struct mount *mp; 3413 struct vnode *vp; 3414 struct mac mac; 3415 char *buffer; 3416 int error; 3417 3418 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3419 if (error) 3420 return (error); 3421 3422 error = mac_check_structmac_consistent(&mac); 3423 if (error) 3424 return (error); 3425 3426 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3427 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3428 if (error) { 3429 free(buffer, M_MACTEMP); 3430 return (error); 3431 } 3432 3433 mtx_lock(&Giant); /* VFS */ 3434 3435 error = fget(td, uap->fd, &fp); 3436 if (error) 3437 goto out; 3438 3439 switch (fp->f_type) { 3440 case DTYPE_FIFO: 3441 case DTYPE_VNODE: 3442 mac_init_vnode_label(&intlabel); 3443 error = mac_internalize_vnode_label(&intlabel, buffer); 3444 if (error) { 3445 mac_destroy_vnode_label(&intlabel); 3446 break; 3447 } 3448 3449 vp = fp->f_data; 3450 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3451 if (error != 0) { 3452 mac_destroy_vnode_label(&intlabel); 3453 break; 3454 } 3455 3456 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3457 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3458 VOP_UNLOCK(vp, 0, td); 3459 vn_finished_write(mp); 3460 3461 mac_destroy_vnode_label(&intlabel); 3462 break; 3463 3464 case DTYPE_PIPE: 3465 mac_init_pipe_label(&intlabel); 3466 error = mac_internalize_pipe_label(&intlabel, buffer); 3467 if (error == 0) { 3468 pipe = fp->f_data; 3469 PIPE_LOCK(pipe); 3470 error = mac_pipe_label_set(td->td_ucred, pipe, 3471 &intlabel); 3472 PIPE_UNLOCK(pipe); 3473 } 3474 3475 mac_destroy_pipe_label(&intlabel); 3476 break; 3477 3478 default: 3479 error = EINVAL; 3480 } 3481 3482 fdrop(fp, td); 3483out: 3484 mtx_unlock(&Giant); /* VFS */ 3485 3486 free(buffer, M_MACTEMP); 3487 3488 return (error); 3489} 3490 3491/* 3492 * MPSAFE 3493 */ 3494int 3495__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3496{ 3497 struct label intlabel; 3498 struct nameidata nd; 3499 struct mount *mp; 3500 struct mac mac; 3501 char *buffer; 3502 int error; 3503 3504 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3505 if (error) 3506 return (error); 3507 3508 error = mac_check_structmac_consistent(&mac); 3509 if (error) 3510 return (error); 3511 3512 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3513 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3514 if (error) { 3515 free(buffer, M_MACTEMP); 3516 return (error); 3517 } 3518 3519 mac_init_vnode_label(&intlabel); 3520 error = mac_internalize_vnode_label(&intlabel, buffer); 3521 free(buffer, M_MACTEMP); 3522 if (error) { 3523 mac_destroy_vnode_label(&intlabel); 3524 return (error); 3525 } 3526 3527 mtx_lock(&Giant); /* VFS */ 3528 3529 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3530 td); 3531 error = namei(&nd); 3532 if (error == 0) { 3533 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3534 if (error == 0) 3535 error = vn_setlabel(nd.ni_vp, &intlabel, 3536 td->td_ucred); 3537 vn_finished_write(mp); 3538 } 3539 3540 NDFREE(&nd, 0); 3541 mtx_unlock(&Giant); /* VFS */ 3542 mac_destroy_vnode_label(&intlabel); 3543 3544 return (error); 3545} 3546 3547/* 3548 * MPSAFE 3549 */ 3550int 3551__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3552{ 3553 struct label intlabel; 3554 struct nameidata nd; 3555 struct mount *mp; 3556 struct mac mac; 3557 char *buffer; 3558 int error; 3559 3560 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3561 if (error) 3562 return (error); 3563 3564 error = mac_check_structmac_consistent(&mac); 3565 if (error) 3566 return (error); 3567 3568 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3569 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3570 if (error) { 3571 free(buffer, M_MACTEMP); 3572 return (error); 3573 } 3574 3575 mac_init_vnode_label(&intlabel); 3576 error = mac_internalize_vnode_label(&intlabel, buffer); 3577 free(buffer, M_MACTEMP); 3578 if (error) { 3579 mac_destroy_vnode_label(&intlabel); 3580 return (error); 3581 } 3582 3583 mtx_lock(&Giant); /* VFS */ 3584 3585 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3586 td); 3587 error = namei(&nd); 3588 if (error == 0) { 3589 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3590 if (error == 0) 3591 error = vn_setlabel(nd.ni_vp, &intlabel, 3592 td->td_ucred); 3593 vn_finished_write(mp); 3594 } 3595 3596 NDFREE(&nd, 0); 3597 mtx_unlock(&Giant); /* VFS */ 3598 mac_destroy_vnode_label(&intlabel); 3599 3600 return (error); 3601} 3602 3603/* 3604 * MPSAFE 3605 */ 3606int 3607mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3608{ 3609 struct mac_policy_conf *mpc; 3610 char target[MAC_MAX_POLICY_NAME]; 3611 int error; 3612 3613 error = copyinstr(uap->policy, target, sizeof(target), NULL); 3614 if (error) 3615 return (error); 3616 3617 error = ENOSYS; 3618 MAC_POLICY_LIST_BUSY(); 3619 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3620 if (strcmp(mpc->mpc_name, target) == 0 && 3621 mpc->mpc_ops->mpo_syscall != NULL) { 3622 error = mpc->mpc_ops->mpo_syscall(td, 3623 uap->call, uap->arg); 3624 goto out; 3625 } 3626 } 3627 3628out: 3629 MAC_POLICY_LIST_UNBUSY(); 3630 return (error); 3631} 3632 3633SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3634SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3635 3636#else /* !MAC */ 3637 3638int 3639__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3640{ 3641 3642 return (ENOSYS); 3643} 3644 3645int 3646__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3647{ 3648 3649 return (ENOSYS); 3650} 3651 3652int 3653__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3654{ 3655 3656 return (ENOSYS); 3657} 3658 3659int 3660__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3661{ 3662 3663 return (ENOSYS); 3664} 3665 3666int 3667__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3668{ 3669 3670 return (ENOSYS); 3671} 3672 3673int 3674__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3675{ 3676 3677 return (ENOSYS); 3678} 3679 3680int 3681__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3682{ 3683 3684 return (ENOSYS); 3685} 3686 3687int 3688__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3689{ 3690 3691 return (ENOSYS); 3692} 3693 3694int 3695__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3696{ 3697 3698 return (ENOSYS); 3699} 3700 3701int 3702mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3703{ 3704 3705 return (ENOSYS); 3706} 3707 3708#endif 3709