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