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