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