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