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