49 50#include <sys/param.h> 51#include <sys/extattr.h> 52#include <sys/kernel.h> 53#include <sys/lock.h> 54#include <sys/malloc.h> 55#include <sys/mutex.h> 56#include <sys/mac.h> 57#include <sys/module.h> 58#include <sys/proc.h> 59#include <sys/systm.h> 60#include <sys/sysproto.h> 61#include <sys/sysent.h> 62#include <sys/vnode.h> 63#include <sys/mount.h> 64#include <sys/file.h> 65#include <sys/namei.h> 66#include <sys/socket.h> 67#include <sys/pipe.h> 68#include <sys/socketvar.h> 69#include <sys/sysctl.h> 70 71#include <vm/vm.h> 72#include <vm/pmap.h> 73#include <vm/vm_map.h> 74#include <vm/vm_object.h> 75 76#include <sys/mac_policy.h> 77 78#include <fs/devfs/devfs.h> 79 80#include <net/bpfdesc.h> 81#include <net/if.h> 82#include <net/if_var.h> 83 84#include <netinet/in.h> 85#include <netinet/ip_var.h> 86 87#ifdef MAC 88 89/* 90 * Declare that the kernel provides MAC support, version 1. This permits 91 * modules to refuse to be loaded if the necessary support isn't present, 92 * even if it's pre-boot. 93 */ 94MODULE_VERSION(kernel_mac_support, 1); 95 96SYSCTL_DECL(_security); 97 98SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 99 "TrustedBSD MAC policy controls"); 100#ifndef MAC_MAX_POLICIES 101#define MAC_MAX_POLICIES 8 102#endif 103#if MAC_MAX_POLICIES > 32 104#error "MAC_MAX_POLICIES too large" 105#endif 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 111static int mac_late = 0; 112 113static int mac_enforce_fs = 1; 114SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 115 &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 116TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 117 118static int mac_enforce_network = 1; 119SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 120 &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 121TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 122 123static int mac_enforce_pipe = 1; 124SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 125 &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 126TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 127 128static int mac_enforce_process = 1; 129SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 130 &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 131TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 132 133static int mac_enforce_socket = 1; 134SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 135 &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 136TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 137 138static int mac_enforce_vm = 1; 139SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 140 &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 141TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 142 143static int mac_label_size = sizeof(struct mac); 144SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD, 145 &mac_label_size, 0, "Pre-compiled MAC label size"); 146 147static int mac_cache_fslabel_in_vnode = 1; 148SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW, 149 &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode"); 150TUNABLE_INT("security.mac.cache_fslabel_in_vnode", 151 &mac_cache_fslabel_in_vnode); 152 153static int mac_vnode_label_cache_hits = 0; 154SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD, 155 &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels"); 156static int mac_vnode_label_cache_misses = 0; 157SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD, 158 &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels"); 159 160static int mac_mmap_revocation = 1; 161SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 162 &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 163 "relabel"); 164static int mac_mmap_revocation_via_cow = 0; 165SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 166 &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 167 "copy-on-write semantics, or by removing all write access"); 168 169#ifdef MAC_DEBUG 170SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 171 "TrustedBSD MAC debug info"); 172 173static int mac_debug_label_fallback = 0; 174SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 175 &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 176 "when label is corrupted."); 177TUNABLE_INT("security.mac.debug_label_fallback", 178 &mac_debug_label_fallback); 179 180static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 181 nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 182 nmacipqs, nmacpipes; 183SYSCTL_UINT(_security_mac_debug, OID_AUTO, mbufs, CTLFLAG_RD, 184 &nmacmbufs, 0, "number of mbufs in use"); 185SYSCTL_UINT(_security_mac_debug, OID_AUTO, creds, CTLFLAG_RD, 186 &nmaccreds, 0, "number of ucreds in use"); 187SYSCTL_UINT(_security_mac_debug, OID_AUTO, ifnets, CTLFLAG_RD, 188 &nmacifnets, 0, "number of ifnets in use"); 189SYSCTL_UINT(_security_mac_debug, OID_AUTO, ipqs, CTLFLAG_RD, 190 &nmacipqs, 0, "number of ipqs in use"); 191SYSCTL_UINT(_security_mac_debug, OID_AUTO, bpfdescs, CTLFLAG_RD, 192 &nmacbpfdescs, 0, "number of bpfdescs in use"); 193SYSCTL_UINT(_security_mac_debug, OID_AUTO, sockets, CTLFLAG_RD, 194 &nmacsockets, 0, "number of sockets in use"); 195SYSCTL_UINT(_security_mac_debug, OID_AUTO, pipes, CTLFLAG_RD, 196 &nmacpipes, 0, "number of pipes in use"); 197SYSCTL_UINT(_security_mac_debug, OID_AUTO, mounts, CTLFLAG_RD, 198 &nmacmounts, 0, "number of mounts in use"); 199SYSCTL_UINT(_security_mac_debug, OID_AUTO, temp, CTLFLAG_RD, 200 &nmactemp, 0, "number of temporary labels in use"); 201SYSCTL_UINT(_security_mac_debug, OID_AUTO, vnodes, CTLFLAG_RD, 202 &nmacvnodes, 0, "number of vnodes in use"); 203SYSCTL_UINT(_security_mac_debug, OID_AUTO, devfsdirents, CTLFLAG_RD, 204 &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 205#endif 206 207static int error_select(int error1, int error2); 208static int mac_externalize(struct label *label, struct mac *mac); 209static int mac_policy_register(struct mac_policy_conf *mpc); 210static int mac_policy_unregister(struct mac_policy_conf *mpc); 211 212static int mac_stdcreatevnode_ea(struct vnode *vp); 213static void mac_cred_mmapped_drop_perms(struct thread *td, 214 struct ucred *cred); 215static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 216 struct ucred *cred, struct vm_map *map); 217 218MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 219MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 220 221/* 222 * mac_policy_list_lock protects the consistency of 'mac_policy_list', 223 * the linked list of attached policy modules. Read-only consumers of 224 * the list must acquire a shared lock for the duration of their use; 225 * writers must acquire an exclusive lock. Note that for compound 226 * operations, locks should be held for the entire compound operation, 227 * and that this is not yet done for relabel requests. 228 */ 229static struct mtx mac_policy_list_lock; 230static LIST_HEAD(, mac_policy_conf) mac_policy_list; 231static int mac_policy_list_busy; 232#define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 233 "mac_policy_list_lock", NULL, MTX_DEF); 234#define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 235#define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 236 237#define MAC_POLICY_LIST_BUSY() do { \ 238 MAC_POLICY_LIST_LOCK(); \ 239 mac_policy_list_busy++; \ 240 MAC_POLICY_LIST_UNLOCK(); \ 241} while (0) 242 243#define MAC_POLICY_LIST_UNBUSY() do { \ 244 MAC_POLICY_LIST_LOCK(); \ 245 mac_policy_list_busy--; \ 246 if (mac_policy_list_busy < 0) \ 247 panic("Extra mac_policy_list_busy--"); \ 248 MAC_POLICY_LIST_UNLOCK(); \ 249} while (0) 250 251/* 252 * MAC_CHECK performs the designated check by walking the policy 253 * module list and checking with each as to how it feels about the 254 * request. Note that it returns its value via 'error' in the scope 255 * of the caller. 256 */ 257#define MAC_CHECK(check, args...) do { \ 258 struct mac_policy_conf *mpc; \ 259 \ 260 error = 0; \ 261 MAC_POLICY_LIST_BUSY(); \ 262 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 263 if (mpc->mpc_ops->mpo_ ## check != NULL) \ 264 error = error_select( \ 265 mpc->mpc_ops->mpo_ ## check (args), \ 266 error); \ 267 } \ 268 MAC_POLICY_LIST_UNBUSY(); \ 269} while (0) 270 271/* 272 * MAC_BOOLEAN performs the designated boolean composition by walking 273 * the module list, invoking each instance of the operation, and 274 * combining the results using the passed C operator. Note that it 275 * returns its value via 'result' in the scope of the caller, which 276 * should be initialized by the caller in a meaningful way to get 277 * a meaningful result. 278 */ 279#define MAC_BOOLEAN(operation, composition, args...) do { \ 280 struct mac_policy_conf *mpc; \ 281 \ 282 MAC_POLICY_LIST_BUSY(); \ 283 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 284 if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 285 result = result composition \ 286 mpc->mpc_ops->mpo_ ## operation (args); \ 287 } \ 288 MAC_POLICY_LIST_UNBUSY(); \ 289} while (0) 290 291/* 292 * MAC_PERFORM performs the designated operation by walking the policy 293 * module list and invoking that operation for each policy. 294 */ 295#define MAC_PERFORM(operation, args...) do { \ 296 struct mac_policy_conf *mpc; \ 297 \ 298 MAC_POLICY_LIST_BUSY(); \ 299 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 300 if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 301 mpc->mpc_ops->mpo_ ## operation (args); \ 302 } \ 303 MAC_POLICY_LIST_UNBUSY(); \ 304} while (0) 305 306/* 307 * Initialize the MAC subsystem, including appropriate SMP locks. 308 */ 309static void 310mac_init(void) 311{ 312 313 LIST_INIT(&mac_policy_list); 314 MAC_POLICY_LIST_LOCKINIT(); 315} 316 317/* 318 * For the purposes of modules that want to know if they were loaded 319 * "early", set the mac_late flag once we've processed modules either 320 * linked into the kernel, or loaded before the kernel startup. 321 */ 322static void 323mac_late_init(void) 324{ 325 326 mac_late = 1; 327} 328 329/* 330 * Allow MAC policy modules to register during boot, etc. 331 */ 332int 333mac_policy_modevent(module_t mod, int type, void *data) 334{ 335 struct mac_policy_conf *mpc; 336 int error; 337 338 error = 0; 339 mpc = (struct mac_policy_conf *) data; 340 341 switch (type) { 342 case MOD_LOAD: 343 if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 344 mac_late) { 345 printf("mac_policy_modevent: can't load %s policy " 346 "after booting\n", mpc->mpc_name); 347 error = EBUSY; 348 break; 349 } 350 error = mac_policy_register(mpc); 351 break; 352 case MOD_UNLOAD: 353 /* Don't unregister the module if it was never registered. */ 354 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 355 != 0) 356 error = mac_policy_unregister(mpc); 357 else 358 error = 0; 359 break; 360 default: 361 break; 362 } 363 364 return (error); 365} 366 367static int 368mac_policy_register(struct mac_policy_conf *mpc) 369{ 370 struct mac_policy_conf *tmpc; 371 struct mac_policy_op_entry *mpe; 372 int slot; 373 374 MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops), 375 M_MACOPVEC, M_WAITOK | M_ZERO); 376 for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) { 377 switch (mpe->mpe_constant) { 378 case MAC_OP_LAST: 379 /* 380 * Doesn't actually happen, but this allows checking 381 * that all enumerated values are handled. 382 */ 383 break; 384 case MAC_DESTROY: 385 mpc->mpc_ops->mpo_destroy = 386 mpe->mpe_function; 387 break; 388 case MAC_INIT: 389 mpc->mpc_ops->mpo_init = 390 mpe->mpe_function; 391 break; 392 case MAC_SYSCALL: 393 mpc->mpc_ops->mpo_syscall = 394 mpe->mpe_function; 395 break; 396 case MAC_INIT_BPFDESC: 397 mpc->mpc_ops->mpo_init_bpfdesc = 398 mpe->mpe_function; 399 break; 400 case MAC_INIT_CRED: 401 mpc->mpc_ops->mpo_init_cred = 402 mpe->mpe_function; 403 break; 404 case MAC_INIT_DEVFSDIRENT: 405 mpc->mpc_ops->mpo_init_devfsdirent = 406 mpe->mpe_function; 407 break; 408 case MAC_INIT_IFNET: 409 mpc->mpc_ops->mpo_init_ifnet = 410 mpe->mpe_function; 411 break; 412 case MAC_INIT_IPQ: 413 mpc->mpc_ops->mpo_init_ipq = 414 mpe->mpe_function; 415 break; 416 case MAC_INIT_MBUF: 417 mpc->mpc_ops->mpo_init_mbuf = 418 mpe->mpe_function; 419 break; 420 case MAC_INIT_MOUNT: 421 mpc->mpc_ops->mpo_init_mount = 422 mpe->mpe_function; 423 break; 424 case MAC_INIT_PIPE: 425 mpc->mpc_ops->mpo_init_pipe = 426 mpe->mpe_function; 427 break; 428 case MAC_INIT_SOCKET: 429 mpc->mpc_ops->mpo_init_socket = 430 mpe->mpe_function; 431 break; 432 case MAC_INIT_TEMP: 433 mpc->mpc_ops->mpo_init_temp = 434 mpe->mpe_function; 435 break; 436 case MAC_INIT_VNODE: 437 mpc->mpc_ops->mpo_init_vnode = 438 mpe->mpe_function; 439 break; 440 case MAC_DESTROY_BPFDESC: 441 mpc->mpc_ops->mpo_destroy_bpfdesc = 442 mpe->mpe_function; 443 break; 444 case MAC_DESTROY_CRED: 445 mpc->mpc_ops->mpo_destroy_cred = 446 mpe->mpe_function; 447 break; 448 case MAC_DESTROY_DEVFSDIRENT: 449 mpc->mpc_ops->mpo_destroy_devfsdirent = 450 mpe->mpe_function; 451 break; 452 case MAC_DESTROY_IFNET: 453 mpc->mpc_ops->mpo_destroy_ifnet = 454 mpe->mpe_function; 455 break; 456 case MAC_DESTROY_IPQ: 457 mpc->mpc_ops->mpo_destroy_ipq = 458 mpe->mpe_function; 459 break; 460 case MAC_DESTROY_MBUF: 461 mpc->mpc_ops->mpo_destroy_mbuf = 462 mpe->mpe_function; 463 break; 464 case MAC_DESTROY_MOUNT: 465 mpc->mpc_ops->mpo_destroy_mount = 466 mpe->mpe_function; 467 break; 468 case MAC_DESTROY_PIPE: 469 mpc->mpc_ops->mpo_destroy_pipe = 470 mpe->mpe_function; 471 break; 472 case MAC_DESTROY_SOCKET: 473 mpc->mpc_ops->mpo_destroy_socket = 474 mpe->mpe_function; 475 break; 476 case MAC_DESTROY_TEMP: 477 mpc->mpc_ops->mpo_destroy_temp = 478 mpe->mpe_function; 479 break; 480 case MAC_DESTROY_VNODE: 481 mpc->mpc_ops->mpo_destroy_vnode = 482 mpe->mpe_function; 483 break; 484 case MAC_EXTERNALIZE: 485 mpc->mpc_ops->mpo_externalize = 486 mpe->mpe_function; 487 break; 488 case MAC_INTERNALIZE: 489 mpc->mpc_ops->mpo_internalize = 490 mpe->mpe_function; 491 break; 492 case MAC_CREATE_DEVFS_DEVICE: 493 mpc->mpc_ops->mpo_create_devfs_device = 494 mpe->mpe_function; 495 break; 496 case MAC_CREATE_DEVFS_DIRECTORY: 497 mpc->mpc_ops->mpo_create_devfs_directory = 498 mpe->mpe_function; 499 break; 500 case MAC_CREATE_DEVFS_VNODE: 501 mpc->mpc_ops->mpo_create_devfs_vnode = 502 mpe->mpe_function; 503 break; 504 case MAC_STDCREATEVNODE_EA: 505 mpc->mpc_ops->mpo_stdcreatevnode_ea = 506 mpe->mpe_function; 507 break; 508 case MAC_CREATE_VNODE: 509 mpc->mpc_ops->mpo_create_vnode = 510 mpe->mpe_function; 511 break; 512 case MAC_CREATE_MOUNT: 513 mpc->mpc_ops->mpo_create_mount = 514 mpe->mpe_function; 515 break; 516 case MAC_CREATE_ROOT_MOUNT: 517 mpc->mpc_ops->mpo_create_root_mount = 518 mpe->mpe_function; 519 break; 520 case MAC_RELABEL_VNODE: 521 mpc->mpc_ops->mpo_relabel_vnode = 522 mpe->mpe_function; 523 break; 524 case MAC_UPDATE_DEVFSDIRENT: 525 mpc->mpc_ops->mpo_update_devfsdirent = 526 mpe->mpe_function; 527 break; 528 case MAC_UPDATE_PROCFSVNODE: 529 mpc->mpc_ops->mpo_update_procfsvnode = 530 mpe->mpe_function; 531 break; 532 case MAC_UPDATE_VNODE_FROM_EXTATTR: 533 mpc->mpc_ops->mpo_update_vnode_from_extattr = 534 mpe->mpe_function; 535 break; 536 case MAC_UPDATE_VNODE_FROM_EXTERNALIZED: 537 mpc->mpc_ops->mpo_update_vnode_from_externalized = 538 mpe->mpe_function; 539 break; 540 case MAC_UPDATE_VNODE_FROM_MOUNT: 541 mpc->mpc_ops->mpo_update_vnode_from_mount = 542 mpe->mpe_function; 543 break; 544 case MAC_CREATE_MBUF_FROM_SOCKET: 545 mpc->mpc_ops->mpo_create_mbuf_from_socket = 546 mpe->mpe_function; 547 break; 548 case MAC_CREATE_PIPE: 549 mpc->mpc_ops->mpo_create_pipe = 550 mpe->mpe_function; 551 break; 552 case MAC_CREATE_SOCKET: 553 mpc->mpc_ops->mpo_create_socket = 554 mpe->mpe_function; 555 break; 556 case MAC_CREATE_SOCKET_FROM_SOCKET: 557 mpc->mpc_ops->mpo_create_socket_from_socket = 558 mpe->mpe_function; 559 break; 560 case MAC_RELABEL_PIPE: 561 mpc->mpc_ops->mpo_relabel_pipe = 562 mpe->mpe_function; 563 break; 564 case MAC_RELABEL_SOCKET: 565 mpc->mpc_ops->mpo_relabel_socket = 566 mpe->mpe_function; 567 break; 568 case MAC_SET_SOCKET_PEER_FROM_MBUF: 569 mpc->mpc_ops->mpo_set_socket_peer_from_mbuf = 570 mpe->mpe_function; 571 break; 572 case MAC_SET_SOCKET_PEER_FROM_SOCKET: 573 mpc->mpc_ops->mpo_set_socket_peer_from_socket = 574 mpe->mpe_function; 575 break; 576 case MAC_CREATE_BPFDESC: 577 mpc->mpc_ops->mpo_create_bpfdesc = 578 mpe->mpe_function; 579 break; 580 case MAC_CREATE_DATAGRAM_FROM_IPQ: 581 mpc->mpc_ops->mpo_create_datagram_from_ipq = 582 mpe->mpe_function; 583 break; 584 case MAC_CREATE_FRAGMENT: 585 mpc->mpc_ops->mpo_create_fragment = 586 mpe->mpe_function; 587 break; 588 case MAC_CREATE_IFNET: 589 mpc->mpc_ops->mpo_create_ifnet = 590 mpe->mpe_function; 591 break; 592 case MAC_CREATE_IPQ: 593 mpc->mpc_ops->mpo_create_ipq = 594 mpe->mpe_function; 595 break; 596 case MAC_CREATE_MBUF_FROM_MBUF: 597 mpc->mpc_ops->mpo_create_mbuf_from_mbuf = 598 mpe->mpe_function; 599 break; 600 case MAC_CREATE_MBUF_LINKLAYER: 601 mpc->mpc_ops->mpo_create_mbuf_linklayer = 602 mpe->mpe_function; 603 break; 604 case MAC_CREATE_MBUF_FROM_BPFDESC: 605 mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc = 606 mpe->mpe_function; 607 break; 608 case MAC_CREATE_MBUF_FROM_IFNET: 609 mpc->mpc_ops->mpo_create_mbuf_from_ifnet = 610 mpe->mpe_function; 611 break; 612 case MAC_CREATE_MBUF_MULTICAST_ENCAP: 613 mpc->mpc_ops->mpo_create_mbuf_multicast_encap = 614 mpe->mpe_function; 615 break; 616 case MAC_CREATE_MBUF_NETLAYER: 617 mpc->mpc_ops->mpo_create_mbuf_netlayer = 618 mpe->mpe_function; 619 break; 620 case MAC_FRAGMENT_MATCH: 621 mpc->mpc_ops->mpo_fragment_match = 622 mpe->mpe_function; 623 break; 624 case MAC_RELABEL_IFNET: 625 mpc->mpc_ops->mpo_relabel_ifnet = 626 mpe->mpe_function; 627 break; 628 case MAC_UPDATE_IPQ: 629 mpc->mpc_ops->mpo_update_ipq = 630 mpe->mpe_function; 631 break; 632 case MAC_CREATE_CRED: 633 mpc->mpc_ops->mpo_create_cred = 634 mpe->mpe_function; 635 break; 636 case MAC_EXECVE_TRANSITION: 637 mpc->mpc_ops->mpo_execve_transition = 638 mpe->mpe_function; 639 break; 640 case MAC_EXECVE_WILL_TRANSITION: 641 mpc->mpc_ops->mpo_execve_will_transition = 642 mpe->mpe_function; 643 break; 644 case MAC_CREATE_PROC0: 645 mpc->mpc_ops->mpo_create_proc0 = mpe->mpe_function; 646 break; 647 case MAC_CREATE_PROC1: 648 mpc->mpc_ops->mpo_create_proc1 = mpe->mpe_function; 649 break; 650 case MAC_RELABEL_CRED: 651 mpc->mpc_ops->mpo_relabel_cred = 652 mpe->mpe_function; 653 break; 654 case MAC_CHECK_BPFDESC_RECEIVE: 655 mpc->mpc_ops->mpo_check_bpfdesc_receive = 656 mpe->mpe_function; 657 break; 658 case MAC_CHECK_CRED_RELABEL: 659 mpc->mpc_ops->mpo_check_cred_relabel = 660 mpe->mpe_function; 661 break; 662 case MAC_CHECK_CRED_VISIBLE: 663 mpc->mpc_ops->mpo_check_cred_visible = 664 mpe->mpe_function; 665 break; 666 case MAC_CHECK_IFNET_RELABEL: 667 mpc->mpc_ops->mpo_check_ifnet_relabel = 668 mpe->mpe_function; 669 break; 670 case MAC_CHECK_IFNET_TRANSMIT: 671 mpc->mpc_ops->mpo_check_ifnet_transmit = 672 mpe->mpe_function; 673 break; 674 case MAC_CHECK_MOUNT_STAT: 675 mpc->mpc_ops->mpo_check_mount_stat = 676 mpe->mpe_function; 677 break; 678 case MAC_CHECK_PIPE_IOCTL: 679 mpc->mpc_ops->mpo_check_pipe_ioctl = 680 mpe->mpe_function; 681 break; 682 case MAC_CHECK_PIPE_POLL: 683 mpc->mpc_ops->mpo_check_pipe_poll = 684 mpe->mpe_function; 685 break; 686 case MAC_CHECK_PIPE_READ: 687 mpc->mpc_ops->mpo_check_pipe_read = 688 mpe->mpe_function; 689 break; 690 case MAC_CHECK_PIPE_RELABEL: 691 mpc->mpc_ops->mpo_check_pipe_relabel = 692 mpe->mpe_function; 693 break; 694 case MAC_CHECK_PIPE_STAT: 695 mpc->mpc_ops->mpo_check_pipe_stat = 696 mpe->mpe_function; 697 break; 698 case MAC_CHECK_PIPE_WRITE: 699 mpc->mpc_ops->mpo_check_pipe_write = 700 mpe->mpe_function; 701 break; 702 case MAC_CHECK_PROC_DEBUG: 703 mpc->mpc_ops->mpo_check_proc_debug = 704 mpe->mpe_function; 705 break; 706 case MAC_CHECK_PROC_SCHED: 707 mpc->mpc_ops->mpo_check_proc_sched = 708 mpe->mpe_function; 709 break; 710 case MAC_CHECK_PROC_SIGNAL: 711 mpc->mpc_ops->mpo_check_proc_signal = 712 mpe->mpe_function; 713 break; 714 case MAC_CHECK_SOCKET_BIND: 715 mpc->mpc_ops->mpo_check_socket_bind = 716 mpe->mpe_function; 717 break; 718 case MAC_CHECK_SOCKET_CONNECT: 719 mpc->mpc_ops->mpo_check_socket_connect = 720 mpe->mpe_function; 721 break; 722 case MAC_CHECK_SOCKET_DELIVER: 723 mpc->mpc_ops->mpo_check_socket_deliver = 724 mpe->mpe_function; 725 break; 726 case MAC_CHECK_SOCKET_LISTEN: 727 mpc->mpc_ops->mpo_check_socket_listen = 728 mpe->mpe_function; 729 break; 730 case MAC_CHECK_SOCKET_RELABEL: 731 mpc->mpc_ops->mpo_check_socket_relabel = 732 mpe->mpe_function; 733 break; 734 case MAC_CHECK_SOCKET_VISIBLE: 735 mpc->mpc_ops->mpo_check_socket_visible = 736 mpe->mpe_function; 737 break; 738 case MAC_CHECK_VNODE_ACCESS: 739 mpc->mpc_ops->mpo_check_vnode_access = 740 mpe->mpe_function; 741 break; 742 case MAC_CHECK_VNODE_CHDIR: 743 mpc->mpc_ops->mpo_check_vnode_chdir = 744 mpe->mpe_function; 745 break; 746 case MAC_CHECK_VNODE_CHROOT: 747 mpc->mpc_ops->mpo_check_vnode_chroot = 748 mpe->mpe_function; 749 break; 750 case MAC_CHECK_VNODE_CREATE: 751 mpc->mpc_ops->mpo_check_vnode_create = 752 mpe->mpe_function; 753 break; 754 case MAC_CHECK_VNODE_DELETE: 755 mpc->mpc_ops->mpo_check_vnode_delete = 756 mpe->mpe_function; 757 break; 758 case MAC_CHECK_VNODE_DELETEACL: 759 mpc->mpc_ops->mpo_check_vnode_deleteacl = 760 mpe->mpe_function; 761 break; 762 case MAC_CHECK_VNODE_EXEC: 763 mpc->mpc_ops->mpo_check_vnode_exec = 764 mpe->mpe_function; 765 break; 766 case MAC_CHECK_VNODE_GETACL: 767 mpc->mpc_ops->mpo_check_vnode_getacl = 768 mpe->mpe_function; 769 break; 770 case MAC_CHECK_VNODE_GETEXTATTR: 771 mpc->mpc_ops->mpo_check_vnode_getextattr = 772 mpe->mpe_function; 773 break; 774 case MAC_CHECK_VNODE_LOOKUP: 775 mpc->mpc_ops->mpo_check_vnode_lookup = 776 mpe->mpe_function; 777 break; 778 case MAC_CHECK_VNODE_MMAP_PERMS: 779 mpc->mpc_ops->mpo_check_vnode_mmap_perms = 780 mpe->mpe_function; 781 break; 782 case MAC_CHECK_VNODE_OPEN: 783 mpc->mpc_ops->mpo_check_vnode_open = 784 mpe->mpe_function; 785 break; 786 case MAC_CHECK_VNODE_POLL: 787 mpc->mpc_ops->mpo_check_vnode_poll = 788 mpe->mpe_function; 789 break; 790 case MAC_CHECK_VNODE_READ: 791 mpc->mpc_ops->mpo_check_vnode_read = 792 mpe->mpe_function; 793 break; 794 case MAC_CHECK_VNODE_READDIR: 795 mpc->mpc_ops->mpo_check_vnode_readdir = 796 mpe->mpe_function; 797 break; 798 case MAC_CHECK_VNODE_READLINK: 799 mpc->mpc_ops->mpo_check_vnode_readlink = 800 mpe->mpe_function; 801 break; 802 case MAC_CHECK_VNODE_RELABEL: 803 mpc->mpc_ops->mpo_check_vnode_relabel = 804 mpe->mpe_function; 805 break; 806 case MAC_CHECK_VNODE_RENAME_FROM: 807 mpc->mpc_ops->mpo_check_vnode_rename_from = 808 mpe->mpe_function; 809 break; 810 case MAC_CHECK_VNODE_RENAME_TO: 811 mpc->mpc_ops->mpo_check_vnode_rename_to = 812 mpe->mpe_function; 813 break; 814 case MAC_CHECK_VNODE_REVOKE: 815 mpc->mpc_ops->mpo_check_vnode_revoke = 816 mpe->mpe_function; 817 break; 818 case MAC_CHECK_VNODE_SETACL: 819 mpc->mpc_ops->mpo_check_vnode_setacl = 820 mpe->mpe_function; 821 break; 822 case MAC_CHECK_VNODE_SETEXTATTR: 823 mpc->mpc_ops->mpo_check_vnode_setextattr = 824 mpe->mpe_function; 825 break; 826 case MAC_CHECK_VNODE_SETFLAGS: 827 mpc->mpc_ops->mpo_check_vnode_setflags = 828 mpe->mpe_function; 829 break; 830 case MAC_CHECK_VNODE_SETMODE: 831 mpc->mpc_ops->mpo_check_vnode_setmode = 832 mpe->mpe_function; 833 break; 834 case MAC_CHECK_VNODE_SETOWNER: 835 mpc->mpc_ops->mpo_check_vnode_setowner = 836 mpe->mpe_function; 837 break; 838 case MAC_CHECK_VNODE_SETUTIMES: 839 mpc->mpc_ops->mpo_check_vnode_setutimes = 840 mpe->mpe_function; 841 break; 842 case MAC_CHECK_VNODE_STAT: 843 mpc->mpc_ops->mpo_check_vnode_stat = 844 mpe->mpe_function; 845 break; 846 case MAC_CHECK_VNODE_WRITE: 847 mpc->mpc_ops->mpo_check_vnode_write = 848 mpe->mpe_function; 849 break; 850/* 851 default: 852 printf("MAC policy `%s': unknown operation %d\n", 853 mpc->mpc_name, mpe->mpe_constant); 854 return (EINVAL); 855*/ 856 } 857 } 858 MAC_POLICY_LIST_LOCK(); 859 if (mac_policy_list_busy > 0) { 860 MAC_POLICY_LIST_UNLOCK(); 861 FREE(mpc->mpc_ops, M_MACOPVEC); 862 mpc->mpc_ops = NULL; 863 return (EBUSY); 864 } 865 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 866 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 867 MAC_POLICY_LIST_UNLOCK(); 868 FREE(mpc->mpc_ops, M_MACOPVEC); 869 mpc->mpc_ops = NULL; 870 return (EEXIST); 871 } 872 } 873 if (mpc->mpc_field_off != NULL) { 874 slot = ffs(mac_policy_offsets_free); 875 if (slot == 0) { 876 MAC_POLICY_LIST_UNLOCK(); 877 FREE(mpc->mpc_ops, M_MACOPVEC); 878 mpc->mpc_ops = NULL; 879 return (ENOMEM); 880 } 881 slot--; 882 mac_policy_offsets_free &= ~(1 << slot); 883 *mpc->mpc_field_off = slot; 884 } 885 mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 886 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 887 888 /* Per-policy initialization. */ 889 if (mpc->mpc_ops->mpo_init != NULL) 890 (*(mpc->mpc_ops->mpo_init))(mpc); 891 MAC_POLICY_LIST_UNLOCK(); 892 893 printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 894 mpc->mpc_name); 895 896 return (0); 897} 898 899static int 900mac_policy_unregister(struct mac_policy_conf *mpc) 901{ 902 903#if 0 904 /* 905 * Don't allow unloading modules with private data. 906 */ 907 if (mpc->mpc_field_off != NULL) 908 return (EBUSY); 909#endif 910 if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) 911 return (EBUSY); 912 MAC_POLICY_LIST_LOCK(); 913 if (mac_policy_list_busy > 0) { 914 MAC_POLICY_LIST_UNLOCK(); 915 return (EBUSY); 916 } 917 if (mpc->mpc_ops->mpo_destroy != NULL) 918 (*(mpc->mpc_ops->mpo_destroy))(mpc); 919 920 LIST_REMOVE(mpc, mpc_list); 921 MAC_POLICY_LIST_UNLOCK(); 922 923 FREE(mpc->mpc_ops, M_MACOPVEC); 924 mpc->mpc_ops = NULL; 925 926 printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 927 mpc->mpc_name); 928 929 return (0); 930} 931 932/* 933 * Define an error value precedence, and given two arguments, selects the 934 * value with the higher precedence. 935 */ 936static int 937error_select(int error1, int error2) 938{ 939 940 /* Certain decision-making errors take top priority. */ 941 if (error1 == EDEADLK || error2 == EDEADLK) 942 return (EDEADLK); 943 944 /* Invalid arguments should be reported where possible. */ 945 if (error1 == EINVAL || error2 == EINVAL) 946 return (EINVAL); 947 948 /* Precedence goes to "visibility", with both process and file. */ 949 if (error1 == ESRCH || error2 == ESRCH) 950 return (ESRCH); 951 952 if (error1 == ENOENT || error2 == ENOENT) 953 return (ENOENT); 954 955 /* Precedence goes to DAC/MAC protections. */ 956 if (error1 == EACCES || error2 == EACCES) 957 return (EACCES); 958 959 /* Precedence goes to privilege. */ 960 if (error1 == EPERM || error2 == EPERM) 961 return (EPERM); 962 963 /* Precedence goes to error over success; otherwise, arbitrary. */ 964 if (error1 != 0) 965 return (error1); 966 return (error2); 967} 968 969void 970mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 971{ 972 973 MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 974} 975 976void 977mac_update_procfsvnode(struct vnode *vp, struct ucred *cred) 978{ 979 980 MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred); 981} 982 983/* 984 * Support callout for policies that manage their own externalization 985 * using extended attributes. 986 */ 987static int 988mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp) 989{ 990 int error; 991 992 MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp, 993 &mp->mnt_fslabel); 994 995 return (error); 996} 997 998/* 999 * Given an externalized mac label, internalize it and stamp it on a 1000 * vnode. 1001 */ 1002static int 1003mac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac) 1004{ 1005 int error; 1006 1007 MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac); 1008 1009 return (error); 1010} 1011 1012/* 1013 * Call out to individual policies to update the label in a vnode from 1014 * the mountpoint. 1015 */ 1016void 1017mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp) 1018{ 1019 1020 MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp, 1021 &mp->mnt_fslabel); 1022 1023 ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount"); 1024 if (mac_cache_fslabel_in_vnode) 1025 vp->v_vflag |= VV_CACHEDLABEL; 1026} 1027 1028/* 1029 * Implementation of VOP_REFRESHLABEL() that relies on extended attributes 1030 * to store label data. Can be referenced by filesystems supporting 1031 * extended attributes. 1032 */ 1033int 1034vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap) 1035{ 1036 struct vnode *vp = ap->a_vp; 1037 struct mac extmac; 1038 int buflen, error; 1039 1040 ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea"); 1041 1042 /* 1043 * Call out to external policies first. Order doesn't really 1044 * matter, as long as failure of one assures failure of all. 1045 */ 1046 error = mac_update_vnode_from_extattr(vp, vp->v_mount); 1047 if (error) 1048 return (error); 1049 1050 buflen = sizeof(extmac); 1051 error = vn_extattr_get(vp, IO_NODELOCKED, 1052 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen, 1053 (char *)&extmac, curthread); 1054 switch (error) { 1055 case 0: 1056 /* Got it */ 1057 break; 1058 1059 case ENOATTR: 1060 /* 1061 * Use the label from the mount point. 1062 */ 1063 mac_update_vnode_from_mount(vp, vp->v_mount); 1064 return (0); 1065 1066 case EOPNOTSUPP: 1067 default: 1068 /* Fail horribly. */ 1069 return (error); 1070 } 1071 1072 if (buflen != sizeof(extmac)) 1073 error = EPERM; /* Fail very closed. */ 1074 if (error == 0) 1075 error = mac_update_vnode_from_externalized(vp, &extmac); 1076 if (error == 0) 1077 vp->v_vflag |= VV_CACHEDLABEL; 1078 else { 1079 struct vattr va; 1080 1081 printf("Corrupted label on %s", 1082 vp->v_mount->mnt_stat.f_mntonname); 1083 if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0) 1084 printf(" inum %ld", va.va_fileid); 1085#ifdef MAC_DEBUG 1086 if (mac_debug_label_fallback) { 1087 printf(", falling back.\n"); 1088 mac_update_vnode_from_mount(vp, vp->v_mount); 1089 error = 0; 1090 } else { 1091#endif 1092 printf(".\n"); 1093 error = EPERM; 1094#ifdef MAC_DEBUG 1095 } 1096#endif 1097 } 1098 1099 return (error); 1100} 1101 1102/* 1103 * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle 1104 * the labeling activity outselves. Filesystems should be careful not 1105 * to change their minds regarding whether they support vop_refreshlabel() 1106 * for a vnode or not. Don't cache the vnode here, allow the file 1107 * system code to determine if it's safe to cache. If we update from 1108 * the mount, don't cache since a change to the mount label should affect 1109 * all vnodes. 1110 */ 1111static int 1112vn_refreshlabel(struct vnode *vp, struct ucred *cred) 1113{ 1114 int error; 1115 1116 ASSERT_VOP_LOCKED(vp, "vn_refreshlabel"); 1117 1118 if (vp->v_mount == NULL) { 1119/* 1120 Eventually, we probably want to special-case refreshing 1121 of deadfs vnodes, and if there's a lock-free race somewhere, 1122 that case might be handled here. 1123 1124 mac_update_vnode_deadfs(vp); 1125 return (0); 1126 */ 1127 /* printf("vn_refreshlabel: null v_mount\n"); */ 1128 if (vp->v_type != VNON) 1129 printf( 1130 "vn_refreshlabel: null v_mount with non-VNON\n"); 1131 return (EBADF); 1132 } 1133 1134 if (vp->v_vflag & VV_CACHEDLABEL) { 1135 mac_vnode_label_cache_hits++; 1136 return (0); 1137 } else 1138 mac_vnode_label_cache_misses++; 1139 1140 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1141 mac_update_vnode_from_mount(vp, vp->v_mount); 1142 return (0); 1143 } 1144 1145 error = VOP_REFRESHLABEL(vp, cred, curthread); 1146 switch (error) { 1147 case EOPNOTSUPP: 1148 /* 1149 * If labels are not supported on this vnode, fall back to 1150 * the label in the mount and propagate it to the vnode. 1151 * There should probably be some sort of policy/flag/decision 1152 * about doing this. 1153 */ 1154 mac_update_vnode_from_mount(vp, vp->v_mount); 1155 error = 0; 1156 default: 1157 return (error); 1158 } 1159} 1160 1161/* 1162 * Helper function for file systems using the vop_std*_ea() calls. This 1163 * function must be called after EA service is available for the vnode, 1164 * but before it's hooked up to the namespace so that the node persists 1165 * if there's a crash, or before it can be accessed. On successful 1166 * commit of the label to disk (etc), do cache the label. 1167 */ 1168int 1169vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred) 1170{ 1171 struct mac extmac; 1172 int error; 1173 1174 ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea"); 1175 if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1176 mac_update_vnode_from_mount(tvp, tvp->v_mount); 1177 } else { 1178 error = vn_refreshlabel(dvp, cred); 1179 if (error) 1180 return (error); 1181 1182 /* 1183 * Stick the label in the vnode. Then try to write to 1184 * disk. If we fail, return a failure to abort the 1185 * create operation. Really, this failure shouldn't 1186 * happen except in fairly unusual circumstances (out 1187 * of disk, etc). 1188 */ 1189 mac_create_vnode(cred, dvp, tvp); 1190 1191 error = mac_stdcreatevnode_ea(tvp); 1192 if (error) 1193 return (error); 1194 1195 /* 1196 * XXX: Eventually this will go away and all policies will 1197 * directly manage their extended attributes. 1198 */ 1199 error = mac_externalize(&tvp->v_label, &extmac); 1200 if (error) 1201 return (error); 1202 1203 error = vn_extattr_set(tvp, IO_NODELOCKED, 1204 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 1205 sizeof(extmac), (char *)&extmac, curthread); 1206 if (error == 0) 1207 tvp->v_vflag |= VV_CACHEDLABEL; 1208 else { 1209#if 0 1210 /* 1211 * In theory, we could have fall-back behavior here. 1212 * It would probably be incorrect. 1213 */ 1214#endif 1215 return (error); 1216 } 1217 } 1218 1219 return (0); 1220} 1221 1222void 1223mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 1224{ 1225 int error; 1226 1227 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1228 1229 error = vn_refreshlabel(vp, old); 1230 if (error) { 1231 printf("mac_execve_transition: vn_refreshlabel returned %d\n", 1232 error); 1233 printf("mac_execve_transition: using old vnode label\n"); 1234 } 1235 1236 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 1237} 1238 1239int 1240mac_execve_will_transition(struct ucred *old, struct vnode *vp) 1241{ 1242 int error, result; 1243 1244 error = vn_refreshlabel(vp, old); 1245 if (error) 1246 return (error); 1247 1248 result = 0; 1249 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 1250 1251 return (result); 1252} 1253 1254static void 1255mac_init_label(struct label *label) 1256{ 1257 1258 bzero(label, sizeof(*label)); 1259 label->l_flags = MAC_FLAG_INITIALIZED; 1260} 1261 1262static void 1263mac_init_structmac(struct mac *mac) 1264{ 1265 1266 bzero(mac, sizeof(*mac)); 1267 mac->m_macflags = MAC_FLAG_INITIALIZED; 1268} 1269 1270static void 1271mac_destroy_label(struct label *label) 1272{ 1273 1274 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 1275 ("destroying uninitialized label")); 1276 1277 bzero(label, sizeof(*label)); 1278 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 1279} 1280 1281int 1282mac_init_mbuf(struct mbuf *m, int how) 1283{ 1284 KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 1285 1286 /* "how" is one of M_(TRY|DONT)WAIT */ 1287 mac_init_label(&m->m_pkthdr.label); 1288 MAC_PERFORM(init_mbuf, m, how, &m->m_pkthdr.label); 1289#ifdef MAC_DEBUG 1290 atomic_add_int(&nmacmbufs, 1); 1291#endif 1292 return (0); 1293} 1294 1295void 1296mac_destroy_mbuf(struct mbuf *m) 1297{ 1298 1299 MAC_PERFORM(destroy_mbuf, m, &m->m_pkthdr.label); 1300 mac_destroy_label(&m->m_pkthdr.label); 1301#ifdef MAC_DEBUG 1302 atomic_subtract_int(&nmacmbufs, 1); 1303#endif 1304} 1305 1306void 1307mac_init_cred(struct ucred *cr) 1308{ 1309 1310 mac_init_label(&cr->cr_label); 1311 MAC_PERFORM(init_cred, cr, &cr->cr_label); 1312#ifdef MAC_DEBUG 1313 atomic_add_int(&nmaccreds, 1); 1314#endif 1315} 1316 1317void 1318mac_destroy_cred(struct ucred *cr) 1319{ 1320 1321 MAC_PERFORM(destroy_cred, cr, &cr->cr_label); 1322 mac_destroy_label(&cr->cr_label); 1323#ifdef MAC_DEBUG 1324 atomic_subtract_int(&nmaccreds, 1); 1325#endif 1326} 1327 1328void 1329mac_init_ifnet(struct ifnet *ifp) 1330{ 1331 1332 mac_init_label(&ifp->if_label); 1333 MAC_PERFORM(init_ifnet, ifp, &ifp->if_label); 1334#ifdef MAC_DEBUG 1335 atomic_add_int(&nmacifnets, 1); 1336#endif 1337} 1338 1339void 1340mac_destroy_ifnet(struct ifnet *ifp) 1341{ 1342 1343 MAC_PERFORM(destroy_ifnet, ifp, &ifp->if_label); 1344 mac_destroy_label(&ifp->if_label); 1345#ifdef MAC_DEBUG 1346 atomic_subtract_int(&nmacifnets, 1); 1347#endif 1348} 1349 1350void 1351mac_init_ipq(struct ipq *ipq) 1352{ 1353 1354 mac_init_label(&ipq->ipq_label); 1355 MAC_PERFORM(init_ipq, ipq, &ipq->ipq_label); 1356#ifdef MAC_DEBUG 1357 atomic_add_int(&nmacipqs, 1); 1358#endif 1359} 1360 1361void 1362mac_destroy_ipq(struct ipq *ipq) 1363{ 1364 1365 MAC_PERFORM(destroy_ipq, ipq, &ipq->ipq_label); 1366 mac_destroy_label(&ipq->ipq_label); 1367#ifdef MAC_DEBUG 1368 atomic_subtract_int(&nmacipqs, 1); 1369#endif 1370} 1371 1372void 1373mac_init_socket(struct socket *socket) 1374{ 1375 1376 mac_init_label(&socket->so_label); 1377 mac_init_label(&socket->so_peerlabel); 1378 MAC_PERFORM(init_socket, socket, &socket->so_label, 1379 &socket->so_peerlabel); 1380#ifdef MAC_DEBUG 1381 atomic_add_int(&nmacsockets, 1); 1382#endif 1383} 1384 1385void 1386mac_destroy_socket(struct socket *socket) 1387{ 1388 1389 MAC_PERFORM(destroy_socket, socket, &socket->so_label, 1390 &socket->so_peerlabel); 1391 mac_destroy_label(&socket->so_label); 1392 mac_destroy_label(&socket->so_peerlabel); 1393#ifdef MAC_DEBUG 1394 atomic_subtract_int(&nmacsockets, 1); 1395#endif 1396} 1397 1398void 1399mac_init_pipe(struct pipe *pipe) 1400{ 1401 struct label *label; 1402 1403 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 1404 mac_init_label(label); 1405 pipe->pipe_label = label; 1406 pipe->pipe_peer->pipe_label = label; 1407 MAC_PERFORM(init_pipe, pipe, pipe->pipe_label); 1408#ifdef MAC_DEBUG 1409 atomic_add_int(&nmacpipes, 1); 1410#endif 1411} 1412 1413void 1414mac_destroy_pipe(struct pipe *pipe) 1415{ 1416 1417 MAC_PERFORM(destroy_pipe, pipe, pipe->pipe_label); 1418 mac_destroy_label(pipe->pipe_label); 1419 free(pipe->pipe_label, M_MACPIPELABEL); 1420#ifdef MAC_DEBUG 1421 atomic_subtract_int(&nmacpipes, 1); 1422#endif 1423} 1424 1425void 1426mac_init_bpfdesc(struct bpf_d *bpf_d) 1427{ 1428 1429 mac_init_label(&bpf_d->bd_label); 1430 MAC_PERFORM(init_bpfdesc, bpf_d, &bpf_d->bd_label); 1431#ifdef MAC_DEBUG 1432 atomic_add_int(&nmacbpfdescs, 1); 1433#endif 1434} 1435 1436void 1437mac_destroy_bpfdesc(struct bpf_d *bpf_d) 1438{ 1439 1440 MAC_PERFORM(destroy_bpfdesc, bpf_d, &bpf_d->bd_label); 1441 mac_destroy_label(&bpf_d->bd_label); 1442#ifdef MAC_DEBUG 1443 atomic_subtract_int(&nmacbpfdescs, 1); 1444#endif 1445} 1446 1447void 1448mac_init_mount(struct mount *mp) 1449{ 1450 1451 mac_init_label(&mp->mnt_mntlabel); 1452 mac_init_label(&mp->mnt_fslabel); 1453 MAC_PERFORM(init_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 1454#ifdef MAC_DEBUG 1455 atomic_add_int(&nmacmounts, 1); 1456#endif 1457} 1458 1459void 1460mac_destroy_mount(struct mount *mp) 1461{ 1462 1463 MAC_PERFORM(destroy_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 1464 mac_destroy_label(&mp->mnt_fslabel); 1465 mac_destroy_label(&mp->mnt_mntlabel); 1466#ifdef MAC_DEBUG 1467 atomic_subtract_int(&nmacmounts, 1); 1468#endif 1469} 1470 1471static void 1472mac_init_temp(struct label *label) 1473{ 1474 1475 mac_init_label(label); 1476 MAC_PERFORM(init_temp, label); 1477#ifdef MAC_DEBUG 1478 atomic_add_int(&nmactemp, 1); 1479#endif 1480} 1481 1482static void 1483mac_destroy_temp(struct label *label) 1484{ 1485 1486 MAC_PERFORM(destroy_temp, label); 1487 mac_destroy_label(label); 1488#ifdef MAC_DEBUG 1489 atomic_subtract_int(&nmactemp, 1); 1490#endif 1491} 1492 1493void 1494mac_init_vnode(struct vnode *vp) 1495{ 1496 1497 mac_init_label(&vp->v_label); 1498 MAC_PERFORM(init_vnode, vp, &vp->v_label); 1499#ifdef MAC_DEBUG 1500 atomic_add_int(&nmacvnodes, 1); 1501#endif 1502} 1503 1504void 1505mac_destroy_vnode(struct vnode *vp) 1506{ 1507 1508 MAC_PERFORM(destroy_vnode, vp, &vp->v_label); 1509 mac_destroy_label(&vp->v_label); 1510#ifdef MAC_DEBUG 1511 atomic_subtract_int(&nmacvnodes, 1); 1512#endif 1513} 1514 1515void 1516mac_init_devfsdirent(struct devfs_dirent *de) 1517{ 1518 1519 mac_init_label(&de->de_label); 1520 MAC_PERFORM(init_devfsdirent, de, &de->de_label); 1521#ifdef MAC_DEBUG 1522 atomic_add_int(&nmacdevfsdirents, 1); 1523#endif 1524} 1525 1526void 1527mac_destroy_devfsdirent(struct devfs_dirent *de) 1528{ 1529 1530 MAC_PERFORM(destroy_devfsdirent, de, &de->de_label); 1531 mac_destroy_label(&de->de_label); 1532#ifdef MAC_DEBUG 1533 atomic_subtract_int(&nmacdevfsdirents, 1); 1534#endif 1535} 1536 1537static int 1538mac_externalize(struct label *label, struct mac *mac) 1539{ 1540 int error; 1541 1542 mac_init_structmac(mac); 1543 MAC_CHECK(externalize, label, mac); 1544 1545 return (error); 1546} 1547 1548static int 1549mac_internalize(struct label *label, struct mac *mac) 1550{ 1551 int error; 1552 1553 mac_init_temp(label); 1554 MAC_CHECK(internalize, label, mac); 1555 if (error) 1556 mac_destroy_temp(label); 1557 1558 return (error); 1559} 1560 1561/* 1562 * Initialize MAC label for the first kernel process, from which other 1563 * kernel processes and threads are spawned. 1564 */ 1565void 1566mac_create_proc0(struct ucred *cred) 1567{ 1568 1569 MAC_PERFORM(create_proc0, cred); 1570} 1571 1572/* 1573 * Initialize MAC label for the first userland process, from which other 1574 * userland processes and threads are spawned. 1575 */ 1576void 1577mac_create_proc1(struct ucred *cred) 1578{ 1579 1580 MAC_PERFORM(create_proc1, cred); 1581} 1582 1583/* 1584 * When a new process is created, its label must be initialized. Generally, 1585 * this involves inheritence from the parent process, modulo possible 1586 * deltas. This function allows that processing to take place. 1587 */ 1588void 1589mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1590{ 1591 1592 MAC_PERFORM(create_cred, parent_cred, child_cred); 1593} 1594 1595int 1596mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 1597{ 1598 int error; 1599 1600 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1601 1602 if (!mac_enforce_fs) 1603 return (0); 1604 1605 error = vn_refreshlabel(vp, cred); 1606 if (error) 1607 return (error); 1608 1609 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 1610 return (error); 1611} 1612 1613int 1614mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1615{ 1616 int error; 1617 1618 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1619 1620 if (!mac_enforce_fs) 1621 return (0); 1622 1623 error = vn_refreshlabel(dvp, cred); 1624 if (error) 1625 return (error); 1626 1627 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1628 return (error); 1629} 1630 1631int 1632mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1633{ 1634 int error; 1635 1636 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1637 1638 if (!mac_enforce_fs) 1639 return (0); 1640 1641 error = vn_refreshlabel(dvp, cred); 1642 if (error) 1643 return (error); 1644 1645 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1646 return (error); 1647} 1648 1649int 1650mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1651 struct componentname *cnp, struct vattr *vap) 1652{ 1653 int error; 1654 1655 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1656 1657 if (!mac_enforce_fs) 1658 return (0); 1659 1660 error = vn_refreshlabel(dvp, cred); 1661 if (error) 1662 return (error); 1663 1664 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1665 return (error); 1666} 1667 1668int 1669mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1670 struct componentname *cnp) 1671{ 1672 int error; 1673 1674 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1675 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1676 1677 if (!mac_enforce_fs) 1678 return (0); 1679 1680 error = vn_refreshlabel(dvp, cred); 1681 if (error) 1682 return (error); 1683 error = vn_refreshlabel(vp, cred); 1684 if (error) 1685 return (error); 1686 1687 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1688 &vp->v_label, cnp); 1689 return (error); 1690} 1691 1692int 1693mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1694 acl_type_t type) 1695{ 1696 int error; 1697 1698 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1699 1700 if (!mac_enforce_fs) 1701 return (0); 1702 1703 error = vn_refreshlabel(vp, cred); 1704 if (error) 1705 return (error); 1706 1707 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1708 return (error); 1709} 1710 1711int 1712mac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 1713{ 1714 int error; 1715 1716 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1717 1718 if (!mac_enforce_process && !mac_enforce_fs) 1719 return (0); 1720 1721 error = vn_refreshlabel(vp, cred); 1722 if (error) 1723 return (error); 1724 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 1725 1726 return (error); 1727} 1728 1729int 1730mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1731{ 1732 int error; 1733 1734 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1735 1736 if (!mac_enforce_fs) 1737 return (0); 1738 1739 error = vn_refreshlabel(vp, cred); 1740 if (error) 1741 return (error); 1742 1743 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1744 return (error); 1745} 1746 1747int 1748mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1749 int attrnamespace, const char *name, struct uio *uio) 1750{ 1751 int error; 1752 1753 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1754 1755 if (!mac_enforce_fs) 1756 return (0); 1757 1758 error = vn_refreshlabel(vp, cred); 1759 if (error) 1760 return (error); 1761 1762 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1763 attrnamespace, name, uio); 1764 return (error); 1765} 1766 1767int 1768mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1769 struct componentname *cnp) 1770{ 1771 int error; 1772 1773 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1774 1775 if (!mac_enforce_fs) 1776 return (0); 1777 1778 error = vn_refreshlabel(dvp, cred); 1779 if (error) 1780 return (error); 1781 1782 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1783 return (error); 1784} 1785 1786vm_prot_t 1787mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) 1788{ 1789 vm_prot_t result = VM_PROT_ALL; 1790 1791 if (!mac_enforce_vm) 1792 return (result); 1793 1794 /* 1795 * This should be some sort of MAC_BITWISE, maybe :) 1796 */ 1797 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); 1798 MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, 1799 newmapping); 1800 return (result); 1801} 1802 1803int 1804mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 1805{ 1806 int error; 1807 1808 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1809 1810 if (!mac_enforce_fs) 1811 return (0); 1812 1813 error = vn_refreshlabel(vp, cred); 1814 if (error) 1815 return (error); 1816 1817 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1818 return (error); 1819} 1820 1821int 1822mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1823 struct vnode *vp) 1824{ 1825 int error; 1826 1827 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1828 1829 if (!mac_enforce_fs) 1830 return (0); 1831 1832 error = vn_refreshlabel(vp, active_cred); 1833 if (error) 1834 return (error); 1835 1836 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1837 &vp->v_label); 1838 1839 return (error); 1840} 1841 1842int 1843mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1844 struct vnode *vp) 1845{ 1846 int error; 1847 1848 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1849 1850 if (!mac_enforce_fs) 1851 return (0); 1852 1853 error = vn_refreshlabel(vp, active_cred); 1854 if (error) 1855 return (error); 1856 1857 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1858 &vp->v_label); 1859 1860 return (error); 1861} 1862 1863int 1864mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1865{ 1866 int error; 1867 1868 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1869 1870 if (!mac_enforce_fs) 1871 return (0); 1872 1873 error = vn_refreshlabel(dvp, cred); 1874 if (error) 1875 return (error); 1876 1877 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1878 return (error); 1879} 1880 1881int 1882mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1883{ 1884 int error; 1885 1886 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1887 1888 if (!mac_enforce_fs) 1889 return (0); 1890 1891 error = vn_refreshlabel(vp, cred); 1892 if (error) 1893 return (error); 1894 1895 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1896 return (error); 1897} 1898 1899static int 1900mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1901 struct label *newlabel) 1902{ 1903 int error; 1904 1905 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1906 1907 error = vn_refreshlabel(vp, cred); 1908 if (error) 1909 return (error); 1910 1911 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1912 1913 return (error); 1914} 1915 1916int 1917mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1918 struct vnode *vp, struct componentname *cnp) 1919{ 1920 int error; 1921 1922 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1923 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1924 1925 if (!mac_enforce_fs) 1926 return (0); 1927 1928 error = vn_refreshlabel(dvp, cred); 1929 if (error) 1930 return (error); 1931 error = vn_refreshlabel(vp, cred); 1932 if (error) 1933 return (error); 1934 1935 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1936 &vp->v_label, cnp); 1937 return (error); 1938} 1939 1940int 1941mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1942 struct vnode *vp, int samedir, struct componentname *cnp) 1943{ 1944 int error; 1945 1946 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1947 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1948 1949 if (!mac_enforce_fs) 1950 return (0); 1951 1952 error = vn_refreshlabel(dvp, cred); 1953 if (error) 1954 return (error); 1955 if (vp != NULL) { 1956 error = vn_refreshlabel(vp, cred); 1957 if (error) 1958 return (error); 1959 } 1960 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1961 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1962 return (error); 1963} 1964 1965int 1966mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1967{ 1968 int error; 1969 1970 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1971 1972 if (!mac_enforce_fs) 1973 return (0); 1974 1975 error = vn_refreshlabel(vp, cred); 1976 if (error) 1977 return (error); 1978 1979 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1980 return (error); 1981} 1982 1983int 1984mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1985 struct acl *acl) 1986{ 1987 int error; 1988 1989 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1990 1991 if (!mac_enforce_fs) 1992 return (0); 1993 1994 error = vn_refreshlabel(vp, cred); 1995 if (error) 1996 return (error); 1997 1998 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1999 return (error); 2000} 2001 2002int 2003mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2004 int attrnamespace, const char *name, struct uio *uio) 2005{ 2006 int error; 2007 2008 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 2009 2010 if (!mac_enforce_fs) 2011 return (0); 2012 2013 error = vn_refreshlabel(vp, cred); 2014 if (error) 2015 return (error); 2016 2017 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 2018 attrnamespace, name, uio); 2019 return (error); 2020} 2021 2022int 2023mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 2024{ 2025 int error; 2026 2027 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 2028 2029 if (!mac_enforce_fs) 2030 return (0); 2031 2032 error = vn_refreshlabel(vp, cred); 2033 if (error) 2034 return (error); 2035 2036 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 2037 return (error); 2038} 2039 2040int 2041mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 2042{ 2043 int error; 2044 2045 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 2046 2047 if (!mac_enforce_fs) 2048 return (0); 2049 2050 error = vn_refreshlabel(vp, cred); 2051 if (error) 2052 return (error); 2053 2054 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 2055 return (error); 2056} 2057 2058int 2059mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 2060 gid_t gid) 2061{ 2062 int error; 2063 2064 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 2065 2066 if (!mac_enforce_fs) 2067 return (0); 2068 2069 error = vn_refreshlabel(vp, cred); 2070 if (error) 2071 return (error); 2072 2073 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 2074 return (error); 2075} 2076 2077int 2078mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2079 struct timespec atime, struct timespec mtime) 2080{ 2081 int error; 2082 2083 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 2084 2085 if (!mac_enforce_fs) 2086 return (0); 2087 2088 error = vn_refreshlabel(vp, cred); 2089 if (error) 2090 return (error); 2091 2092 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 2093 mtime); 2094 return (error); 2095} 2096 2097int 2098mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2099 struct vnode *vp) 2100{ 2101 int error; 2102 2103 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2104 2105 if (!mac_enforce_fs) 2106 return (0); 2107 2108 error = vn_refreshlabel(vp, active_cred); 2109 if (error) 2110 return (error); 2111 2112 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2113 &vp->v_label); 2114 return (error); 2115} 2116 2117int 2118mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2119 struct vnode *vp) 2120{ 2121 int error; 2122 2123 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2124 2125 if (!mac_enforce_fs) 2126 return (0); 2127 2128 error = vn_refreshlabel(vp, active_cred); 2129 if (error) 2130 return (error); 2131 2132 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2133 &vp->v_label); 2134 2135 return (error); 2136} 2137 2138/* 2139 * When relabeling a process, call out to the policies for the maximum 2140 * permission allowed for each object type we know about in its 2141 * memory space, and revoke access (in the least surprising ways we 2142 * know) when necessary. The process lock is not held here. 2143 */ 2144static void 2145mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2146{ 2147 2148 /* XXX freeze all other threads */ 2149 mac_cred_mmapped_drop_perms_recurse(td, cred, 2150 &td->td_proc->p_vmspace->vm_map); 2151 /* XXX allow other threads to continue */ 2152} 2153 2154static __inline const char * 2155prot2str(vm_prot_t prot) 2156{ 2157 2158 switch (prot & VM_PROT_ALL) { 2159 case VM_PROT_READ: 2160 return ("r--"); 2161 case VM_PROT_READ | VM_PROT_WRITE: 2162 return ("rw-"); 2163 case VM_PROT_READ | VM_PROT_EXECUTE: 2164 return ("r-x"); 2165 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2166 return ("rwx"); 2167 case VM_PROT_WRITE: 2168 return ("-w-"); 2169 case VM_PROT_EXECUTE: 2170 return ("--x"); 2171 case VM_PROT_WRITE | VM_PROT_EXECUTE: 2172 return ("-wx"); 2173 default: 2174 return ("---"); 2175 } 2176} 2177 2178static void 2179mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2180 struct vm_map *map) 2181{ 2182 struct vm_map_entry *vme; 2183 vm_prot_t result, revokeperms; 2184 vm_object_t object; 2185 vm_ooffset_t offset; 2186 struct vnode *vp; 2187 2188 if (!mac_mmap_revocation) 2189 return; 2190 2191 vm_map_lock_read(map); 2192 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2193 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2194 mac_cred_mmapped_drop_perms_recurse(td, cred, 2195 vme->object.sub_map); 2196 continue; 2197 } 2198 /* 2199 * Skip over entries that obviously are not shared. 2200 */ 2201 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2202 !vme->max_protection) 2203 continue; 2204 /* 2205 * Drill down to the deepest backing object. 2206 */ 2207 offset = vme->offset; 2208 object = vme->object.vm_object; 2209 if (object == NULL) 2210 continue; 2211 while (object->backing_object != NULL) { 2212 object = object->backing_object; 2213 offset += object->backing_object_offset; 2214 } 2215 /* 2216 * At the moment, vm_maps and objects aren't considered 2217 * by the MAC system, so only things with backing by a 2218 * normal object (read: vnodes) are checked. 2219 */ 2220 if (object->type != OBJT_VNODE) 2221 continue; 2222 vp = (struct vnode *)object->handle; 2223 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2224 result = mac_check_vnode_mmap_prot(cred, vp, 0); 2225 VOP_UNLOCK(vp, 0, td); 2226 /* 2227 * Find out what maximum protection we may be allowing 2228 * now but a policy needs to get removed. 2229 */ 2230 revokeperms = vme->max_protection & ~result; 2231 if (!revokeperms) 2232 continue; 2233 printf("pid %ld: revoking %s perms from %#lx:%ld " 2234 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2235 prot2str(revokeperms), (u_long)vme->start, 2236 (long)(vme->end - vme->start), 2237 prot2str(vme->max_protection), prot2str(vme->protection)); 2238 vm_map_lock_upgrade(map); 2239 /* 2240 * This is the really simple case: if a map has more 2241 * max_protection than is allowed, but it's not being 2242 * actually used (that is, the current protection is 2243 * still allowed), we can just wipe it out and do 2244 * nothing more. 2245 */ 2246 if ((vme->protection & revokeperms) == 0) { 2247 vme->max_protection -= revokeperms; 2248 } else { 2249 if (revokeperms & VM_PROT_WRITE) { 2250 /* 2251 * In the more complicated case, flush out all 2252 * pending changes to the object then turn it 2253 * copy-on-write. 2254 */ 2255 vm_object_reference(object); 2256 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2257 vm_object_page_clean(object, 2258 OFF_TO_IDX(offset), 2259 OFF_TO_IDX(offset + vme->end - vme->start + 2260 PAGE_MASK), 2261 OBJPC_SYNC); 2262 VOP_UNLOCK(vp, 0, td); 2263 vm_object_deallocate(object); 2264 /* 2265 * Why bother if there's no read permissions 2266 * anymore? For the rest, we need to leave 2267 * the write permissions on for COW, or 2268 * remove them entirely if configured to. 2269 */ 2270 if (!mac_mmap_revocation_via_cow) { 2271 vme->max_protection &= ~VM_PROT_WRITE; 2272 vme->protection &= ~VM_PROT_WRITE; 2273 } if ((revokeperms & VM_PROT_READ) == 0) 2274 vme->eflags |= MAP_ENTRY_COW | 2275 MAP_ENTRY_NEEDS_COPY; 2276 } 2277 if (revokeperms & VM_PROT_EXECUTE) { 2278 vme->max_protection &= ~VM_PROT_EXECUTE; 2279 vme->protection &= ~VM_PROT_EXECUTE; 2280 } 2281 if (revokeperms & VM_PROT_READ) { 2282 vme->max_protection = 0; 2283 vme->protection = 0; 2284 } 2285 pmap_protect(map->pmap, vme->start, vme->end, 2286 vme->protection & ~revokeperms); 2287 vm_map_simplify_entry(map, vme); 2288 } 2289 vm_map_lock_downgrade(map); 2290 } 2291 vm_map_unlock_read(map); 2292} 2293 2294/* 2295 * When the subject's label changes, it may require revocation of privilege 2296 * to mapped objects. This can't be done on-the-fly later with a unified 2297 * buffer cache. 2298 */ 2299static void 2300mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2301{ 2302 2303 MAC_PERFORM(relabel_cred, cred, newlabel); 2304} 2305 2306void 2307mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2308{ 2309 2310 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2311} 2312 2313void 2314mac_create_ifnet(struct ifnet *ifnet) 2315{ 2316 2317 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2318} 2319 2320void 2321mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2322{ 2323 2324 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2325} 2326 2327void 2328mac_create_socket(struct ucred *cred, struct socket *socket) 2329{ 2330 2331 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2332} 2333 2334void 2335mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2336{ 2337 2338 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2339} 2340 2341void 2342mac_create_socket_from_socket(struct socket *oldsocket, 2343 struct socket *newsocket) 2344{ 2345 2346 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2347 newsocket, &newsocket->so_label); 2348} 2349 2350static void 2351mac_relabel_socket(struct ucred *cred, struct socket *socket, 2352 struct label *newlabel) 2353{ 2354 2355 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2356} 2357 2358static void 2359mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2360{ 2361 2362 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2363} 2364 2365void 2366mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2367{ 2368 2369 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2370 socket, &socket->so_peerlabel); 2371} 2372 2373void 2374mac_set_socket_peer_from_socket(struct socket *oldsocket, 2375 struct socket *newsocket) 2376{ 2377 2378 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2379 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2380} 2381 2382void 2383mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2384{ 2385 2386 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2387 datagram, &datagram->m_pkthdr.label); 2388} 2389 2390void 2391mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2392{ 2393 2394 MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2395 fragment, &fragment->m_pkthdr.label); 2396} 2397 2398void 2399mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2400{ 2401 2402 MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2403 &ipq->ipq_label); 2404} 2405 2406void 2407mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2408{ 2409 2410 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2411 newmbuf, &newmbuf->m_pkthdr.label); 2412} 2413 2414void 2415mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2416{ 2417 2418 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2419 &mbuf->m_pkthdr.label); 2420} 2421 2422void 2423mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2424{ 2425 2426 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2427 &mbuf->m_pkthdr.label); 2428} 2429 2430void 2431mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2432{ 2433 2434 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2435 &mbuf->m_pkthdr.label); 2436} 2437 2438void 2439mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2440 struct mbuf *newmbuf) 2441{ 2442 2443 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2444 &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2445 &newmbuf->m_pkthdr.label); 2446} 2447 2448void 2449mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2450{ 2451 2452 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2453 newmbuf, &newmbuf->m_pkthdr.label); 2454} 2455 2456int 2457mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2458{ 2459 int result; 2460 2461 result = 1; 2462 MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2463 ipq, &ipq->ipq_label); 2464 2465 return (result); 2466} 2467 2468void 2469mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2470{ 2471 2472 MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2473 &ipq->ipq_label); 2474} 2475 2476void 2477mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2478{ 2479 2480 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2481 &mbuf->m_pkthdr.label); 2482} 2483 2484void 2485mac_create_mount(struct ucred *cred, struct mount *mp) 2486{ 2487 2488 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2489 &mp->mnt_fslabel); 2490} 2491 2492void 2493mac_create_root_mount(struct ucred *cred, struct mount *mp) 2494{ 2495 2496 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2497 &mp->mnt_fslabel); 2498} 2499 2500int 2501mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2502{ 2503 int error; 2504 2505 if (!mac_enforce_network) 2506 return (0); 2507 2508 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2509 &ifnet->if_label); 2510 2511 return (error); 2512} 2513 2514static int 2515mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2516{ 2517 int error; 2518 2519 MAC_CHECK(check_cred_relabel, cred, newlabel); 2520 2521 return (error); 2522} 2523 2524int 2525mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2526{ 2527 int error; 2528 2529 if (!mac_enforce_process) 2530 return (0); 2531 2532 MAC_CHECK(check_cred_visible, u1, u2); 2533 2534 return (error); 2535} 2536 2537int 2538mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2539{ 2540 int error; 2541 2542 if (!mac_enforce_network) 2543 return (0); 2544 2545 KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2546 if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2547 printf("%s%d: not initialized\n", ifnet->if_name, 2548 ifnet->if_unit); 2549 2550 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2551 &mbuf->m_pkthdr.label); 2552 2553 return (error); 2554} 2555 2556int 2557mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2558{ 2559 int error; 2560 2561 if (!mac_enforce_fs) 2562 return (0); 2563 2564 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2565 2566 return (error); 2567} 2568 2569int 2570mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2571 void *data) 2572{ 2573 int error; 2574 2575 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2576 2577 if (!mac_enforce_pipe) 2578 return (0); 2579 2580 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2581 2582 return (error); 2583} 2584 2585int 2586mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2587{ 2588 int error; 2589 2590 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2591 2592 if (!mac_enforce_pipe) 2593 return (0); 2594 2595 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2596 2597 return (error); 2598} 2599 2600int 2601mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2602{ 2603 int error; 2604 2605 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2606 2607 if (!mac_enforce_pipe) 2608 return (0); 2609 2610 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2611 2612 return (error); 2613} 2614 2615static int 2616mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2617 struct label *newlabel) 2618{ 2619 int error; 2620 2621 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2622 2623 if (!mac_enforce_pipe) 2624 return (0); 2625 2626 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2627 2628 return (error); 2629} 2630 2631int 2632mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2633{ 2634 int error; 2635 2636 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2637 2638 if (!mac_enforce_pipe) 2639 return (0); 2640 2641 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2642 2643 return (error); 2644} 2645 2646int 2647mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2648{ 2649 int error; 2650 2651 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2652 2653 if (!mac_enforce_pipe) 2654 return (0); 2655 2656 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2657 2658 return (error); 2659} 2660 2661int 2662mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2663{ 2664 int error; 2665 2666 PROC_LOCK_ASSERT(proc, MA_OWNED); 2667 2668 if (!mac_enforce_process) 2669 return (0); 2670 2671 MAC_CHECK(check_proc_debug, cred, proc); 2672 2673 return (error); 2674} 2675 2676int 2677mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2678{ 2679 int error; 2680 2681 PROC_LOCK_ASSERT(proc, MA_OWNED); 2682 2683 if (!mac_enforce_process) 2684 return (0); 2685 2686 MAC_CHECK(check_proc_sched, cred, proc); 2687 2688 return (error); 2689} 2690 2691int 2692mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2693{ 2694 int error; 2695 2696 PROC_LOCK_ASSERT(proc, MA_OWNED); 2697 2698 if (!mac_enforce_process) 2699 return (0); 2700 2701 MAC_CHECK(check_proc_signal, cred, proc, signum); 2702 2703 return (error); 2704} 2705 2706int 2707mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2708 struct sockaddr *sockaddr) 2709{ 2710 int error; 2711 2712 if (!mac_enforce_socket) 2713 return (0); 2714 2715 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2716 sockaddr); 2717 2718 return (error); 2719} 2720 2721int 2722mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2723 struct sockaddr *sockaddr) 2724{ 2725 int error; 2726 2727 if (!mac_enforce_socket) 2728 return (0); 2729 2730 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2731 sockaddr); 2732 2733 return (error); 2734} 2735 2736int 2737mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2738{ 2739 int error; 2740 2741 if (!mac_enforce_socket) 2742 return (0); 2743 2744 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2745 &mbuf->m_pkthdr.label); 2746 2747 return (error); 2748} 2749 2750int 2751mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2752{ 2753 int error; 2754 2755 if (!mac_enforce_socket) 2756 return (0); 2757 2758 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2759 return (error); 2760} 2761 2762static int 2763mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2764 struct label *newlabel) 2765{ 2766 int error; 2767 2768 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2769 newlabel); 2770 2771 return (error); 2772} 2773 2774int 2775mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2776{ 2777 int error; 2778 2779 if (!mac_enforce_socket) 2780 return (0); 2781 2782 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2783 2784 return (error); 2785} 2786 2787int 2788mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2789 struct ifnet *ifnet) 2790{ 2791 struct mac label; 2792 int error; 2793 2794 error = mac_externalize(&ifnet->if_label, &label); 2795 if (error) 2796 return (error); 2797 2798 return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label))); 2799} 2800 2801int 2802mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2803 struct ifnet *ifnet) 2804{ 2805 struct mac newlabel; 2806 struct label intlabel; 2807 int error; 2808 2809 error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel)); 2810 if (error) 2811 return (error); 2812 2813 error = mac_internalize(&intlabel, &newlabel); 2814 if (error) 2815 return (error); 2816 2817 /* 2818 * XXX: Note that this is a redundant privilege check, since 2819 * policies impose this check themselves if required by the 2820 * policy. Eventually, this should go away. 2821 */ 2822 error = suser_cred(cred, 0); 2823 if (error) 2824 goto out; 2825 2826 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2827 &intlabel); 2828 if (error) 2829 goto out; 2830 2831 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2832 2833out: 2834 mac_destroy_temp(&intlabel); 2835 return (error); 2836} 2837 2838void 2839mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 2840{ 2841 2842 MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 2843} 2844 2845void 2846mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 2847{ 2848 2849 MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 2850} 2851 2852static int 2853mac_stdcreatevnode_ea(struct vnode *vp) 2854{ 2855 int error; 2856 2857 MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label); 2858 2859 return (error); 2860} 2861 2862void 2863mac_create_devfs_directory(char *dirname, int dirnamelen, 2864 struct devfs_dirent *de) 2865{ 2866 2867 MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 2868 &de->de_label); 2869} 2870 2871/* 2872 * When a new vnode is created, this call will initialize its label. 2873 */ 2874void 2875mac_create_vnode(struct ucred *cred, struct vnode *parent, 2876 struct vnode *child) 2877{ 2878 int error; 2879 2880 ASSERT_VOP_LOCKED(parent, "mac_create_vnode"); 2881 ASSERT_VOP_LOCKED(child, "mac_create_vnode"); 2882 2883 error = vn_refreshlabel(parent, cred); 2884 if (error) { 2885 printf("mac_create_vnode: vn_refreshlabel returned %d\n", 2886 error); 2887 printf("mac_create_vnode: using old vnode label\n"); 2888 } 2889 2890 MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child, 2891 &child->v_label); 2892} 2893 2894int 2895mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2896 struct mac *extmac) 2897{ 2898 struct label intlabel; 2899 int error; 2900 2901 error = mac_internalize(&intlabel, extmac); 2902 if (error) 2903 return (error); 2904 2905 mac_check_socket_relabel(cred, so, &intlabel); 2906 if (error) { 2907 mac_destroy_temp(&intlabel); 2908 return (error); 2909 } 2910 2911 mac_relabel_socket(cred, so, &intlabel); 2912 2913 mac_destroy_temp(&intlabel); 2914 return (0); 2915} 2916 2917int 2918mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 2919{ 2920 int error; 2921 2922 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2923 2924 error = mac_check_pipe_relabel(cred, pipe, label); 2925 if (error) 2926 return (error); 2927 2928 mac_relabel_pipe(cred, pipe, label); 2929 2930 return (0); 2931} 2932 2933int 2934mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2935 struct mac *extmac) 2936{ 2937 2938 return (mac_externalize(&so->so_label, extmac)); 2939} 2940 2941int 2942mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2943 struct mac *extmac) 2944{ 2945 2946 return (mac_externalize(&so->so_peerlabel, extmac)); 2947} 2948 2949/* 2950 * Implementation of VOP_SETLABEL() that relies on extended attributes 2951 * to store label data. Can be referenced by filesystems supporting 2952 * extended attributes. 2953 */ 2954int 2955vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 2956{ 2957 struct vnode *vp = ap->a_vp; 2958 struct label *intlabel = ap->a_label; 2959 struct mac extmac; 2960 int error; 2961 2962 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 2963 2964 /* 2965 * XXX: Eventually call out to EA check/set calls here. 2966 * Be particularly careful to avoid race conditions, 2967 * consistency problems, and stability problems when 2968 * dealing with multiple EAs. In particular, we require 2969 * the ability to write multiple EAs on the same file in 2970 * a single transaction, which the current EA interface 2971 * does not provide. 2972 */ 2973 2974 error = mac_externalize(intlabel, &extmac); 2975 if (error) 2976 return (error); 2977 2978 error = vn_extattr_set(vp, IO_NODELOCKED, 2979 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 2980 sizeof(extmac), (char *)&extmac, curthread); 2981 if (error) 2982 return (error); 2983 2984 mac_relabel_vnode(ap->a_cred, vp, intlabel); 2985 2986 vp->v_vflag |= VV_CACHEDLABEL; 2987 2988 return (0); 2989} 2990 2991static int 2992vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 2993{ 2994 int error; 2995 2996 if (vp->v_mount == NULL) { 2997 /* printf("vn_setlabel: null v_mount\n"); */ 2998 if (vp->v_type != VNON) 2999 printf("vn_setlabel: null v_mount with non-VNON\n"); 3000 return (EBADF); 3001 } 3002 3003 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3004 return (EOPNOTSUPP); 3005 3006 /* 3007 * Multi-phase commit. First check the policies to confirm the 3008 * change is OK. Then commit via the filesystem. Finally, 3009 * update the actual vnode label. Question: maybe the filesystem 3010 * should update the vnode at the end as part of VOP_SETLABEL()? 3011 */ 3012 error = mac_check_vnode_relabel(cred, vp, intlabel); 3013 if (error) 3014 return (error); 3015 3016 /* 3017 * VADMIN provides the opportunity for the filesystem to make 3018 * decisions about who is and is not able to modify labels 3019 * and protections on files. This might not be right. We can't 3020 * assume VOP_SETLABEL() will do it, because we might implement 3021 * that as part of vop_stdsetlabel_ea(). 3022 */ 3023 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3024 if (error) 3025 return (error); 3026 3027 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3028 if (error) 3029 return (error); 3030 3031 return (0); 3032} 3033 3034/* 3035 * MPSAFE 3036 */ 3037int 3038__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3039{ 3040 struct mac extmac; 3041 int error; 3042 3043 error = mac_externalize(&td->td_ucred->cr_label, &extmac); 3044 if (error == 0) 3045 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3046 3047 return (error); 3048} 3049 3050/* 3051 * MPSAFE 3052 */ 3053int 3054__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3055{ 3056 struct ucred *newcred, *oldcred; 3057 struct proc *p; 3058 struct mac extmac; 3059 struct label intlabel; 3060 int error; 3061 3062 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3063 if (error) 3064 return (error); 3065 3066 error = mac_internalize(&intlabel, &extmac); 3067 if (error) 3068 return (error); 3069 3070 newcred = crget(); 3071 3072 p = td->td_proc; 3073 PROC_LOCK(p); 3074 oldcred = p->p_ucred; 3075 3076 error = mac_check_cred_relabel(oldcred, &intlabel); 3077 if (error) { 3078 PROC_UNLOCK(p); 3079 mac_destroy_temp(&intlabel); 3080 crfree(newcred); 3081 return (error); 3082 } 3083 3084 setsugid(p); 3085 crcopy(newcred, oldcred); 3086 mac_relabel_cred(newcred, &intlabel); 3087 p->p_ucred = newcred; 3088 3089 /* 3090 * Grab additional reference for use while revoking mmaps, prior 3091 * to releasing the proc lock and sharing the cred. 3092 */ 3093 crhold(newcred); 3094 PROC_UNLOCK(p); 3095 3096 mtx_lock(&Giant); 3097 mac_cred_mmapped_drop_perms(td, newcred); 3098 mtx_unlock(&Giant); 3099 3100 crfree(newcred); /* Free revocation reference. */ 3101 crfree(oldcred); 3102 mac_destroy_temp(&intlabel); 3103 return (0); 3104} 3105 3106/* 3107 * MPSAFE 3108 */ 3109int 3110__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3111{ 3112 struct file *fp; 3113 struct mac extmac; 3114 struct vnode *vp; 3115 struct pipe *pipe; 3116 int error; 3117 3118 mtx_lock(&Giant); 3119 3120 error = fget(td, SCARG(uap, fd), &fp); 3121 if (error) 3122 goto out; 3123 3124 switch (fp->f_type) { 3125 case DTYPE_FIFO: 3126 case DTYPE_VNODE: 3127 vp = (struct vnode *)fp->f_data; 3128 3129 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3130 error = vn_refreshlabel(vp, td->td_ucred); 3131 if (error == 0) 3132 error = mac_externalize(&vp->v_label, &extmac); 3133 VOP_UNLOCK(vp, 0, td); 3134 break; 3135 case DTYPE_PIPE: 3136 pipe = (struct pipe *)fp->f_data; 3137 error = mac_externalize(pipe->pipe_label, &extmac); 3138 break; 3139 default: 3140 error = EINVAL; 3141 } 3142 3143 if (error == 0) 3144 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3145 3146 fdrop(fp, td); 3147 3148out: 3149 mtx_unlock(&Giant); 3150 return (error); 3151} 3152 3153/* 3154 * MPSAFE 3155 */ 3156int 3157__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3158{ 3159 struct nameidata nd; 3160 struct mac extmac; 3161 int error; 3162 3163 mtx_lock(&Giant); 3164 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3165 SCARG(uap, path_p), td); 3166 error = namei(&nd); 3167 if (error) 3168 goto out; 3169 3170 error = vn_refreshlabel(nd.ni_vp, td->td_ucred); 3171 if (error == 0) 3172 error = mac_externalize(&nd.ni_vp->v_label, &extmac); 3173 NDFREE(&nd, 0); 3174 if (error) 3175 goto out; 3176 3177 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3178 3179out: 3180 mtx_unlock(&Giant); 3181 return (error); 3182} 3183 3184/* 3185 * MPSAFE 3186 */ 3187int 3188__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3189{ 3190 struct file *fp; 3191 struct mac extmac; 3192 struct label intlabel; 3193 struct mount *mp; 3194 struct vnode *vp; 3195 struct pipe *pipe; 3196 int error; 3197 3198 mtx_lock(&Giant); 3199 error = fget(td, SCARG(uap, fd), &fp); 3200 if (error) 3201 goto out1; 3202 3203 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3204 if (error) 3205 goto out2; 3206 3207 error = mac_internalize(&intlabel, &extmac); 3208 if (error) 3209 goto out2; 3210 3211 switch (fp->f_type) { 3212 case DTYPE_FIFO: 3213 case DTYPE_VNODE: 3214 vp = (struct vnode *)fp->f_data; 3215 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3216 if (error != 0) 3217 break; 3218 3219 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3220 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3221 VOP_UNLOCK(vp, 0, td); 3222 vn_finished_write(mp); 3223 mac_destroy_temp(&intlabel); 3224 break; 3225 case DTYPE_PIPE: 3226 pipe = (struct pipe *)fp->f_data; 3227 PIPE_LOCK(pipe); 3228 error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel); 3229 PIPE_UNLOCK(pipe); 3230 break; 3231 default: 3232 error = EINVAL; 3233 } 3234 3235out2: 3236 fdrop(fp, td); 3237out1: 3238 mtx_unlock(&Giant); 3239 return (error); 3240} 3241 3242/* 3243 * MPSAFE 3244 */ 3245int 3246__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3247{ 3248 struct nameidata nd; 3249 struct mac extmac; 3250 struct label intlabel; 3251 struct mount *mp; 3252 int error; 3253 3254 mtx_lock(&Giant); 3255 3256 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3257 if (error) 3258 goto out; 3259 3260 error = mac_internalize(&intlabel, &extmac); 3261 if (error) 3262 goto out; 3263 3264 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3265 SCARG(uap, path_p), td); 3266 error = namei(&nd); 3267 if (error) 3268 goto out2; 3269 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3270 if (error) 3271 goto out2; 3272 3273 error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred); 3274 3275 vn_finished_write(mp); 3276out2: 3277 mac_destroy_temp(&intlabel); 3278 NDFREE(&nd, 0); 3279out: 3280 mtx_unlock(&Giant); 3281 return (error); 3282} 3283 3284int 3285mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3286{ 3287 struct mac_policy_conf *mpc; 3288 char target[MAC_MAX_POLICY_NAME]; 3289 int error; 3290 3291 error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3292 if (error) 3293 return (error); 3294 3295 error = ENOSYS; 3296 MAC_POLICY_LIST_BUSY(); 3297 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3298 if (strcmp(mpc->mpc_name, target) == 0 && 3299 mpc->mpc_ops->mpo_syscall != NULL) { 3300 error = mpc->mpc_ops->mpo_syscall(td, 3301 SCARG(uap, call), SCARG(uap, arg)); 3302 goto out; 3303 } 3304 } 3305 3306out: 3307 MAC_POLICY_LIST_UNBUSY(); 3308 return (error); 3309} 3310 3311SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3312SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3313 3314#else /* !MAC */ 3315 3316int 3317__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3318{ 3319 3320 return (ENOSYS); 3321} 3322 3323int 3324__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3325{ 3326 3327 return (ENOSYS); 3328} 3329 3330int 3331__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3332{ 3333 3334 return (ENOSYS); 3335} 3336 3337int 3338__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3339{ 3340 3341 return (ENOSYS); 3342} 3343 3344int 3345__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3346{ 3347 3348 return (ENOSYS); 3349} 3350 3351int 3352__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3353{ 3354 3355 return (ENOSYS); 3356} 3357 3358int 3359mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3360{ 3361 3362 return (ENOSYS); 3363} 3364 3365#endif /* !MAC */
| 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#ifndef MAC_MAX_POLICIES 102#define MAC_MAX_POLICIES 8 103#endif 104#if MAC_MAX_POLICIES > 32 105#error "MAC_MAX_POLICIES too large" 106#endif 107static unsigned int mac_max_policies = MAC_MAX_POLICIES; 108static unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 109SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 110 &mac_max_policies, 0, ""); 111 112static int mac_late = 0; 113 114static int mac_enforce_fs = 1; 115SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 116 &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 117TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 118 119static int mac_enforce_network = 1; 120SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 121 &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 122TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 123 124static int mac_enforce_pipe = 1; 125SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 126 &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 127TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 128 129static int mac_enforce_process = 1; 130SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 131 &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 132TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 133 134static int mac_enforce_socket = 1; 135SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 136 &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 137TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 138 139static int mac_enforce_vm = 1; 140SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 141 &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 142TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 143 144static int mac_label_size = sizeof(struct mac); 145SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD, 146 &mac_label_size, 0, "Pre-compiled MAC label size"); 147 148static int mac_cache_fslabel_in_vnode = 1; 149SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW, 150 &mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode"); 151TUNABLE_INT("security.mac.cache_fslabel_in_vnode", 152 &mac_cache_fslabel_in_vnode); 153 154static int mac_vnode_label_cache_hits = 0; 155SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD, 156 &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels"); 157static int mac_vnode_label_cache_misses = 0; 158SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD, 159 &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels"); 160 161static int mac_mmap_revocation = 1; 162SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 163 &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 164 "relabel"); 165static int mac_mmap_revocation_via_cow = 0; 166SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 167 &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 168 "copy-on-write semantics, or by removing all write access"); 169 170#ifdef MAC_DEBUG 171SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 172 "TrustedBSD MAC debug info"); 173 174static int mac_debug_label_fallback = 0; 175SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 176 &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 177 "when label is corrupted."); 178TUNABLE_INT("security.mac.debug_label_fallback", 179 &mac_debug_label_fallback); 180 181static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 182 nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 183 nmacipqs, nmacpipes; 184SYSCTL_UINT(_security_mac_debug, OID_AUTO, mbufs, CTLFLAG_RD, 185 &nmacmbufs, 0, "number of mbufs in use"); 186SYSCTL_UINT(_security_mac_debug, OID_AUTO, creds, CTLFLAG_RD, 187 &nmaccreds, 0, "number of ucreds in use"); 188SYSCTL_UINT(_security_mac_debug, OID_AUTO, ifnets, CTLFLAG_RD, 189 &nmacifnets, 0, "number of ifnets in use"); 190SYSCTL_UINT(_security_mac_debug, OID_AUTO, ipqs, CTLFLAG_RD, 191 &nmacipqs, 0, "number of ipqs in use"); 192SYSCTL_UINT(_security_mac_debug, OID_AUTO, bpfdescs, CTLFLAG_RD, 193 &nmacbpfdescs, 0, "number of bpfdescs in use"); 194SYSCTL_UINT(_security_mac_debug, OID_AUTO, sockets, CTLFLAG_RD, 195 &nmacsockets, 0, "number of sockets in use"); 196SYSCTL_UINT(_security_mac_debug, OID_AUTO, pipes, CTLFLAG_RD, 197 &nmacpipes, 0, "number of pipes in use"); 198SYSCTL_UINT(_security_mac_debug, OID_AUTO, mounts, CTLFLAG_RD, 199 &nmacmounts, 0, "number of mounts in use"); 200SYSCTL_UINT(_security_mac_debug, OID_AUTO, temp, CTLFLAG_RD, 201 &nmactemp, 0, "number of temporary labels in use"); 202SYSCTL_UINT(_security_mac_debug, OID_AUTO, vnodes, CTLFLAG_RD, 203 &nmacvnodes, 0, "number of vnodes in use"); 204SYSCTL_UINT(_security_mac_debug, OID_AUTO, devfsdirents, CTLFLAG_RD, 205 &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 206#endif 207 208static int error_select(int error1, int error2); 209static int mac_externalize(struct label *label, struct mac *mac); 210static int mac_policy_register(struct mac_policy_conf *mpc); 211static int mac_policy_unregister(struct mac_policy_conf *mpc); 212 213static int mac_stdcreatevnode_ea(struct vnode *vp); 214static void mac_cred_mmapped_drop_perms(struct thread *td, 215 struct ucred *cred); 216static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 217 struct ucred *cred, struct vm_map *map); 218 219MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector"); 220MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 221 222/* 223 * mac_policy_list_lock protects the consistency of 'mac_policy_list', 224 * the linked list of attached policy modules. Read-only consumers of 225 * the list must acquire a shared lock for the duration of their use; 226 * writers must acquire an exclusive lock. Note that for compound 227 * operations, locks should be held for the entire compound operation, 228 * and that this is not yet done for relabel requests. 229 */ 230static struct mtx mac_policy_list_lock; 231static LIST_HEAD(, mac_policy_conf) mac_policy_list; 232static int mac_policy_list_busy; 233#define MAC_POLICY_LIST_LOCKINIT() mtx_init(&mac_policy_list_lock, \ 234 "mac_policy_list_lock", NULL, MTX_DEF); 235#define MAC_POLICY_LIST_LOCK() mtx_lock(&mac_policy_list_lock); 236#define MAC_POLICY_LIST_UNLOCK() mtx_unlock(&mac_policy_list_lock); 237 238#define MAC_POLICY_LIST_BUSY() do { \ 239 MAC_POLICY_LIST_LOCK(); \ 240 mac_policy_list_busy++; \ 241 MAC_POLICY_LIST_UNLOCK(); \ 242} while (0) 243 244#define MAC_POLICY_LIST_UNBUSY() do { \ 245 MAC_POLICY_LIST_LOCK(); \ 246 mac_policy_list_busy--; \ 247 if (mac_policy_list_busy < 0) \ 248 panic("Extra mac_policy_list_busy--"); \ 249 MAC_POLICY_LIST_UNLOCK(); \ 250} while (0) 251 252/* 253 * MAC_CHECK performs the designated check by walking the policy 254 * module list and checking with each as to how it feels about the 255 * request. Note that it returns its value via 'error' in the scope 256 * of the caller. 257 */ 258#define MAC_CHECK(check, args...) do { \ 259 struct mac_policy_conf *mpc; \ 260 \ 261 error = 0; \ 262 MAC_POLICY_LIST_BUSY(); \ 263 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 264 if (mpc->mpc_ops->mpo_ ## check != NULL) \ 265 error = error_select( \ 266 mpc->mpc_ops->mpo_ ## check (args), \ 267 error); \ 268 } \ 269 MAC_POLICY_LIST_UNBUSY(); \ 270} while (0) 271 272/* 273 * MAC_BOOLEAN performs the designated boolean composition by walking 274 * the module list, invoking each instance of the operation, and 275 * combining the results using the passed C operator. Note that it 276 * returns its value via 'result' in the scope of the caller, which 277 * should be initialized by the caller in a meaningful way to get 278 * a meaningful result. 279 */ 280#define MAC_BOOLEAN(operation, composition, args...) do { \ 281 struct mac_policy_conf *mpc; \ 282 \ 283 MAC_POLICY_LIST_BUSY(); \ 284 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 285 if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 286 result = result composition \ 287 mpc->mpc_ops->mpo_ ## operation (args); \ 288 } \ 289 MAC_POLICY_LIST_UNBUSY(); \ 290} while (0) 291 292/* 293 * MAC_PERFORM performs the designated operation by walking the policy 294 * module list and invoking that operation for each policy. 295 */ 296#define MAC_PERFORM(operation, args...) do { \ 297 struct mac_policy_conf *mpc; \ 298 \ 299 MAC_POLICY_LIST_BUSY(); \ 300 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 301 if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 302 mpc->mpc_ops->mpo_ ## operation (args); \ 303 } \ 304 MAC_POLICY_LIST_UNBUSY(); \ 305} while (0) 306 307/* 308 * Initialize the MAC subsystem, including appropriate SMP locks. 309 */ 310static void 311mac_init(void) 312{ 313 314 LIST_INIT(&mac_policy_list); 315 MAC_POLICY_LIST_LOCKINIT(); 316} 317 318/* 319 * For the purposes of modules that want to know if they were loaded 320 * "early", set the mac_late flag once we've processed modules either 321 * linked into the kernel, or loaded before the kernel startup. 322 */ 323static void 324mac_late_init(void) 325{ 326 327 mac_late = 1; 328} 329 330/* 331 * Allow MAC policy modules to register during boot, etc. 332 */ 333int 334mac_policy_modevent(module_t mod, int type, void *data) 335{ 336 struct mac_policy_conf *mpc; 337 int error; 338 339 error = 0; 340 mpc = (struct mac_policy_conf *) data; 341 342 switch (type) { 343 case MOD_LOAD: 344 if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 345 mac_late) { 346 printf("mac_policy_modevent: can't load %s policy " 347 "after booting\n", mpc->mpc_name); 348 error = EBUSY; 349 break; 350 } 351 error = mac_policy_register(mpc); 352 break; 353 case MOD_UNLOAD: 354 /* Don't unregister the module if it was never registered. */ 355 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 356 != 0) 357 error = mac_policy_unregister(mpc); 358 else 359 error = 0; 360 break; 361 default: 362 break; 363 } 364 365 return (error); 366} 367 368static int 369mac_policy_register(struct mac_policy_conf *mpc) 370{ 371 struct mac_policy_conf *tmpc; 372 struct mac_policy_op_entry *mpe; 373 int slot; 374 375 MALLOC(mpc->mpc_ops, struct mac_policy_ops *, sizeof(*mpc->mpc_ops), 376 M_MACOPVEC, M_WAITOK | M_ZERO); 377 for (mpe = mpc->mpc_entries; mpe->mpe_constant != MAC_OP_LAST; mpe++) { 378 switch (mpe->mpe_constant) { 379 case MAC_OP_LAST: 380 /* 381 * Doesn't actually happen, but this allows checking 382 * that all enumerated values are handled. 383 */ 384 break; 385 case MAC_DESTROY: 386 mpc->mpc_ops->mpo_destroy = 387 mpe->mpe_function; 388 break; 389 case MAC_INIT: 390 mpc->mpc_ops->mpo_init = 391 mpe->mpe_function; 392 break; 393 case MAC_SYSCALL: 394 mpc->mpc_ops->mpo_syscall = 395 mpe->mpe_function; 396 break; 397 case MAC_INIT_BPFDESC: 398 mpc->mpc_ops->mpo_init_bpfdesc = 399 mpe->mpe_function; 400 break; 401 case MAC_INIT_CRED: 402 mpc->mpc_ops->mpo_init_cred = 403 mpe->mpe_function; 404 break; 405 case MAC_INIT_DEVFSDIRENT: 406 mpc->mpc_ops->mpo_init_devfsdirent = 407 mpe->mpe_function; 408 break; 409 case MAC_INIT_IFNET: 410 mpc->mpc_ops->mpo_init_ifnet = 411 mpe->mpe_function; 412 break; 413 case MAC_INIT_IPQ: 414 mpc->mpc_ops->mpo_init_ipq = 415 mpe->mpe_function; 416 break; 417 case MAC_INIT_MBUF: 418 mpc->mpc_ops->mpo_init_mbuf = 419 mpe->mpe_function; 420 break; 421 case MAC_INIT_MOUNT: 422 mpc->mpc_ops->mpo_init_mount = 423 mpe->mpe_function; 424 break; 425 case MAC_INIT_PIPE: 426 mpc->mpc_ops->mpo_init_pipe = 427 mpe->mpe_function; 428 break; 429 case MAC_INIT_SOCKET: 430 mpc->mpc_ops->mpo_init_socket = 431 mpe->mpe_function; 432 break; 433 case MAC_INIT_TEMP: 434 mpc->mpc_ops->mpo_init_temp = 435 mpe->mpe_function; 436 break; 437 case MAC_INIT_VNODE: 438 mpc->mpc_ops->mpo_init_vnode = 439 mpe->mpe_function; 440 break; 441 case MAC_DESTROY_BPFDESC: 442 mpc->mpc_ops->mpo_destroy_bpfdesc = 443 mpe->mpe_function; 444 break; 445 case MAC_DESTROY_CRED: 446 mpc->mpc_ops->mpo_destroy_cred = 447 mpe->mpe_function; 448 break; 449 case MAC_DESTROY_DEVFSDIRENT: 450 mpc->mpc_ops->mpo_destroy_devfsdirent = 451 mpe->mpe_function; 452 break; 453 case MAC_DESTROY_IFNET: 454 mpc->mpc_ops->mpo_destroy_ifnet = 455 mpe->mpe_function; 456 break; 457 case MAC_DESTROY_IPQ: 458 mpc->mpc_ops->mpo_destroy_ipq = 459 mpe->mpe_function; 460 break; 461 case MAC_DESTROY_MBUF: 462 mpc->mpc_ops->mpo_destroy_mbuf = 463 mpe->mpe_function; 464 break; 465 case MAC_DESTROY_MOUNT: 466 mpc->mpc_ops->mpo_destroy_mount = 467 mpe->mpe_function; 468 break; 469 case MAC_DESTROY_PIPE: 470 mpc->mpc_ops->mpo_destroy_pipe = 471 mpe->mpe_function; 472 break; 473 case MAC_DESTROY_SOCKET: 474 mpc->mpc_ops->mpo_destroy_socket = 475 mpe->mpe_function; 476 break; 477 case MAC_DESTROY_TEMP: 478 mpc->mpc_ops->mpo_destroy_temp = 479 mpe->mpe_function; 480 break; 481 case MAC_DESTROY_VNODE: 482 mpc->mpc_ops->mpo_destroy_vnode = 483 mpe->mpe_function; 484 break; 485 case MAC_EXTERNALIZE: 486 mpc->mpc_ops->mpo_externalize = 487 mpe->mpe_function; 488 break; 489 case MAC_INTERNALIZE: 490 mpc->mpc_ops->mpo_internalize = 491 mpe->mpe_function; 492 break; 493 case MAC_CREATE_DEVFS_DEVICE: 494 mpc->mpc_ops->mpo_create_devfs_device = 495 mpe->mpe_function; 496 break; 497 case MAC_CREATE_DEVFS_DIRECTORY: 498 mpc->mpc_ops->mpo_create_devfs_directory = 499 mpe->mpe_function; 500 break; 501 case MAC_CREATE_DEVFS_VNODE: 502 mpc->mpc_ops->mpo_create_devfs_vnode = 503 mpe->mpe_function; 504 break; 505 case MAC_STDCREATEVNODE_EA: 506 mpc->mpc_ops->mpo_stdcreatevnode_ea = 507 mpe->mpe_function; 508 break; 509 case MAC_CREATE_VNODE: 510 mpc->mpc_ops->mpo_create_vnode = 511 mpe->mpe_function; 512 break; 513 case MAC_CREATE_MOUNT: 514 mpc->mpc_ops->mpo_create_mount = 515 mpe->mpe_function; 516 break; 517 case MAC_CREATE_ROOT_MOUNT: 518 mpc->mpc_ops->mpo_create_root_mount = 519 mpe->mpe_function; 520 break; 521 case MAC_RELABEL_VNODE: 522 mpc->mpc_ops->mpo_relabel_vnode = 523 mpe->mpe_function; 524 break; 525 case MAC_UPDATE_DEVFSDIRENT: 526 mpc->mpc_ops->mpo_update_devfsdirent = 527 mpe->mpe_function; 528 break; 529 case MAC_UPDATE_PROCFSVNODE: 530 mpc->mpc_ops->mpo_update_procfsvnode = 531 mpe->mpe_function; 532 break; 533 case MAC_UPDATE_VNODE_FROM_EXTATTR: 534 mpc->mpc_ops->mpo_update_vnode_from_extattr = 535 mpe->mpe_function; 536 break; 537 case MAC_UPDATE_VNODE_FROM_EXTERNALIZED: 538 mpc->mpc_ops->mpo_update_vnode_from_externalized = 539 mpe->mpe_function; 540 break; 541 case MAC_UPDATE_VNODE_FROM_MOUNT: 542 mpc->mpc_ops->mpo_update_vnode_from_mount = 543 mpe->mpe_function; 544 break; 545 case MAC_CREATE_MBUF_FROM_SOCKET: 546 mpc->mpc_ops->mpo_create_mbuf_from_socket = 547 mpe->mpe_function; 548 break; 549 case MAC_CREATE_PIPE: 550 mpc->mpc_ops->mpo_create_pipe = 551 mpe->mpe_function; 552 break; 553 case MAC_CREATE_SOCKET: 554 mpc->mpc_ops->mpo_create_socket = 555 mpe->mpe_function; 556 break; 557 case MAC_CREATE_SOCKET_FROM_SOCKET: 558 mpc->mpc_ops->mpo_create_socket_from_socket = 559 mpe->mpe_function; 560 break; 561 case MAC_RELABEL_PIPE: 562 mpc->mpc_ops->mpo_relabel_pipe = 563 mpe->mpe_function; 564 break; 565 case MAC_RELABEL_SOCKET: 566 mpc->mpc_ops->mpo_relabel_socket = 567 mpe->mpe_function; 568 break; 569 case MAC_SET_SOCKET_PEER_FROM_MBUF: 570 mpc->mpc_ops->mpo_set_socket_peer_from_mbuf = 571 mpe->mpe_function; 572 break; 573 case MAC_SET_SOCKET_PEER_FROM_SOCKET: 574 mpc->mpc_ops->mpo_set_socket_peer_from_socket = 575 mpe->mpe_function; 576 break; 577 case MAC_CREATE_BPFDESC: 578 mpc->mpc_ops->mpo_create_bpfdesc = 579 mpe->mpe_function; 580 break; 581 case MAC_CREATE_DATAGRAM_FROM_IPQ: 582 mpc->mpc_ops->mpo_create_datagram_from_ipq = 583 mpe->mpe_function; 584 break; 585 case MAC_CREATE_FRAGMENT: 586 mpc->mpc_ops->mpo_create_fragment = 587 mpe->mpe_function; 588 break; 589 case MAC_CREATE_IFNET: 590 mpc->mpc_ops->mpo_create_ifnet = 591 mpe->mpe_function; 592 break; 593 case MAC_CREATE_IPQ: 594 mpc->mpc_ops->mpo_create_ipq = 595 mpe->mpe_function; 596 break; 597 case MAC_CREATE_MBUF_FROM_MBUF: 598 mpc->mpc_ops->mpo_create_mbuf_from_mbuf = 599 mpe->mpe_function; 600 break; 601 case MAC_CREATE_MBUF_LINKLAYER: 602 mpc->mpc_ops->mpo_create_mbuf_linklayer = 603 mpe->mpe_function; 604 break; 605 case MAC_CREATE_MBUF_FROM_BPFDESC: 606 mpc->mpc_ops->mpo_create_mbuf_from_bpfdesc = 607 mpe->mpe_function; 608 break; 609 case MAC_CREATE_MBUF_FROM_IFNET: 610 mpc->mpc_ops->mpo_create_mbuf_from_ifnet = 611 mpe->mpe_function; 612 break; 613 case MAC_CREATE_MBUF_MULTICAST_ENCAP: 614 mpc->mpc_ops->mpo_create_mbuf_multicast_encap = 615 mpe->mpe_function; 616 break; 617 case MAC_CREATE_MBUF_NETLAYER: 618 mpc->mpc_ops->mpo_create_mbuf_netlayer = 619 mpe->mpe_function; 620 break; 621 case MAC_FRAGMENT_MATCH: 622 mpc->mpc_ops->mpo_fragment_match = 623 mpe->mpe_function; 624 break; 625 case MAC_RELABEL_IFNET: 626 mpc->mpc_ops->mpo_relabel_ifnet = 627 mpe->mpe_function; 628 break; 629 case MAC_UPDATE_IPQ: 630 mpc->mpc_ops->mpo_update_ipq = 631 mpe->mpe_function; 632 break; 633 case MAC_CREATE_CRED: 634 mpc->mpc_ops->mpo_create_cred = 635 mpe->mpe_function; 636 break; 637 case MAC_EXECVE_TRANSITION: 638 mpc->mpc_ops->mpo_execve_transition = 639 mpe->mpe_function; 640 break; 641 case MAC_EXECVE_WILL_TRANSITION: 642 mpc->mpc_ops->mpo_execve_will_transition = 643 mpe->mpe_function; 644 break; 645 case MAC_CREATE_PROC0: 646 mpc->mpc_ops->mpo_create_proc0 = mpe->mpe_function; 647 break; 648 case MAC_CREATE_PROC1: 649 mpc->mpc_ops->mpo_create_proc1 = mpe->mpe_function; 650 break; 651 case MAC_RELABEL_CRED: 652 mpc->mpc_ops->mpo_relabel_cred = 653 mpe->mpe_function; 654 break; 655 case MAC_CHECK_BPFDESC_RECEIVE: 656 mpc->mpc_ops->mpo_check_bpfdesc_receive = 657 mpe->mpe_function; 658 break; 659 case MAC_CHECK_CRED_RELABEL: 660 mpc->mpc_ops->mpo_check_cred_relabel = 661 mpe->mpe_function; 662 break; 663 case MAC_CHECK_CRED_VISIBLE: 664 mpc->mpc_ops->mpo_check_cred_visible = 665 mpe->mpe_function; 666 break; 667 case MAC_CHECK_IFNET_RELABEL: 668 mpc->mpc_ops->mpo_check_ifnet_relabel = 669 mpe->mpe_function; 670 break; 671 case MAC_CHECK_IFNET_TRANSMIT: 672 mpc->mpc_ops->mpo_check_ifnet_transmit = 673 mpe->mpe_function; 674 break; 675 case MAC_CHECK_MOUNT_STAT: 676 mpc->mpc_ops->mpo_check_mount_stat = 677 mpe->mpe_function; 678 break; 679 case MAC_CHECK_PIPE_IOCTL: 680 mpc->mpc_ops->mpo_check_pipe_ioctl = 681 mpe->mpe_function; 682 break; 683 case MAC_CHECK_PIPE_POLL: 684 mpc->mpc_ops->mpo_check_pipe_poll = 685 mpe->mpe_function; 686 break; 687 case MAC_CHECK_PIPE_READ: 688 mpc->mpc_ops->mpo_check_pipe_read = 689 mpe->mpe_function; 690 break; 691 case MAC_CHECK_PIPE_RELABEL: 692 mpc->mpc_ops->mpo_check_pipe_relabel = 693 mpe->mpe_function; 694 break; 695 case MAC_CHECK_PIPE_STAT: 696 mpc->mpc_ops->mpo_check_pipe_stat = 697 mpe->mpe_function; 698 break; 699 case MAC_CHECK_PIPE_WRITE: 700 mpc->mpc_ops->mpo_check_pipe_write = 701 mpe->mpe_function; 702 break; 703 case MAC_CHECK_PROC_DEBUG: 704 mpc->mpc_ops->mpo_check_proc_debug = 705 mpe->mpe_function; 706 break; 707 case MAC_CHECK_PROC_SCHED: 708 mpc->mpc_ops->mpo_check_proc_sched = 709 mpe->mpe_function; 710 break; 711 case MAC_CHECK_PROC_SIGNAL: 712 mpc->mpc_ops->mpo_check_proc_signal = 713 mpe->mpe_function; 714 break; 715 case MAC_CHECK_SOCKET_BIND: 716 mpc->mpc_ops->mpo_check_socket_bind = 717 mpe->mpe_function; 718 break; 719 case MAC_CHECK_SOCKET_CONNECT: 720 mpc->mpc_ops->mpo_check_socket_connect = 721 mpe->mpe_function; 722 break; 723 case MAC_CHECK_SOCKET_DELIVER: 724 mpc->mpc_ops->mpo_check_socket_deliver = 725 mpe->mpe_function; 726 break; 727 case MAC_CHECK_SOCKET_LISTEN: 728 mpc->mpc_ops->mpo_check_socket_listen = 729 mpe->mpe_function; 730 break; 731 case MAC_CHECK_SOCKET_RELABEL: 732 mpc->mpc_ops->mpo_check_socket_relabel = 733 mpe->mpe_function; 734 break; 735 case MAC_CHECK_SOCKET_VISIBLE: 736 mpc->mpc_ops->mpo_check_socket_visible = 737 mpe->mpe_function; 738 break; 739 case MAC_CHECK_VNODE_ACCESS: 740 mpc->mpc_ops->mpo_check_vnode_access = 741 mpe->mpe_function; 742 break; 743 case MAC_CHECK_VNODE_CHDIR: 744 mpc->mpc_ops->mpo_check_vnode_chdir = 745 mpe->mpe_function; 746 break; 747 case MAC_CHECK_VNODE_CHROOT: 748 mpc->mpc_ops->mpo_check_vnode_chroot = 749 mpe->mpe_function; 750 break; 751 case MAC_CHECK_VNODE_CREATE: 752 mpc->mpc_ops->mpo_check_vnode_create = 753 mpe->mpe_function; 754 break; 755 case MAC_CHECK_VNODE_DELETE: 756 mpc->mpc_ops->mpo_check_vnode_delete = 757 mpe->mpe_function; 758 break; 759 case MAC_CHECK_VNODE_DELETEACL: 760 mpc->mpc_ops->mpo_check_vnode_deleteacl = 761 mpe->mpe_function; 762 break; 763 case MAC_CHECK_VNODE_EXEC: 764 mpc->mpc_ops->mpo_check_vnode_exec = 765 mpe->mpe_function; 766 break; 767 case MAC_CHECK_VNODE_GETACL: 768 mpc->mpc_ops->mpo_check_vnode_getacl = 769 mpe->mpe_function; 770 break; 771 case MAC_CHECK_VNODE_GETEXTATTR: 772 mpc->mpc_ops->mpo_check_vnode_getextattr = 773 mpe->mpe_function; 774 break; 775 case MAC_CHECK_VNODE_LOOKUP: 776 mpc->mpc_ops->mpo_check_vnode_lookup = 777 mpe->mpe_function; 778 break; 779 case MAC_CHECK_VNODE_MMAP_PERMS: 780 mpc->mpc_ops->mpo_check_vnode_mmap_perms = 781 mpe->mpe_function; 782 break; 783 case MAC_CHECK_VNODE_OPEN: 784 mpc->mpc_ops->mpo_check_vnode_open = 785 mpe->mpe_function; 786 break; 787 case MAC_CHECK_VNODE_POLL: 788 mpc->mpc_ops->mpo_check_vnode_poll = 789 mpe->mpe_function; 790 break; 791 case MAC_CHECK_VNODE_READ: 792 mpc->mpc_ops->mpo_check_vnode_read = 793 mpe->mpe_function; 794 break; 795 case MAC_CHECK_VNODE_READDIR: 796 mpc->mpc_ops->mpo_check_vnode_readdir = 797 mpe->mpe_function; 798 break; 799 case MAC_CHECK_VNODE_READLINK: 800 mpc->mpc_ops->mpo_check_vnode_readlink = 801 mpe->mpe_function; 802 break; 803 case MAC_CHECK_VNODE_RELABEL: 804 mpc->mpc_ops->mpo_check_vnode_relabel = 805 mpe->mpe_function; 806 break; 807 case MAC_CHECK_VNODE_RENAME_FROM: 808 mpc->mpc_ops->mpo_check_vnode_rename_from = 809 mpe->mpe_function; 810 break; 811 case MAC_CHECK_VNODE_RENAME_TO: 812 mpc->mpc_ops->mpo_check_vnode_rename_to = 813 mpe->mpe_function; 814 break; 815 case MAC_CHECK_VNODE_REVOKE: 816 mpc->mpc_ops->mpo_check_vnode_revoke = 817 mpe->mpe_function; 818 break; 819 case MAC_CHECK_VNODE_SETACL: 820 mpc->mpc_ops->mpo_check_vnode_setacl = 821 mpe->mpe_function; 822 break; 823 case MAC_CHECK_VNODE_SETEXTATTR: 824 mpc->mpc_ops->mpo_check_vnode_setextattr = 825 mpe->mpe_function; 826 break; 827 case MAC_CHECK_VNODE_SETFLAGS: 828 mpc->mpc_ops->mpo_check_vnode_setflags = 829 mpe->mpe_function; 830 break; 831 case MAC_CHECK_VNODE_SETMODE: 832 mpc->mpc_ops->mpo_check_vnode_setmode = 833 mpe->mpe_function; 834 break; 835 case MAC_CHECK_VNODE_SETOWNER: 836 mpc->mpc_ops->mpo_check_vnode_setowner = 837 mpe->mpe_function; 838 break; 839 case MAC_CHECK_VNODE_SETUTIMES: 840 mpc->mpc_ops->mpo_check_vnode_setutimes = 841 mpe->mpe_function; 842 break; 843 case MAC_CHECK_VNODE_STAT: 844 mpc->mpc_ops->mpo_check_vnode_stat = 845 mpe->mpe_function; 846 break; 847 case MAC_CHECK_VNODE_WRITE: 848 mpc->mpc_ops->mpo_check_vnode_write = 849 mpe->mpe_function; 850 break; 851/* 852 default: 853 printf("MAC policy `%s': unknown operation %d\n", 854 mpc->mpc_name, mpe->mpe_constant); 855 return (EINVAL); 856*/ 857 } 858 } 859 MAC_POLICY_LIST_LOCK(); 860 if (mac_policy_list_busy > 0) { 861 MAC_POLICY_LIST_UNLOCK(); 862 FREE(mpc->mpc_ops, M_MACOPVEC); 863 mpc->mpc_ops = NULL; 864 return (EBUSY); 865 } 866 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 867 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 868 MAC_POLICY_LIST_UNLOCK(); 869 FREE(mpc->mpc_ops, M_MACOPVEC); 870 mpc->mpc_ops = NULL; 871 return (EEXIST); 872 } 873 } 874 if (mpc->mpc_field_off != NULL) { 875 slot = ffs(mac_policy_offsets_free); 876 if (slot == 0) { 877 MAC_POLICY_LIST_UNLOCK(); 878 FREE(mpc->mpc_ops, M_MACOPVEC); 879 mpc->mpc_ops = NULL; 880 return (ENOMEM); 881 } 882 slot--; 883 mac_policy_offsets_free &= ~(1 << slot); 884 *mpc->mpc_field_off = slot; 885 } 886 mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 887 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 888 889 /* Per-policy initialization. */ 890 if (mpc->mpc_ops->mpo_init != NULL) 891 (*(mpc->mpc_ops->mpo_init))(mpc); 892 MAC_POLICY_LIST_UNLOCK(); 893 894 printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 895 mpc->mpc_name); 896 897 return (0); 898} 899 900static int 901mac_policy_unregister(struct mac_policy_conf *mpc) 902{ 903 904#if 0 905 /* 906 * Don't allow unloading modules with private data. 907 */ 908 if (mpc->mpc_field_off != NULL) 909 return (EBUSY); 910#endif 911 if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) 912 return (EBUSY); 913 MAC_POLICY_LIST_LOCK(); 914 if (mac_policy_list_busy > 0) { 915 MAC_POLICY_LIST_UNLOCK(); 916 return (EBUSY); 917 } 918 if (mpc->mpc_ops->mpo_destroy != NULL) 919 (*(mpc->mpc_ops->mpo_destroy))(mpc); 920 921 LIST_REMOVE(mpc, mpc_list); 922 MAC_POLICY_LIST_UNLOCK(); 923 924 FREE(mpc->mpc_ops, M_MACOPVEC); 925 mpc->mpc_ops = NULL; 926 927 printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 928 mpc->mpc_name); 929 930 return (0); 931} 932 933/* 934 * Define an error value precedence, and given two arguments, selects the 935 * value with the higher precedence. 936 */ 937static int 938error_select(int error1, int error2) 939{ 940 941 /* Certain decision-making errors take top priority. */ 942 if (error1 == EDEADLK || error2 == EDEADLK) 943 return (EDEADLK); 944 945 /* Invalid arguments should be reported where possible. */ 946 if (error1 == EINVAL || error2 == EINVAL) 947 return (EINVAL); 948 949 /* Precedence goes to "visibility", with both process and file. */ 950 if (error1 == ESRCH || error2 == ESRCH) 951 return (ESRCH); 952 953 if (error1 == ENOENT || error2 == ENOENT) 954 return (ENOENT); 955 956 /* Precedence goes to DAC/MAC protections. */ 957 if (error1 == EACCES || error2 == EACCES) 958 return (EACCES); 959 960 /* Precedence goes to privilege. */ 961 if (error1 == EPERM || error2 == EPERM) 962 return (EPERM); 963 964 /* Precedence goes to error over success; otherwise, arbitrary. */ 965 if (error1 != 0) 966 return (error1); 967 return (error2); 968} 969 970void 971mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 972{ 973 974 MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 975} 976 977void 978mac_update_procfsvnode(struct vnode *vp, struct ucred *cred) 979{ 980 981 MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred); 982} 983 984/* 985 * Support callout for policies that manage their own externalization 986 * using extended attributes. 987 */ 988static int 989mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp) 990{ 991 int error; 992 993 MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp, 994 &mp->mnt_fslabel); 995 996 return (error); 997} 998 999/* 1000 * Given an externalized mac label, internalize it and stamp it on a 1001 * vnode. 1002 */ 1003static int 1004mac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac) 1005{ 1006 int error; 1007 1008 MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac); 1009 1010 return (error); 1011} 1012 1013/* 1014 * Call out to individual policies to update the label in a vnode from 1015 * the mountpoint. 1016 */ 1017void 1018mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp) 1019{ 1020 1021 MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp, 1022 &mp->mnt_fslabel); 1023 1024 ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount"); 1025 if (mac_cache_fslabel_in_vnode) 1026 vp->v_vflag |= VV_CACHEDLABEL; 1027} 1028 1029/* 1030 * Implementation of VOP_REFRESHLABEL() that relies on extended attributes 1031 * to store label data. Can be referenced by filesystems supporting 1032 * extended attributes. 1033 */ 1034int 1035vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap) 1036{ 1037 struct vnode *vp = ap->a_vp; 1038 struct mac extmac; 1039 int buflen, error; 1040 1041 ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea"); 1042 1043 /* 1044 * Call out to external policies first. Order doesn't really 1045 * matter, as long as failure of one assures failure of all. 1046 */ 1047 error = mac_update_vnode_from_extattr(vp, vp->v_mount); 1048 if (error) 1049 return (error); 1050 1051 buflen = sizeof(extmac); 1052 error = vn_extattr_get(vp, IO_NODELOCKED, 1053 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen, 1054 (char *)&extmac, curthread); 1055 switch (error) { 1056 case 0: 1057 /* Got it */ 1058 break; 1059 1060 case ENOATTR: 1061 /* 1062 * Use the label from the mount point. 1063 */ 1064 mac_update_vnode_from_mount(vp, vp->v_mount); 1065 return (0); 1066 1067 case EOPNOTSUPP: 1068 default: 1069 /* Fail horribly. */ 1070 return (error); 1071 } 1072 1073 if (buflen != sizeof(extmac)) 1074 error = EPERM; /* Fail very closed. */ 1075 if (error == 0) 1076 error = mac_update_vnode_from_externalized(vp, &extmac); 1077 if (error == 0) 1078 vp->v_vflag |= VV_CACHEDLABEL; 1079 else { 1080 struct vattr va; 1081 1082 printf("Corrupted label on %s", 1083 vp->v_mount->mnt_stat.f_mntonname); 1084 if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0) 1085 printf(" inum %ld", va.va_fileid); 1086#ifdef MAC_DEBUG 1087 if (mac_debug_label_fallback) { 1088 printf(", falling back.\n"); 1089 mac_update_vnode_from_mount(vp, vp->v_mount); 1090 error = 0; 1091 } else { 1092#endif 1093 printf(".\n"); 1094 error = EPERM; 1095#ifdef MAC_DEBUG 1096 } 1097#endif 1098 } 1099 1100 return (error); 1101} 1102 1103/* 1104 * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle 1105 * the labeling activity outselves. Filesystems should be careful not 1106 * to change their minds regarding whether they support vop_refreshlabel() 1107 * for a vnode or not. Don't cache the vnode here, allow the file 1108 * system code to determine if it's safe to cache. If we update from 1109 * the mount, don't cache since a change to the mount label should affect 1110 * all vnodes. 1111 */ 1112static int 1113vn_refreshlabel(struct vnode *vp, struct ucred *cred) 1114{ 1115 int error; 1116 1117 ASSERT_VOP_LOCKED(vp, "vn_refreshlabel"); 1118 1119 if (vp->v_mount == NULL) { 1120/* 1121 Eventually, we probably want to special-case refreshing 1122 of deadfs vnodes, and if there's a lock-free race somewhere, 1123 that case might be handled here. 1124 1125 mac_update_vnode_deadfs(vp); 1126 return (0); 1127 */ 1128 /* printf("vn_refreshlabel: null v_mount\n"); */ 1129 if (vp->v_type != VNON) 1130 printf( 1131 "vn_refreshlabel: null v_mount with non-VNON\n"); 1132 return (EBADF); 1133 } 1134 1135 if (vp->v_vflag & VV_CACHEDLABEL) { 1136 mac_vnode_label_cache_hits++; 1137 return (0); 1138 } else 1139 mac_vnode_label_cache_misses++; 1140 1141 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1142 mac_update_vnode_from_mount(vp, vp->v_mount); 1143 return (0); 1144 } 1145 1146 error = VOP_REFRESHLABEL(vp, cred, curthread); 1147 switch (error) { 1148 case EOPNOTSUPP: 1149 /* 1150 * If labels are not supported on this vnode, fall back to 1151 * the label in the mount and propagate it to the vnode. 1152 * There should probably be some sort of policy/flag/decision 1153 * about doing this. 1154 */ 1155 mac_update_vnode_from_mount(vp, vp->v_mount); 1156 error = 0; 1157 default: 1158 return (error); 1159 } 1160} 1161 1162/* 1163 * Helper function for file systems using the vop_std*_ea() calls. This 1164 * function must be called after EA service is available for the vnode, 1165 * but before it's hooked up to the namespace so that the node persists 1166 * if there's a crash, or before it can be accessed. On successful 1167 * commit of the label to disk (etc), do cache the label. 1168 */ 1169int 1170vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred) 1171{ 1172 struct mac extmac; 1173 int error; 1174 1175 ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea"); 1176 if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) { 1177 mac_update_vnode_from_mount(tvp, tvp->v_mount); 1178 } else { 1179 error = vn_refreshlabel(dvp, cred); 1180 if (error) 1181 return (error); 1182 1183 /* 1184 * Stick the label in the vnode. Then try to write to 1185 * disk. If we fail, return a failure to abort the 1186 * create operation. Really, this failure shouldn't 1187 * happen except in fairly unusual circumstances (out 1188 * of disk, etc). 1189 */ 1190 mac_create_vnode(cred, dvp, tvp); 1191 1192 error = mac_stdcreatevnode_ea(tvp); 1193 if (error) 1194 return (error); 1195 1196 /* 1197 * XXX: Eventually this will go away and all policies will 1198 * directly manage their extended attributes. 1199 */ 1200 error = mac_externalize(&tvp->v_label, &extmac); 1201 if (error) 1202 return (error); 1203 1204 error = vn_extattr_set(tvp, IO_NODELOCKED, 1205 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 1206 sizeof(extmac), (char *)&extmac, curthread); 1207 if (error == 0) 1208 tvp->v_vflag |= VV_CACHEDLABEL; 1209 else { 1210#if 0 1211 /* 1212 * In theory, we could have fall-back behavior here. 1213 * It would probably be incorrect. 1214 */ 1215#endif 1216 return (error); 1217 } 1218 } 1219 1220 return (0); 1221} 1222 1223void 1224mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp) 1225{ 1226 int error; 1227 1228 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1229 1230 error = vn_refreshlabel(vp, old); 1231 if (error) { 1232 printf("mac_execve_transition: vn_refreshlabel returned %d\n", 1233 error); 1234 printf("mac_execve_transition: using old vnode label\n"); 1235 } 1236 1237 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label); 1238} 1239 1240int 1241mac_execve_will_transition(struct ucred *old, struct vnode *vp) 1242{ 1243 int error, result; 1244 1245 error = vn_refreshlabel(vp, old); 1246 if (error) 1247 return (error); 1248 1249 result = 0; 1250 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label); 1251 1252 return (result); 1253} 1254 1255static void 1256mac_init_label(struct label *label) 1257{ 1258 1259 bzero(label, sizeof(*label)); 1260 label->l_flags = MAC_FLAG_INITIALIZED; 1261} 1262 1263static void 1264mac_init_structmac(struct mac *mac) 1265{ 1266 1267 bzero(mac, sizeof(*mac)); 1268 mac->m_macflags = MAC_FLAG_INITIALIZED; 1269} 1270 1271static void 1272mac_destroy_label(struct label *label) 1273{ 1274 1275 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 1276 ("destroying uninitialized label")); 1277 1278 bzero(label, sizeof(*label)); 1279 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 1280} 1281 1282int 1283mac_init_mbuf(struct mbuf *m, int how) 1284{ 1285 KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 1286 1287 /* "how" is one of M_(TRY|DONT)WAIT */ 1288 mac_init_label(&m->m_pkthdr.label); 1289 MAC_PERFORM(init_mbuf, m, how, &m->m_pkthdr.label); 1290#ifdef MAC_DEBUG 1291 atomic_add_int(&nmacmbufs, 1); 1292#endif 1293 return (0); 1294} 1295 1296void 1297mac_destroy_mbuf(struct mbuf *m) 1298{ 1299 1300 MAC_PERFORM(destroy_mbuf, m, &m->m_pkthdr.label); 1301 mac_destroy_label(&m->m_pkthdr.label); 1302#ifdef MAC_DEBUG 1303 atomic_subtract_int(&nmacmbufs, 1); 1304#endif 1305} 1306 1307void 1308mac_init_cred(struct ucred *cr) 1309{ 1310 1311 mac_init_label(&cr->cr_label); 1312 MAC_PERFORM(init_cred, cr, &cr->cr_label); 1313#ifdef MAC_DEBUG 1314 atomic_add_int(&nmaccreds, 1); 1315#endif 1316} 1317 1318void 1319mac_destroy_cred(struct ucred *cr) 1320{ 1321 1322 MAC_PERFORM(destroy_cred, cr, &cr->cr_label); 1323 mac_destroy_label(&cr->cr_label); 1324#ifdef MAC_DEBUG 1325 atomic_subtract_int(&nmaccreds, 1); 1326#endif 1327} 1328 1329void 1330mac_init_ifnet(struct ifnet *ifp) 1331{ 1332 1333 mac_init_label(&ifp->if_label); 1334 MAC_PERFORM(init_ifnet, ifp, &ifp->if_label); 1335#ifdef MAC_DEBUG 1336 atomic_add_int(&nmacifnets, 1); 1337#endif 1338} 1339 1340void 1341mac_destroy_ifnet(struct ifnet *ifp) 1342{ 1343 1344 MAC_PERFORM(destroy_ifnet, ifp, &ifp->if_label); 1345 mac_destroy_label(&ifp->if_label); 1346#ifdef MAC_DEBUG 1347 atomic_subtract_int(&nmacifnets, 1); 1348#endif 1349} 1350 1351void 1352mac_init_ipq(struct ipq *ipq) 1353{ 1354 1355 mac_init_label(&ipq->ipq_label); 1356 MAC_PERFORM(init_ipq, ipq, &ipq->ipq_label); 1357#ifdef MAC_DEBUG 1358 atomic_add_int(&nmacipqs, 1); 1359#endif 1360} 1361 1362void 1363mac_destroy_ipq(struct ipq *ipq) 1364{ 1365 1366 MAC_PERFORM(destroy_ipq, ipq, &ipq->ipq_label); 1367 mac_destroy_label(&ipq->ipq_label); 1368#ifdef MAC_DEBUG 1369 atomic_subtract_int(&nmacipqs, 1); 1370#endif 1371} 1372 1373void 1374mac_init_socket(struct socket *socket) 1375{ 1376 1377 mac_init_label(&socket->so_label); 1378 mac_init_label(&socket->so_peerlabel); 1379 MAC_PERFORM(init_socket, socket, &socket->so_label, 1380 &socket->so_peerlabel); 1381#ifdef MAC_DEBUG 1382 atomic_add_int(&nmacsockets, 1); 1383#endif 1384} 1385 1386void 1387mac_destroy_socket(struct socket *socket) 1388{ 1389 1390 MAC_PERFORM(destroy_socket, socket, &socket->so_label, 1391 &socket->so_peerlabel); 1392 mac_destroy_label(&socket->so_label); 1393 mac_destroy_label(&socket->so_peerlabel); 1394#ifdef MAC_DEBUG 1395 atomic_subtract_int(&nmacsockets, 1); 1396#endif 1397} 1398 1399void 1400mac_init_pipe(struct pipe *pipe) 1401{ 1402 struct label *label; 1403 1404 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 1405 mac_init_label(label); 1406 pipe->pipe_label = label; 1407 pipe->pipe_peer->pipe_label = label; 1408 MAC_PERFORM(init_pipe, pipe, pipe->pipe_label); 1409#ifdef MAC_DEBUG 1410 atomic_add_int(&nmacpipes, 1); 1411#endif 1412} 1413 1414void 1415mac_destroy_pipe(struct pipe *pipe) 1416{ 1417 1418 MAC_PERFORM(destroy_pipe, pipe, pipe->pipe_label); 1419 mac_destroy_label(pipe->pipe_label); 1420 free(pipe->pipe_label, M_MACPIPELABEL); 1421#ifdef MAC_DEBUG 1422 atomic_subtract_int(&nmacpipes, 1); 1423#endif 1424} 1425 1426void 1427mac_init_bpfdesc(struct bpf_d *bpf_d) 1428{ 1429 1430 mac_init_label(&bpf_d->bd_label); 1431 MAC_PERFORM(init_bpfdesc, bpf_d, &bpf_d->bd_label); 1432#ifdef MAC_DEBUG 1433 atomic_add_int(&nmacbpfdescs, 1); 1434#endif 1435} 1436 1437void 1438mac_destroy_bpfdesc(struct bpf_d *bpf_d) 1439{ 1440 1441 MAC_PERFORM(destroy_bpfdesc, bpf_d, &bpf_d->bd_label); 1442 mac_destroy_label(&bpf_d->bd_label); 1443#ifdef MAC_DEBUG 1444 atomic_subtract_int(&nmacbpfdescs, 1); 1445#endif 1446} 1447 1448void 1449mac_init_mount(struct mount *mp) 1450{ 1451 1452 mac_init_label(&mp->mnt_mntlabel); 1453 mac_init_label(&mp->mnt_fslabel); 1454 MAC_PERFORM(init_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 1455#ifdef MAC_DEBUG 1456 atomic_add_int(&nmacmounts, 1); 1457#endif 1458} 1459 1460void 1461mac_destroy_mount(struct mount *mp) 1462{ 1463 1464 MAC_PERFORM(destroy_mount, mp, &mp->mnt_mntlabel, &mp->mnt_fslabel); 1465 mac_destroy_label(&mp->mnt_fslabel); 1466 mac_destroy_label(&mp->mnt_mntlabel); 1467#ifdef MAC_DEBUG 1468 atomic_subtract_int(&nmacmounts, 1); 1469#endif 1470} 1471 1472static void 1473mac_init_temp(struct label *label) 1474{ 1475 1476 mac_init_label(label); 1477 MAC_PERFORM(init_temp, label); 1478#ifdef MAC_DEBUG 1479 atomic_add_int(&nmactemp, 1); 1480#endif 1481} 1482 1483static void 1484mac_destroy_temp(struct label *label) 1485{ 1486 1487 MAC_PERFORM(destroy_temp, label); 1488 mac_destroy_label(label); 1489#ifdef MAC_DEBUG 1490 atomic_subtract_int(&nmactemp, 1); 1491#endif 1492} 1493 1494void 1495mac_init_vnode(struct vnode *vp) 1496{ 1497 1498 mac_init_label(&vp->v_label); 1499 MAC_PERFORM(init_vnode, vp, &vp->v_label); 1500#ifdef MAC_DEBUG 1501 atomic_add_int(&nmacvnodes, 1); 1502#endif 1503} 1504 1505void 1506mac_destroy_vnode(struct vnode *vp) 1507{ 1508 1509 MAC_PERFORM(destroy_vnode, vp, &vp->v_label); 1510 mac_destroy_label(&vp->v_label); 1511#ifdef MAC_DEBUG 1512 atomic_subtract_int(&nmacvnodes, 1); 1513#endif 1514} 1515 1516void 1517mac_init_devfsdirent(struct devfs_dirent *de) 1518{ 1519 1520 mac_init_label(&de->de_label); 1521 MAC_PERFORM(init_devfsdirent, de, &de->de_label); 1522#ifdef MAC_DEBUG 1523 atomic_add_int(&nmacdevfsdirents, 1); 1524#endif 1525} 1526 1527void 1528mac_destroy_devfsdirent(struct devfs_dirent *de) 1529{ 1530 1531 MAC_PERFORM(destroy_devfsdirent, de, &de->de_label); 1532 mac_destroy_label(&de->de_label); 1533#ifdef MAC_DEBUG 1534 atomic_subtract_int(&nmacdevfsdirents, 1); 1535#endif 1536} 1537 1538static int 1539mac_externalize(struct label *label, struct mac *mac) 1540{ 1541 int error; 1542 1543 mac_init_structmac(mac); 1544 MAC_CHECK(externalize, label, mac); 1545 1546 return (error); 1547} 1548 1549static int 1550mac_internalize(struct label *label, struct mac *mac) 1551{ 1552 int error; 1553 1554 mac_init_temp(label); 1555 MAC_CHECK(internalize, label, mac); 1556 if (error) 1557 mac_destroy_temp(label); 1558 1559 return (error); 1560} 1561 1562/* 1563 * Initialize MAC label for the first kernel process, from which other 1564 * kernel processes and threads are spawned. 1565 */ 1566void 1567mac_create_proc0(struct ucred *cred) 1568{ 1569 1570 MAC_PERFORM(create_proc0, cred); 1571} 1572 1573/* 1574 * Initialize MAC label for the first userland process, from which other 1575 * userland processes and threads are spawned. 1576 */ 1577void 1578mac_create_proc1(struct ucred *cred) 1579{ 1580 1581 MAC_PERFORM(create_proc1, cred); 1582} 1583 1584/* 1585 * When a new process is created, its label must be initialized. Generally, 1586 * this involves inheritence from the parent process, modulo possible 1587 * deltas. This function allows that processing to take place. 1588 */ 1589void 1590mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1591{ 1592 1593 MAC_PERFORM(create_cred, parent_cred, child_cred); 1594} 1595 1596int 1597mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags) 1598{ 1599 int error; 1600 1601 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1602 1603 if (!mac_enforce_fs) 1604 return (0); 1605 1606 error = vn_refreshlabel(vp, cred); 1607 if (error) 1608 return (error); 1609 1610 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags); 1611 return (error); 1612} 1613 1614int 1615mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1616{ 1617 int error; 1618 1619 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1620 1621 if (!mac_enforce_fs) 1622 return (0); 1623 1624 error = vn_refreshlabel(dvp, cred); 1625 if (error) 1626 return (error); 1627 1628 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1629 return (error); 1630} 1631 1632int 1633mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1634{ 1635 int error; 1636 1637 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1638 1639 if (!mac_enforce_fs) 1640 return (0); 1641 1642 error = vn_refreshlabel(dvp, cred); 1643 if (error) 1644 return (error); 1645 1646 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1647 return (error); 1648} 1649 1650int 1651mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1652 struct componentname *cnp, struct vattr *vap) 1653{ 1654 int error; 1655 1656 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1657 1658 if (!mac_enforce_fs) 1659 return (0); 1660 1661 error = vn_refreshlabel(dvp, cred); 1662 if (error) 1663 return (error); 1664 1665 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1666 return (error); 1667} 1668 1669int 1670mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1671 struct componentname *cnp) 1672{ 1673 int error; 1674 1675 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1676 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1677 1678 if (!mac_enforce_fs) 1679 return (0); 1680 1681 error = vn_refreshlabel(dvp, cred); 1682 if (error) 1683 return (error); 1684 error = vn_refreshlabel(vp, cred); 1685 if (error) 1686 return (error); 1687 1688 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1689 &vp->v_label, cnp); 1690 return (error); 1691} 1692 1693int 1694mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1695 acl_type_t type) 1696{ 1697 int error; 1698 1699 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1700 1701 if (!mac_enforce_fs) 1702 return (0); 1703 1704 error = vn_refreshlabel(vp, cred); 1705 if (error) 1706 return (error); 1707 1708 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1709 return (error); 1710} 1711 1712int 1713mac_check_vnode_exec(struct ucred *cred, struct vnode *vp) 1714{ 1715 int error; 1716 1717 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1718 1719 if (!mac_enforce_process && !mac_enforce_fs) 1720 return (0); 1721 1722 error = vn_refreshlabel(vp, cred); 1723 if (error) 1724 return (error); 1725 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label); 1726 1727 return (error); 1728} 1729 1730int 1731mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1732{ 1733 int error; 1734 1735 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1736 1737 if (!mac_enforce_fs) 1738 return (0); 1739 1740 error = vn_refreshlabel(vp, cred); 1741 if (error) 1742 return (error); 1743 1744 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1745 return (error); 1746} 1747 1748int 1749mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1750 int attrnamespace, const char *name, struct uio *uio) 1751{ 1752 int error; 1753 1754 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1755 1756 if (!mac_enforce_fs) 1757 return (0); 1758 1759 error = vn_refreshlabel(vp, cred); 1760 if (error) 1761 return (error); 1762 1763 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1764 attrnamespace, name, uio); 1765 return (error); 1766} 1767 1768int 1769mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1770 struct componentname *cnp) 1771{ 1772 int error; 1773 1774 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1775 1776 if (!mac_enforce_fs) 1777 return (0); 1778 1779 error = vn_refreshlabel(dvp, cred); 1780 if (error) 1781 return (error); 1782 1783 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1784 return (error); 1785} 1786 1787vm_prot_t 1788mac_check_vnode_mmap_prot(struct ucred *cred, struct vnode *vp, int newmapping) 1789{ 1790 vm_prot_t result = VM_PROT_ALL; 1791 1792 if (!mac_enforce_vm) 1793 return (result); 1794 1795 /* 1796 * This should be some sort of MAC_BITWISE, maybe :) 1797 */ 1798 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_perms"); 1799 MAC_BOOLEAN(check_vnode_mmap_perms, &, cred, vp, &vp->v_label, 1800 newmapping); 1801 return (result); 1802} 1803 1804int 1805mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode) 1806{ 1807 int error; 1808 1809 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1810 1811 if (!mac_enforce_fs) 1812 return (0); 1813 1814 error = vn_refreshlabel(vp, cred); 1815 if (error) 1816 return (error); 1817 1818 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1819 return (error); 1820} 1821 1822int 1823mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1824 struct vnode *vp) 1825{ 1826 int error; 1827 1828 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1829 1830 if (!mac_enforce_fs) 1831 return (0); 1832 1833 error = vn_refreshlabel(vp, active_cred); 1834 if (error) 1835 return (error); 1836 1837 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1838 &vp->v_label); 1839 1840 return (error); 1841} 1842 1843int 1844mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1845 struct vnode *vp) 1846{ 1847 int error; 1848 1849 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1850 1851 if (!mac_enforce_fs) 1852 return (0); 1853 1854 error = vn_refreshlabel(vp, active_cred); 1855 if (error) 1856 return (error); 1857 1858 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1859 &vp->v_label); 1860 1861 return (error); 1862} 1863 1864int 1865mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1866{ 1867 int error; 1868 1869 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1870 1871 if (!mac_enforce_fs) 1872 return (0); 1873 1874 error = vn_refreshlabel(dvp, cred); 1875 if (error) 1876 return (error); 1877 1878 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1879 return (error); 1880} 1881 1882int 1883mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1884{ 1885 int error; 1886 1887 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1888 1889 if (!mac_enforce_fs) 1890 return (0); 1891 1892 error = vn_refreshlabel(vp, cred); 1893 if (error) 1894 return (error); 1895 1896 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1897 return (error); 1898} 1899 1900static int 1901mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1902 struct label *newlabel) 1903{ 1904 int error; 1905 1906 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1907 1908 error = vn_refreshlabel(vp, cred); 1909 if (error) 1910 return (error); 1911 1912 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1913 1914 return (error); 1915} 1916 1917int 1918mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1919 struct vnode *vp, struct componentname *cnp) 1920{ 1921 int error; 1922 1923 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1924 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1925 1926 if (!mac_enforce_fs) 1927 return (0); 1928 1929 error = vn_refreshlabel(dvp, cred); 1930 if (error) 1931 return (error); 1932 error = vn_refreshlabel(vp, cred); 1933 if (error) 1934 return (error); 1935 1936 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1937 &vp->v_label, cnp); 1938 return (error); 1939} 1940 1941int 1942mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1943 struct vnode *vp, int samedir, struct componentname *cnp) 1944{ 1945 int error; 1946 1947 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1948 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1949 1950 if (!mac_enforce_fs) 1951 return (0); 1952 1953 error = vn_refreshlabel(dvp, cred); 1954 if (error) 1955 return (error); 1956 if (vp != NULL) { 1957 error = vn_refreshlabel(vp, cred); 1958 if (error) 1959 return (error); 1960 } 1961 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1962 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1963 return (error); 1964} 1965 1966int 1967mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1968{ 1969 int error; 1970 1971 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1972 1973 if (!mac_enforce_fs) 1974 return (0); 1975 1976 error = vn_refreshlabel(vp, cred); 1977 if (error) 1978 return (error); 1979 1980 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1981 return (error); 1982} 1983 1984int 1985mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1986 struct acl *acl) 1987{ 1988 int error; 1989 1990 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1991 1992 if (!mac_enforce_fs) 1993 return (0); 1994 1995 error = vn_refreshlabel(vp, cred); 1996 if (error) 1997 return (error); 1998 1999 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 2000 return (error); 2001} 2002 2003int 2004mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2005 int attrnamespace, const char *name, struct uio *uio) 2006{ 2007 int error; 2008 2009 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 2010 2011 if (!mac_enforce_fs) 2012 return (0); 2013 2014 error = vn_refreshlabel(vp, cred); 2015 if (error) 2016 return (error); 2017 2018 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 2019 attrnamespace, name, uio); 2020 return (error); 2021} 2022 2023int 2024mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 2025{ 2026 int error; 2027 2028 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 2029 2030 if (!mac_enforce_fs) 2031 return (0); 2032 2033 error = vn_refreshlabel(vp, cred); 2034 if (error) 2035 return (error); 2036 2037 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 2038 return (error); 2039} 2040 2041int 2042mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 2043{ 2044 int error; 2045 2046 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 2047 2048 if (!mac_enforce_fs) 2049 return (0); 2050 2051 error = vn_refreshlabel(vp, cred); 2052 if (error) 2053 return (error); 2054 2055 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 2056 return (error); 2057} 2058 2059int 2060mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 2061 gid_t gid) 2062{ 2063 int error; 2064 2065 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 2066 2067 if (!mac_enforce_fs) 2068 return (0); 2069 2070 error = vn_refreshlabel(vp, cred); 2071 if (error) 2072 return (error); 2073 2074 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 2075 return (error); 2076} 2077 2078int 2079mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2080 struct timespec atime, struct timespec mtime) 2081{ 2082 int error; 2083 2084 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 2085 2086 if (!mac_enforce_fs) 2087 return (0); 2088 2089 error = vn_refreshlabel(vp, cred); 2090 if (error) 2091 return (error); 2092 2093 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 2094 mtime); 2095 return (error); 2096} 2097 2098int 2099mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2100 struct vnode *vp) 2101{ 2102 int error; 2103 2104 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 2105 2106 if (!mac_enforce_fs) 2107 return (0); 2108 2109 error = vn_refreshlabel(vp, active_cred); 2110 if (error) 2111 return (error); 2112 2113 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 2114 &vp->v_label); 2115 return (error); 2116} 2117 2118int 2119mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2120 struct vnode *vp) 2121{ 2122 int error; 2123 2124 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 2125 2126 if (!mac_enforce_fs) 2127 return (0); 2128 2129 error = vn_refreshlabel(vp, active_cred); 2130 if (error) 2131 return (error); 2132 2133 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 2134 &vp->v_label); 2135 2136 return (error); 2137} 2138 2139/* 2140 * When relabeling a process, call out to the policies for the maximum 2141 * permission allowed for each object type we know about in its 2142 * memory space, and revoke access (in the least surprising ways we 2143 * know) when necessary. The process lock is not held here. 2144 */ 2145static void 2146mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 2147{ 2148 2149 /* XXX freeze all other threads */ 2150 mac_cred_mmapped_drop_perms_recurse(td, cred, 2151 &td->td_proc->p_vmspace->vm_map); 2152 /* XXX allow other threads to continue */ 2153} 2154 2155static __inline const char * 2156prot2str(vm_prot_t prot) 2157{ 2158 2159 switch (prot & VM_PROT_ALL) { 2160 case VM_PROT_READ: 2161 return ("r--"); 2162 case VM_PROT_READ | VM_PROT_WRITE: 2163 return ("rw-"); 2164 case VM_PROT_READ | VM_PROT_EXECUTE: 2165 return ("r-x"); 2166 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 2167 return ("rwx"); 2168 case VM_PROT_WRITE: 2169 return ("-w-"); 2170 case VM_PROT_EXECUTE: 2171 return ("--x"); 2172 case VM_PROT_WRITE | VM_PROT_EXECUTE: 2173 return ("-wx"); 2174 default: 2175 return ("---"); 2176 } 2177} 2178 2179static void 2180mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 2181 struct vm_map *map) 2182{ 2183 struct vm_map_entry *vme; 2184 vm_prot_t result, revokeperms; 2185 vm_object_t object; 2186 vm_ooffset_t offset; 2187 struct vnode *vp; 2188 2189 if (!mac_mmap_revocation) 2190 return; 2191 2192 vm_map_lock_read(map); 2193 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 2194 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 2195 mac_cred_mmapped_drop_perms_recurse(td, cred, 2196 vme->object.sub_map); 2197 continue; 2198 } 2199 /* 2200 * Skip over entries that obviously are not shared. 2201 */ 2202 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 2203 !vme->max_protection) 2204 continue; 2205 /* 2206 * Drill down to the deepest backing object. 2207 */ 2208 offset = vme->offset; 2209 object = vme->object.vm_object; 2210 if (object == NULL) 2211 continue; 2212 while (object->backing_object != NULL) { 2213 object = object->backing_object; 2214 offset += object->backing_object_offset; 2215 } 2216 /* 2217 * At the moment, vm_maps and objects aren't considered 2218 * by the MAC system, so only things with backing by a 2219 * normal object (read: vnodes) are checked. 2220 */ 2221 if (object->type != OBJT_VNODE) 2222 continue; 2223 vp = (struct vnode *)object->handle; 2224 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2225 result = mac_check_vnode_mmap_prot(cred, vp, 0); 2226 VOP_UNLOCK(vp, 0, td); 2227 /* 2228 * Find out what maximum protection we may be allowing 2229 * now but a policy needs to get removed. 2230 */ 2231 revokeperms = vme->max_protection & ~result; 2232 if (!revokeperms) 2233 continue; 2234 printf("pid %ld: revoking %s perms from %#lx:%ld " 2235 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 2236 prot2str(revokeperms), (u_long)vme->start, 2237 (long)(vme->end - vme->start), 2238 prot2str(vme->max_protection), prot2str(vme->protection)); 2239 vm_map_lock_upgrade(map); 2240 /* 2241 * This is the really simple case: if a map has more 2242 * max_protection than is allowed, but it's not being 2243 * actually used (that is, the current protection is 2244 * still allowed), we can just wipe it out and do 2245 * nothing more. 2246 */ 2247 if ((vme->protection & revokeperms) == 0) { 2248 vme->max_protection -= revokeperms; 2249 } else { 2250 if (revokeperms & VM_PROT_WRITE) { 2251 /* 2252 * In the more complicated case, flush out all 2253 * pending changes to the object then turn it 2254 * copy-on-write. 2255 */ 2256 vm_object_reference(object); 2257 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 2258 vm_object_page_clean(object, 2259 OFF_TO_IDX(offset), 2260 OFF_TO_IDX(offset + vme->end - vme->start + 2261 PAGE_MASK), 2262 OBJPC_SYNC); 2263 VOP_UNLOCK(vp, 0, td); 2264 vm_object_deallocate(object); 2265 /* 2266 * Why bother if there's no read permissions 2267 * anymore? For the rest, we need to leave 2268 * the write permissions on for COW, or 2269 * remove them entirely if configured to. 2270 */ 2271 if (!mac_mmap_revocation_via_cow) { 2272 vme->max_protection &= ~VM_PROT_WRITE; 2273 vme->protection &= ~VM_PROT_WRITE; 2274 } if ((revokeperms & VM_PROT_READ) == 0) 2275 vme->eflags |= MAP_ENTRY_COW | 2276 MAP_ENTRY_NEEDS_COPY; 2277 } 2278 if (revokeperms & VM_PROT_EXECUTE) { 2279 vme->max_protection &= ~VM_PROT_EXECUTE; 2280 vme->protection &= ~VM_PROT_EXECUTE; 2281 } 2282 if (revokeperms & VM_PROT_READ) { 2283 vme->max_protection = 0; 2284 vme->protection = 0; 2285 } 2286 pmap_protect(map->pmap, vme->start, vme->end, 2287 vme->protection & ~revokeperms); 2288 vm_map_simplify_entry(map, vme); 2289 } 2290 vm_map_lock_downgrade(map); 2291 } 2292 vm_map_unlock_read(map); 2293} 2294 2295/* 2296 * When the subject's label changes, it may require revocation of privilege 2297 * to mapped objects. This can't be done on-the-fly later with a unified 2298 * buffer cache. 2299 */ 2300static void 2301mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2302{ 2303 2304 MAC_PERFORM(relabel_cred, cred, newlabel); 2305} 2306 2307void 2308mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2309{ 2310 2311 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2312} 2313 2314void 2315mac_create_ifnet(struct ifnet *ifnet) 2316{ 2317 2318 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2319} 2320 2321void 2322mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2323{ 2324 2325 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2326} 2327 2328void 2329mac_create_socket(struct ucred *cred, struct socket *socket) 2330{ 2331 2332 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2333} 2334 2335void 2336mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2337{ 2338 2339 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2340} 2341 2342void 2343mac_create_socket_from_socket(struct socket *oldsocket, 2344 struct socket *newsocket) 2345{ 2346 2347 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2348 newsocket, &newsocket->so_label); 2349} 2350 2351static void 2352mac_relabel_socket(struct ucred *cred, struct socket *socket, 2353 struct label *newlabel) 2354{ 2355 2356 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2357} 2358 2359static void 2360mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2361{ 2362 2363 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2364} 2365 2366void 2367mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2368{ 2369 2370 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2371 socket, &socket->so_peerlabel); 2372} 2373 2374void 2375mac_set_socket_peer_from_socket(struct socket *oldsocket, 2376 struct socket *newsocket) 2377{ 2378 2379 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2380 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2381} 2382 2383void 2384mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2385{ 2386 2387 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2388 datagram, &datagram->m_pkthdr.label); 2389} 2390 2391void 2392mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2393{ 2394 2395 MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2396 fragment, &fragment->m_pkthdr.label); 2397} 2398 2399void 2400mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2401{ 2402 2403 MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2404 &ipq->ipq_label); 2405} 2406 2407void 2408mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2409{ 2410 2411 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2412 newmbuf, &newmbuf->m_pkthdr.label); 2413} 2414 2415void 2416mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2417{ 2418 2419 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2420 &mbuf->m_pkthdr.label); 2421} 2422 2423void 2424mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2425{ 2426 2427 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2428 &mbuf->m_pkthdr.label); 2429} 2430 2431void 2432mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2433{ 2434 2435 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2436 &mbuf->m_pkthdr.label); 2437} 2438 2439void 2440mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2441 struct mbuf *newmbuf) 2442{ 2443 2444 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2445 &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2446 &newmbuf->m_pkthdr.label); 2447} 2448 2449void 2450mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2451{ 2452 2453 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2454 newmbuf, &newmbuf->m_pkthdr.label); 2455} 2456 2457int 2458mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2459{ 2460 int result; 2461 2462 result = 1; 2463 MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2464 ipq, &ipq->ipq_label); 2465 2466 return (result); 2467} 2468 2469void 2470mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2471{ 2472 2473 MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2474 &ipq->ipq_label); 2475} 2476 2477void 2478mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2479{ 2480 2481 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2482 &mbuf->m_pkthdr.label); 2483} 2484 2485void 2486mac_create_mount(struct ucred *cred, struct mount *mp) 2487{ 2488 2489 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2490 &mp->mnt_fslabel); 2491} 2492 2493void 2494mac_create_root_mount(struct ucred *cred, struct mount *mp) 2495{ 2496 2497 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2498 &mp->mnt_fslabel); 2499} 2500 2501int 2502mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2503{ 2504 int error; 2505 2506 if (!mac_enforce_network) 2507 return (0); 2508 2509 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2510 &ifnet->if_label); 2511 2512 return (error); 2513} 2514 2515static int 2516mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2517{ 2518 int error; 2519 2520 MAC_CHECK(check_cred_relabel, cred, newlabel); 2521 2522 return (error); 2523} 2524 2525int 2526mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2527{ 2528 int error; 2529 2530 if (!mac_enforce_process) 2531 return (0); 2532 2533 MAC_CHECK(check_cred_visible, u1, u2); 2534 2535 return (error); 2536} 2537 2538int 2539mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2540{ 2541 int error; 2542 2543 if (!mac_enforce_network) 2544 return (0); 2545 2546 KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2547 if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2548 printf("%s%d: not initialized\n", ifnet->if_name, 2549 ifnet->if_unit); 2550 2551 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2552 &mbuf->m_pkthdr.label); 2553 2554 return (error); 2555} 2556 2557int 2558mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2559{ 2560 int error; 2561 2562 if (!mac_enforce_fs) 2563 return (0); 2564 2565 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2566 2567 return (error); 2568} 2569 2570int 2571mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2572 void *data) 2573{ 2574 int error; 2575 2576 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2577 2578 if (!mac_enforce_pipe) 2579 return (0); 2580 2581 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2582 2583 return (error); 2584} 2585 2586int 2587mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2588{ 2589 int error; 2590 2591 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2592 2593 if (!mac_enforce_pipe) 2594 return (0); 2595 2596 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2597 2598 return (error); 2599} 2600 2601int 2602mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2603{ 2604 int error; 2605 2606 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2607 2608 if (!mac_enforce_pipe) 2609 return (0); 2610 2611 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2612 2613 return (error); 2614} 2615 2616static int 2617mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2618 struct label *newlabel) 2619{ 2620 int error; 2621 2622 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2623 2624 if (!mac_enforce_pipe) 2625 return (0); 2626 2627 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2628 2629 return (error); 2630} 2631 2632int 2633mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2634{ 2635 int error; 2636 2637 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2638 2639 if (!mac_enforce_pipe) 2640 return (0); 2641 2642 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2643 2644 return (error); 2645} 2646 2647int 2648mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2649{ 2650 int error; 2651 2652 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2653 2654 if (!mac_enforce_pipe) 2655 return (0); 2656 2657 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2658 2659 return (error); 2660} 2661 2662int 2663mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2664{ 2665 int error; 2666 2667 PROC_LOCK_ASSERT(proc, MA_OWNED); 2668 2669 if (!mac_enforce_process) 2670 return (0); 2671 2672 MAC_CHECK(check_proc_debug, cred, proc); 2673 2674 return (error); 2675} 2676 2677int 2678mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2679{ 2680 int error; 2681 2682 PROC_LOCK_ASSERT(proc, MA_OWNED); 2683 2684 if (!mac_enforce_process) 2685 return (0); 2686 2687 MAC_CHECK(check_proc_sched, cred, proc); 2688 2689 return (error); 2690} 2691 2692int 2693mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2694{ 2695 int error; 2696 2697 PROC_LOCK_ASSERT(proc, MA_OWNED); 2698 2699 if (!mac_enforce_process) 2700 return (0); 2701 2702 MAC_CHECK(check_proc_signal, cred, proc, signum); 2703 2704 return (error); 2705} 2706 2707int 2708mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2709 struct sockaddr *sockaddr) 2710{ 2711 int error; 2712 2713 if (!mac_enforce_socket) 2714 return (0); 2715 2716 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2717 sockaddr); 2718 2719 return (error); 2720} 2721 2722int 2723mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2724 struct sockaddr *sockaddr) 2725{ 2726 int error; 2727 2728 if (!mac_enforce_socket) 2729 return (0); 2730 2731 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2732 sockaddr); 2733 2734 return (error); 2735} 2736 2737int 2738mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2739{ 2740 int error; 2741 2742 if (!mac_enforce_socket) 2743 return (0); 2744 2745 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2746 &mbuf->m_pkthdr.label); 2747 2748 return (error); 2749} 2750 2751int 2752mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2753{ 2754 int error; 2755 2756 if (!mac_enforce_socket) 2757 return (0); 2758 2759 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2760 return (error); 2761} 2762 2763static int 2764mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2765 struct label *newlabel) 2766{ 2767 int error; 2768 2769 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2770 newlabel); 2771 2772 return (error); 2773} 2774 2775int 2776mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2777{ 2778 int error; 2779 2780 if (!mac_enforce_socket) 2781 return (0); 2782 2783 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2784 2785 return (error); 2786} 2787 2788int 2789mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2790 struct ifnet *ifnet) 2791{ 2792 struct mac label; 2793 int error; 2794 2795 error = mac_externalize(&ifnet->if_label, &label); 2796 if (error) 2797 return (error); 2798 2799 return (copyout(&label, ifr->ifr_ifru.ifru_data, sizeof(label))); 2800} 2801 2802int 2803mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2804 struct ifnet *ifnet) 2805{ 2806 struct mac newlabel; 2807 struct label intlabel; 2808 int error; 2809 2810 error = copyin(ifr->ifr_ifru.ifru_data, &newlabel, sizeof(newlabel)); 2811 if (error) 2812 return (error); 2813 2814 error = mac_internalize(&intlabel, &newlabel); 2815 if (error) 2816 return (error); 2817 2818 /* 2819 * XXX: Note that this is a redundant privilege check, since 2820 * policies impose this check themselves if required by the 2821 * policy. Eventually, this should go away. 2822 */ 2823 error = suser_cred(cred, 0); 2824 if (error) 2825 goto out; 2826 2827 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2828 &intlabel); 2829 if (error) 2830 goto out; 2831 2832 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2833 2834out: 2835 mac_destroy_temp(&intlabel); 2836 return (error); 2837} 2838 2839void 2840mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp) 2841{ 2842 2843 MAC_PERFORM(create_devfs_vnode, de, &de->de_label, vp, &vp->v_label); 2844} 2845 2846void 2847mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 2848{ 2849 2850 MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 2851} 2852 2853static int 2854mac_stdcreatevnode_ea(struct vnode *vp) 2855{ 2856 int error; 2857 2858 MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label); 2859 2860 return (error); 2861} 2862 2863void 2864mac_create_devfs_directory(char *dirname, int dirnamelen, 2865 struct devfs_dirent *de) 2866{ 2867 2868 MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 2869 &de->de_label); 2870} 2871 2872/* 2873 * When a new vnode is created, this call will initialize its label. 2874 */ 2875void 2876mac_create_vnode(struct ucred *cred, struct vnode *parent, 2877 struct vnode *child) 2878{ 2879 int error; 2880 2881 ASSERT_VOP_LOCKED(parent, "mac_create_vnode"); 2882 ASSERT_VOP_LOCKED(child, "mac_create_vnode"); 2883 2884 error = vn_refreshlabel(parent, cred); 2885 if (error) { 2886 printf("mac_create_vnode: vn_refreshlabel returned %d\n", 2887 error); 2888 printf("mac_create_vnode: using old vnode label\n"); 2889 } 2890 2891 MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child, 2892 &child->v_label); 2893} 2894 2895int 2896mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2897 struct mac *extmac) 2898{ 2899 struct label intlabel; 2900 int error; 2901 2902 error = mac_internalize(&intlabel, extmac); 2903 if (error) 2904 return (error); 2905 2906 mac_check_socket_relabel(cred, so, &intlabel); 2907 if (error) { 2908 mac_destroy_temp(&intlabel); 2909 return (error); 2910 } 2911 2912 mac_relabel_socket(cred, so, &intlabel); 2913 2914 mac_destroy_temp(&intlabel); 2915 return (0); 2916} 2917 2918int 2919mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 2920{ 2921 int error; 2922 2923 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2924 2925 error = mac_check_pipe_relabel(cred, pipe, label); 2926 if (error) 2927 return (error); 2928 2929 mac_relabel_pipe(cred, pipe, label); 2930 2931 return (0); 2932} 2933 2934int 2935mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2936 struct mac *extmac) 2937{ 2938 2939 return (mac_externalize(&so->so_label, extmac)); 2940} 2941 2942int 2943mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2944 struct mac *extmac) 2945{ 2946 2947 return (mac_externalize(&so->so_peerlabel, extmac)); 2948} 2949 2950/* 2951 * Implementation of VOP_SETLABEL() that relies on extended attributes 2952 * to store label data. Can be referenced by filesystems supporting 2953 * extended attributes. 2954 */ 2955int 2956vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 2957{ 2958 struct vnode *vp = ap->a_vp; 2959 struct label *intlabel = ap->a_label; 2960 struct mac extmac; 2961 int error; 2962 2963 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 2964 2965 /* 2966 * XXX: Eventually call out to EA check/set calls here. 2967 * Be particularly careful to avoid race conditions, 2968 * consistency problems, and stability problems when 2969 * dealing with multiple EAs. In particular, we require 2970 * the ability to write multiple EAs on the same file in 2971 * a single transaction, which the current EA interface 2972 * does not provide. 2973 */ 2974 2975 error = mac_externalize(intlabel, &extmac); 2976 if (error) 2977 return (error); 2978 2979 error = vn_extattr_set(vp, IO_NODELOCKED, 2980 FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, 2981 sizeof(extmac), (char *)&extmac, curthread); 2982 if (error) 2983 return (error); 2984 2985 mac_relabel_vnode(ap->a_cred, vp, intlabel); 2986 2987 vp->v_vflag |= VV_CACHEDLABEL; 2988 2989 return (0); 2990} 2991 2992static int 2993vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 2994{ 2995 int error; 2996 2997 if (vp->v_mount == NULL) { 2998 /* printf("vn_setlabel: null v_mount\n"); */ 2999 if (vp->v_type != VNON) 3000 printf("vn_setlabel: null v_mount with non-VNON\n"); 3001 return (EBADF); 3002 } 3003 3004 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 3005 return (EOPNOTSUPP); 3006 3007 /* 3008 * Multi-phase commit. First check the policies to confirm the 3009 * change is OK. Then commit via the filesystem. Finally, 3010 * update the actual vnode label. Question: maybe the filesystem 3011 * should update the vnode at the end as part of VOP_SETLABEL()? 3012 */ 3013 error = mac_check_vnode_relabel(cred, vp, intlabel); 3014 if (error) 3015 return (error); 3016 3017 /* 3018 * VADMIN provides the opportunity for the filesystem to make 3019 * decisions about who is and is not able to modify labels 3020 * and protections on files. This might not be right. We can't 3021 * assume VOP_SETLABEL() will do it, because we might implement 3022 * that as part of vop_stdsetlabel_ea(). 3023 */ 3024 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3025 if (error) 3026 return (error); 3027 3028 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3029 if (error) 3030 return (error); 3031 3032 return (0); 3033} 3034 3035/* 3036 * MPSAFE 3037 */ 3038int 3039__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3040{ 3041 struct mac extmac; 3042 int error; 3043 3044 error = mac_externalize(&td->td_ucred->cr_label, &extmac); 3045 if (error == 0) 3046 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3047 3048 return (error); 3049} 3050 3051/* 3052 * MPSAFE 3053 */ 3054int 3055__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3056{ 3057 struct ucred *newcred, *oldcred; 3058 struct proc *p; 3059 struct mac extmac; 3060 struct label intlabel; 3061 int error; 3062 3063 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3064 if (error) 3065 return (error); 3066 3067 error = mac_internalize(&intlabel, &extmac); 3068 if (error) 3069 return (error); 3070 3071 newcred = crget(); 3072 3073 p = td->td_proc; 3074 PROC_LOCK(p); 3075 oldcred = p->p_ucred; 3076 3077 error = mac_check_cred_relabel(oldcred, &intlabel); 3078 if (error) { 3079 PROC_UNLOCK(p); 3080 mac_destroy_temp(&intlabel); 3081 crfree(newcred); 3082 return (error); 3083 } 3084 3085 setsugid(p); 3086 crcopy(newcred, oldcred); 3087 mac_relabel_cred(newcred, &intlabel); 3088 p->p_ucred = newcred; 3089 3090 /* 3091 * Grab additional reference for use while revoking mmaps, prior 3092 * to releasing the proc lock and sharing the cred. 3093 */ 3094 crhold(newcred); 3095 PROC_UNLOCK(p); 3096 3097 mtx_lock(&Giant); 3098 mac_cred_mmapped_drop_perms(td, newcred); 3099 mtx_unlock(&Giant); 3100 3101 crfree(newcred); /* Free revocation reference. */ 3102 crfree(oldcred); 3103 mac_destroy_temp(&intlabel); 3104 return (0); 3105} 3106 3107/* 3108 * MPSAFE 3109 */ 3110int 3111__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3112{ 3113 struct file *fp; 3114 struct mac extmac; 3115 struct vnode *vp; 3116 struct pipe *pipe; 3117 int error; 3118 3119 mtx_lock(&Giant); 3120 3121 error = fget(td, SCARG(uap, fd), &fp); 3122 if (error) 3123 goto out; 3124 3125 switch (fp->f_type) { 3126 case DTYPE_FIFO: 3127 case DTYPE_VNODE: 3128 vp = (struct vnode *)fp->f_data; 3129 3130 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3131 error = vn_refreshlabel(vp, td->td_ucred); 3132 if (error == 0) 3133 error = mac_externalize(&vp->v_label, &extmac); 3134 VOP_UNLOCK(vp, 0, td); 3135 break; 3136 case DTYPE_PIPE: 3137 pipe = (struct pipe *)fp->f_data; 3138 error = mac_externalize(pipe->pipe_label, &extmac); 3139 break; 3140 default: 3141 error = EINVAL; 3142 } 3143 3144 if (error == 0) 3145 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3146 3147 fdrop(fp, td); 3148 3149out: 3150 mtx_unlock(&Giant); 3151 return (error); 3152} 3153 3154/* 3155 * MPSAFE 3156 */ 3157int 3158__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3159{ 3160 struct nameidata nd; 3161 struct mac extmac; 3162 int error; 3163 3164 mtx_lock(&Giant); 3165 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3166 SCARG(uap, path_p), td); 3167 error = namei(&nd); 3168 if (error) 3169 goto out; 3170 3171 error = vn_refreshlabel(nd.ni_vp, td->td_ucred); 3172 if (error == 0) 3173 error = mac_externalize(&nd.ni_vp->v_label, &extmac); 3174 NDFREE(&nd, 0); 3175 if (error) 3176 goto out; 3177 3178 error = copyout(&extmac, SCARG(uap, mac_p), sizeof(extmac)); 3179 3180out: 3181 mtx_unlock(&Giant); 3182 return (error); 3183} 3184 3185/* 3186 * MPSAFE 3187 */ 3188int 3189__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3190{ 3191 struct file *fp; 3192 struct mac extmac; 3193 struct label intlabel; 3194 struct mount *mp; 3195 struct vnode *vp; 3196 struct pipe *pipe; 3197 int error; 3198 3199 mtx_lock(&Giant); 3200 error = fget(td, SCARG(uap, fd), &fp); 3201 if (error) 3202 goto out1; 3203 3204 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3205 if (error) 3206 goto out2; 3207 3208 error = mac_internalize(&intlabel, &extmac); 3209 if (error) 3210 goto out2; 3211 3212 switch (fp->f_type) { 3213 case DTYPE_FIFO: 3214 case DTYPE_VNODE: 3215 vp = (struct vnode *)fp->f_data; 3216 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3217 if (error != 0) 3218 break; 3219 3220 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3221 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3222 VOP_UNLOCK(vp, 0, td); 3223 vn_finished_write(mp); 3224 mac_destroy_temp(&intlabel); 3225 break; 3226 case DTYPE_PIPE: 3227 pipe = (struct pipe *)fp->f_data; 3228 PIPE_LOCK(pipe); 3229 error = mac_pipe_label_set(td->td_ucred, pipe, &intlabel); 3230 PIPE_UNLOCK(pipe); 3231 break; 3232 default: 3233 error = EINVAL; 3234 } 3235 3236out2: 3237 fdrop(fp, td); 3238out1: 3239 mtx_unlock(&Giant); 3240 return (error); 3241} 3242 3243/* 3244 * MPSAFE 3245 */ 3246int 3247__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3248{ 3249 struct nameidata nd; 3250 struct mac extmac; 3251 struct label intlabel; 3252 struct mount *mp; 3253 int error; 3254 3255 mtx_lock(&Giant); 3256 3257 error = copyin(SCARG(uap, mac_p), &extmac, sizeof(extmac)); 3258 if (error) 3259 goto out; 3260 3261 error = mac_internalize(&intlabel, &extmac); 3262 if (error) 3263 goto out; 3264 3265 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, 3266 SCARG(uap, path_p), td); 3267 error = namei(&nd); 3268 if (error) 3269 goto out2; 3270 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3271 if (error) 3272 goto out2; 3273 3274 error = vn_setlabel(nd.ni_vp, &intlabel, td->td_ucred); 3275 3276 vn_finished_write(mp); 3277out2: 3278 mac_destroy_temp(&intlabel); 3279 NDFREE(&nd, 0); 3280out: 3281 mtx_unlock(&Giant); 3282 return (error); 3283} 3284 3285int 3286mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3287{ 3288 struct mac_policy_conf *mpc; 3289 char target[MAC_MAX_POLICY_NAME]; 3290 int error; 3291 3292 error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3293 if (error) 3294 return (error); 3295 3296 error = ENOSYS; 3297 MAC_POLICY_LIST_BUSY(); 3298 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3299 if (strcmp(mpc->mpc_name, target) == 0 && 3300 mpc->mpc_ops->mpo_syscall != NULL) { 3301 error = mpc->mpc_ops->mpo_syscall(td, 3302 SCARG(uap, call), SCARG(uap, arg)); 3303 goto out; 3304 } 3305 } 3306 3307out: 3308 MAC_POLICY_LIST_UNBUSY(); 3309 return (error); 3310} 3311 3312SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3313SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3314 3315#else /* !MAC */ 3316 3317int 3318__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3319{ 3320 3321 return (ENOSYS); 3322} 3323 3324int 3325__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3326{ 3327 3328 return (ENOSYS); 3329} 3330 3331int 3332__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3333{ 3334 3335 return (ENOSYS); 3336} 3337 3338int 3339__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3340{ 3341 3342 return (ENOSYS); 3343} 3344 3345int 3346__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3347{ 3348 3349 return (ENOSYS); 3350} 3351 3352int 3353__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3354{ 3355 3356 return (ENOSYS); 3357} 3358 3359int 3360mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3361{ 3362 3363 return (ENOSYS); 3364} 3365 3366#endif /* !MAC */
|