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