mac_internal.h revision 113487
1/*- 2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3 * Copyright (c) 2001 Ilmar S. Habibulin 4 * Copyright (c) 2001, 2002 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_internal.h 113487 2003-04-14 20:39:06Z 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, trflag; 787 788 label = (struct label *) (tag + 1); 789 mac_init_label(label); 790 791 trflag = (flag == M_DONTWAIT ? M_NOWAIT : M_WAITOK); 792 MAC_CHECK(init_mbuf_label, label, trflag); 793 if (error) { 794 MAC_PERFORM(destroy_mbuf_label, label); 795 mac_destroy_label(label); 796 } 797#ifdef MAC_DEBUG 798 if (error == 0) 799 atomic_add_int(&nmacmbufs, 1); 800#endif 801 return (error); 802} 803 804int 805mac_init_mbuf(struct mbuf *m, int flag) 806{ 807 struct m_tag *tag; 808 int error; 809 810 M_ASSERTPKTHDR(m); 811 812#ifndef MAC_ALWAYS_LABEL_MBUF 813 /* 814 * Don't reserve space for labels on mbufs unless we have a policy 815 * that uses the labels. 816 */ 817 if (mac_labelmbufs) { 818#endif 819 tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 820 flag); 821 if (tag == NULL) 822 return (ENOMEM); 823 error = mac_init_mbuf_tag(tag, flag); 824 if (error) { 825 m_tag_free(tag); 826 return (error); 827 } 828 m_tag_prepend(m, tag); 829#ifndef MAC_ALWAYS_LABEL_MBUF 830 } 831#endif 832 return (0); 833} 834 835void 836mac_init_mount(struct mount *mp) 837{ 838 839 mac_init_label(&mp->mnt_mntlabel); 840 mac_init_label(&mp->mnt_fslabel); 841 MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 842 MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 843#ifdef MAC_DEBUG 844 atomic_add_int(&nmacmounts, 1); 845#endif 846} 847 848static void 849mac_init_pipe_label(struct label *label) 850{ 851 852 mac_init_label(label); 853 MAC_PERFORM(init_pipe_label, label); 854#ifdef MAC_DEBUG 855 atomic_add_int(&nmacpipes, 1); 856#endif 857} 858 859void 860mac_init_pipe(struct pipe *pipe) 861{ 862 struct label *label; 863 864 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 865 pipe->pipe_label = label; 866 pipe->pipe_peer->pipe_label = label; 867 mac_init_pipe_label(label); 868} 869 870void 871mac_init_proc(struct proc *p) 872{ 873 874 mac_init_label(&p->p_label); 875 MAC_PERFORM(init_proc_label, &p->p_label); 876#ifdef MAC_DEBUG 877 atomic_add_int(&nmacprocs, 1); 878#endif 879} 880 881static int 882mac_init_socket_label(struct label *label, int flag) 883{ 884 int error; 885 886 mac_init_label(label); 887 888 MAC_CHECK(init_socket_label, label, flag); 889 if (error) { 890 MAC_PERFORM(destroy_socket_label, label); 891 mac_destroy_label(label); 892 } 893 894#ifdef MAC_DEBUG 895 if (error == 0) 896 atomic_add_int(&nmacsockets, 1); 897#endif 898 899 return (error); 900} 901 902static int 903mac_init_socket_peer_label(struct label *label, int flag) 904{ 905 int error; 906 907 mac_init_label(label); 908 909 MAC_CHECK(init_socket_peer_label, label, flag); 910 if (error) { 911 MAC_PERFORM(destroy_socket_label, label); 912 mac_destroy_label(label); 913 } 914 915 return (error); 916} 917 918int 919mac_init_socket(struct socket *socket, int flag) 920{ 921 int error; 922 923 error = mac_init_socket_label(&socket->so_label, flag); 924 if (error) 925 return (error); 926 927 error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 928 if (error) 929 mac_destroy_socket_label(&socket->so_label); 930 931 return (error); 932} 933 934void 935mac_init_vnode_label(struct label *label) 936{ 937 938 mac_init_label(label); 939 MAC_PERFORM(init_vnode_label, label); 940#ifdef MAC_DEBUG 941 atomic_add_int(&nmacvnodes, 1); 942#endif 943} 944 945void 946mac_init_vnode(struct vnode *vp) 947{ 948 949 mac_init_vnode_label(&vp->v_label); 950} 951 952void 953mac_destroy_bpfdesc(struct bpf_d *bpf_d) 954{ 955 956 MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 957 mac_destroy_label(&bpf_d->bd_label); 958#ifdef MAC_DEBUG 959 atomic_subtract_int(&nmacbpfdescs, 1); 960#endif 961} 962 963static void 964mac_destroy_cred_label(struct label *label) 965{ 966 967 MAC_PERFORM(destroy_cred_label, label); 968 mac_destroy_label(label); 969#ifdef MAC_DEBUG 970 atomic_subtract_int(&nmaccreds, 1); 971#endif 972} 973 974void 975mac_destroy_cred(struct ucred *cred) 976{ 977 978 mac_destroy_cred_label(&cred->cr_label); 979} 980 981void 982mac_destroy_devfsdirent(struct devfs_dirent *de) 983{ 984 985 MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 986 mac_destroy_label(&de->de_label); 987#ifdef MAC_DEBUG 988 atomic_subtract_int(&nmacdevfsdirents, 1); 989#endif 990} 991 992static void 993mac_destroy_ifnet_label(struct label *label) 994{ 995 996 MAC_PERFORM(destroy_ifnet_label, label); 997 mac_destroy_label(label); 998#ifdef MAC_DEBUG 999 atomic_subtract_int(&nmacifnets, 1); 1000#endif 1001} 1002 1003void 1004mac_destroy_ifnet(struct ifnet *ifp) 1005{ 1006 1007 mac_destroy_ifnet_label(&ifp->if_label); 1008} 1009 1010void 1011mac_destroy_ipq(struct ipq *ipq) 1012{ 1013 1014 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 1015 mac_destroy_label(&ipq->ipq_label); 1016#ifdef MAC_DEBUG 1017 atomic_subtract_int(&nmacipqs, 1); 1018#endif 1019} 1020 1021void 1022mac_destroy_mbuf_tag(struct m_tag *tag) 1023{ 1024 struct label *label; 1025 1026 label = (struct label *)(tag+1); 1027 1028 MAC_PERFORM(destroy_mbuf_label, label); 1029 mac_destroy_label(label); 1030#ifdef MAC_DEBUG 1031 atomic_subtract_int(&nmacmbufs, 1); 1032#endif 1033} 1034 1035void 1036mac_destroy_mount(struct mount *mp) 1037{ 1038 1039 MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 1040 MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 1041 mac_destroy_label(&mp->mnt_fslabel); 1042 mac_destroy_label(&mp->mnt_mntlabel); 1043#ifdef MAC_DEBUG 1044 atomic_subtract_int(&nmacmounts, 1); 1045#endif 1046} 1047 1048static void 1049mac_destroy_pipe_label(struct label *label) 1050{ 1051 1052 MAC_PERFORM(destroy_pipe_label, label); 1053 mac_destroy_label(label); 1054#ifdef MAC_DEBUG 1055 atomic_subtract_int(&nmacpipes, 1); 1056#endif 1057} 1058 1059void 1060mac_destroy_pipe(struct pipe *pipe) 1061{ 1062 1063 mac_destroy_pipe_label(pipe->pipe_label); 1064 free(pipe->pipe_label, M_MACPIPELABEL); 1065} 1066 1067void 1068mac_destroy_proc(struct proc *p) 1069{ 1070 1071 MAC_PERFORM(destroy_proc_label, &p->p_label); 1072 mac_destroy_label(&p->p_label); 1073#ifdef MAC_DEBUG 1074 atomic_subtract_int(&nmacprocs, 1); 1075#endif 1076} 1077 1078static void 1079mac_destroy_socket_label(struct label *label) 1080{ 1081 1082 MAC_PERFORM(destroy_socket_label, label); 1083 mac_destroy_label(label); 1084#ifdef MAC_DEBUG 1085 atomic_subtract_int(&nmacsockets, 1); 1086#endif 1087} 1088 1089static void 1090mac_destroy_socket_peer_label(struct label *label) 1091{ 1092 1093 MAC_PERFORM(destroy_socket_peer_label, label); 1094 mac_destroy_label(label); 1095} 1096 1097void 1098mac_destroy_socket(struct socket *socket) 1099{ 1100 1101 mac_destroy_socket_label(&socket->so_label); 1102 mac_destroy_socket_peer_label(&socket->so_peerlabel); 1103} 1104 1105void 1106mac_destroy_vnode_label(struct label *label) 1107{ 1108 1109 MAC_PERFORM(destroy_vnode_label, label); 1110 mac_destroy_label(label); 1111#ifdef MAC_DEBUG 1112 atomic_subtract_int(&nmacvnodes, 1); 1113#endif 1114} 1115 1116void 1117mac_destroy_vnode(struct vnode *vp) 1118{ 1119 1120 mac_destroy_vnode_label(&vp->v_label); 1121} 1122 1123void 1124mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 1125{ 1126 struct label *src_label, *dest_label; 1127 1128 src_label = (struct label *)(src+1); 1129 dest_label = (struct label *)(dest+1); 1130 1131 /* 1132 * mac_init_mbuf_tag() is called on the target tag in 1133 * m_tag_copy(), so we don't need to call it here. 1134 */ 1135 MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 1136} 1137 1138static void 1139mac_copy_pipe_label(struct label *src, struct label *dest) 1140{ 1141 1142 MAC_PERFORM(copy_pipe_label, src, dest); 1143} 1144 1145void 1146mac_copy_vnode_label(struct label *src, struct label *dest) 1147{ 1148 1149 MAC_PERFORM(copy_vnode_label, src, dest); 1150} 1151 1152static int 1153mac_check_structmac_consistent(struct mac *mac) 1154{ 1155 1156 if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1157 return (EINVAL); 1158 1159 return (0); 1160} 1161 1162static int 1163mac_externalize_cred_label(struct label *label, char *elements, 1164 char *outbuf, size_t outbuflen, int flags) 1165{ 1166 int error; 1167 1168 MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1169 1170 return (error); 1171} 1172 1173static int 1174mac_externalize_ifnet_label(struct label *label, char *elements, 1175 char *outbuf, size_t outbuflen, int flags) 1176{ 1177 int error; 1178 1179 MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1180 1181 return (error); 1182} 1183 1184static int 1185mac_externalize_pipe_label(struct label *label, char *elements, 1186 char *outbuf, size_t outbuflen, int flags) 1187{ 1188 int error; 1189 1190 MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1191 1192 return (error); 1193} 1194 1195static int 1196mac_externalize_socket_label(struct label *label, char *elements, 1197 char *outbuf, size_t outbuflen, int flags) 1198{ 1199 int error; 1200 1201 MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1202 1203 return (error); 1204} 1205 1206static int 1207mac_externalize_socket_peer_label(struct label *label, char *elements, 1208 char *outbuf, size_t outbuflen, int flags) 1209{ 1210 int error; 1211 1212 MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1213 1214 return (error); 1215} 1216 1217static int 1218mac_externalize_vnode_label(struct label *label, char *elements, 1219 char *outbuf, size_t outbuflen, int flags) 1220{ 1221 int error; 1222 1223 MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1224 1225 return (error); 1226} 1227 1228static int 1229mac_internalize_cred_label(struct label *label, char *string) 1230{ 1231 int error; 1232 1233 MAC_INTERNALIZE(cred_label, label, string); 1234 1235 return (error); 1236} 1237 1238static int 1239mac_internalize_ifnet_label(struct label *label, char *string) 1240{ 1241 int error; 1242 1243 MAC_INTERNALIZE(ifnet_label, label, string); 1244 1245 return (error); 1246} 1247 1248static int 1249mac_internalize_pipe_label(struct label *label, char *string) 1250{ 1251 int error; 1252 1253 MAC_INTERNALIZE(pipe_label, label, string); 1254 1255 return (error); 1256} 1257 1258static int 1259mac_internalize_socket_label(struct label *label, char *string) 1260{ 1261 int error; 1262 1263 MAC_INTERNALIZE(socket_label, label, string); 1264 1265 return (error); 1266} 1267 1268static int 1269mac_internalize_vnode_label(struct label *label, char *string) 1270{ 1271 int error; 1272 1273 MAC_INTERNALIZE(vnode_label, label, string); 1274 1275 return (error); 1276} 1277 1278/* 1279 * Initialize MAC label for the first kernel process, from which other 1280 * kernel processes and threads are spawned. 1281 */ 1282void 1283mac_create_proc0(struct ucred *cred) 1284{ 1285 1286 MAC_PERFORM(create_proc0, cred); 1287} 1288 1289/* 1290 * Initialize MAC label for the first userland process, from which other 1291 * userland processes and threads are spawned. 1292 */ 1293void 1294mac_create_proc1(struct ucred *cred) 1295{ 1296 1297 MAC_PERFORM(create_proc1, cred); 1298} 1299 1300void 1301mac_thread_userret(struct thread *td) 1302{ 1303 1304 MAC_PERFORM(thread_userret, td); 1305} 1306 1307/* 1308 * When a new process is created, its label must be initialized. Generally, 1309 * this involves inheritence from the parent process, modulo possible 1310 * deltas. This function allows that processing to take place. 1311 */ 1312void 1313mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1314{ 1315 1316 MAC_PERFORM(create_cred, parent_cred, child_cred); 1317} 1318 1319void 1320mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 1321 struct vnode *vp) 1322{ 1323 1324 MAC_PERFORM(update_devfsdirent, mp, de, &de->de_label, vp, 1325 &vp->v_label); 1326} 1327 1328void 1329mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1330 struct vnode *vp) 1331{ 1332 1333 MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1334 &de->de_label, vp, &vp->v_label); 1335} 1336 1337int 1338mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1339{ 1340 int error; 1341 1342 ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1343 1344 MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1345 &vp->v_label); 1346 1347 return (error); 1348} 1349 1350void 1351mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1352{ 1353 1354 MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1355 &vp->v_label); 1356} 1357 1358int 1359mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1360 struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1361{ 1362 int error; 1363 1364 ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1365 ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1366 1367 error = VOP_OPENEXTATTR(vp, cred, curthread); 1368 if (error == EOPNOTSUPP) { 1369 /* XXX: Optionally abort if transactions not supported. */ 1370 if (ea_warn_once == 0) { 1371 printf("Warning: transactions not supported " 1372 "in EA write.\n"); 1373 ea_warn_once = 1; 1374 } 1375 } else if (error) 1376 return (error); 1377 1378 MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1379 dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1380 1381 if (error) { 1382 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1383 return (error); 1384 } 1385 1386 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1387 1388 if (error == EOPNOTSUPP) 1389 error = 0; /* XXX */ 1390 1391 return (error); 1392} 1393 1394static int 1395mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1396 struct label *intlabel) 1397{ 1398 int error; 1399 1400 ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1401 1402 error = VOP_OPENEXTATTR(vp, cred, curthread); 1403 if (error == EOPNOTSUPP) { 1404 /* XXX: Optionally abort if transactions not supported. */ 1405 if (ea_warn_once == 0) { 1406 printf("Warning: transactions not supported " 1407 "in EA write.\n"); 1408 ea_warn_once = 1; 1409 } 1410 } else if (error) 1411 return (error); 1412 1413 MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1414 1415 if (error) { 1416 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1417 return (error); 1418 } 1419 1420 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1421 1422 if (error == EOPNOTSUPP) 1423 error = 0; /* XXX */ 1424 1425 return (error); 1426} 1427 1428int 1429mac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1430 struct label *execlabelstorage) 1431{ 1432 struct mac mac; 1433 char *buffer; 1434 int error; 1435 1436 if (mac_p == NULL) 1437 return (0); 1438 1439 error = copyin(mac_p, &mac, sizeof(mac)); 1440 if (error) 1441 return (error); 1442 1443 error = mac_check_structmac_consistent(&mac); 1444 if (error) 1445 return (error); 1446 1447 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1448 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1449 if (error) { 1450 free(buffer, M_MACTEMP); 1451 return (error); 1452 } 1453 1454 mac_init_cred_label(execlabelstorage); 1455 error = mac_internalize_cred_label(execlabelstorage, buffer); 1456 free(buffer, M_MACTEMP); 1457 if (error) { 1458 mac_destroy_cred_label(execlabelstorage); 1459 return (error); 1460 } 1461 imgp->execlabel = execlabelstorage; 1462 return (0); 1463} 1464 1465void 1466mac_execve_exit(struct image_params *imgp) 1467{ 1468 if (imgp->execlabel != NULL) 1469 mac_destroy_cred_label(imgp->execlabel); 1470} 1471 1472void 1473mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1474 struct label *interpvnodelabel, struct image_params *imgp) 1475{ 1476 1477 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1478 1479 if (!mac_enforce_process && !mac_enforce_fs) 1480 return; 1481 1482 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1483 interpvnodelabel, imgp, imgp->execlabel); 1484} 1485 1486int 1487mac_execve_will_transition(struct ucred *old, struct vnode *vp, 1488 struct label *interpvnodelabel, struct image_params *imgp) 1489{ 1490 int result; 1491 1492 ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1493 1494 if (!mac_enforce_process && !mac_enforce_fs) 1495 return (0); 1496 1497 result = 0; 1498 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1499 interpvnodelabel, imgp, imgp->execlabel); 1500 1501 return (result); 1502} 1503 1504int 1505mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1506{ 1507 int error; 1508 1509 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1510 1511 if (!mac_enforce_fs) 1512 return (0); 1513 1514 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1515 return (error); 1516} 1517 1518int 1519mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1520{ 1521 int error; 1522 1523 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1524 1525 if (!mac_enforce_fs) 1526 return (0); 1527 1528 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1529 return (error); 1530} 1531 1532int 1533mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1534{ 1535 int error; 1536 1537 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1538 1539 if (!mac_enforce_fs) 1540 return (0); 1541 1542 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1543 return (error); 1544} 1545 1546int 1547mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1548 struct componentname *cnp, struct vattr *vap) 1549{ 1550 int error; 1551 1552 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1553 1554 if (!mac_enforce_fs) 1555 return (0); 1556 1557 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1558 return (error); 1559} 1560 1561int 1562mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1563 struct componentname *cnp) 1564{ 1565 int error; 1566 1567 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1568 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1569 1570 if (!mac_enforce_fs) 1571 return (0); 1572 1573 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1574 &vp->v_label, cnp); 1575 return (error); 1576} 1577 1578int 1579mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1580 acl_type_t type) 1581{ 1582 int error; 1583 1584 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1585 1586 if (!mac_enforce_fs) 1587 return (0); 1588 1589 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1590 return (error); 1591} 1592 1593int 1594mac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1595 struct image_params *imgp) 1596{ 1597 int error; 1598 1599 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1600 1601 if (!mac_enforce_process && !mac_enforce_fs) 1602 return (0); 1603 1604 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1605 imgp->execlabel); 1606 1607 return (error); 1608} 1609 1610int 1611mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1612{ 1613 int error; 1614 1615 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1616 1617 if (!mac_enforce_fs) 1618 return (0); 1619 1620 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1621 return (error); 1622} 1623 1624int 1625mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1626 int attrnamespace, const char *name, struct uio *uio) 1627{ 1628 int error; 1629 1630 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1631 1632 if (!mac_enforce_fs) 1633 return (0); 1634 1635 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1636 attrnamespace, name, uio); 1637 return (error); 1638} 1639 1640int 1641mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1642 struct vnode *vp, struct componentname *cnp) 1643{ 1644 int error; 1645 1646 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1647 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1648 1649 if (!mac_enforce_fs) 1650 return (0); 1651 1652 MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1653 &vp->v_label, cnp); 1654 return (error); 1655} 1656 1657int 1658mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1659 struct componentname *cnp) 1660{ 1661 int error; 1662 1663 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1664 1665 if (!mac_enforce_fs) 1666 return (0); 1667 1668 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1669 return (error); 1670} 1671 1672int 1673mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1674{ 1675 int error; 1676 1677 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1678 1679 if (!mac_enforce_fs || !mac_enforce_vm) 1680 return (0); 1681 1682 MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1683 return (error); 1684} 1685 1686void 1687mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1688{ 1689 int result = *prot; 1690 1691 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1692 1693 if (!mac_enforce_fs || !mac_enforce_vm) 1694 return; 1695 1696 MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1697 &result); 1698 1699 *prot = result; 1700} 1701 1702int 1703mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1704{ 1705 int error; 1706 1707 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1708 1709 if (!mac_enforce_fs || !mac_enforce_vm) 1710 return (0); 1711 1712 MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1713 return (error); 1714} 1715 1716int 1717mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1718{ 1719 int error; 1720 1721 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1722 1723 if (!mac_enforce_fs) 1724 return (0); 1725 1726 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1727 return (error); 1728} 1729 1730int 1731mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1732 struct vnode *vp) 1733{ 1734 int error; 1735 1736 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1737 1738 if (!mac_enforce_fs) 1739 return (0); 1740 1741 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1742 &vp->v_label); 1743 1744 return (error); 1745} 1746 1747int 1748mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1749 struct vnode *vp) 1750{ 1751 int error; 1752 1753 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1754 1755 if (!mac_enforce_fs) 1756 return (0); 1757 1758 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1759 &vp->v_label); 1760 1761 return (error); 1762} 1763 1764int 1765mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1766{ 1767 int error; 1768 1769 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1770 1771 if (!mac_enforce_fs) 1772 return (0); 1773 1774 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1775 return (error); 1776} 1777 1778int 1779mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1780{ 1781 int error; 1782 1783 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1784 1785 if (!mac_enforce_fs) 1786 return (0); 1787 1788 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1789 return (error); 1790} 1791 1792static int 1793mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1794 struct label *newlabel) 1795{ 1796 int error; 1797 1798 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1799 1800 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1801 1802 return (error); 1803} 1804 1805int 1806mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1807 struct vnode *vp, struct componentname *cnp) 1808{ 1809 int error; 1810 1811 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1812 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1813 1814 if (!mac_enforce_fs) 1815 return (0); 1816 1817 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1818 &vp->v_label, cnp); 1819 return (error); 1820} 1821 1822int 1823mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1824 struct vnode *vp, int samedir, struct componentname *cnp) 1825{ 1826 int error; 1827 1828 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1829 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1830 1831 if (!mac_enforce_fs) 1832 return (0); 1833 1834 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1835 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1836 return (error); 1837} 1838 1839int 1840mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1841{ 1842 int error; 1843 1844 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1845 1846 if (!mac_enforce_fs) 1847 return (0); 1848 1849 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1850 return (error); 1851} 1852 1853int 1854mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1855 struct acl *acl) 1856{ 1857 int error; 1858 1859 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1860 1861 if (!mac_enforce_fs) 1862 return (0); 1863 1864 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1865 return (error); 1866} 1867 1868int 1869mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1870 int attrnamespace, const char *name, struct uio *uio) 1871{ 1872 int error; 1873 1874 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1875 1876 if (!mac_enforce_fs) 1877 return (0); 1878 1879 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1880 attrnamespace, name, uio); 1881 return (error); 1882} 1883 1884int 1885mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1886{ 1887 int error; 1888 1889 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1890 1891 if (!mac_enforce_fs) 1892 return (0); 1893 1894 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1895 return (error); 1896} 1897 1898int 1899mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1900{ 1901 int error; 1902 1903 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1904 1905 if (!mac_enforce_fs) 1906 return (0); 1907 1908 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1909 return (error); 1910} 1911 1912int 1913mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1914 gid_t gid) 1915{ 1916 int error; 1917 1918 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1919 1920 if (!mac_enforce_fs) 1921 return (0); 1922 1923 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1924 return (error); 1925} 1926 1927int 1928mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1929 struct timespec atime, struct timespec mtime) 1930{ 1931 int error; 1932 1933 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1934 1935 if (!mac_enforce_fs) 1936 return (0); 1937 1938 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1939 mtime); 1940 return (error); 1941} 1942 1943int 1944mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1945 struct vnode *vp) 1946{ 1947 int error; 1948 1949 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 1950 1951 if (!mac_enforce_fs) 1952 return (0); 1953 1954 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 1955 &vp->v_label); 1956 return (error); 1957} 1958 1959int 1960mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1961 struct vnode *vp) 1962{ 1963 int error; 1964 1965 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 1966 1967 if (!mac_enforce_fs) 1968 return (0); 1969 1970 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 1971 &vp->v_label); 1972 1973 return (error); 1974} 1975 1976/* 1977 * When relabeling a process, call out to the policies for the maximum 1978 * permission allowed for each object type we know about in its 1979 * memory space, and revoke access (in the least surprising ways we 1980 * know) when necessary. The process lock is not held here. 1981 */ 1982void 1983mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 1984{ 1985 1986 /* XXX freeze all other threads */ 1987 mac_cred_mmapped_drop_perms_recurse(td, cred, 1988 &td->td_proc->p_vmspace->vm_map); 1989 /* XXX allow other threads to continue */ 1990} 1991 1992static __inline const char * 1993prot2str(vm_prot_t prot) 1994{ 1995 1996 switch (prot & VM_PROT_ALL) { 1997 case VM_PROT_READ: 1998 return ("r--"); 1999 case VM_PROT_READ | VM_PROT_WRITE: 2000 return ("rw-"); 2001 case VM_PROT_READ | VM_PROT_EXECUTE: 2002 return ("r-x"); 2003 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2004 return ("rwx"); 2005 case VM_PROT_WRITE: 2006 return ("-w-"); 2007 case VM_PROT_EXECUTE: 2008 return ("--x"); 2009 case VM_PROT_WRITE | VM_PROT_EXECUTE: 2010 return ("-wx"); 2011 default: 2012 return ("---"); 2013 } 2014} 2015 2016static void 2017mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2018 struct vm_map *map) 2019{ 2020 struct vm_map_entry *vme; 2021 int result; 2022 vm_prot_t revokeperms; 2023 vm_object_t object; 2024 vm_ooffset_t offset; 2025 struct vnode *vp; 2026 2027 if (!mac_mmap_revocation) 2028 return; 2029 2030 vm_map_lock_read(map); 2031 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2032 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2033 mac_cred_mmapped_drop_perms_recurse(td, cred, 2034 vme->object.sub_map); 2035 continue; 2036 } 2037 /* 2038 * Skip over entries that obviously are not shared. 2039 */ 2040 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2041 !vme->max_protection) 2042 continue; 2043 /* 2044 * Drill down to the deepest backing object. 2045 */ 2046 offset = vme->offset; 2047 object = vme->object.vm_object; 2048 if (object == NULL) 2049 continue; 2050 while (object->backing_object != NULL) { 2051 object = object->backing_object; 2052 offset += object->backing_object_offset; 2053 } 2054 /* 2055 * At the moment, vm_maps and objects aren't considered 2056 * by the MAC system, so only things with backing by a 2057 * normal object (read: vnodes) are checked. 2058 */ 2059 if (object->type != OBJT_VNODE) 2060 continue; 2061 vp = (struct vnode *)object->handle; 2062 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2063 result = vme->max_protection; 2064 mac_check_vnode_mmap_downgrade(cred, vp, &result); 2065 VOP_UNLOCK(vp, 0, td); 2066 /* 2067 * Find out what maximum protection we may be allowing 2068 * now but a policy needs to get removed. 2069 */ 2070 revokeperms = vme->max_protection & ~result; 2071 if (!revokeperms) 2072 continue; 2073 printf("pid %ld: revoking %s perms from %#lx:%ld " 2074 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2075 prot2str(revokeperms), (u_long)vme->start, 2076 (long)(vme->end - vme->start), 2077 prot2str(vme->max_protection), prot2str(vme->protection)); 2078 vm_map_lock_upgrade(map); 2079 /* 2080 * This is the really simple case: if a map has more 2081 * max_protection than is allowed, but it's not being 2082 * actually used (that is, the current protection is 2083 * still allowed), we can just wipe it out and do 2084 * nothing more. 2085 */ 2086 if ((vme->protection & revokeperms) == 0) { 2087 vme->max_protection -= revokeperms; 2088 } else { 2089 if (revokeperms & VM_PROT_WRITE) { 2090 /* 2091 * In the more complicated case, flush out all 2092 * pending changes to the object then turn it 2093 * copy-on-write. 2094 */ 2095 vm_object_reference(object); 2096 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2097 vm_object_page_clean(object, 2098 OFF_TO_IDX(offset), 2099 OFF_TO_IDX(offset + vme->end - vme->start + 2100 PAGE_MASK), 2101 OBJPC_SYNC); 2102 VOP_UNLOCK(vp, 0, td); 2103 vm_object_deallocate(object); 2104 /* 2105 * Why bother if there's no read permissions 2106 * anymore? For the rest, we need to leave 2107 * the write permissions on for COW, or 2108 * remove them entirely if configured to. 2109 */ 2110 if (!mac_mmap_revocation_via_cow) { 2111 vme->max_protection &= ~VM_PROT_WRITE; 2112 vme->protection &= ~VM_PROT_WRITE; 2113 } if ((revokeperms & VM_PROT_READ) == 0) 2114 vme->eflags |= MAP_ENTRY_COW | 2115 MAP_ENTRY_NEEDS_COPY; 2116 } 2117 if (revokeperms & VM_PROT_EXECUTE) { 2118 vme->max_protection &= ~VM_PROT_EXECUTE; 2119 vme->protection &= ~VM_PROT_EXECUTE; 2120 } 2121 if (revokeperms & VM_PROT_READ) { 2122 vme->max_protection = 0; 2123 vme->protection = 0; 2124 } 2125 pmap_protect(map->pmap, vme->start, vme->end, 2126 vme->protection & ~revokeperms); 2127 vm_map_simplify_entry(map, vme); 2128 } 2129 vm_map_lock_downgrade(map); 2130 } 2131 vm_map_unlock_read(map); 2132} 2133 2134/* 2135 * When the subject's label changes, it may require revocation of privilege 2136 * to mapped objects. This can't be done on-the-fly later with a unified 2137 * buffer cache. 2138 */ 2139static void 2140mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2141{ 2142 2143 MAC_PERFORM(relabel_cred, cred, newlabel); 2144} 2145 2146void 2147mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2148{ 2149 2150 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2151} 2152 2153void 2154mac_create_ifnet(struct ifnet *ifnet) 2155{ 2156 2157 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2158} 2159 2160void 2161mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2162{ 2163 2164 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2165} 2166 2167void 2168mac_create_socket(struct ucred *cred, struct socket *socket) 2169{ 2170 2171 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2172} 2173 2174void 2175mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2176{ 2177 2178 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2179} 2180 2181void 2182mac_create_socket_from_socket(struct socket *oldsocket, 2183 struct socket *newsocket) 2184{ 2185 2186 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2187 newsocket, &newsocket->so_label); 2188} 2189 2190static void 2191mac_relabel_socket(struct ucred *cred, struct socket *socket, 2192 struct label *newlabel) 2193{ 2194 2195 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2196} 2197 2198static void 2199mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2200{ 2201 2202 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2203} 2204 2205void 2206mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2207{ 2208 struct label *label; 2209 2210 label = mbuf_to_label(mbuf); 2211 2212 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 2213 &socket->so_peerlabel); 2214} 2215 2216void 2217mac_set_socket_peer_from_socket(struct socket *oldsocket, 2218 struct socket *newsocket) 2219{ 2220 2221 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2222 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2223} 2224 2225void 2226mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2227{ 2228 struct label *label; 2229 2230 label = mbuf_to_label(datagram); 2231 2232 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2233 datagram, label); 2234} 2235 2236void 2237mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2238{ 2239 struct label *datagramlabel, *fragmentlabel; 2240 2241 datagramlabel = mbuf_to_label(datagram); 2242 fragmentlabel = mbuf_to_label(fragment); 2243 2244 MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 2245 fragmentlabel); 2246} 2247 2248void 2249mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2250{ 2251 struct label *label; 2252 2253 label = mbuf_to_label(fragment); 2254 2255 MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label); 2256} 2257 2258void 2259mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2260{ 2261 struct label *oldmbuflabel, *newmbuflabel; 2262 2263 oldmbuflabel = mbuf_to_label(oldmbuf); 2264 newmbuflabel = mbuf_to_label(newmbuf); 2265 2266 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 2267 newmbuflabel); 2268} 2269 2270void 2271mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2272{ 2273 struct label *label; 2274 2275 label = mbuf_to_label(mbuf); 2276 2277 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2278 label); 2279} 2280 2281void 2282mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2283{ 2284 struct label *label; 2285 2286 label = mbuf_to_label(mbuf); 2287 2288 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2289 label); 2290} 2291 2292void 2293mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2294{ 2295 struct label *label; 2296 2297 label = mbuf_to_label(mbuf); 2298 2299 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2300 label); 2301} 2302 2303void 2304mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2305 struct mbuf *newmbuf) 2306{ 2307 struct label *oldmbuflabel, *newmbuflabel; 2308 2309 oldmbuflabel = mbuf_to_label(oldmbuf); 2310 newmbuflabel = mbuf_to_label(newmbuf); 2311 2312 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 2313 ifnet, &ifnet->if_label, newmbuf, newmbuflabel); 2314} 2315 2316void 2317mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2318{ 2319 struct label *oldmbuflabel, *newmbuflabel; 2320 2321 oldmbuflabel = mbuf_to_label(oldmbuf); 2322 newmbuflabel = mbuf_to_label(newmbuf); 2323 2324 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 2325 newmbuflabel); 2326} 2327 2328int 2329mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2330{ 2331 struct label *label; 2332 int result; 2333 2334 label = mbuf_to_label(fragment); 2335 2336 result = 1; 2337 MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 2338 &ipq->ipq_label); 2339 2340 return (result); 2341} 2342 2343void 2344mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2345{ 2346 struct label *label; 2347 2348 label = mbuf_to_label(fragment); 2349 2350 MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label); 2351} 2352 2353void 2354mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2355{ 2356 struct label *label; 2357 2358 label = mbuf_to_label(mbuf); 2359 2360 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2361 label); 2362} 2363 2364void 2365mac_create_mount(struct ucred *cred, struct mount *mp) 2366{ 2367 2368 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2369 &mp->mnt_fslabel); 2370} 2371 2372void 2373mac_create_root_mount(struct ucred *cred, struct mount *mp) 2374{ 2375 2376 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2377 &mp->mnt_fslabel); 2378} 2379 2380int 2381mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2382{ 2383 int error; 2384 2385 if (!mac_enforce_network) 2386 return (0); 2387 2388 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2389 &ifnet->if_label); 2390 2391 return (error); 2392} 2393 2394static int 2395mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2396{ 2397 int error; 2398 2399 MAC_CHECK(check_cred_relabel, cred, newlabel); 2400 2401 return (error); 2402} 2403 2404int 2405mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2406{ 2407 int error; 2408 2409 if (!mac_enforce_process) 2410 return (0); 2411 2412 MAC_CHECK(check_cred_visible, u1, u2); 2413 2414 return (error); 2415} 2416 2417int 2418mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2419{ 2420 struct label *label; 2421 int error; 2422 2423 M_ASSERTPKTHDR(mbuf); 2424 2425 if (!mac_enforce_network) 2426 return (0); 2427 2428 label = mbuf_to_label(mbuf); 2429 2430 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2431 label); 2432 2433 return (error); 2434} 2435 2436int 2437mac_check_kenv_dump(struct ucred *cred) 2438{ 2439 int error; 2440 2441 if (!mac_enforce_system) 2442 return (0); 2443 2444 MAC_CHECK(check_kenv_dump, cred); 2445 2446 return (error); 2447} 2448 2449int 2450mac_check_kenv_get(struct ucred *cred, char *name) 2451{ 2452 int error; 2453 2454 if (!mac_enforce_system) 2455 return (0); 2456 2457 MAC_CHECK(check_kenv_get, cred, name); 2458 2459 return (error); 2460} 2461 2462int 2463mac_check_kenv_set(struct ucred *cred, char *name, char *value) 2464{ 2465 int error; 2466 2467 if (!mac_enforce_system) 2468 return (0); 2469 2470 MAC_CHECK(check_kenv_set, cred, name, value); 2471 2472 return (error); 2473} 2474 2475int 2476mac_check_kenv_unset(struct ucred *cred, char *name) 2477{ 2478 int error; 2479 2480 if (!mac_enforce_system) 2481 return (0); 2482 2483 MAC_CHECK(check_kenv_unset, cred, name); 2484 2485 return (error); 2486} 2487 2488int 2489mac_check_kld_load(struct ucred *cred, struct vnode *vp) 2490{ 2491 int error; 2492 2493 ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2494 2495 if (!mac_enforce_kld) 2496 return (0); 2497 2498 MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2499 2500 return (error); 2501} 2502 2503int 2504mac_check_kld_stat(struct ucred *cred) 2505{ 2506 int error; 2507 2508 if (!mac_enforce_kld) 2509 return (0); 2510 2511 MAC_CHECK(check_kld_stat, cred); 2512 2513 return (error); 2514} 2515 2516int 2517mac_check_kld_unload(struct ucred *cred) 2518{ 2519 int error; 2520 2521 if (!mac_enforce_kld) 2522 return (0); 2523 2524 MAC_CHECK(check_kld_unload, cred); 2525 2526 return (error); 2527} 2528 2529int 2530mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2531{ 2532 int error; 2533 2534 if (!mac_enforce_fs) 2535 return (0); 2536 2537 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2538 2539 return (error); 2540} 2541 2542int 2543mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2544 void *data) 2545{ 2546 int error; 2547 2548 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2549 2550 if (!mac_enforce_pipe) 2551 return (0); 2552 2553 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2554 2555 return (error); 2556} 2557 2558int 2559mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2560{ 2561 int error; 2562 2563 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2564 2565 if (!mac_enforce_pipe) 2566 return (0); 2567 2568 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2569 2570 return (error); 2571} 2572 2573int 2574mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2575{ 2576 int error; 2577 2578 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2579 2580 if (!mac_enforce_pipe) 2581 return (0); 2582 2583 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2584 2585 return (error); 2586} 2587 2588static int 2589mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2590 struct label *newlabel) 2591{ 2592 int error; 2593 2594 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2595 2596 if (!mac_enforce_pipe) 2597 return (0); 2598 2599 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2600 2601 return (error); 2602} 2603 2604int 2605mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2606{ 2607 int error; 2608 2609 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2610 2611 if (!mac_enforce_pipe) 2612 return (0); 2613 2614 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2615 2616 return (error); 2617} 2618 2619int 2620mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2621{ 2622 int error; 2623 2624 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2625 2626 if (!mac_enforce_pipe) 2627 return (0); 2628 2629 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2630 2631 return (error); 2632} 2633 2634int 2635mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2636{ 2637 int error; 2638 2639 PROC_LOCK_ASSERT(proc, MA_OWNED); 2640 2641 if (!mac_enforce_process) 2642 return (0); 2643 2644 MAC_CHECK(check_proc_debug, cred, proc); 2645 2646 return (error); 2647} 2648 2649int 2650mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2651{ 2652 int error; 2653 2654 PROC_LOCK_ASSERT(proc, MA_OWNED); 2655 2656 if (!mac_enforce_process) 2657 return (0); 2658 2659 MAC_CHECK(check_proc_sched, cred, proc); 2660 2661 return (error); 2662} 2663 2664int 2665mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2666{ 2667 int error; 2668 2669 PROC_LOCK_ASSERT(proc, MA_OWNED); 2670 2671 if (!mac_enforce_process) 2672 return (0); 2673 2674 MAC_CHECK(check_proc_signal, cred, proc, signum); 2675 2676 return (error); 2677} 2678 2679int 2680mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2681 struct sockaddr *sockaddr) 2682{ 2683 int error; 2684 2685 if (!mac_enforce_socket) 2686 return (0); 2687 2688 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2689 sockaddr); 2690 2691 return (error); 2692} 2693 2694int 2695mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2696 struct sockaddr *sockaddr) 2697{ 2698 int error; 2699 2700 if (!mac_enforce_socket) 2701 return (0); 2702 2703 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2704 sockaddr); 2705 2706 return (error); 2707} 2708 2709int 2710mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2711{ 2712 struct label *label; 2713 int error; 2714 2715 if (!mac_enforce_socket) 2716 return (0); 2717 2718 label = mbuf_to_label(mbuf); 2719 2720 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2721 label); 2722 2723 return (error); 2724} 2725 2726int 2727mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2728{ 2729 int error; 2730 2731 if (!mac_enforce_socket) 2732 return (0); 2733 2734 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2735 return (error); 2736} 2737 2738int 2739mac_check_socket_receive(struct ucred *cred, struct socket *so) 2740{ 2741 int error; 2742 2743 if (!mac_enforce_socket) 2744 return (0); 2745 2746 MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2747 2748 return (error); 2749} 2750 2751static int 2752mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2753 struct label *newlabel) 2754{ 2755 int error; 2756 2757 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2758 newlabel); 2759 2760 return (error); 2761} 2762 2763int 2764mac_check_socket_send(struct ucred *cred, struct socket *so) 2765{ 2766 int error; 2767 2768 if (!mac_enforce_socket) 2769 return (0); 2770 2771 MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2772 2773 return (error); 2774} 2775 2776int 2777mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2778{ 2779 int error; 2780 2781 if (!mac_enforce_socket) 2782 return (0); 2783 2784 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2785 2786 return (error); 2787} 2788 2789int 2790mac_check_sysarch_ioperm(struct ucred *cred) 2791{ 2792 int error; 2793 2794 if (!mac_enforce_system) 2795 return (0); 2796 2797 MAC_CHECK(check_sysarch_ioperm, cred); 2798 return (error); 2799} 2800 2801int 2802mac_check_system_acct(struct ucred *cred, struct vnode *vp) 2803{ 2804 int error; 2805 2806 if (vp != NULL) { 2807 ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2808 } 2809 2810 if (!mac_enforce_system) 2811 return (0); 2812 2813 MAC_CHECK(check_system_acct, cred, vp, 2814 vp != NULL ? &vp->v_label : NULL); 2815 2816 return (error); 2817} 2818 2819int 2820mac_check_system_nfsd(struct ucred *cred) 2821{ 2822 int error; 2823 2824 if (!mac_enforce_system) 2825 return (0); 2826 2827 MAC_CHECK(check_system_nfsd, cred); 2828 2829 return (error); 2830} 2831 2832int 2833mac_check_system_reboot(struct ucred *cred, int howto) 2834{ 2835 int error; 2836 2837 if (!mac_enforce_system) 2838 return (0); 2839 2840 MAC_CHECK(check_system_reboot, cred, howto); 2841 2842 return (error); 2843} 2844 2845int 2846mac_check_system_settime(struct ucred *cred) 2847{ 2848 int error; 2849 2850 if (!mac_enforce_system) 2851 return (0); 2852 2853 MAC_CHECK(check_system_settime, cred); 2854 2855 return (error); 2856} 2857 2858int 2859mac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2860{ 2861 int error; 2862 2863 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2864 2865 if (!mac_enforce_system) 2866 return (0); 2867 2868 MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2869 return (error); 2870} 2871 2872int 2873mac_check_system_swapoff(struct ucred *cred, struct vnode *vp) 2874{ 2875 int error; 2876 2877 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapoff"); 2878 2879 if (!mac_enforce_system) 2880 return (0); 2881 2882 MAC_CHECK(check_system_swapoff, cred, vp, &vp->v_label); 2883 return (error); 2884} 2885 2886int 2887mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2888 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2889{ 2890 int error; 2891 2892 /* 2893 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2894 * but since it's not exported from kern_sysctl.c, we can't. 2895 */ 2896 if (!mac_enforce_system) 2897 return (0); 2898 2899 MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2900 inkernel, new, newlen); 2901 2902 return (error); 2903} 2904 2905int 2906mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2907 struct ifnet *ifnet) 2908{ 2909 char *elements, *buffer; 2910 struct mac mac; 2911 int error; 2912 2913 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2914 if (error) 2915 return (error); 2916 2917 error = mac_check_structmac_consistent(&mac); 2918 if (error) 2919 return (error); 2920 2921 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2922 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2923 if (error) { 2924 free(elements, M_MACTEMP); 2925 return (error); 2926 } 2927 2928 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2929 error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 2930 buffer, mac.m_buflen, M_WAITOK); 2931 if (error == 0) 2932 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2933 2934 free(buffer, M_MACTEMP); 2935 free(elements, M_MACTEMP); 2936 2937 return (error); 2938} 2939 2940int 2941mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2942 struct ifnet *ifnet) 2943{ 2944 struct label intlabel; 2945 struct mac mac; 2946 char *buffer; 2947 int error; 2948 2949 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2950 if (error) 2951 return (error); 2952 2953 error = mac_check_structmac_consistent(&mac); 2954 if (error) 2955 return (error); 2956 2957 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2958 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2959 if (error) { 2960 free(buffer, M_MACTEMP); 2961 return (error); 2962 } 2963 2964 mac_init_ifnet_label(&intlabel); 2965 error = mac_internalize_ifnet_label(&intlabel, buffer); 2966 free(buffer, M_MACTEMP); 2967 if (error) { 2968 mac_destroy_ifnet_label(&intlabel); 2969 return (error); 2970 } 2971 2972 /* 2973 * XXX: Note that this is a redundant privilege check, since 2974 * policies impose this check themselves if required by the 2975 * policy. Eventually, this should go away. 2976 */ 2977 error = suser_cred(cred, 0); 2978 if (error) { 2979 mac_destroy_ifnet_label(&intlabel); 2980 return (error); 2981 } 2982 2983 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2984 &intlabel); 2985 if (error) { 2986 mac_destroy_ifnet_label(&intlabel); 2987 return (error); 2988 } 2989 2990 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2991 2992 mac_destroy_ifnet_label(&intlabel); 2993 return (0); 2994} 2995 2996void 2997mac_create_devfs_device(struct mount *mp, dev_t dev, struct devfs_dirent *de) 2998{ 2999 3000 MAC_PERFORM(create_devfs_device, mp, dev, de, &de->de_label); 3001} 3002 3003void 3004mac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 3005 struct devfs_dirent *dd, struct devfs_dirent *de) 3006{ 3007 3008 MAC_PERFORM(create_devfs_symlink, cred, mp, dd, &dd->de_label, de, 3009 &de->de_label); 3010} 3011 3012void 3013mac_create_devfs_directory(struct mount *mp, char *dirname, int dirnamelen, 3014 struct devfs_dirent *de) 3015{ 3016 3017 MAC_PERFORM(create_devfs_directory, mp, dirname, dirnamelen, de, 3018 &de->de_label); 3019} 3020 3021int 3022mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 3023 struct mac *mac) 3024{ 3025 struct label intlabel; 3026 char *buffer; 3027 int error; 3028 3029 error = mac_check_structmac_consistent(mac); 3030 if (error) 3031 return (error); 3032 3033 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3034 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 3035 if (error) { 3036 free(buffer, M_MACTEMP); 3037 return (error); 3038 } 3039 3040 mac_init_socket_label(&intlabel, M_WAITOK); 3041 error = mac_internalize_socket_label(&intlabel, buffer); 3042 free(buffer, M_MACTEMP); 3043 if (error) { 3044 mac_destroy_socket_label(&intlabel); 3045 return (error); 3046 } 3047 3048 mac_check_socket_relabel(cred, so, &intlabel); 3049 if (error) { 3050 mac_destroy_socket_label(&intlabel); 3051 return (error); 3052 } 3053 3054 mac_relabel_socket(cred, so, &intlabel); 3055 3056 mac_destroy_socket_label(&intlabel); 3057 return (0); 3058} 3059 3060int 3061mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 3062{ 3063 int error; 3064 3065 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 3066 3067 error = mac_check_pipe_relabel(cred, pipe, label); 3068 if (error) 3069 return (error); 3070 3071 mac_relabel_pipe(cred, pipe, label); 3072 3073 return (0); 3074} 3075 3076int 3077mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 3078 struct mac *mac) 3079{ 3080 char *buffer, *elements; 3081 int error; 3082 3083 error = mac_check_structmac_consistent(mac); 3084 if (error) 3085 return (error); 3086 3087 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3088 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3089 if (error) { 3090 free(elements, M_MACTEMP); 3091 return (error); 3092 } 3093 3094 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3095 error = mac_externalize_socket_label(&so->so_label, elements, 3096 buffer, mac->m_buflen, M_WAITOK); 3097 if (error == 0) 3098 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3099 3100 free(buffer, M_MACTEMP); 3101 free(elements, M_MACTEMP); 3102 3103 return (error); 3104} 3105 3106int 3107mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 3108 struct mac *mac) 3109{ 3110 char *elements, *buffer; 3111 int error; 3112 3113 error = mac_check_structmac_consistent(mac); 3114 if (error) 3115 return (error); 3116 3117 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 3118 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 3119 if (error) { 3120 free(elements, M_MACTEMP); 3121 return (error); 3122 } 3123 3124 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3125 error = mac_externalize_socket_peer_label(&so->so_peerlabel, 3126 elements, buffer, mac->m_buflen, M_WAITOK); 3127 if (error == 0) 3128 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 3129 3130 free(buffer, M_MACTEMP); 3131 free(elements, M_MACTEMP); 3132 3133 return (error); 3134} 3135 3136/* 3137 * Implementation of VOP_SETLABEL() that relies on extended attributes 3138 * to store label data. Can be referenced by filesystems supporting 3139 * extended attributes. 3140 */ 3141int 3142vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 3143{ 3144 struct vnode *vp = ap->a_vp; 3145 struct label *intlabel = ap->a_label; 3146 int error; 3147 3148 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 3149 3150 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3151 return (EOPNOTSUPP); 3152 3153 error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 3154 if (error) 3155 return (error); 3156 3157 mac_relabel_vnode(ap->a_cred, vp, intlabel); 3158 3159 return (0); 3160} 3161 3162static int 3163vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 3164{ 3165 int error; 3166 3167 if (vp->v_mount == NULL) { 3168 /* printf("vn_setlabel: null v_mount\n"); */ 3169 if (vp->v_type != VNON) 3170 printf("vn_setlabel: null v_mount with non-VNON\n"); 3171 return (EBADF); 3172 } 3173 3174 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3175 return (EOPNOTSUPP); 3176 3177 /* 3178 * Multi-phase commit. First check the policies to confirm the 3179 * change is OK. Then commit via the filesystem. Finally, 3180 * update the actual vnode label. Question: maybe the filesystem 3181 * should update the vnode at the end as part of VOP_SETLABEL()? 3182 */ 3183 error = mac_check_vnode_relabel(cred, vp, intlabel); 3184 if (error) 3185 return (error); 3186 3187 /* 3188 * VADMIN provides the opportunity for the filesystem to make 3189 * decisions about who is and is not able to modify labels 3190 * and protections on files. This might not be right. We can't 3191 * assume VOP_SETLABEL() will do it, because we might implement 3192 * that as part of vop_stdsetlabel_ea(). 3193 */ 3194 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3195 if (error) 3196 return (error); 3197 3198 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3199 if (error) 3200 return (error); 3201 3202 return (0); 3203} 3204 3205int 3206__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3207{ 3208 char *elements, *buffer; 3209 struct mac mac; 3210 struct proc *tproc; 3211 struct ucred *tcred; 3212 int error; 3213 3214 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3215 if (error) 3216 return (error); 3217 3218 error = mac_check_structmac_consistent(&mac); 3219 if (error) 3220 return (error); 3221 3222 tproc = pfind(uap->pid); 3223 if (tproc == NULL) 3224 return (ESRCH); 3225 3226 tcred = NULL; /* Satisfy gcc. */ 3227 error = p_cansee(td, tproc); 3228 if (error == 0) 3229 tcred = crhold(tproc->p_ucred); 3230 PROC_UNLOCK(tproc); 3231 if (error) 3232 return (error); 3233 3234 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3235 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3236 if (error) { 3237 free(elements, M_MACTEMP); 3238 crfree(tcred); 3239 return (error); 3240 } 3241 3242 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3243 error = mac_externalize_cred_label(&tcred->cr_label, elements, 3244 buffer, mac.m_buflen, M_WAITOK); 3245 if (error == 0) 3246 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3247 3248 free(buffer, M_MACTEMP); 3249 free(elements, M_MACTEMP); 3250 crfree(tcred); 3251 return (error); 3252} 3253 3254/* 3255 * MPSAFE 3256 */ 3257int 3258__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3259{ 3260 char *elements, *buffer; 3261 struct mac mac; 3262 int error; 3263 3264 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3265 if (error) 3266 return (error); 3267 3268 error = mac_check_structmac_consistent(&mac); 3269 if (error) 3270 return (error); 3271 3272 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3273 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3274 if (error) { 3275 free(elements, M_MACTEMP); 3276 return (error); 3277 } 3278 3279 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3280 error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3281 elements, buffer, mac.m_buflen, M_WAITOK); 3282 if (error == 0) 3283 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3284 3285 free(buffer, M_MACTEMP); 3286 free(elements, M_MACTEMP); 3287 return (error); 3288} 3289 3290/* 3291 * MPSAFE 3292 */ 3293int 3294__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3295{ 3296 struct ucred *newcred, *oldcred; 3297 struct label intlabel; 3298 struct proc *p; 3299 struct mac mac; 3300 char *buffer; 3301 int error; 3302 3303 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3304 if (error) 3305 return (error); 3306 3307 error = mac_check_structmac_consistent(&mac); 3308 if (error) 3309 return (error); 3310 3311 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3312 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3313 if (error) { 3314 free(buffer, M_MACTEMP); 3315 return (error); 3316 } 3317 3318 mac_init_cred_label(&intlabel); 3319 error = mac_internalize_cred_label(&intlabel, buffer); 3320 free(buffer, M_MACTEMP); 3321 if (error) { 3322 mac_destroy_cred_label(&intlabel); 3323 return (error); 3324 } 3325 3326 newcred = crget(); 3327 3328 p = td->td_proc; 3329 PROC_LOCK(p); 3330 oldcred = p->p_ucred; 3331 3332 error = mac_check_cred_relabel(oldcred, &intlabel); 3333 if (error) { 3334 PROC_UNLOCK(p); 3335 crfree(newcred); 3336 goto out; 3337 } 3338 3339 setsugid(p); 3340 crcopy(newcred, oldcred); 3341 mac_relabel_cred(newcred, &intlabel); 3342 p->p_ucred = newcred; 3343 3344 /* 3345 * Grab additional reference for use while revoking mmaps, prior 3346 * to releasing the proc lock and sharing the cred. 3347 */ 3348 crhold(newcred); 3349 PROC_UNLOCK(p); 3350 3351 if (mac_enforce_vm) { 3352 mtx_lock(&Giant); 3353 mac_cred_mmapped_drop_perms(td, newcred); 3354 mtx_unlock(&Giant); 3355 } 3356 3357 crfree(newcred); /* Free revocation reference. */ 3358 crfree(oldcred); 3359 3360out: 3361 mac_destroy_cred_label(&intlabel); 3362 return (error); 3363} 3364 3365/* 3366 * MPSAFE 3367 */ 3368int 3369__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3370{ 3371 char *elements, *buffer; 3372 struct label intlabel; 3373 struct file *fp; 3374 struct mac mac; 3375 struct vnode *vp; 3376 struct pipe *pipe; 3377 short label_type; 3378 int error; 3379 3380 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3381 if (error) 3382 return (error); 3383 3384 error = mac_check_structmac_consistent(&mac); 3385 if (error) 3386 return (error); 3387 3388 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3389 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3390 if (error) { 3391 free(elements, M_MACTEMP); 3392 return (error); 3393 } 3394 3395 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3396 mtx_lock(&Giant); /* VFS */ 3397 error = fget(td, uap->fd, &fp); 3398 if (error) 3399 goto out; 3400 3401 label_type = fp->f_type; 3402 switch (fp->f_type) { 3403 case DTYPE_FIFO: 3404 case DTYPE_VNODE: 3405 vp = fp->f_data; 3406 3407 mac_init_vnode_label(&intlabel); 3408 3409 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3410 mac_copy_vnode_label(&vp->v_label, &intlabel); 3411 VOP_UNLOCK(vp, 0, td); 3412 3413 break; 3414 case DTYPE_PIPE: 3415 pipe = fp->f_data; 3416 3417 mac_init_pipe_label(&intlabel); 3418 3419 PIPE_LOCK(pipe); 3420 mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3421 PIPE_UNLOCK(pipe); 3422 break; 3423 default: 3424 error = EINVAL; 3425 fdrop(fp, td); 3426 goto out; 3427 } 3428 fdrop(fp, td); 3429 3430 switch (label_type) { 3431 case DTYPE_FIFO: 3432 case DTYPE_VNODE: 3433 if (error == 0) 3434 error = mac_externalize_vnode_label(&intlabel, 3435 elements, buffer, mac.m_buflen, M_WAITOK); 3436 mac_destroy_vnode_label(&intlabel); 3437 break; 3438 case DTYPE_PIPE: 3439 error = mac_externalize_pipe_label(&intlabel, elements, 3440 buffer, mac.m_buflen, M_WAITOK); 3441 mac_destroy_pipe_label(&intlabel); 3442 break; 3443 default: 3444 panic("__mac_get_fd: corrupted label_type"); 3445 } 3446 3447 if (error == 0) 3448 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3449 3450out: 3451 mtx_unlock(&Giant); /* VFS */ 3452 free(buffer, M_MACTEMP); 3453 free(elements, M_MACTEMP); 3454 3455 return (error); 3456} 3457 3458/* 3459 * MPSAFE 3460 */ 3461int 3462__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3463{ 3464 char *elements, *buffer; 3465 struct nameidata nd; 3466 struct label intlabel; 3467 struct mac mac; 3468 int error; 3469 3470 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3471 if (error) 3472 return (error); 3473 3474 error = mac_check_structmac_consistent(&mac); 3475 if (error) 3476 return (error); 3477 3478 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3479 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3480 if (error) { 3481 free(elements, M_MACTEMP); 3482 return (error); 3483 } 3484 3485 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3486 mtx_lock(&Giant); /* VFS */ 3487 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3488 td); 3489 error = namei(&nd); 3490 if (error) 3491 goto out; 3492 3493 mac_init_vnode_label(&intlabel); 3494 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3495 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3496 mac.m_buflen, M_WAITOK); 3497 3498 NDFREE(&nd, 0); 3499 mac_destroy_vnode_label(&intlabel); 3500 3501 if (error == 0) 3502 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3503 3504out: 3505 mtx_unlock(&Giant); /* VFS */ 3506 3507 free(buffer, M_MACTEMP); 3508 free(elements, M_MACTEMP); 3509 3510 return (error); 3511} 3512 3513/* 3514 * MPSAFE 3515 */ 3516int 3517__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3518{ 3519 char *elements, *buffer; 3520 struct nameidata nd; 3521 struct label intlabel; 3522 struct mac mac; 3523 int error; 3524 3525 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3526 if (error) 3527 return (error); 3528 3529 error = mac_check_structmac_consistent(&mac); 3530 if (error) 3531 return (error); 3532 3533 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3534 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3535 if (error) { 3536 free(elements, M_MACTEMP); 3537 return (error); 3538 } 3539 3540 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3541 mtx_lock(&Giant); /* VFS */ 3542 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3543 td); 3544 error = namei(&nd); 3545 if (error) 3546 goto out; 3547 3548 mac_init_vnode_label(&intlabel); 3549 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3550 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3551 mac.m_buflen, M_WAITOK); 3552 NDFREE(&nd, 0); 3553 mac_destroy_vnode_label(&intlabel); 3554 3555 if (error == 0) 3556 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3557 3558out: 3559 mtx_unlock(&Giant); /* VFS */ 3560 3561 free(buffer, M_MACTEMP); 3562 free(elements, M_MACTEMP); 3563 3564 return (error); 3565} 3566 3567/* 3568 * MPSAFE 3569 */ 3570int 3571__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3572{ 3573 struct label intlabel; 3574 struct pipe *pipe; 3575 struct file *fp; 3576 struct mount *mp; 3577 struct vnode *vp; 3578 struct mac mac; 3579 char *buffer; 3580 int error; 3581 3582 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3583 if (error) 3584 return (error); 3585 3586 error = mac_check_structmac_consistent(&mac); 3587 if (error) 3588 return (error); 3589 3590 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3591 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3592 if (error) { 3593 free(buffer, M_MACTEMP); 3594 return (error); 3595 } 3596 3597 mtx_lock(&Giant); /* VFS */ 3598 3599 error = fget(td, uap->fd, &fp); 3600 if (error) 3601 goto out; 3602 3603 switch (fp->f_type) { 3604 case DTYPE_FIFO: 3605 case DTYPE_VNODE: 3606 mac_init_vnode_label(&intlabel); 3607 error = mac_internalize_vnode_label(&intlabel, buffer); 3608 if (error) { 3609 mac_destroy_vnode_label(&intlabel); 3610 break; 3611 } 3612 3613 vp = fp->f_data; 3614 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3615 if (error != 0) { 3616 mac_destroy_vnode_label(&intlabel); 3617 break; 3618 } 3619 3620 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3621 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3622 VOP_UNLOCK(vp, 0, td); 3623 vn_finished_write(mp); 3624 3625 mac_destroy_vnode_label(&intlabel); 3626 break; 3627 3628 case DTYPE_PIPE: 3629 mac_init_pipe_label(&intlabel); 3630 error = mac_internalize_pipe_label(&intlabel, buffer); 3631 if (error == 0) { 3632 pipe = fp->f_data; 3633 PIPE_LOCK(pipe); 3634 error = mac_pipe_label_set(td->td_ucred, pipe, 3635 &intlabel); 3636 PIPE_UNLOCK(pipe); 3637 } 3638 3639 mac_destroy_pipe_label(&intlabel); 3640 break; 3641 3642 default: 3643 error = EINVAL; 3644 } 3645 3646 fdrop(fp, td); 3647out: 3648 mtx_unlock(&Giant); /* VFS */ 3649 3650 free(buffer, M_MACTEMP); 3651 3652 return (error); 3653} 3654 3655/* 3656 * MPSAFE 3657 */ 3658int 3659__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3660{ 3661 struct label intlabel; 3662 struct nameidata nd; 3663 struct mount *mp; 3664 struct mac mac; 3665 char *buffer; 3666 int error; 3667 3668 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3669 if (error) 3670 return (error); 3671 3672 error = mac_check_structmac_consistent(&mac); 3673 if (error) 3674 return (error); 3675 3676 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3677 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3678 if (error) { 3679 free(buffer, M_MACTEMP); 3680 return (error); 3681 } 3682 3683 mac_init_vnode_label(&intlabel); 3684 error = mac_internalize_vnode_label(&intlabel, buffer); 3685 free(buffer, M_MACTEMP); 3686 if (error) { 3687 mac_destroy_vnode_label(&intlabel); 3688 return (error); 3689 } 3690 3691 mtx_lock(&Giant); /* VFS */ 3692 3693 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3694 td); 3695 error = namei(&nd); 3696 if (error == 0) { 3697 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3698 if (error == 0) 3699 error = vn_setlabel(nd.ni_vp, &intlabel, 3700 td->td_ucred); 3701 vn_finished_write(mp); 3702 } 3703 3704 NDFREE(&nd, 0); 3705 mtx_unlock(&Giant); /* VFS */ 3706 mac_destroy_vnode_label(&intlabel); 3707 3708 return (error); 3709} 3710 3711/* 3712 * MPSAFE 3713 */ 3714int 3715__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3716{ 3717 struct label intlabel; 3718 struct nameidata nd; 3719 struct mount *mp; 3720 struct mac mac; 3721 char *buffer; 3722 int error; 3723 3724 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3725 if (error) 3726 return (error); 3727 3728 error = mac_check_structmac_consistent(&mac); 3729 if (error) 3730 return (error); 3731 3732 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3733 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3734 if (error) { 3735 free(buffer, M_MACTEMP); 3736 return (error); 3737 } 3738 3739 mac_init_vnode_label(&intlabel); 3740 error = mac_internalize_vnode_label(&intlabel, buffer); 3741 free(buffer, M_MACTEMP); 3742 if (error) { 3743 mac_destroy_vnode_label(&intlabel); 3744 return (error); 3745 } 3746 3747 mtx_lock(&Giant); /* VFS */ 3748 3749 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3750 td); 3751 error = namei(&nd); 3752 if (error == 0) { 3753 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3754 if (error == 0) 3755 error = vn_setlabel(nd.ni_vp, &intlabel, 3756 td->td_ucred); 3757 vn_finished_write(mp); 3758 } 3759 3760 NDFREE(&nd, 0); 3761 mtx_unlock(&Giant); /* VFS */ 3762 mac_destroy_vnode_label(&intlabel); 3763 3764 return (error); 3765} 3766 3767/* 3768 * MPSAFE 3769 */ 3770int 3771mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3772{ 3773 struct mac_policy_conf *mpc; 3774 char target[MAC_MAX_POLICY_NAME]; 3775 int error; 3776 3777 error = copyinstr(uap->policy, target, sizeof(target), NULL); 3778 if (error) 3779 return (error); 3780 3781 error = ENOSYS; 3782 MAC_POLICY_LIST_BUSY(); 3783 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3784 if (strcmp(mpc->mpc_name, target) == 0 && 3785 mpc->mpc_ops->mpo_syscall != NULL) { 3786 error = mpc->mpc_ops->mpo_syscall(td, 3787 uap->call, uap->arg); 3788 goto out; 3789 } 3790 } 3791 3792out: 3793 MAC_POLICY_LIST_UNBUSY(); 3794 return (error); 3795} 3796 3797SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3798SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3799 3800#else /* !MAC */ 3801 3802int 3803__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3804{ 3805 3806 return (ENOSYS); 3807} 3808 3809int 3810__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3811{ 3812 3813 return (ENOSYS); 3814} 3815 3816int 3817__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3818{ 3819 3820 return (ENOSYS); 3821} 3822 3823int 3824__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3825{ 3826 3827 return (ENOSYS); 3828} 3829 3830int 3831__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3832{ 3833 3834 return (ENOSYS); 3835} 3836 3837int 3838__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3839{ 3840 3841 return (ENOSYS); 3842} 3843 3844int 3845__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3846{ 3847 3848 return (ENOSYS); 3849} 3850 3851int 3852__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3853{ 3854 3855 return (ENOSYS); 3856} 3857 3858int 3859__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3860{ 3861 3862 return (ENOSYS); 3863} 3864 3865int 3866mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3867{ 3868 3869 return (ENOSYS); 3870} 3871 3872#endif 3873