87 88static int destroyed_not_inited; 89SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 90 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 91 92static int mac_mls_revocation_enabled = 0; 93SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, 94 &mac_mls_revocation_enabled, 0, "Revoke access to objects on relabel"); 95TUNABLE_INT("security.mac.mls.revocation_enabled", 96 &mac_mls_revocation_enabled); 97 98static int mac_mls_slot; 99#define SLOT(l) ((struct mac_mls *)LABEL_TO_SLOT((l), mac_mls_slot).l_ptr) 100 101MALLOC_DEFINE(M_MACMLS, "mls label", "MAC/MLS labels"); 102 103static int mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, 104 struct label *vnodelabel, mode_t acc_mode); 105 106static struct mac_mls * 107mls_alloc(int how) 108{ 109 struct mac_mls *mac_mls; 110 111 mac_mls = malloc(sizeof(struct mac_mls), M_MACMLS, M_ZERO | how); 112 113 return (mac_mls); 114} 115 116static void 117mls_free(struct mac_mls *mac_mls) 118{ 119 120 if (mac_mls != NULL) 121 free(mac_mls, M_MACMLS); 122 else 123 atomic_add_int(&destroyed_not_inited, 1); 124} 125 126static int 127mac_mls_dominate_element(struct mac_mls_element *a, 128 struct mac_mls_element *b) 129{ 130 131 switch(a->mme_type) { 132 case MAC_MLS_TYPE_EQUAL: 133 case MAC_MLS_TYPE_HIGH: 134 return (1); 135 136 case MAC_MLS_TYPE_LOW: 137 switch (b->mme_type) { 138 case MAC_MLS_TYPE_LEVEL: 139 case MAC_MLS_TYPE_HIGH: 140 return (0); 141 142 case MAC_MLS_TYPE_EQUAL: 143 case MAC_MLS_TYPE_LOW: 144 return (1); 145 146 default: 147 panic("mac_mls_dominate_element: b->mme_type invalid"); 148 } 149 150 case MAC_MLS_TYPE_LEVEL: 151 switch (b->mme_type) { 152 case MAC_MLS_TYPE_EQUAL: 153 case MAC_MLS_TYPE_LOW: 154 return (1); 155 156 case MAC_MLS_TYPE_HIGH: 157 return (0); 158 159 case MAC_MLS_TYPE_LEVEL: 160 return (a->mme_level >= b->mme_level); 161 162 default: 163 panic("mac_mls_dominate_element: b->mme_type invalid"); 164 } 165 166 default: 167 panic("mac_mls_dominate_element: a->mme_type invalid"); 168 } 169 170 return (0); 171} 172 173static int 174mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) 175{ 176 177 return (mac_mls_dominate_element(&rangeb->mm_rangehigh, 178 &rangea->mm_rangehigh) && 179 mac_mls_dominate_element(&rangea->mm_rangelow, 180 &rangeb->mm_rangelow)); 181} 182 183static int 184mac_mls_single_in_range(struct mac_mls *single, struct mac_mls *range) 185{ 186 187 KASSERT((single->mm_flag & MAC_MLS_FLAG_SINGLE) != 0, 188 ("mac_mls_single_in_range: a not single")); 189 KASSERT((range->mm_flag & MAC_MLS_FLAG_RANGE) != 0, 190 ("mac_mls_single_in_range: b not range")); 191 192 return (mac_mls_dominate_element(&range->mm_rangehigh, 193 &single->mm_single) && 194 mac_mls_dominate_element(&single->mm_single, 195 &range->mm_rangelow)); 196 197 return (1); 198} 199 200static int 201mac_mls_dominate_single(struct mac_mls *a, struct mac_mls *b) 202{ 203 KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 204 ("mac_mls_dominate_single: a not single")); 205 KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 206 ("mac_mls_dominate_single: b not single")); 207 208 return (mac_mls_dominate_element(&a->mm_single, &b->mm_single)); 209} 210 211static int 212mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) 213{ 214 215 if (a->mme_type == MAC_MLS_TYPE_EQUAL || 216 b->mme_type == MAC_MLS_TYPE_EQUAL) 217 return (1); 218 219 return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); 220} 221 222static int 223mac_mls_equal_range(struct mac_mls *a, struct mac_mls *b) 224{ 225 226 KASSERT((a->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 227 ("mac_mls_equal_range: a not range")); 228 KASSERT((b->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 229 ("mac_mls_equal_range: b not range")); 230 231 return (mac_mls_equal_element(&a->mm_rangelow, &b->mm_rangelow) && 232 mac_mls_equal_element(&a->mm_rangehigh, &b->mm_rangehigh)); 233} 234 235static int 236mac_mls_equal_single(struct mac_mls *a, struct mac_mls *b) 237{ 238 239 KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 240 ("mac_mls_equal_single: a not single")); 241 KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 242 ("mac_mls_equal_single: b not single")); 243 244 return (mac_mls_equal_element(&a->mm_single, &b->mm_single)); 245} 246 247static int 248mac_mls_valid(struct mac_mls *mac_mls) 249{ 250 251 if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE) { 252 switch (mac_mls->mm_single.mme_type) { 253 case MAC_MLS_TYPE_LEVEL: 254 break; 255 256 case MAC_MLS_TYPE_EQUAL: 257 case MAC_MLS_TYPE_HIGH: 258 case MAC_MLS_TYPE_LOW: 259 if (mac_mls->mm_single.mme_level != 0) 260 return (EINVAL); 261 break; 262 263 default: 264 return (EINVAL); 265 } 266 } else { 267 if (mac_mls->mm_single.mme_type != MAC_MLS_TYPE_UNDEF) 268 return (EINVAL); 269 } 270 271 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 272 switch (mac_mls->mm_rangelow.mme_type) { 273 case MAC_MLS_TYPE_LEVEL: 274 break; 275 276 case MAC_MLS_TYPE_EQUAL: 277 case MAC_MLS_TYPE_HIGH: 278 case MAC_MLS_TYPE_LOW: 279 if (mac_mls->mm_rangelow.mme_level != 0) 280 return (EINVAL); 281 break; 282 283 default: 284 return (EINVAL); 285 } 286 287 switch (mac_mls->mm_rangehigh.mme_type) { 288 case MAC_MLS_TYPE_LEVEL: 289 break; 290 291 case MAC_MLS_TYPE_EQUAL: 292 case MAC_MLS_TYPE_HIGH: 293 case MAC_MLS_TYPE_LOW: 294 if (mac_mls->mm_rangehigh.mme_level != 0) 295 return (EINVAL); 296 break; 297 298 default: 299 return (EINVAL); 300 } 301 if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh, 302 &mac_mls->mm_rangelow)) 303 return (EINVAL); 304 } else { 305 if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || 306 mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) 307 return (EINVAL); 308 } 309 310 return (0); 311} 312 313static void 314mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow, 315 u_short levellow, u_short typehigh, u_short levelhigh) 316{ 317 318 mac_mls->mm_rangelow.mme_type = typelow; 319 mac_mls->mm_rangelow.mme_level = levellow; 320 mac_mls->mm_rangehigh.mme_type = typehigh; 321 mac_mls->mm_rangehigh.mme_level = levelhigh; 322 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 323} 324 325static void 326mac_mls_set_single(struct mac_mls *mac_mls, u_short type, u_short level) 327{ 328 329 mac_mls->mm_single.mme_type = type; 330 mac_mls->mm_single.mme_level = level; 331 mac_mls->mm_flags |= MAC_MLS_FLAG_SINGLE; 332} 333 334static void 335mac_mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 336{ 337 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 338 ("mac_mls_copy_range: labelfrom not range")); 339 340 labelto->mm_rangelow = labelfrom->mm_rangelow; 341 labelto->mm_rangehigh = labelfrom->mm_rangehigh; 342 labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 343} 344 345static void 346mac_mls_copy_single(struct mac_mls *labelfrom, struct mac_mls *labelto) 347{ 348 349 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 350 ("mac_mls_copy_single: labelfrom not single")); 351 352 labelto->mm_single = labelfrom->mm_single; 353 labelto->mm_flags |= MAC_MLS_FLAG_SINGLE; 354} 355 356static void 357mac_mls_copy_single_to_range(struct mac_mls *labelfrom, 358 struct mac_mls *labelto) 359{ 360 361 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 362 ("mac_mls_copy_single_to_range: labelfrom not single")); 363 364 labelto->mm_rangelow = labelfrom->mm_single; 365 labelto->mm_rangehigh = labelfrom->mm_single; 366 labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 367} 368 369/* 370 * Policy module operations. 371 */ 372static void 373mac_mls_destroy(struct mac_policy_conf *conf) 374{ 375 376} 377 378static void 379mac_mls_init(struct mac_policy_conf *conf) 380{ 381 382} 383 384/* 385 * Label operations. 386 */ 387static void 388mac_mls_init_bpfdesc(struct bpf_d *bpf_d, struct label *label) 389{ 390 391 SLOT(label) = mls_alloc(M_WAITOK); 392} 393 394static void 395mac_mls_init_cred(struct ucred *ucred, struct label *label) 396{ 397 398 SLOT(label) = mls_alloc(M_WAITOK); 399} 400 401static void 402mac_mls_init_devfsdirent(struct devfs_dirent *devfs_dirent, 403 struct label *label) 404{ 405 406 SLOT(label) = mls_alloc(M_WAITOK); 407} 408 409static void 410mac_mls_init_ifnet(struct ifnet *ifnet, struct label *label) 411{ 412 413 SLOT(label) = mls_alloc(M_WAITOK); 414} 415 416static void 417mac_mls_init_ipq(struct ipq *ipq, struct label *label) 418{ 419 420 SLOT(label) = mls_alloc(M_WAITOK); 421} 422 423static int 424mac_mls_init_mbuf(struct mbuf *mbuf, int how, struct label *label) 425{ 426 427 SLOT(label) = mls_alloc(how); 428 if (SLOT(label) == NULL) 429 return (ENOMEM); 430 431 return (0); 432} 433 434static void 435mac_mls_init_mount(struct mount *mount, struct label *mntlabel, 436 struct label *fslabel) 437{ 438 439 SLOT(mntlabel) = mls_alloc(M_WAITOK); 440 SLOT(fslabel) = mls_alloc(M_WAITOK); 441} 442 443static void 444mac_mls_init_socket(struct socket *socket, struct label *label, 445 struct label *peerlabel) 446{ 447 448 SLOT(label) = mls_alloc(M_WAITOK); 449 SLOT(peerlabel) = mls_alloc(M_WAITOK); 450} 451 452static void 453mac_mls_init_pipe(struct pipe *pipe, struct label *label) 454{ 455 456 SLOT(label) = mls_alloc(M_WAITOK); 457} 458 459static void 460mac_mls_init_temp(struct label *label) 461{ 462 463 SLOT(label) = mls_alloc(M_WAITOK); 464} 465 466static void 467mac_mls_init_vnode(struct vnode *vp, struct label *label) 468{ 469 470 SLOT(label) = mls_alloc(M_WAITOK); 471} 472 473static void 474mac_mls_destroy_bpfdesc(struct bpf_d *bpf_d, struct label *label) 475{ 476 477 mls_free(SLOT(label)); 478 SLOT(label) = NULL; 479} 480 481static void 482mac_mls_destroy_cred(struct ucred *ucred, struct label *label) 483{ 484 485 mls_free(SLOT(label)); 486 SLOT(label) = NULL; 487} 488 489static void 490mac_mls_destroy_devfsdirent(struct devfs_dirent *devfs_dirent, 491 struct label *label) 492{ 493 494 mls_free(SLOT(label)); 495 SLOT(label) = NULL; 496} 497 498static void 499mac_mls_destroy_ifnet(struct ifnet *ifnet, struct label *label) 500{ 501 502 mls_free(SLOT(label)); 503 SLOT(label) = NULL; 504} 505 506static void 507mac_mls_destroy_ipq(struct ipq *ipq, struct label *label) 508{ 509 510 mls_free(SLOT(label)); 511 SLOT(label) = NULL; 512} 513 514static void 515mac_mls_destroy_mbuf(struct mbuf *mbuf, struct label *label) 516{ 517 518 mls_free(SLOT(label)); 519 SLOT(label) = NULL; 520} 521 522static void 523mac_mls_destroy_mount(struct mount *mount, struct label *mntlabel, 524 struct label *fslabel) 525{ 526 527 mls_free(SLOT(mntlabel)); 528 SLOT(mntlabel) = NULL; 529 mls_free(SLOT(fslabel)); 530 SLOT(fslabel) = NULL; 531} 532 533static void 534mac_mls_destroy_socket(struct socket *socket, struct label *label, 535 struct label *peerlabel) 536{ 537 538 mls_free(SLOT(label)); 539 SLOT(label) = NULL; 540 mls_free(SLOT(peerlabel)); 541 SLOT(peerlabel) = NULL; 542} 543 544static void 545mac_mls_destroy_pipe(struct pipe *pipe, struct label *label) 546{ 547 548 mls_free(SLOT(label)); 549 SLOT(label) = NULL; 550} 551 552static void 553mac_mls_destroy_temp(struct label *label) 554{ 555 556 mls_free(SLOT(label)); 557 SLOT(label) = NULL; 558} 559 560static void 561mac_mls_destroy_vnode(struct vnode *vp, struct label *label) 562{ 563 564 mls_free(SLOT(label)); 565 SLOT(label) = NULL; 566} 567 568static int 569mac_mls_externalize(struct label *label, struct mac *extmac) 570{ 571 struct mac_mls *mac_mls; 572 573 mac_mls = SLOT(label); 574 575 if (mac_mls == NULL) { 576 printf("mac_mls_externalize: NULL pointer\n"); 577 return (0); 578 } 579 580 extmac->m_mls = *mac_mls; 581 582 return (0); 583} 584 585static int 586mac_mls_internalize(struct label *label, struct mac *extmac) 587{ 588 struct mac_mls *mac_mls; 589 int error; 590 591 mac_mls = SLOT(label); 592 593 error = mac_mls_valid(mac_mls); 594 if (error) 595 return (error); 596 597 *mac_mls = extmac->m_mls; 598 599 return (0); 600} 601 602/* 603 * Labeling event operations: file system objects, and things that look 604 * a lot like file system objects. 605 */ 606static void 607mac_mls_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 608 struct label *label) 609{ 610 struct mac_mls *mac_mls; 611 int mls_type; 612 613 mac_mls = SLOT(label); 614 if (strcmp(dev->si_name, "null") == 0 || 615 strcmp(dev->si_name, "zero") == 0 || 616 strcmp(dev->si_name, "random") == 0 || 617 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 618 mls_type = MAC_MLS_TYPE_EQUAL; 619 else if (strcmp(dev->si_name, "kmem") == 0 || 620 strcmp(dev->si_name, "mem") == 0) 621 mls_type = MAC_MLS_TYPE_HIGH; 622 else 623 mls_type = MAC_MLS_TYPE_LOW; 624 mac_mls_set_single(mac_mls, mls_type, 0); 625} 626 627static void 628mac_mls_create_devfs_directory(char *dirname, int dirnamelen, 629 struct devfs_dirent *devfs_dirent, struct label *label) 630{ 631 struct mac_mls *mac_mls; 632 633 mac_mls = SLOT(label); 634 mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0); 635} 636 637static void 638mac_mls_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 639 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 640{ 641 struct mac_mls *source, *dest; 642 643 source = SLOT(direntlabel); 644 dest = SLOT(vnodelabel); 645 mac_mls_copy_single(source, dest); 646} 647 648static void 649mac_mls_create_vnode(struct ucred *cred, struct vnode *parent, 650 struct label *parentlabel, struct vnode *child, struct label *childlabel) 651{ 652 struct mac_mls *source, *dest; 653 654 source = SLOT(&cred->cr_label); 655 dest = SLOT(childlabel); 656 657 mac_mls_copy_single(source, dest); 658} 659 660static void 661mac_mls_create_mount(struct ucred *cred, struct mount *mp, 662 struct label *mntlabel, struct label *fslabel) 663{ 664 struct mac_mls *source, *dest; 665 666 source = SLOT(&cred->cr_label); 667 dest = SLOT(mntlabel); 668 mac_mls_copy_single(source, dest); 669 dest = SLOT(fslabel); 670 mac_mls_copy_single(source, dest); 671} 672 673static void 674mac_mls_create_root_mount(struct ucred *cred, struct mount *mp, 675 struct label *mntlabel, struct label *fslabel) 676{ 677 struct mac_mls *mac_mls; 678 679 /* Always mount root as high integrity. */ 680 mac_mls = SLOT(fslabel); 681 mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0); 682 mac_mls = SLOT(mntlabel); 683 mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0); 684} 685 686static void 687mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp, 688 struct label *vnodelabel, struct label *label) 689{ 690 struct mac_mls *source, *dest; 691 692 source = SLOT(label); 693 dest = SLOT(vnodelabel); 694 695 mac_mls_copy_single(source, dest); 696} 697 698static void 699mac_mls_update_devfsdirent(struct devfs_dirent *devfs_dirent, 700 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 701{ 702 struct mac_mls *source, *dest; 703 704 source = SLOT(vnodelabel); 705 dest = SLOT(direntlabel); 706 707 mac_mls_copy_single(source, dest); 708} 709 710static void 711mac_mls_update_procfsvnode(struct vnode *vp, struct label *vnodelabel, 712 struct ucred *cred) 713{ 714 struct mac_mls *source, *dest; 715 716 source = SLOT(&cred->cr_label); 717 dest = SLOT(vnodelabel); 718 719 /* 720 * Only copy the single, not the range, since vnodes only have 721 * a single. 722 */ 723 mac_mls_copy_single(source, dest); 724} 725 726static int 727mac_mls_update_vnode_from_externalized(struct vnode *vp, 728 struct label *vnodelabel, struct mac *extmac) 729{ 730 struct mac_mls *source, *dest; 731 int error; 732 733 source = &extmac->m_mls; 734 dest = SLOT(vnodelabel); 735 736 error = mac_mls_valid(source); 737 if (error) 738 return (error); 739 740 if ((source->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) 741 return (EINVAL); 742 743 mac_mls_copy_single(source, dest); 744 745 return (0); 746} 747 748static void 749mac_mls_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel, 750 struct mount *mp, struct label *fslabel) 751{ 752 struct mac_mls *source, *dest; 753 754 source = SLOT(fslabel); 755 dest = SLOT(vnodelabel); 756 757 mac_mls_copy_single(source, dest); 758} 759 760/* 761 * Labeling event operations: IPC object. 762 */ 763static void 764mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 765 struct mbuf *m, struct label *mbuflabel) 766{ 767 struct mac_mls *source, *dest; 768 769 source = SLOT(socketlabel); 770 dest = SLOT(mbuflabel); 771 772 mac_mls_copy_single(source, dest); 773} 774 775static void 776mac_mls_create_socket(struct ucred *cred, struct socket *socket, 777 struct label *socketlabel) 778{ 779 struct mac_mls *source, *dest; 780 781 source = SLOT(&cred->cr_label); 782 dest = SLOT(socketlabel); 783 784 mac_mls_copy_single(source, dest); 785 mac_mls_copy_single_to_range(source, dest); 786} 787 788static void 789mac_mls_create_pipe(struct ucred *cred, struct pipe *pipe, 790 struct label *pipelabel) 791{ 792 struct mac_mls *source, *dest; 793 794 source = SLOT(&cred->cr_label); 795 dest = SLOT(pipelabel); 796 797 mac_mls_copy_single(source, dest); 798} 799 800static void 801mac_mls_create_socket_from_socket(struct socket *oldsocket, 802 struct label *oldsocketlabel, struct socket *newsocket, 803 struct label *newsocketlabel) 804{ 805 struct mac_mls *source, *dest; 806 807 source = SLOT(oldsocketlabel); 808 dest = SLOT(newsocketlabel); 809 810 mac_mls_copy_single(source, dest); 811 mac_mls_copy_range(source, dest); 812} 813 814static void 815mac_mls_relabel_socket(struct ucred *cred, struct socket *socket, 816 struct label *socketlabel, struct label *newlabel) 817{ 818 struct mac_mls *source, *dest; 819 820 source = SLOT(newlabel); 821 dest = SLOT(socketlabel); 822 823 mac_mls_copy_single(source, dest); 824 mac_mls_copy_range(source, dest); 825} 826 827static void 828mac_mls_relabel_pipe(struct ucred *cred, struct pipe *pipe, 829 struct label *pipelabel, struct label *newlabel) 830{ 831 struct mac_mls *source, *dest; 832 833 source = SLOT(newlabel); 834 dest = SLOT(pipelabel); 835 836 mac_mls_copy_single(source, dest); 837} 838 839static void 840mac_mls_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 841 struct socket *socket, struct label *socketpeerlabel) 842{ 843 struct mac_mls *source, *dest; 844 845 source = SLOT(mbuflabel); 846 dest = SLOT(socketpeerlabel); 847 848 mac_mls_copy_single(source, dest); 849} 850 851/* 852 * Labeling event operations: network objects. 853 */ 854static void 855mac_mls_set_socket_peer_from_socket(struct socket *oldsocket, 856 struct label *oldsocketlabel, struct socket *newsocket, 857 struct label *newsocketpeerlabel) 858{ 859 struct mac_mls *source, *dest; 860 861 source = SLOT(oldsocketlabel); 862 dest = SLOT(newsocketpeerlabel); 863 864 mac_mls_copy_single(source, dest); 865} 866 867static void 868mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 869 struct label *bpflabel) 870{ 871 struct mac_mls *source, *dest; 872 873 source = SLOT(&cred->cr_label); 874 dest = SLOT(bpflabel); 875 876 mac_mls_copy_single(source, dest); 877} 878 879static void 880mac_mls_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 881{ 882 struct mac_mls *dest; 883 int level; 884 885 dest = SLOT(ifnetlabel); 886 887 if (ifnet->if_type == IFT_LOOP) 888 level = MAC_MLS_TYPE_EQUAL; 889 else 890 level = MAC_MLS_TYPE_LOW; 891 892 mac_mls_set_single(dest, level, 0); 893 mac_mls_set_range(dest, level, 0, level, 0); 894} 895 896static void 897mac_mls_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 898 struct ipq *ipq, struct label *ipqlabel) 899{ 900 struct mac_mls *source, *dest; 901 902 source = SLOT(fragmentlabel); 903 dest = SLOT(ipqlabel); 904 905 mac_mls_copy_single(source, dest); 906} 907 908static void 909mac_mls_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 910 struct mbuf *datagram, struct label *datagramlabel) 911{ 912 struct mac_mls *source, *dest; 913 914 source = SLOT(ipqlabel); 915 dest = SLOT(datagramlabel); 916 917 /* Just use the head, since we require them all to match. */ 918 mac_mls_copy_single(source, dest); 919} 920 921static void 922mac_mls_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 923 struct mbuf *fragment, struct label *fragmentlabel) 924{ 925 struct mac_mls *source, *dest; 926 927 source = SLOT(datagramlabel); 928 dest = SLOT(fragmentlabel); 929 930 mac_mls_copy_single(source, dest); 931} 932 933static void 934mac_mls_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 935 struct label *oldmbuflabel, struct mbuf *newmbuf, 936 struct label *newmbuflabel) 937{ 938 struct mac_mls *source, *dest; 939 940 source = SLOT(oldmbuflabel); 941 dest = SLOT(newmbuflabel); 942 943 mac_mls_copy_single(source, dest); 944} 945 946static void 947mac_mls_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 948 struct mbuf *mbuf, struct label *mbuflabel) 949{ 950 struct mac_mls *dest; 951 952 dest = SLOT(mbuflabel); 953 954 mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0); 955} 956 957static void 958mac_mls_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 959 struct mbuf *mbuf, struct label *mbuflabel) 960{ 961 struct mac_mls *source, *dest; 962 963 source = SLOT(bpflabel); 964 dest = SLOT(mbuflabel); 965 966 mac_mls_copy_single(source, dest); 967} 968 969static void 970mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 971 struct mbuf *m, struct label *mbuflabel) 972{ 973 struct mac_mls *source, *dest; 974 975 source = SLOT(ifnetlabel); 976 dest = SLOT(mbuflabel); 977 978 mac_mls_copy_single(source, dest); 979} 980 981static void 982mac_mls_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 983 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 984 struct mbuf *newmbuf, struct label *newmbuflabel) 985{ 986 struct mac_mls *source, *dest; 987 988 source = SLOT(oldmbuflabel); 989 dest = SLOT(newmbuflabel); 990 991 mac_mls_copy_single(source, dest); 992} 993 994static void 995mac_mls_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 996 struct mbuf *newmbuf, struct label *newmbuflabel) 997{ 998 struct mac_mls *source, *dest; 999 1000 source = SLOT(oldmbuflabel); 1001 dest = SLOT(newmbuflabel); 1002 1003 mac_mls_copy_single(source, dest); 1004} 1005 1006static int 1007mac_mls_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1008 struct ipq *ipq, struct label *ipqlabel) 1009{ 1010 struct mac_mls *a, *b; 1011 1012 a = SLOT(ipqlabel); 1013 b = SLOT(fragmentlabel); 1014 1015 return (mac_mls_equal_single(a, b)); 1016} 1017 1018static void 1019mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1020 struct label *ifnetlabel, struct label *newlabel) 1021{ 1022 struct mac_mls *source, *dest; 1023 1024 source = SLOT(newlabel); 1025 dest = SLOT(ifnetlabel); 1026 1027 mac_mls_copy_single(source, dest); 1028 mac_mls_copy_range(source, dest); 1029} 1030 1031static void 1032mac_mls_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1033 struct ipq *ipq, struct label *ipqlabel) 1034{ 1035 1036 /* NOOP: we only accept matching labels, so no need to update */ 1037} 1038 1039/* 1040 * Labeling event operations: processes. 1041 */ 1042static void 1043mac_mls_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1044{ 1045 struct mac_mls *source, *dest; 1046 1047 source = SLOT(&cred_parent->cr_label); 1048 dest = SLOT(&cred_child->cr_label); 1049 1050 mac_mls_copy_single(source, dest); 1051 mac_mls_copy_range(source, dest); 1052} 1053 1054static void 1055mac_mls_execve_transition(struct ucred *old, struct ucred *new, 1056 struct vnode *vp, struct mac *vnodelabel) 1057{ 1058 struct mac_mls *source, *dest; 1059 1060 source = SLOT(&old->cr_label); 1061 dest = SLOT(&new->cr_label); 1062 1063 mac_mls_copy_single(source, dest); 1064 mac_mls_copy_range(source, dest); 1065} 1066 1067static int 1068mac_mls_execve_will_transition(struct ucred *old, struct vnode *vp, 1069 struct mac *vnodelabel) 1070{ 1071 1072 return (0); 1073} 1074 1075static void 1076mac_mls_create_proc0(struct ucred *cred) 1077{ 1078 struct mac_mls *dest; 1079 1080 dest = SLOT(&cred->cr_label); 1081 1082 mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0); 1083 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, MAC_MLS_TYPE_HIGH, 0); 1084} 1085 1086static void 1087mac_mls_create_proc1(struct ucred *cred) 1088{ 1089 struct mac_mls *dest; 1090 1091 dest = SLOT(&cred->cr_label); 1092 1093 mac_mls_set_single(dest, MAC_MLS_TYPE_LOW, 0); 1094 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, MAC_MLS_TYPE_HIGH, 0); 1095} 1096 1097static void 1098mac_mls_relabel_cred(struct ucred *cred, struct label *newlabel) 1099{ 1100 struct mac_mls *source, *dest; 1101 1102 source = SLOT(newlabel); 1103 dest = SLOT(&cred->cr_label); 1104 1105 mac_mls_copy_single(source, dest); 1106 mac_mls_copy_range(source, dest); 1107} 1108 1109/* 1110 * Access control checks. 1111 */ 1112static int 1113mac_mls_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1114 struct ifnet *ifnet, struct label *ifnetlabel) 1115{ 1116 struct mac_mls *a, *b; 1117 1118 if (!mac_mls_enabled) 1119 return (0); 1120 1121 a = SLOT(bpflabel); 1122 b = SLOT(ifnetlabel); 1123 1124 if (mac_mls_equal_single(a, b)) 1125 return (0); 1126 return (EACCES); 1127} 1128 1129static int 1130mac_mls_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1131{ 1132 struct mac_mls *subj, *new; 1133 1134 subj = SLOT(&cred->cr_label); 1135 new = SLOT(newlabel); 1136 1137 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAGS_BOTH) 1138 return (EINVAL); 1139 1140 /* 1141 * XXX: Allow processes with root privilege to set labels outside 1142 * their range, so suid things like "su" work. This WILL go away 1143 * when we figure out the 'correct' solution... 1144 */ 1145 if (!suser_cred(cred, 0)) 1146 return (0); 1147 1148 /* 1149 * The new single must be in the old range. 1150 */ 1151 if (!mac_mls_single_in_range(new, subj)) 1152 return (EPERM); 1153 1154 /* 1155 * The new range must be in the old range. 1156 */ 1157 if (!mac_mls_range_in_range(new, subj)) 1158 return (EPERM); 1159 1160 /* 1161 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL. 1162 */ 1163 1164 return (0); 1165} 1166 1167 1168static int 1169mac_mls_check_cred_visible(struct ucred *u1, struct ucred *u2) 1170{ 1171 struct mac_mls *subj, *obj; 1172 1173 if (!mac_mls_enabled) 1174 return (0); 1175 1176 subj = SLOT(&u1->cr_label); 1177 obj = SLOT(&u2->cr_label); 1178 1179 /* XXX: range */ 1180 if (!mac_mls_dominate_single(subj, obj)) 1181 return (ESRCH); 1182 1183 return (0); 1184} 1185 1186static int 1187mac_mls_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1188 struct label *ifnetlabel, struct label *newlabel) 1189{ 1190 struct mac_mls *subj, *new; 1191 1192 subj = SLOT(&cred->cr_label); 1193 new = SLOT(newlabel); 1194 1195 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAGS_BOTH) 1196 return (EINVAL); 1197 1198 /* XXX: privilege model here? */ 1199 1200 return (suser_cred(cred, 0)); 1201} 1202 1203static int 1204mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1205 struct mbuf *m, struct label *mbuflabel) 1206{ 1207 struct mac_mls *p, *i; 1208 1209 if (!mac_mls_enabled) 1210 return (0); 1211 1212 p = SLOT(mbuflabel); 1213 i = SLOT(ifnetlabel); 1214 1215 return (mac_mls_single_in_range(p, i) ? 0 : EACCES); 1216} 1217 1218static int 1219mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp, 1220 struct label *mntlabel) 1221{ 1222 struct mac_mls *subj, *obj; 1223 1224 if (!mac_mls_enabled) 1225 return (0); 1226 1227 subj = SLOT(&cred->cr_label); 1228 obj = SLOT(mntlabel); 1229 1230 if (!mac_mls_dominate_single(subj, obj)) 1231 return (EACCES); 1232 1233 return (0); 1234} 1235 1236static int 1237mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1238 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1239{ 1240 1241 if(!mac_mls_enabled) 1242 return (0); 1243 1244 /* XXX: This will be implemented soon... */ 1245 1246 return (0); 1247} 1248 1249static int 1250mac_mls_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1251 struct label *pipelabel) 1252{ 1253 struct mac_mls *subj, *obj; 1254 1255 if (!mac_mls_enabled) 1256 return (0); 1257 1258 subj = SLOT(&cred->cr_label); 1259 obj = SLOT((pipelabel)); 1260 1261 if (!mac_mls_dominate_single(subj, obj)) 1262 return (EACCES); 1263 1264 return (0); 1265} 1266 1267static int 1268mac_mls_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1269 struct label *pipelabel) 1270{ 1271 struct mac_mls *subj, *obj; 1272 1273 if (!mac_mls_enabled) 1274 return (0); 1275 1276 subj = SLOT(&cred->cr_label); 1277 obj = SLOT((pipelabel)); 1278 1279 if (!mac_mls_dominate_single(subj, obj)) 1280 return (EACCES); 1281 1282 return (0); 1283} 1284 1285static int 1286mac_mls_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1287 struct label *pipelabel, struct label *newlabel) 1288{ 1289 struct mac_mls *subj, *obj, *new; 1290 1291 new = SLOT(newlabel); 1292 subj = SLOT(&cred->cr_label); 1293 obj = SLOT(pipelabel); 1294 1295 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) 1296 return (EINVAL); 1297 1298 /* 1299 * To relabel a pipe, the old pipe label must be in the subject 1300 * range. 1301 */ 1302 if (!mac_mls_single_in_range(obj, subj)) 1303 return (EPERM); 1304 1305 /* 1306 * To relabel a pipe, the new pipe label must be in the subject 1307 * range. 1308 */ 1309 if (!mac_mls_single_in_range(new, subj)) 1310 return (EPERM); 1311 1312 /* 1313 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL. 1314 */ 1315 1316 return (0); 1317} 1318 1319static int 1320mac_mls_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1321 struct label *pipelabel) 1322{ 1323 struct mac_mls *subj, *obj; 1324 1325 if (!mac_mls_enabled) 1326 return (0); 1327 1328 subj = SLOT(&cred->cr_label); 1329 obj = SLOT((pipelabel)); 1330 1331 if (!mac_mls_dominate_single(subj, obj)) 1332 return (EACCES); 1333 1334 return (0); 1335} 1336 1337static int 1338mac_mls_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1339 struct label *pipelabel) 1340{ 1341 struct mac_mls *subj, *obj; 1342 1343 if (!mac_mls_enabled) 1344 return (0); 1345 1346 subj = SLOT(&cred->cr_label); 1347 obj = SLOT((pipelabel)); 1348 1349 if (!mac_mls_dominate_single(obj, subj)) 1350 return (EACCES); 1351 1352 return (0); 1353} 1354 1355static int 1356mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc) 1357{ 1358 struct mac_mls *subj, *obj; 1359 1360 if (!mac_mls_enabled) 1361 return (0); 1362 1363 subj = SLOT(&cred->cr_label); 1364 obj = SLOT(&proc->p_ucred->cr_label); 1365 1366 /* XXX: range checks */ 1367 if (!mac_mls_dominate_single(subj, obj)) 1368 return (ESRCH); 1369 if (!mac_mls_dominate_single(obj, subj)) 1370 return (EACCES); 1371 1372 return (0); 1373} 1374 1375static int 1376mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc) 1377{ 1378 struct mac_mls *subj, *obj; 1379 1380 if (!mac_mls_enabled) 1381 return (0); 1382 1383 subj = SLOT(&cred->cr_label); 1384 obj = SLOT(&proc->p_ucred->cr_label); 1385 1386 /* XXX: range checks */ 1387 if (!mac_mls_dominate_single(subj, obj)) 1388 return (ESRCH); 1389 if (!mac_mls_dominate_single(obj, subj)) 1390 return (EACCES); 1391 1392 return (0); 1393} 1394 1395static int 1396mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1397{ 1398 struct mac_mls *subj, *obj; 1399 1400 if (!mac_mls_enabled) 1401 return (0); 1402 1403 subj = SLOT(&cred->cr_label); 1404 obj = SLOT(&proc->p_ucred->cr_label); 1405 1406 /* XXX: range checks */ 1407 if (!mac_mls_dominate_single(subj, obj)) 1408 return (ESRCH); 1409 if (!mac_mls_dominate_single(obj, subj)) 1410 return (EACCES); 1411 1412 return (0); 1413} 1414 1415static int 1416mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel, 1417 struct mbuf *m, struct label *mbuflabel) 1418{ 1419 struct mac_mls *p, *s; 1420 1421 if (!mac_mls_enabled) 1422 return (0); 1423 1424 p = SLOT(mbuflabel); 1425 s = SLOT(socketlabel); 1426 1427 return (mac_mls_equal_single(p, s) ? 0 : EACCES); 1428} 1429 1430static int 1431mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket, 1432 struct label *socketlabel, struct label *newlabel) 1433{ 1434 struct mac_mls *subj, *obj, *new; 1435 1436 new = SLOT(newlabel); 1437 subj = SLOT(&cred->cr_label); 1438 obj = SLOT(socketlabel); 1439 1440 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) 1441 return (EINVAL); 1442 1443 /* 1444 * To relabel a socket, the old socket label must be in the subject 1445 * range. 1446 */ 1447 if (!mac_mls_single_in_range(obj, subj)) 1448 return (EPERM); 1449 1450 /* 1451 * To relabel a socket, the new socket label must be in the subject 1452 * range. 1453 */ 1454 if (!mac_mls_single_in_range(new, subj)) 1455 return (EPERM); 1456 1457 /* 1458 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL. 1459 */ 1460 1461 return (0); 1462} 1463 1464static int 1465mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket, 1466 struct label *socketlabel) 1467{ 1468 struct mac_mls *subj, *obj; 1469 1470 if (!mac_mls_enabled) 1471 return (0); 1472 1473 subj = SLOT(&cred->cr_label); 1474 obj = SLOT(socketlabel); 1475 1476 if (!mac_mls_dominate_single(subj, obj)) 1477 return (ENOENT); 1478 1479 return (0); 1480} 1481 1482static int 1483mac_mls_check_vnode_access(struct ucred *cred, struct vnode *vp, 1484 struct label *label, mode_t flags) 1485{ 1486 1487 return (mac_mls_check_vnode_open(cred, vp, label, flags)); 1488} 1489 1490static int 1491mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1492 struct label *dlabel) 1493{ 1494 struct mac_mls *subj, *obj; 1495 1496 if (!mac_mls_enabled) 1497 return (0); 1498 1499 subj = SLOT(&cred->cr_label); 1500 obj = SLOT(dlabel); 1501 1502 if (!mac_mls_dominate_single(subj, obj)) 1503 return (EACCES); 1504 1505 return (0); 1506} 1507 1508static int 1509mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1510 struct label *dlabel) 1511{ 1512 struct mac_mls *subj, *obj; 1513 1514 if (!mac_mls_enabled) 1515 return (0); 1516 1517 subj = SLOT(&cred->cr_label); 1518 obj = SLOT(dlabel); 1519 1520 if (!mac_mls_dominate_single(subj, obj)) 1521 return (EACCES); 1522 1523 return (0); 1524} 1525 1526static int 1527mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1528 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1529{ 1530 struct mac_mls *subj, *obj; 1531 1532 if (!mac_mls_enabled) 1533 return (0); 1534 1535 subj = SLOT(&cred->cr_label); 1536 obj = SLOT(dlabel); 1537 1538 if (!mac_mls_dominate_single(obj, subj)) 1539 return (EACCES); 1540 1541 return (0); 1542} 1543 1544static int 1545mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1546 struct label *dlabel, struct vnode *vp, struct label *label, 1547 struct componentname *cnp) 1548{ 1549 struct mac_mls *subj, *obj; 1550 1551 if (!mac_mls_enabled) 1552 return (0); 1553 1554 subj = SLOT(&cred->cr_label); 1555 obj = SLOT(dlabel); 1556 1557 if (!mac_mls_dominate_single(obj, subj)) 1558 return (EACCES); 1559 1560 obj = SLOT(label); 1561 1562 if (!mac_mls_dominate_single(obj, subj)) 1563 return (EACCES); 1564 1565 return (0); 1566} 1567 1568static int 1569mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1570 struct label *label, acl_type_t type) 1571{ 1572 struct mac_mls *subj, *obj; 1573 1574 if (!mac_mls_enabled) 1575 return (0); 1576 1577 subj = SLOT(&cred->cr_label); 1578 obj = SLOT(label); 1579 1580 if (!mac_mls_dominate_single(obj, subj)) 1581 return (EACCES); 1582 1583 return (0); 1584} 1585 1586static int 1587mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1588 struct label *label) 1589{ 1590 struct mac_mls *subj, *obj; 1591 1592 if (!mac_mls_enabled) 1593 return (0); 1594 1595 subj = SLOT(&cred->cr_label); 1596 obj = SLOT(label); 1597 1598 if (!mac_mls_dominate_single(subj, obj)) 1599 return (EACCES); 1600 1601 return (0); 1602} 1603 1604static int 1605mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 1606 struct label *label, acl_type_t type) 1607{ 1608 struct mac_mls *subj, *obj; 1609 1610 if (!mac_mls_enabled) 1611 return (0); 1612 1613 subj = SLOT(&cred->cr_label); 1614 obj = SLOT(label); 1615 1616 if (!mac_mls_dominate_single(subj, obj)) 1617 return (EACCES); 1618 1619 return (0); 1620} 1621 1622static int 1623mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1624 struct label *label, int attrnamespace, const char *name, struct uio *uio) 1625{ 1626 struct mac_mls *subj, *obj; 1627 1628 if (!mac_mls_enabled) 1629 return (0); 1630 1631 subj = SLOT(&cred->cr_label); 1632 obj = SLOT(label); 1633 1634 if (!mac_mls_dominate_single(subj, obj)) 1635 return (EACCES); 1636 1637 return (0); 1638} 1639 1640static int 1641mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1642 struct label *dlabel, struct componentname *cnp) 1643{ 1644 struct mac_mls *subj, *obj; 1645 1646 if (!mac_mls_enabled) 1647 return (0); 1648 1649 subj = SLOT(&cred->cr_label); 1650 obj = SLOT(dlabel); 1651 1652 if (!mac_mls_dominate_single(subj, obj)) 1653 return (EACCES); 1654 1655 return (0); 1656} 1657 1658static int 1659mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, 1660 struct label *vnodelabel, mode_t acc_mode) 1661{ 1662 struct mac_mls *subj, *obj; 1663 1664 if (!mac_mls_enabled) 1665 return (0); 1666 1667 subj = SLOT(&cred->cr_label); 1668 obj = SLOT(vnodelabel); 1669 1670 /* XXX privilege override for admin? */ 1671 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 1672 if (!mac_mls_dominate_single(subj, obj)) 1673 return (EACCES); 1674 } 1675 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 1676 if (!mac_mls_dominate_single(obj, subj)) 1677 return (EACCES); 1678 } 1679 1680 return (0); 1681} 1682 1683static int 1684mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1685 struct vnode *vp, struct label *label) 1686{ 1687 struct mac_mls *subj, *obj; 1688 1689 if (!mac_mls_enabled || !mac_mls_revocation_enabled) 1690 return (0); 1691 1692 subj = SLOT(&active_cred->cr_label); 1693 obj = SLOT(label); 1694 1695 if (!mac_mls_dominate_single(subj, obj)) 1696 return (EACCES); 1697 1698 return (0); 1699} 1700 1701static int 1702mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1703 struct vnode *vp, struct label *label) 1704{ 1705 struct mac_mls *subj, *obj; 1706 1707 if (!mac_mls_enabled || !mac_mls_revocation_enabled) 1708 return (0); 1709 1710 subj = SLOT(&active_cred->cr_label); 1711 obj = SLOT(label); 1712 1713 if (!mac_mls_dominate_single(subj, obj)) 1714 return (EACCES); 1715 1716 return (0); 1717} 1718 1719static int 1720mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 1721 struct label *dlabel) 1722{ 1723 struct mac_mls *subj, *obj; 1724 1725 if (!mac_mls_enabled) 1726 return (0); 1727 1728 subj = SLOT(&cred->cr_label); 1729 obj = SLOT(dlabel); 1730 1731 if (!mac_mls_dominate_single(subj, obj)) 1732 return (EACCES); 1733 1734 return (0); 1735} 1736 1737static int 1738mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 1739 struct label *vnodelabel) 1740{ 1741 struct mac_mls *subj, *obj; 1742 1743 if (!mac_mls_enabled) 1744 return (0); 1745 1746 subj = SLOT(&cred->cr_label); 1747 obj = SLOT(vnodelabel); 1748 1749 if (!mac_mls_dominate_single(subj, obj)) 1750 return (EACCES); 1751 1752 return (0); 1753} 1754 1755static int 1756mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1757 struct label *vnodelabel, struct label *newlabel) 1758{ 1759 struct mac_mls *old, *new, *subj; 1760 1761 old = SLOT(vnodelabel); 1762 new = SLOT(newlabel); 1763 subj = SLOT(&cred->cr_label); 1764 1765 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) 1766 return (EINVAL); 1767 1768 /* 1769 * To relabel a vnode, the old vnode label must be in the subject 1770 * range. 1771 */ 1772 if (!mac_mls_single_in_range(old, subj)) 1773 return (EPERM); 1774 1775 /* 1776 * To relabel a vnode, the new vnode label must be in the subject 1777 * range. 1778 */ 1779 if (!mac_mls_single_in_range(new, subj)) 1780 return (EPERM); 1781 1782 /* 1783 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL. 1784 */ 1785 1786 return (suser_cred(cred, 0)); 1787} 1788 1789 1790static int 1791mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1792 struct label *dlabel, struct vnode *vp, struct label *label, 1793 struct componentname *cnp) 1794{ 1795 struct mac_mls *subj, *obj; 1796 1797 if (!mac_mls_enabled) 1798 return (0); 1799 1800 subj = SLOT(&cred->cr_label); 1801 obj = SLOT(dlabel); 1802 1803 if (!mac_mls_dominate_single(obj, subj)) 1804 return (EACCES); 1805 1806 obj = SLOT(label); 1807 1808 if (!mac_mls_dominate_single(obj, subj)) 1809 return (EACCES); 1810 1811 return (0); 1812} 1813 1814static int 1815mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1816 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 1817 struct componentname *cnp) 1818{ 1819 struct mac_mls *subj, *obj; 1820 1821 if (!mac_mls_enabled) 1822 return (0); 1823 1824 subj = SLOT(&cred->cr_label); 1825 obj = SLOT(dlabel); 1826 1827 if (!mac_mls_dominate_single(obj, subj)) 1828 return (EACCES); 1829 1830 if (vp != NULL) { 1831 obj = SLOT(label); 1832 1833 if (!mac_mls_dominate_single(obj, subj)) 1834 return (EACCES); 1835 } 1836 1837 return (0); 1838} 1839 1840static int 1841mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 1842 struct label *label) 1843{ 1844 struct mac_mls *subj, *obj; 1845 1846 if (!mac_mls_enabled) 1847 return (0); 1848 1849 subj = SLOT(&cred->cr_label); 1850 obj = SLOT(label); 1851 1852 if (!mac_mls_dominate_single(obj, subj)) 1853 return (EACCES); 1854 1855 return (0); 1856} 1857 1858static int 1859mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 1860 struct label *label, acl_type_t type, struct acl *acl) 1861{ 1862 struct mac_mls *subj, *obj; 1863 1864 if (!mac_mls_enabled) 1865 return (0); 1866 1867 subj = SLOT(&cred->cr_label); 1868 obj = SLOT(label); 1869 1870 if (!mac_mls_dominate_single(obj, subj)) 1871 return (EACCES); 1872 1873 return (0); 1874} 1875 1876static int 1877mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1878 struct label *vnodelabel, int attrnamespace, const char *name, 1879 struct uio *uio) 1880{ 1881 struct mac_mls *subj, *obj; 1882 1883 if (!mac_mls_enabled) 1884 return (0); 1885 1886 subj = SLOT(&cred->cr_label); 1887 obj = SLOT(vnodelabel); 1888 1889 if (!mac_mls_dominate_single(obj, subj)) 1890 return (EACCES); 1891 1892 /* XXX: protect the MAC EA in a special way? */ 1893 1894 return (0); 1895} 1896 1897static int 1898mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 1899 struct label *vnodelabel, u_long flags) 1900{ 1901 struct mac_mls *subj, *obj; 1902 1903 if (!mac_mls_enabled) 1904 return (0); 1905 1906 subj = SLOT(&cred->cr_label); 1907 obj = SLOT(vnodelabel); 1908 1909 if (!mac_mls_dominate_single(obj, subj)) 1910 return (EACCES); 1911 1912 return (0); 1913} 1914 1915static int 1916mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 1917 struct label *vnodelabel, mode_t mode) 1918{ 1919 struct mac_mls *subj, *obj; 1920 1921 if (!mac_mls_enabled) 1922 return (0); 1923 1924 subj = SLOT(&cred->cr_label); 1925 obj = SLOT(vnodelabel); 1926 1927 if (!mac_mls_dominate_single(obj, subj)) 1928 return (EACCES); 1929 1930 return (0); 1931} 1932 1933static int 1934mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 1935 struct label *vnodelabel, uid_t uid, gid_t gid) 1936{ 1937 struct mac_mls *subj, *obj; 1938 1939 if (!mac_mls_enabled) 1940 return (0); 1941 1942 subj = SLOT(&cred->cr_label); 1943 obj = SLOT(vnodelabel); 1944 1945 if (!mac_mls_dominate_single(obj, subj)) 1946 return (EACCES); 1947 1948 return (0); 1949} 1950 1951static int 1952mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1953 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 1954{ 1955 struct mac_mls *subj, *obj; 1956 1957 if (!mac_mls_enabled) 1958 return (0); 1959 1960 subj = SLOT(&cred->cr_label); 1961 obj = SLOT(vnodelabel); 1962 1963 if (!mac_mls_dominate_single(obj, subj)) 1964 return (EACCES); 1965 1966 return (0); 1967} 1968 1969static int 1970mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1971 struct vnode *vp, struct label *vnodelabel) 1972{ 1973 struct mac_mls *subj, *obj; 1974 1975 if (!mac_mls_enabled) 1976 return (0); 1977 1978 subj = SLOT(&active_cred->cr_label); 1979 obj = SLOT(vnodelabel); 1980 1981 if (!mac_mls_dominate_single(subj, obj)) 1982 return (EACCES); 1983 1984 return (0); 1985} 1986 1987static int 1988mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1989 struct vnode *vp, struct label *label) 1990{ 1991 struct mac_mls *subj, *obj; 1992 1993 if (!mac_mls_enabled || !mac_mls_revocation_enabled) 1994 return (0); 1995 1996 subj = SLOT(&active_cred->cr_label); 1997 obj = SLOT(label); 1998 1999 if (!mac_mls_dominate_single(obj, subj)) 2000 return (EACCES); 2001 2002 return (0); 2003} 2004 2005static vm_prot_t 2006mac_mls_check_vnode_mmap_perms(struct ucred *cred, struct vnode *vp, 2007 struct label *label, int newmapping) 2008{ 2009 struct mac_mls *subj, *obj; 2010 vm_prot_t prot = 0; 2011 2012 if (!mac_mls_enabled || (!mac_mls_revocation_enabled && !newmapping)) 2013 return (VM_PROT_ALL); 2014 2015 subj = SLOT(&cred->cr_label); 2016 obj = SLOT(label); 2017 2018 if (mac_mls_dominate_single(subj, obj)) 2019 prot |= VM_PROT_READ | VM_PROT_EXECUTE; 2020 if (mac_mls_dominate_single(obj, subj)) 2021 prot |= VM_PROT_WRITE; 2022 return (prot); 2023} 2024 2025static struct mac_policy_op_entry mac_mls_ops[] = 2026{ 2027 { MAC_DESTROY, 2028 (macop_t)mac_mls_destroy }, 2029 { MAC_INIT, 2030 (macop_t)mac_mls_init }, 2031 { MAC_INIT_BPFDESC, 2032 (macop_t)mac_mls_init_bpfdesc }, 2033 { MAC_INIT_CRED, 2034 (macop_t)mac_mls_init_cred }, 2035 { MAC_INIT_DEVFSDIRENT, 2036 (macop_t)mac_mls_init_devfsdirent }, 2037 { MAC_INIT_IFNET, 2038 (macop_t)mac_mls_init_ifnet }, 2039 { MAC_INIT_IPQ, 2040 (macop_t)mac_mls_init_ipq }, 2041 { MAC_INIT_MBUF, 2042 (macop_t)mac_mls_init_mbuf }, 2043 { MAC_INIT_MOUNT, 2044 (macop_t)mac_mls_init_mount }, 2045 { MAC_INIT_PIPE, 2046 (macop_t)mac_mls_init_pipe }, 2047 { MAC_INIT_SOCKET, 2048 (macop_t)mac_mls_init_socket }, 2049 { MAC_INIT_TEMP, 2050 (macop_t)mac_mls_init_temp }, 2051 { MAC_INIT_VNODE, 2052 (macop_t)mac_mls_init_vnode }, 2053 { MAC_DESTROY_BPFDESC, 2054 (macop_t)mac_mls_destroy_bpfdesc }, 2055 { MAC_DESTROY_CRED, 2056 (macop_t)mac_mls_destroy_cred }, 2057 { MAC_DESTROY_DEVFSDIRENT, 2058 (macop_t)mac_mls_destroy_devfsdirent }, 2059 { MAC_DESTROY_IFNET, 2060 (macop_t)mac_mls_destroy_ifnet }, 2061 { MAC_DESTROY_IPQ, 2062 (macop_t)mac_mls_destroy_ipq }, 2063 { MAC_DESTROY_MBUF, 2064 (macop_t)mac_mls_destroy_mbuf }, 2065 { MAC_DESTROY_MOUNT, 2066 (macop_t)mac_mls_destroy_mount }, 2067 { MAC_DESTROY_PIPE, 2068 (macop_t)mac_mls_destroy_pipe }, 2069 { MAC_DESTROY_SOCKET, 2070 (macop_t)mac_mls_destroy_socket }, 2071 { MAC_DESTROY_TEMP, 2072 (macop_t)mac_mls_destroy_temp }, 2073 { MAC_DESTROY_VNODE, 2074 (macop_t)mac_mls_destroy_vnode }, 2075 { MAC_EXTERNALIZE, 2076 (macop_t)mac_mls_externalize }, 2077 { MAC_INTERNALIZE, 2078 (macop_t)mac_mls_internalize }, 2079 { MAC_CREATE_DEVFS_DEVICE, 2080 (macop_t)mac_mls_create_devfs_device }, 2081 { MAC_CREATE_DEVFS_DIRECTORY, 2082 (macop_t)mac_mls_create_devfs_directory }, 2083 { MAC_CREATE_DEVFS_VNODE, 2084 (macop_t)mac_mls_create_devfs_vnode }, 2085 { MAC_CREATE_VNODE, 2086 (macop_t)mac_mls_create_vnode }, 2087 { MAC_CREATE_MOUNT, 2088 (macop_t)mac_mls_create_mount }, 2089 { MAC_CREATE_ROOT_MOUNT, 2090 (macop_t)mac_mls_create_root_mount }, 2091 { MAC_RELABEL_VNODE, 2092 (macop_t)mac_mls_relabel_vnode }, 2093 { MAC_UPDATE_DEVFSDIRENT, 2094 (macop_t)mac_mls_update_devfsdirent }, 2095 { MAC_UPDATE_PROCFSVNODE, 2096 (macop_t)mac_mls_update_procfsvnode }, 2097 { MAC_UPDATE_VNODE_FROM_EXTERNALIZED, 2098 (macop_t)mac_mls_update_vnode_from_externalized }, 2099 { MAC_UPDATE_VNODE_FROM_MOUNT, 2100 (macop_t)mac_mls_update_vnode_from_mount }, 2101 { MAC_CREATE_MBUF_FROM_SOCKET, 2102 (macop_t)mac_mls_create_mbuf_from_socket }, 2103 { MAC_CREATE_PIPE, 2104 (macop_t)mac_mls_create_pipe }, 2105 { MAC_CREATE_SOCKET, 2106 (macop_t)mac_mls_create_socket }, 2107 { MAC_CREATE_SOCKET_FROM_SOCKET, 2108 (macop_t)mac_mls_create_socket_from_socket }, 2109 { MAC_RELABEL_PIPE, 2110 (macop_t)mac_mls_relabel_pipe }, 2111 { MAC_RELABEL_SOCKET, 2112 (macop_t)mac_mls_relabel_socket }, 2113 { MAC_SET_SOCKET_PEER_FROM_MBUF, 2114 (macop_t)mac_mls_set_socket_peer_from_mbuf }, 2115 { MAC_SET_SOCKET_PEER_FROM_SOCKET, 2116 (macop_t)mac_mls_set_socket_peer_from_socket }, 2117 { MAC_CREATE_BPFDESC, 2118 (macop_t)mac_mls_create_bpfdesc }, 2119 { MAC_CREATE_DATAGRAM_FROM_IPQ, 2120 (macop_t)mac_mls_create_datagram_from_ipq }, 2121 { MAC_CREATE_FRAGMENT, 2122 (macop_t)mac_mls_create_fragment }, 2123 { MAC_CREATE_IFNET, 2124 (macop_t)mac_mls_create_ifnet }, 2125 { MAC_CREATE_IPQ, 2126 (macop_t)mac_mls_create_ipq }, 2127 { MAC_CREATE_MBUF_FROM_MBUF, 2128 (macop_t)mac_mls_create_mbuf_from_mbuf }, 2129 { MAC_CREATE_MBUF_LINKLAYER, 2130 (macop_t)mac_mls_create_mbuf_linklayer }, 2131 { MAC_CREATE_MBUF_FROM_BPFDESC, 2132 (macop_t)mac_mls_create_mbuf_from_bpfdesc }, 2133 { MAC_CREATE_MBUF_FROM_IFNET, 2134 (macop_t)mac_mls_create_mbuf_from_ifnet }, 2135 { MAC_CREATE_MBUF_MULTICAST_ENCAP, 2136 (macop_t)mac_mls_create_mbuf_multicast_encap }, 2137 { MAC_CREATE_MBUF_NETLAYER, 2138 (macop_t)mac_mls_create_mbuf_netlayer }, 2139 { MAC_FRAGMENT_MATCH, 2140 (macop_t)mac_mls_fragment_match }, 2141 { MAC_RELABEL_IFNET, 2142 (macop_t)mac_mls_relabel_ifnet }, 2143 { MAC_UPDATE_IPQ, 2144 (macop_t)mac_mls_update_ipq }, 2145 { MAC_CREATE_CRED, 2146 (macop_t)mac_mls_create_cred }, 2147 { MAC_EXECVE_TRANSITION, 2148 (macop_t)mac_mls_execve_transition }, 2149 { MAC_EXECVE_WILL_TRANSITION, 2150 (macop_t)mac_mls_execve_will_transition }, 2151 { MAC_CREATE_PROC0, 2152 (macop_t)mac_mls_create_proc0 }, 2153 { MAC_CREATE_PROC1, 2154 (macop_t)mac_mls_create_proc1 }, 2155 { MAC_RELABEL_CRED, 2156 (macop_t)mac_mls_relabel_cred }, 2157 { MAC_CHECK_BPFDESC_RECEIVE, 2158 (macop_t)mac_mls_check_bpfdesc_receive }, 2159 { MAC_CHECK_CRED_RELABEL, 2160 (macop_t)mac_mls_check_cred_relabel }, 2161 { MAC_CHECK_CRED_VISIBLE, 2162 (macop_t)mac_mls_check_cred_visible }, 2163 { MAC_CHECK_IFNET_RELABEL, 2164 (macop_t)mac_mls_check_ifnet_relabel }, 2165 { MAC_CHECK_IFNET_TRANSMIT, 2166 (macop_t)mac_mls_check_ifnet_transmit }, 2167 { MAC_CHECK_MOUNT_STAT, 2168 (macop_t)mac_mls_check_mount_stat }, 2169 { MAC_CHECK_PIPE_IOCTL, 2170 (macop_t)mac_mls_check_pipe_ioctl }, 2171 { MAC_CHECK_PIPE_POLL, 2172 (macop_t)mac_mls_check_pipe_poll }, 2173 { MAC_CHECK_PIPE_READ, 2174 (macop_t)mac_mls_check_pipe_read }, 2175 { MAC_CHECK_PIPE_RELABEL, 2176 (macop_t)mac_mls_check_pipe_relabel }, 2177 { MAC_CHECK_PIPE_STAT, 2178 (macop_t)mac_mls_check_pipe_stat }, 2179 { MAC_CHECK_PIPE_WRITE, 2180 (macop_t)mac_mls_check_pipe_write }, 2181 { MAC_CHECK_PROC_DEBUG, 2182 (macop_t)mac_mls_check_proc_debug }, 2183 { MAC_CHECK_PROC_SCHED, 2184 (macop_t)mac_mls_check_proc_sched }, 2185 { MAC_CHECK_PROC_SIGNAL, 2186 (macop_t)mac_mls_check_proc_signal }, 2187 { MAC_CHECK_SOCKET_DELIVER, 2188 (macop_t)mac_mls_check_socket_deliver }, 2189 { MAC_CHECK_SOCKET_RELABEL, 2190 (macop_t)mac_mls_check_socket_relabel }, 2191 { MAC_CHECK_SOCKET_VISIBLE, 2192 (macop_t)mac_mls_check_socket_visible }, 2193 { MAC_CHECK_VNODE_ACCESS, 2194 (macop_t)mac_mls_check_vnode_access }, 2195 { MAC_CHECK_VNODE_CHDIR, 2196 (macop_t)mac_mls_check_vnode_chdir }, 2197 { MAC_CHECK_VNODE_CHROOT, 2198 (macop_t)mac_mls_check_vnode_chroot }, 2199 { MAC_CHECK_VNODE_CREATE, 2200 (macop_t)mac_mls_check_vnode_create }, 2201 { MAC_CHECK_VNODE_DELETE, 2202 (macop_t)mac_mls_check_vnode_delete }, 2203 { MAC_CHECK_VNODE_DELETEACL, 2204 (macop_t)mac_mls_check_vnode_deleteacl }, 2205 { MAC_CHECK_VNODE_EXEC, 2206 (macop_t)mac_mls_check_vnode_exec }, 2207 { MAC_CHECK_VNODE_GETACL, 2208 (macop_t)mac_mls_check_vnode_getacl }, 2209 { MAC_CHECK_VNODE_GETEXTATTR, 2210 (macop_t)mac_mls_check_vnode_getextattr }, 2211 { MAC_CHECK_VNODE_LOOKUP, 2212 (macop_t)mac_mls_check_vnode_lookup }, 2213 { MAC_CHECK_VNODE_OPEN, 2214 (macop_t)mac_mls_check_vnode_open }, 2215 { MAC_CHECK_VNODE_POLL, 2216 (macop_t)mac_mls_check_vnode_poll }, 2217 { MAC_CHECK_VNODE_READ, 2218 (macop_t)mac_mls_check_vnode_read }, 2219 { MAC_CHECK_VNODE_READDIR, 2220 (macop_t)mac_mls_check_vnode_readdir }, 2221 { MAC_CHECK_VNODE_READLINK, 2222 (macop_t)mac_mls_check_vnode_readlink }, 2223 { MAC_CHECK_VNODE_RELABEL, 2224 (macop_t)mac_mls_check_vnode_relabel }, 2225 { MAC_CHECK_VNODE_RENAME_FROM, 2226 (macop_t)mac_mls_check_vnode_rename_from }, 2227 { MAC_CHECK_VNODE_RENAME_TO, 2228 (macop_t)mac_mls_check_vnode_rename_to }, 2229 { MAC_CHECK_VNODE_REVOKE, 2230 (macop_t)mac_mls_check_vnode_revoke }, 2231 { MAC_CHECK_VNODE_SETACL, 2232 (macop_t)mac_mls_check_vnode_setacl }, 2233 { MAC_CHECK_VNODE_SETEXTATTR, 2234 (macop_t)mac_mls_check_vnode_setextattr }, 2235 { MAC_CHECK_VNODE_SETFLAGS, 2236 (macop_t)mac_mls_check_vnode_setflags }, 2237 { MAC_CHECK_VNODE_SETMODE, 2238 (macop_t)mac_mls_check_vnode_setmode }, 2239 { MAC_CHECK_VNODE_SETOWNER, 2240 (macop_t)mac_mls_check_vnode_setowner }, 2241 { MAC_CHECK_VNODE_SETUTIMES, 2242 (macop_t)mac_mls_check_vnode_setutimes }, 2243 { MAC_CHECK_VNODE_STAT, 2244 (macop_t)mac_mls_check_vnode_stat }, 2245 { MAC_CHECK_VNODE_WRITE, 2246 (macop_t)mac_mls_check_vnode_write }, 2247 { MAC_CHECK_VNODE_MMAP_PERMS, 2248 (macop_t)mac_mls_check_vnode_mmap_perms }, 2249 { MAC_OP_LAST, NULL } 2250}; 2251 2252MAC_POLICY_SET(mac_mls_ops, trustedbsd_mac_mls, "TrustedBSD MAC/MLS", 2253 MPC_LOADTIME_FLAG_NOTLATE, &mac_mls_slot);
| 88 89static int destroyed_not_inited; 90SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 91 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 92 93static int mac_mls_revocation_enabled = 0; 94SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, 95 &mac_mls_revocation_enabled, 0, "Revoke access to objects on relabel"); 96TUNABLE_INT("security.mac.mls.revocation_enabled", 97 &mac_mls_revocation_enabled); 98 99static int mac_mls_slot; 100#define SLOT(l) ((struct mac_mls *)LABEL_TO_SLOT((l), mac_mls_slot).l_ptr) 101 102MALLOC_DEFINE(M_MACMLS, "mls label", "MAC/MLS labels"); 103 104static int mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, 105 struct label *vnodelabel, mode_t acc_mode); 106 107static struct mac_mls * 108mls_alloc(int how) 109{ 110 struct mac_mls *mac_mls; 111 112 mac_mls = malloc(sizeof(struct mac_mls), M_MACMLS, M_ZERO | how); 113 114 return (mac_mls); 115} 116 117static void 118mls_free(struct mac_mls *mac_mls) 119{ 120 121 if (mac_mls != NULL) 122 free(mac_mls, M_MACMLS); 123 else 124 atomic_add_int(&destroyed_not_inited, 1); 125} 126 127static int 128mac_mls_dominate_element(struct mac_mls_element *a, 129 struct mac_mls_element *b) 130{ 131 132 switch(a->mme_type) { 133 case MAC_MLS_TYPE_EQUAL: 134 case MAC_MLS_TYPE_HIGH: 135 return (1); 136 137 case MAC_MLS_TYPE_LOW: 138 switch (b->mme_type) { 139 case MAC_MLS_TYPE_LEVEL: 140 case MAC_MLS_TYPE_HIGH: 141 return (0); 142 143 case MAC_MLS_TYPE_EQUAL: 144 case MAC_MLS_TYPE_LOW: 145 return (1); 146 147 default: 148 panic("mac_mls_dominate_element: b->mme_type invalid"); 149 } 150 151 case MAC_MLS_TYPE_LEVEL: 152 switch (b->mme_type) { 153 case MAC_MLS_TYPE_EQUAL: 154 case MAC_MLS_TYPE_LOW: 155 return (1); 156 157 case MAC_MLS_TYPE_HIGH: 158 return (0); 159 160 case MAC_MLS_TYPE_LEVEL: 161 return (a->mme_level >= b->mme_level); 162 163 default: 164 panic("mac_mls_dominate_element: b->mme_type invalid"); 165 } 166 167 default: 168 panic("mac_mls_dominate_element: a->mme_type invalid"); 169 } 170 171 return (0); 172} 173 174static int 175mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) 176{ 177 178 return (mac_mls_dominate_element(&rangeb->mm_rangehigh, 179 &rangea->mm_rangehigh) && 180 mac_mls_dominate_element(&rangea->mm_rangelow, 181 &rangeb->mm_rangelow)); 182} 183 184static int 185mac_mls_single_in_range(struct mac_mls *single, struct mac_mls *range) 186{ 187 188 KASSERT((single->mm_flag & MAC_MLS_FLAG_SINGLE) != 0, 189 ("mac_mls_single_in_range: a not single")); 190 KASSERT((range->mm_flag & MAC_MLS_FLAG_RANGE) != 0, 191 ("mac_mls_single_in_range: b not range")); 192 193 return (mac_mls_dominate_element(&range->mm_rangehigh, 194 &single->mm_single) && 195 mac_mls_dominate_element(&single->mm_single, 196 &range->mm_rangelow)); 197 198 return (1); 199} 200 201static int 202mac_mls_dominate_single(struct mac_mls *a, struct mac_mls *b) 203{ 204 KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 205 ("mac_mls_dominate_single: a not single")); 206 KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 207 ("mac_mls_dominate_single: b not single")); 208 209 return (mac_mls_dominate_element(&a->mm_single, &b->mm_single)); 210} 211 212static int 213mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) 214{ 215 216 if (a->mme_type == MAC_MLS_TYPE_EQUAL || 217 b->mme_type == MAC_MLS_TYPE_EQUAL) 218 return (1); 219 220 return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); 221} 222 223static int 224mac_mls_equal_range(struct mac_mls *a, struct mac_mls *b) 225{ 226 227 KASSERT((a->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 228 ("mac_mls_equal_range: a not range")); 229 KASSERT((b->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 230 ("mac_mls_equal_range: b not range")); 231 232 return (mac_mls_equal_element(&a->mm_rangelow, &b->mm_rangelow) && 233 mac_mls_equal_element(&a->mm_rangehigh, &b->mm_rangehigh)); 234} 235 236static int 237mac_mls_equal_single(struct mac_mls *a, struct mac_mls *b) 238{ 239 240 KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 241 ("mac_mls_equal_single: a not single")); 242 KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 243 ("mac_mls_equal_single: b not single")); 244 245 return (mac_mls_equal_element(&a->mm_single, &b->mm_single)); 246} 247 248static int 249mac_mls_valid(struct mac_mls *mac_mls) 250{ 251 252 if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE) { 253 switch (mac_mls->mm_single.mme_type) { 254 case MAC_MLS_TYPE_LEVEL: 255 break; 256 257 case MAC_MLS_TYPE_EQUAL: 258 case MAC_MLS_TYPE_HIGH: 259 case MAC_MLS_TYPE_LOW: 260 if (mac_mls->mm_single.mme_level != 0) 261 return (EINVAL); 262 break; 263 264 default: 265 return (EINVAL); 266 } 267 } else { 268 if (mac_mls->mm_single.mme_type != MAC_MLS_TYPE_UNDEF) 269 return (EINVAL); 270 } 271 272 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 273 switch (mac_mls->mm_rangelow.mme_type) { 274 case MAC_MLS_TYPE_LEVEL: 275 break; 276 277 case MAC_MLS_TYPE_EQUAL: 278 case MAC_MLS_TYPE_HIGH: 279 case MAC_MLS_TYPE_LOW: 280 if (mac_mls->mm_rangelow.mme_level != 0) 281 return (EINVAL); 282 break; 283 284 default: 285 return (EINVAL); 286 } 287 288 switch (mac_mls->mm_rangehigh.mme_type) { 289 case MAC_MLS_TYPE_LEVEL: 290 break; 291 292 case MAC_MLS_TYPE_EQUAL: 293 case MAC_MLS_TYPE_HIGH: 294 case MAC_MLS_TYPE_LOW: 295 if (mac_mls->mm_rangehigh.mme_level != 0) 296 return (EINVAL); 297 break; 298 299 default: 300 return (EINVAL); 301 } 302 if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh, 303 &mac_mls->mm_rangelow)) 304 return (EINVAL); 305 } else { 306 if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || 307 mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) 308 return (EINVAL); 309 } 310 311 return (0); 312} 313 314static void 315mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow, 316 u_short levellow, u_short typehigh, u_short levelhigh) 317{ 318 319 mac_mls->mm_rangelow.mme_type = typelow; 320 mac_mls->mm_rangelow.mme_level = levellow; 321 mac_mls->mm_rangehigh.mme_type = typehigh; 322 mac_mls->mm_rangehigh.mme_level = levelhigh; 323 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 324} 325 326static void 327mac_mls_set_single(struct mac_mls *mac_mls, u_short type, u_short level) 328{ 329 330 mac_mls->mm_single.mme_type = type; 331 mac_mls->mm_single.mme_level = level; 332 mac_mls->mm_flags |= MAC_MLS_FLAG_SINGLE; 333} 334 335static void 336mac_mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 337{ 338 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 339 ("mac_mls_copy_range: labelfrom not range")); 340 341 labelto->mm_rangelow = labelfrom->mm_rangelow; 342 labelto->mm_rangehigh = labelfrom->mm_rangehigh; 343 labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 344} 345 346static void 347mac_mls_copy_single(struct mac_mls *labelfrom, struct mac_mls *labelto) 348{ 349 350 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 351 ("mac_mls_copy_single: labelfrom not single")); 352 353 labelto->mm_single = labelfrom->mm_single; 354 labelto->mm_flags |= MAC_MLS_FLAG_SINGLE; 355} 356 357static void 358mac_mls_copy_single_to_range(struct mac_mls *labelfrom, 359 struct mac_mls *labelto) 360{ 361 362 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 363 ("mac_mls_copy_single_to_range: labelfrom not single")); 364 365 labelto->mm_rangelow = labelfrom->mm_single; 366 labelto->mm_rangehigh = labelfrom->mm_single; 367 labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 368} 369 370/* 371 * Policy module operations. 372 */ 373static void 374mac_mls_destroy(struct mac_policy_conf *conf) 375{ 376 377} 378 379static void 380mac_mls_init(struct mac_policy_conf *conf) 381{ 382 383} 384 385/* 386 * Label operations. 387 */ 388static void 389mac_mls_init_bpfdesc(struct bpf_d *bpf_d, struct label *label) 390{ 391 392 SLOT(label) = mls_alloc(M_WAITOK); 393} 394 395static void 396mac_mls_init_cred(struct ucred *ucred, struct label *label) 397{ 398 399 SLOT(label) = mls_alloc(M_WAITOK); 400} 401 402static void 403mac_mls_init_devfsdirent(struct devfs_dirent *devfs_dirent, 404 struct label *label) 405{ 406 407 SLOT(label) = mls_alloc(M_WAITOK); 408} 409 410static void 411mac_mls_init_ifnet(struct ifnet *ifnet, struct label *label) 412{ 413 414 SLOT(label) = mls_alloc(M_WAITOK); 415} 416 417static void 418mac_mls_init_ipq(struct ipq *ipq, struct label *label) 419{ 420 421 SLOT(label) = mls_alloc(M_WAITOK); 422} 423 424static int 425mac_mls_init_mbuf(struct mbuf *mbuf, int how, struct label *label) 426{ 427 428 SLOT(label) = mls_alloc(how); 429 if (SLOT(label) == NULL) 430 return (ENOMEM); 431 432 return (0); 433} 434 435static void 436mac_mls_init_mount(struct mount *mount, struct label *mntlabel, 437 struct label *fslabel) 438{ 439 440 SLOT(mntlabel) = mls_alloc(M_WAITOK); 441 SLOT(fslabel) = mls_alloc(M_WAITOK); 442} 443 444static void 445mac_mls_init_socket(struct socket *socket, struct label *label, 446 struct label *peerlabel) 447{ 448 449 SLOT(label) = mls_alloc(M_WAITOK); 450 SLOT(peerlabel) = mls_alloc(M_WAITOK); 451} 452 453static void 454mac_mls_init_pipe(struct pipe *pipe, struct label *label) 455{ 456 457 SLOT(label) = mls_alloc(M_WAITOK); 458} 459 460static void 461mac_mls_init_temp(struct label *label) 462{ 463 464 SLOT(label) = mls_alloc(M_WAITOK); 465} 466 467static void 468mac_mls_init_vnode(struct vnode *vp, struct label *label) 469{ 470 471 SLOT(label) = mls_alloc(M_WAITOK); 472} 473 474static void 475mac_mls_destroy_bpfdesc(struct bpf_d *bpf_d, struct label *label) 476{ 477 478 mls_free(SLOT(label)); 479 SLOT(label) = NULL; 480} 481 482static void 483mac_mls_destroy_cred(struct ucred *ucred, struct label *label) 484{ 485 486 mls_free(SLOT(label)); 487 SLOT(label) = NULL; 488} 489 490static void 491mac_mls_destroy_devfsdirent(struct devfs_dirent *devfs_dirent, 492 struct label *label) 493{ 494 495 mls_free(SLOT(label)); 496 SLOT(label) = NULL; 497} 498 499static void 500mac_mls_destroy_ifnet(struct ifnet *ifnet, struct label *label) 501{ 502 503 mls_free(SLOT(label)); 504 SLOT(label) = NULL; 505} 506 507static void 508mac_mls_destroy_ipq(struct ipq *ipq, struct label *label) 509{ 510 511 mls_free(SLOT(label)); 512 SLOT(label) = NULL; 513} 514 515static void 516mac_mls_destroy_mbuf(struct mbuf *mbuf, struct label *label) 517{ 518 519 mls_free(SLOT(label)); 520 SLOT(label) = NULL; 521} 522 523static void 524mac_mls_destroy_mount(struct mount *mount, struct label *mntlabel, 525 struct label *fslabel) 526{ 527 528 mls_free(SLOT(mntlabel)); 529 SLOT(mntlabel) = NULL; 530 mls_free(SLOT(fslabel)); 531 SLOT(fslabel) = NULL; 532} 533 534static void 535mac_mls_destroy_socket(struct socket *socket, struct label *label, 536 struct label *peerlabel) 537{ 538 539 mls_free(SLOT(label)); 540 SLOT(label) = NULL; 541 mls_free(SLOT(peerlabel)); 542 SLOT(peerlabel) = NULL; 543} 544 545static void 546mac_mls_destroy_pipe(struct pipe *pipe, struct label *label) 547{ 548 549 mls_free(SLOT(label)); 550 SLOT(label) = NULL; 551} 552 553static void 554mac_mls_destroy_temp(struct label *label) 555{ 556 557 mls_free(SLOT(label)); 558 SLOT(label) = NULL; 559} 560 561static void 562mac_mls_destroy_vnode(struct vnode *vp, struct label *label) 563{ 564 565 mls_free(SLOT(label)); 566 SLOT(label) = NULL; 567} 568 569static int 570mac_mls_externalize(struct label *label, struct mac *extmac) 571{ 572 struct mac_mls *mac_mls; 573 574 mac_mls = SLOT(label); 575 576 if (mac_mls == NULL) { 577 printf("mac_mls_externalize: NULL pointer\n"); 578 return (0); 579 } 580 581 extmac->m_mls = *mac_mls; 582 583 return (0); 584} 585 586static int 587mac_mls_internalize(struct label *label, struct mac *extmac) 588{ 589 struct mac_mls *mac_mls; 590 int error; 591 592 mac_mls = SLOT(label); 593 594 error = mac_mls_valid(mac_mls); 595 if (error) 596 return (error); 597 598 *mac_mls = extmac->m_mls; 599 600 return (0); 601} 602 603/* 604 * Labeling event operations: file system objects, and things that look 605 * a lot like file system objects. 606 */ 607static void 608mac_mls_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 609 struct label *label) 610{ 611 struct mac_mls *mac_mls; 612 int mls_type; 613 614 mac_mls = SLOT(label); 615 if (strcmp(dev->si_name, "null") == 0 || 616 strcmp(dev->si_name, "zero") == 0 || 617 strcmp(dev->si_name, "random") == 0 || 618 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 619 mls_type = MAC_MLS_TYPE_EQUAL; 620 else if (strcmp(dev->si_name, "kmem") == 0 || 621 strcmp(dev->si_name, "mem") == 0) 622 mls_type = MAC_MLS_TYPE_HIGH; 623 else 624 mls_type = MAC_MLS_TYPE_LOW; 625 mac_mls_set_single(mac_mls, mls_type, 0); 626} 627 628static void 629mac_mls_create_devfs_directory(char *dirname, int dirnamelen, 630 struct devfs_dirent *devfs_dirent, struct label *label) 631{ 632 struct mac_mls *mac_mls; 633 634 mac_mls = SLOT(label); 635 mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0); 636} 637 638static void 639mac_mls_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 640 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 641{ 642 struct mac_mls *source, *dest; 643 644 source = SLOT(direntlabel); 645 dest = SLOT(vnodelabel); 646 mac_mls_copy_single(source, dest); 647} 648 649static void 650mac_mls_create_vnode(struct ucred *cred, struct vnode *parent, 651 struct label *parentlabel, struct vnode *child, struct label *childlabel) 652{ 653 struct mac_mls *source, *dest; 654 655 source = SLOT(&cred->cr_label); 656 dest = SLOT(childlabel); 657 658 mac_mls_copy_single(source, dest); 659} 660 661static void 662mac_mls_create_mount(struct ucred *cred, struct mount *mp, 663 struct label *mntlabel, struct label *fslabel) 664{ 665 struct mac_mls *source, *dest; 666 667 source = SLOT(&cred->cr_label); 668 dest = SLOT(mntlabel); 669 mac_mls_copy_single(source, dest); 670 dest = SLOT(fslabel); 671 mac_mls_copy_single(source, dest); 672} 673 674static void 675mac_mls_create_root_mount(struct ucred *cred, struct mount *mp, 676 struct label *mntlabel, struct label *fslabel) 677{ 678 struct mac_mls *mac_mls; 679 680 /* Always mount root as high integrity. */ 681 mac_mls = SLOT(fslabel); 682 mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0); 683 mac_mls = SLOT(mntlabel); 684 mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0); 685} 686 687static void 688mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp, 689 struct label *vnodelabel, struct label *label) 690{ 691 struct mac_mls *source, *dest; 692 693 source = SLOT(label); 694 dest = SLOT(vnodelabel); 695 696 mac_mls_copy_single(source, dest); 697} 698 699static void 700mac_mls_update_devfsdirent(struct devfs_dirent *devfs_dirent, 701 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 702{ 703 struct mac_mls *source, *dest; 704 705 source = SLOT(vnodelabel); 706 dest = SLOT(direntlabel); 707 708 mac_mls_copy_single(source, dest); 709} 710 711static void 712mac_mls_update_procfsvnode(struct vnode *vp, struct label *vnodelabel, 713 struct ucred *cred) 714{ 715 struct mac_mls *source, *dest; 716 717 source = SLOT(&cred->cr_label); 718 dest = SLOT(vnodelabel); 719 720 /* 721 * Only copy the single, not the range, since vnodes only have 722 * a single. 723 */ 724 mac_mls_copy_single(source, dest); 725} 726 727static int 728mac_mls_update_vnode_from_externalized(struct vnode *vp, 729 struct label *vnodelabel, struct mac *extmac) 730{ 731 struct mac_mls *source, *dest; 732 int error; 733 734 source = &extmac->m_mls; 735 dest = SLOT(vnodelabel); 736 737 error = mac_mls_valid(source); 738 if (error) 739 return (error); 740 741 if ((source->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) 742 return (EINVAL); 743 744 mac_mls_copy_single(source, dest); 745 746 return (0); 747} 748 749static void 750mac_mls_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel, 751 struct mount *mp, struct label *fslabel) 752{ 753 struct mac_mls *source, *dest; 754 755 source = SLOT(fslabel); 756 dest = SLOT(vnodelabel); 757 758 mac_mls_copy_single(source, dest); 759} 760 761/* 762 * Labeling event operations: IPC object. 763 */ 764static void 765mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 766 struct mbuf *m, struct label *mbuflabel) 767{ 768 struct mac_mls *source, *dest; 769 770 source = SLOT(socketlabel); 771 dest = SLOT(mbuflabel); 772 773 mac_mls_copy_single(source, dest); 774} 775 776static void 777mac_mls_create_socket(struct ucred *cred, struct socket *socket, 778 struct label *socketlabel) 779{ 780 struct mac_mls *source, *dest; 781 782 source = SLOT(&cred->cr_label); 783 dest = SLOT(socketlabel); 784 785 mac_mls_copy_single(source, dest); 786 mac_mls_copy_single_to_range(source, dest); 787} 788 789static void 790mac_mls_create_pipe(struct ucred *cred, struct pipe *pipe, 791 struct label *pipelabel) 792{ 793 struct mac_mls *source, *dest; 794 795 source = SLOT(&cred->cr_label); 796 dest = SLOT(pipelabel); 797 798 mac_mls_copy_single(source, dest); 799} 800 801static void 802mac_mls_create_socket_from_socket(struct socket *oldsocket, 803 struct label *oldsocketlabel, struct socket *newsocket, 804 struct label *newsocketlabel) 805{ 806 struct mac_mls *source, *dest; 807 808 source = SLOT(oldsocketlabel); 809 dest = SLOT(newsocketlabel); 810 811 mac_mls_copy_single(source, dest); 812 mac_mls_copy_range(source, dest); 813} 814 815static void 816mac_mls_relabel_socket(struct ucred *cred, struct socket *socket, 817 struct label *socketlabel, struct label *newlabel) 818{ 819 struct mac_mls *source, *dest; 820 821 source = SLOT(newlabel); 822 dest = SLOT(socketlabel); 823 824 mac_mls_copy_single(source, dest); 825 mac_mls_copy_range(source, dest); 826} 827 828static void 829mac_mls_relabel_pipe(struct ucred *cred, struct pipe *pipe, 830 struct label *pipelabel, struct label *newlabel) 831{ 832 struct mac_mls *source, *dest; 833 834 source = SLOT(newlabel); 835 dest = SLOT(pipelabel); 836 837 mac_mls_copy_single(source, dest); 838} 839 840static void 841mac_mls_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 842 struct socket *socket, struct label *socketpeerlabel) 843{ 844 struct mac_mls *source, *dest; 845 846 source = SLOT(mbuflabel); 847 dest = SLOT(socketpeerlabel); 848 849 mac_mls_copy_single(source, dest); 850} 851 852/* 853 * Labeling event operations: network objects. 854 */ 855static void 856mac_mls_set_socket_peer_from_socket(struct socket *oldsocket, 857 struct label *oldsocketlabel, struct socket *newsocket, 858 struct label *newsocketpeerlabel) 859{ 860 struct mac_mls *source, *dest; 861 862 source = SLOT(oldsocketlabel); 863 dest = SLOT(newsocketpeerlabel); 864 865 mac_mls_copy_single(source, dest); 866} 867 868static void 869mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 870 struct label *bpflabel) 871{ 872 struct mac_mls *source, *dest; 873 874 source = SLOT(&cred->cr_label); 875 dest = SLOT(bpflabel); 876 877 mac_mls_copy_single(source, dest); 878} 879 880static void 881mac_mls_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 882{ 883 struct mac_mls *dest; 884 int level; 885 886 dest = SLOT(ifnetlabel); 887 888 if (ifnet->if_type == IFT_LOOP) 889 level = MAC_MLS_TYPE_EQUAL; 890 else 891 level = MAC_MLS_TYPE_LOW; 892 893 mac_mls_set_single(dest, level, 0); 894 mac_mls_set_range(dest, level, 0, level, 0); 895} 896 897static void 898mac_mls_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 899 struct ipq *ipq, struct label *ipqlabel) 900{ 901 struct mac_mls *source, *dest; 902 903 source = SLOT(fragmentlabel); 904 dest = SLOT(ipqlabel); 905 906 mac_mls_copy_single(source, dest); 907} 908 909static void 910mac_mls_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 911 struct mbuf *datagram, struct label *datagramlabel) 912{ 913 struct mac_mls *source, *dest; 914 915 source = SLOT(ipqlabel); 916 dest = SLOT(datagramlabel); 917 918 /* Just use the head, since we require them all to match. */ 919 mac_mls_copy_single(source, dest); 920} 921 922static void 923mac_mls_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 924 struct mbuf *fragment, struct label *fragmentlabel) 925{ 926 struct mac_mls *source, *dest; 927 928 source = SLOT(datagramlabel); 929 dest = SLOT(fragmentlabel); 930 931 mac_mls_copy_single(source, dest); 932} 933 934static void 935mac_mls_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 936 struct label *oldmbuflabel, struct mbuf *newmbuf, 937 struct label *newmbuflabel) 938{ 939 struct mac_mls *source, *dest; 940 941 source = SLOT(oldmbuflabel); 942 dest = SLOT(newmbuflabel); 943 944 mac_mls_copy_single(source, dest); 945} 946 947static void 948mac_mls_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 949 struct mbuf *mbuf, struct label *mbuflabel) 950{ 951 struct mac_mls *dest; 952 953 dest = SLOT(mbuflabel); 954 955 mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0); 956} 957 958static void 959mac_mls_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 960 struct mbuf *mbuf, struct label *mbuflabel) 961{ 962 struct mac_mls *source, *dest; 963 964 source = SLOT(bpflabel); 965 dest = SLOT(mbuflabel); 966 967 mac_mls_copy_single(source, dest); 968} 969 970static void 971mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 972 struct mbuf *m, struct label *mbuflabel) 973{ 974 struct mac_mls *source, *dest; 975 976 source = SLOT(ifnetlabel); 977 dest = SLOT(mbuflabel); 978 979 mac_mls_copy_single(source, dest); 980} 981 982static void 983mac_mls_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 984 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 985 struct mbuf *newmbuf, struct label *newmbuflabel) 986{ 987 struct mac_mls *source, *dest; 988 989 source = SLOT(oldmbuflabel); 990 dest = SLOT(newmbuflabel); 991 992 mac_mls_copy_single(source, dest); 993} 994 995static void 996mac_mls_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 997 struct mbuf *newmbuf, struct label *newmbuflabel) 998{ 999 struct mac_mls *source, *dest; 1000 1001 source = SLOT(oldmbuflabel); 1002 dest = SLOT(newmbuflabel); 1003 1004 mac_mls_copy_single(source, dest); 1005} 1006 1007static int 1008mac_mls_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1009 struct ipq *ipq, struct label *ipqlabel) 1010{ 1011 struct mac_mls *a, *b; 1012 1013 a = SLOT(ipqlabel); 1014 b = SLOT(fragmentlabel); 1015 1016 return (mac_mls_equal_single(a, b)); 1017} 1018 1019static void 1020mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1021 struct label *ifnetlabel, struct label *newlabel) 1022{ 1023 struct mac_mls *source, *dest; 1024 1025 source = SLOT(newlabel); 1026 dest = SLOT(ifnetlabel); 1027 1028 mac_mls_copy_single(source, dest); 1029 mac_mls_copy_range(source, dest); 1030} 1031 1032static void 1033mac_mls_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1034 struct ipq *ipq, struct label *ipqlabel) 1035{ 1036 1037 /* NOOP: we only accept matching labels, so no need to update */ 1038} 1039 1040/* 1041 * Labeling event operations: processes. 1042 */ 1043static void 1044mac_mls_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1045{ 1046 struct mac_mls *source, *dest; 1047 1048 source = SLOT(&cred_parent->cr_label); 1049 dest = SLOT(&cred_child->cr_label); 1050 1051 mac_mls_copy_single(source, dest); 1052 mac_mls_copy_range(source, dest); 1053} 1054 1055static void 1056mac_mls_execve_transition(struct ucred *old, struct ucred *new, 1057 struct vnode *vp, struct mac *vnodelabel) 1058{ 1059 struct mac_mls *source, *dest; 1060 1061 source = SLOT(&old->cr_label); 1062 dest = SLOT(&new->cr_label); 1063 1064 mac_mls_copy_single(source, dest); 1065 mac_mls_copy_range(source, dest); 1066} 1067 1068static int 1069mac_mls_execve_will_transition(struct ucred *old, struct vnode *vp, 1070 struct mac *vnodelabel) 1071{ 1072 1073 return (0); 1074} 1075 1076static void 1077mac_mls_create_proc0(struct ucred *cred) 1078{ 1079 struct mac_mls *dest; 1080 1081 dest = SLOT(&cred->cr_label); 1082 1083 mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0); 1084 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, MAC_MLS_TYPE_HIGH, 0); 1085} 1086 1087static void 1088mac_mls_create_proc1(struct ucred *cred) 1089{ 1090 struct mac_mls *dest; 1091 1092 dest = SLOT(&cred->cr_label); 1093 1094 mac_mls_set_single(dest, MAC_MLS_TYPE_LOW, 0); 1095 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, MAC_MLS_TYPE_HIGH, 0); 1096} 1097 1098static void 1099mac_mls_relabel_cred(struct ucred *cred, struct label *newlabel) 1100{ 1101 struct mac_mls *source, *dest; 1102 1103 source = SLOT(newlabel); 1104 dest = SLOT(&cred->cr_label); 1105 1106 mac_mls_copy_single(source, dest); 1107 mac_mls_copy_range(source, dest); 1108} 1109 1110/* 1111 * Access control checks. 1112 */ 1113static int 1114mac_mls_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1115 struct ifnet *ifnet, struct label *ifnetlabel) 1116{ 1117 struct mac_mls *a, *b; 1118 1119 if (!mac_mls_enabled) 1120 return (0); 1121 1122 a = SLOT(bpflabel); 1123 b = SLOT(ifnetlabel); 1124 1125 if (mac_mls_equal_single(a, b)) 1126 return (0); 1127 return (EACCES); 1128} 1129 1130static int 1131mac_mls_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1132{ 1133 struct mac_mls *subj, *new; 1134 1135 subj = SLOT(&cred->cr_label); 1136 new = SLOT(newlabel); 1137 1138 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAGS_BOTH) 1139 return (EINVAL); 1140 1141 /* 1142 * XXX: Allow processes with root privilege to set labels outside 1143 * their range, so suid things like "su" work. This WILL go away 1144 * when we figure out the 'correct' solution... 1145 */ 1146 if (!suser_cred(cred, 0)) 1147 return (0); 1148 1149 /* 1150 * The new single must be in the old range. 1151 */ 1152 if (!mac_mls_single_in_range(new, subj)) 1153 return (EPERM); 1154 1155 /* 1156 * The new range must be in the old range. 1157 */ 1158 if (!mac_mls_range_in_range(new, subj)) 1159 return (EPERM); 1160 1161 /* 1162 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL. 1163 */ 1164 1165 return (0); 1166} 1167 1168 1169static int 1170mac_mls_check_cred_visible(struct ucred *u1, struct ucred *u2) 1171{ 1172 struct mac_mls *subj, *obj; 1173 1174 if (!mac_mls_enabled) 1175 return (0); 1176 1177 subj = SLOT(&u1->cr_label); 1178 obj = SLOT(&u2->cr_label); 1179 1180 /* XXX: range */ 1181 if (!mac_mls_dominate_single(subj, obj)) 1182 return (ESRCH); 1183 1184 return (0); 1185} 1186 1187static int 1188mac_mls_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1189 struct label *ifnetlabel, struct label *newlabel) 1190{ 1191 struct mac_mls *subj, *new; 1192 1193 subj = SLOT(&cred->cr_label); 1194 new = SLOT(newlabel); 1195 1196 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAGS_BOTH) 1197 return (EINVAL); 1198 1199 /* XXX: privilege model here? */ 1200 1201 return (suser_cred(cred, 0)); 1202} 1203 1204static int 1205mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1206 struct mbuf *m, struct label *mbuflabel) 1207{ 1208 struct mac_mls *p, *i; 1209 1210 if (!mac_mls_enabled) 1211 return (0); 1212 1213 p = SLOT(mbuflabel); 1214 i = SLOT(ifnetlabel); 1215 1216 return (mac_mls_single_in_range(p, i) ? 0 : EACCES); 1217} 1218 1219static int 1220mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp, 1221 struct label *mntlabel) 1222{ 1223 struct mac_mls *subj, *obj; 1224 1225 if (!mac_mls_enabled) 1226 return (0); 1227 1228 subj = SLOT(&cred->cr_label); 1229 obj = SLOT(mntlabel); 1230 1231 if (!mac_mls_dominate_single(subj, obj)) 1232 return (EACCES); 1233 1234 return (0); 1235} 1236 1237static int 1238mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1239 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1240{ 1241 1242 if(!mac_mls_enabled) 1243 return (0); 1244 1245 /* XXX: This will be implemented soon... */ 1246 1247 return (0); 1248} 1249 1250static int 1251mac_mls_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1252 struct label *pipelabel) 1253{ 1254 struct mac_mls *subj, *obj; 1255 1256 if (!mac_mls_enabled) 1257 return (0); 1258 1259 subj = SLOT(&cred->cr_label); 1260 obj = SLOT((pipelabel)); 1261 1262 if (!mac_mls_dominate_single(subj, obj)) 1263 return (EACCES); 1264 1265 return (0); 1266} 1267 1268static int 1269mac_mls_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1270 struct label *pipelabel) 1271{ 1272 struct mac_mls *subj, *obj; 1273 1274 if (!mac_mls_enabled) 1275 return (0); 1276 1277 subj = SLOT(&cred->cr_label); 1278 obj = SLOT((pipelabel)); 1279 1280 if (!mac_mls_dominate_single(subj, obj)) 1281 return (EACCES); 1282 1283 return (0); 1284} 1285 1286static int 1287mac_mls_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1288 struct label *pipelabel, struct label *newlabel) 1289{ 1290 struct mac_mls *subj, *obj, *new; 1291 1292 new = SLOT(newlabel); 1293 subj = SLOT(&cred->cr_label); 1294 obj = SLOT(pipelabel); 1295 1296 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) 1297 return (EINVAL); 1298 1299 /* 1300 * To relabel a pipe, the old pipe label must be in the subject 1301 * range. 1302 */ 1303 if (!mac_mls_single_in_range(obj, subj)) 1304 return (EPERM); 1305 1306 /* 1307 * To relabel a pipe, the new pipe label must be in the subject 1308 * range. 1309 */ 1310 if (!mac_mls_single_in_range(new, subj)) 1311 return (EPERM); 1312 1313 /* 1314 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL. 1315 */ 1316 1317 return (0); 1318} 1319 1320static int 1321mac_mls_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1322 struct label *pipelabel) 1323{ 1324 struct mac_mls *subj, *obj; 1325 1326 if (!mac_mls_enabled) 1327 return (0); 1328 1329 subj = SLOT(&cred->cr_label); 1330 obj = SLOT((pipelabel)); 1331 1332 if (!mac_mls_dominate_single(subj, obj)) 1333 return (EACCES); 1334 1335 return (0); 1336} 1337 1338static int 1339mac_mls_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1340 struct label *pipelabel) 1341{ 1342 struct mac_mls *subj, *obj; 1343 1344 if (!mac_mls_enabled) 1345 return (0); 1346 1347 subj = SLOT(&cred->cr_label); 1348 obj = SLOT((pipelabel)); 1349 1350 if (!mac_mls_dominate_single(obj, subj)) 1351 return (EACCES); 1352 1353 return (0); 1354} 1355 1356static int 1357mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc) 1358{ 1359 struct mac_mls *subj, *obj; 1360 1361 if (!mac_mls_enabled) 1362 return (0); 1363 1364 subj = SLOT(&cred->cr_label); 1365 obj = SLOT(&proc->p_ucred->cr_label); 1366 1367 /* XXX: range checks */ 1368 if (!mac_mls_dominate_single(subj, obj)) 1369 return (ESRCH); 1370 if (!mac_mls_dominate_single(obj, subj)) 1371 return (EACCES); 1372 1373 return (0); 1374} 1375 1376static int 1377mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc) 1378{ 1379 struct mac_mls *subj, *obj; 1380 1381 if (!mac_mls_enabled) 1382 return (0); 1383 1384 subj = SLOT(&cred->cr_label); 1385 obj = SLOT(&proc->p_ucred->cr_label); 1386 1387 /* XXX: range checks */ 1388 if (!mac_mls_dominate_single(subj, obj)) 1389 return (ESRCH); 1390 if (!mac_mls_dominate_single(obj, subj)) 1391 return (EACCES); 1392 1393 return (0); 1394} 1395 1396static int 1397mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1398{ 1399 struct mac_mls *subj, *obj; 1400 1401 if (!mac_mls_enabled) 1402 return (0); 1403 1404 subj = SLOT(&cred->cr_label); 1405 obj = SLOT(&proc->p_ucred->cr_label); 1406 1407 /* XXX: range checks */ 1408 if (!mac_mls_dominate_single(subj, obj)) 1409 return (ESRCH); 1410 if (!mac_mls_dominate_single(obj, subj)) 1411 return (EACCES); 1412 1413 return (0); 1414} 1415 1416static int 1417mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel, 1418 struct mbuf *m, struct label *mbuflabel) 1419{ 1420 struct mac_mls *p, *s; 1421 1422 if (!mac_mls_enabled) 1423 return (0); 1424 1425 p = SLOT(mbuflabel); 1426 s = SLOT(socketlabel); 1427 1428 return (mac_mls_equal_single(p, s) ? 0 : EACCES); 1429} 1430 1431static int 1432mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket, 1433 struct label *socketlabel, struct label *newlabel) 1434{ 1435 struct mac_mls *subj, *obj, *new; 1436 1437 new = SLOT(newlabel); 1438 subj = SLOT(&cred->cr_label); 1439 obj = SLOT(socketlabel); 1440 1441 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) 1442 return (EINVAL); 1443 1444 /* 1445 * To relabel a socket, the old socket label must be in the subject 1446 * range. 1447 */ 1448 if (!mac_mls_single_in_range(obj, subj)) 1449 return (EPERM); 1450 1451 /* 1452 * To relabel a socket, the new socket label must be in the subject 1453 * range. 1454 */ 1455 if (!mac_mls_single_in_range(new, subj)) 1456 return (EPERM); 1457 1458 /* 1459 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL. 1460 */ 1461 1462 return (0); 1463} 1464 1465static int 1466mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket, 1467 struct label *socketlabel) 1468{ 1469 struct mac_mls *subj, *obj; 1470 1471 if (!mac_mls_enabled) 1472 return (0); 1473 1474 subj = SLOT(&cred->cr_label); 1475 obj = SLOT(socketlabel); 1476 1477 if (!mac_mls_dominate_single(subj, obj)) 1478 return (ENOENT); 1479 1480 return (0); 1481} 1482 1483static int 1484mac_mls_check_vnode_access(struct ucred *cred, struct vnode *vp, 1485 struct label *label, mode_t flags) 1486{ 1487 1488 return (mac_mls_check_vnode_open(cred, vp, label, flags)); 1489} 1490 1491static int 1492mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1493 struct label *dlabel) 1494{ 1495 struct mac_mls *subj, *obj; 1496 1497 if (!mac_mls_enabled) 1498 return (0); 1499 1500 subj = SLOT(&cred->cr_label); 1501 obj = SLOT(dlabel); 1502 1503 if (!mac_mls_dominate_single(subj, obj)) 1504 return (EACCES); 1505 1506 return (0); 1507} 1508 1509static int 1510mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1511 struct label *dlabel) 1512{ 1513 struct mac_mls *subj, *obj; 1514 1515 if (!mac_mls_enabled) 1516 return (0); 1517 1518 subj = SLOT(&cred->cr_label); 1519 obj = SLOT(dlabel); 1520 1521 if (!mac_mls_dominate_single(subj, obj)) 1522 return (EACCES); 1523 1524 return (0); 1525} 1526 1527static int 1528mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1529 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1530{ 1531 struct mac_mls *subj, *obj; 1532 1533 if (!mac_mls_enabled) 1534 return (0); 1535 1536 subj = SLOT(&cred->cr_label); 1537 obj = SLOT(dlabel); 1538 1539 if (!mac_mls_dominate_single(obj, subj)) 1540 return (EACCES); 1541 1542 return (0); 1543} 1544 1545static int 1546mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1547 struct label *dlabel, struct vnode *vp, struct label *label, 1548 struct componentname *cnp) 1549{ 1550 struct mac_mls *subj, *obj; 1551 1552 if (!mac_mls_enabled) 1553 return (0); 1554 1555 subj = SLOT(&cred->cr_label); 1556 obj = SLOT(dlabel); 1557 1558 if (!mac_mls_dominate_single(obj, subj)) 1559 return (EACCES); 1560 1561 obj = SLOT(label); 1562 1563 if (!mac_mls_dominate_single(obj, subj)) 1564 return (EACCES); 1565 1566 return (0); 1567} 1568 1569static int 1570mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1571 struct label *label, acl_type_t type) 1572{ 1573 struct mac_mls *subj, *obj; 1574 1575 if (!mac_mls_enabled) 1576 return (0); 1577 1578 subj = SLOT(&cred->cr_label); 1579 obj = SLOT(label); 1580 1581 if (!mac_mls_dominate_single(obj, subj)) 1582 return (EACCES); 1583 1584 return (0); 1585} 1586 1587static int 1588mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1589 struct label *label) 1590{ 1591 struct mac_mls *subj, *obj; 1592 1593 if (!mac_mls_enabled) 1594 return (0); 1595 1596 subj = SLOT(&cred->cr_label); 1597 obj = SLOT(label); 1598 1599 if (!mac_mls_dominate_single(subj, obj)) 1600 return (EACCES); 1601 1602 return (0); 1603} 1604 1605static int 1606mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 1607 struct label *label, acl_type_t type) 1608{ 1609 struct mac_mls *subj, *obj; 1610 1611 if (!mac_mls_enabled) 1612 return (0); 1613 1614 subj = SLOT(&cred->cr_label); 1615 obj = SLOT(label); 1616 1617 if (!mac_mls_dominate_single(subj, obj)) 1618 return (EACCES); 1619 1620 return (0); 1621} 1622 1623static int 1624mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1625 struct label *label, int attrnamespace, const char *name, struct uio *uio) 1626{ 1627 struct mac_mls *subj, *obj; 1628 1629 if (!mac_mls_enabled) 1630 return (0); 1631 1632 subj = SLOT(&cred->cr_label); 1633 obj = SLOT(label); 1634 1635 if (!mac_mls_dominate_single(subj, obj)) 1636 return (EACCES); 1637 1638 return (0); 1639} 1640 1641static int 1642mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1643 struct label *dlabel, struct componentname *cnp) 1644{ 1645 struct mac_mls *subj, *obj; 1646 1647 if (!mac_mls_enabled) 1648 return (0); 1649 1650 subj = SLOT(&cred->cr_label); 1651 obj = SLOT(dlabel); 1652 1653 if (!mac_mls_dominate_single(subj, obj)) 1654 return (EACCES); 1655 1656 return (0); 1657} 1658 1659static int 1660mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, 1661 struct label *vnodelabel, mode_t acc_mode) 1662{ 1663 struct mac_mls *subj, *obj; 1664 1665 if (!mac_mls_enabled) 1666 return (0); 1667 1668 subj = SLOT(&cred->cr_label); 1669 obj = SLOT(vnodelabel); 1670 1671 /* XXX privilege override for admin? */ 1672 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 1673 if (!mac_mls_dominate_single(subj, obj)) 1674 return (EACCES); 1675 } 1676 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 1677 if (!mac_mls_dominate_single(obj, subj)) 1678 return (EACCES); 1679 } 1680 1681 return (0); 1682} 1683 1684static int 1685mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1686 struct vnode *vp, struct label *label) 1687{ 1688 struct mac_mls *subj, *obj; 1689 1690 if (!mac_mls_enabled || !mac_mls_revocation_enabled) 1691 return (0); 1692 1693 subj = SLOT(&active_cred->cr_label); 1694 obj = SLOT(label); 1695 1696 if (!mac_mls_dominate_single(subj, obj)) 1697 return (EACCES); 1698 1699 return (0); 1700} 1701 1702static int 1703mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1704 struct vnode *vp, struct label *label) 1705{ 1706 struct mac_mls *subj, *obj; 1707 1708 if (!mac_mls_enabled || !mac_mls_revocation_enabled) 1709 return (0); 1710 1711 subj = SLOT(&active_cred->cr_label); 1712 obj = SLOT(label); 1713 1714 if (!mac_mls_dominate_single(subj, obj)) 1715 return (EACCES); 1716 1717 return (0); 1718} 1719 1720static int 1721mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 1722 struct label *dlabel) 1723{ 1724 struct mac_mls *subj, *obj; 1725 1726 if (!mac_mls_enabled) 1727 return (0); 1728 1729 subj = SLOT(&cred->cr_label); 1730 obj = SLOT(dlabel); 1731 1732 if (!mac_mls_dominate_single(subj, obj)) 1733 return (EACCES); 1734 1735 return (0); 1736} 1737 1738static int 1739mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 1740 struct label *vnodelabel) 1741{ 1742 struct mac_mls *subj, *obj; 1743 1744 if (!mac_mls_enabled) 1745 return (0); 1746 1747 subj = SLOT(&cred->cr_label); 1748 obj = SLOT(vnodelabel); 1749 1750 if (!mac_mls_dominate_single(subj, obj)) 1751 return (EACCES); 1752 1753 return (0); 1754} 1755 1756static int 1757mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1758 struct label *vnodelabel, struct label *newlabel) 1759{ 1760 struct mac_mls *old, *new, *subj; 1761 1762 old = SLOT(vnodelabel); 1763 new = SLOT(newlabel); 1764 subj = SLOT(&cred->cr_label); 1765 1766 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) 1767 return (EINVAL); 1768 1769 /* 1770 * To relabel a vnode, the old vnode label must be in the subject 1771 * range. 1772 */ 1773 if (!mac_mls_single_in_range(old, subj)) 1774 return (EPERM); 1775 1776 /* 1777 * To relabel a vnode, the new vnode label must be in the subject 1778 * range. 1779 */ 1780 if (!mac_mls_single_in_range(new, subj)) 1781 return (EPERM); 1782 1783 /* 1784 * XXX: Don't permit EQUAL in a label unless the subject has EQUAL. 1785 */ 1786 1787 return (suser_cred(cred, 0)); 1788} 1789 1790 1791static int 1792mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1793 struct label *dlabel, struct vnode *vp, struct label *label, 1794 struct componentname *cnp) 1795{ 1796 struct mac_mls *subj, *obj; 1797 1798 if (!mac_mls_enabled) 1799 return (0); 1800 1801 subj = SLOT(&cred->cr_label); 1802 obj = SLOT(dlabel); 1803 1804 if (!mac_mls_dominate_single(obj, subj)) 1805 return (EACCES); 1806 1807 obj = SLOT(label); 1808 1809 if (!mac_mls_dominate_single(obj, subj)) 1810 return (EACCES); 1811 1812 return (0); 1813} 1814 1815static int 1816mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1817 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 1818 struct componentname *cnp) 1819{ 1820 struct mac_mls *subj, *obj; 1821 1822 if (!mac_mls_enabled) 1823 return (0); 1824 1825 subj = SLOT(&cred->cr_label); 1826 obj = SLOT(dlabel); 1827 1828 if (!mac_mls_dominate_single(obj, subj)) 1829 return (EACCES); 1830 1831 if (vp != NULL) { 1832 obj = SLOT(label); 1833 1834 if (!mac_mls_dominate_single(obj, subj)) 1835 return (EACCES); 1836 } 1837 1838 return (0); 1839} 1840 1841static int 1842mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 1843 struct label *label) 1844{ 1845 struct mac_mls *subj, *obj; 1846 1847 if (!mac_mls_enabled) 1848 return (0); 1849 1850 subj = SLOT(&cred->cr_label); 1851 obj = SLOT(label); 1852 1853 if (!mac_mls_dominate_single(obj, subj)) 1854 return (EACCES); 1855 1856 return (0); 1857} 1858 1859static int 1860mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 1861 struct label *label, acl_type_t type, struct acl *acl) 1862{ 1863 struct mac_mls *subj, *obj; 1864 1865 if (!mac_mls_enabled) 1866 return (0); 1867 1868 subj = SLOT(&cred->cr_label); 1869 obj = SLOT(label); 1870 1871 if (!mac_mls_dominate_single(obj, subj)) 1872 return (EACCES); 1873 1874 return (0); 1875} 1876 1877static int 1878mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1879 struct label *vnodelabel, int attrnamespace, const char *name, 1880 struct uio *uio) 1881{ 1882 struct mac_mls *subj, *obj; 1883 1884 if (!mac_mls_enabled) 1885 return (0); 1886 1887 subj = SLOT(&cred->cr_label); 1888 obj = SLOT(vnodelabel); 1889 1890 if (!mac_mls_dominate_single(obj, subj)) 1891 return (EACCES); 1892 1893 /* XXX: protect the MAC EA in a special way? */ 1894 1895 return (0); 1896} 1897 1898static int 1899mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 1900 struct label *vnodelabel, u_long flags) 1901{ 1902 struct mac_mls *subj, *obj; 1903 1904 if (!mac_mls_enabled) 1905 return (0); 1906 1907 subj = SLOT(&cred->cr_label); 1908 obj = SLOT(vnodelabel); 1909 1910 if (!mac_mls_dominate_single(obj, subj)) 1911 return (EACCES); 1912 1913 return (0); 1914} 1915 1916static int 1917mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 1918 struct label *vnodelabel, mode_t mode) 1919{ 1920 struct mac_mls *subj, *obj; 1921 1922 if (!mac_mls_enabled) 1923 return (0); 1924 1925 subj = SLOT(&cred->cr_label); 1926 obj = SLOT(vnodelabel); 1927 1928 if (!mac_mls_dominate_single(obj, subj)) 1929 return (EACCES); 1930 1931 return (0); 1932} 1933 1934static int 1935mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 1936 struct label *vnodelabel, uid_t uid, gid_t gid) 1937{ 1938 struct mac_mls *subj, *obj; 1939 1940 if (!mac_mls_enabled) 1941 return (0); 1942 1943 subj = SLOT(&cred->cr_label); 1944 obj = SLOT(vnodelabel); 1945 1946 if (!mac_mls_dominate_single(obj, subj)) 1947 return (EACCES); 1948 1949 return (0); 1950} 1951 1952static int 1953mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1954 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 1955{ 1956 struct mac_mls *subj, *obj; 1957 1958 if (!mac_mls_enabled) 1959 return (0); 1960 1961 subj = SLOT(&cred->cr_label); 1962 obj = SLOT(vnodelabel); 1963 1964 if (!mac_mls_dominate_single(obj, subj)) 1965 return (EACCES); 1966 1967 return (0); 1968} 1969 1970static int 1971mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1972 struct vnode *vp, struct label *vnodelabel) 1973{ 1974 struct mac_mls *subj, *obj; 1975 1976 if (!mac_mls_enabled) 1977 return (0); 1978 1979 subj = SLOT(&active_cred->cr_label); 1980 obj = SLOT(vnodelabel); 1981 1982 if (!mac_mls_dominate_single(subj, obj)) 1983 return (EACCES); 1984 1985 return (0); 1986} 1987 1988static int 1989mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1990 struct vnode *vp, struct label *label) 1991{ 1992 struct mac_mls *subj, *obj; 1993 1994 if (!mac_mls_enabled || !mac_mls_revocation_enabled) 1995 return (0); 1996 1997 subj = SLOT(&active_cred->cr_label); 1998 obj = SLOT(label); 1999 2000 if (!mac_mls_dominate_single(obj, subj)) 2001 return (EACCES); 2002 2003 return (0); 2004} 2005 2006static vm_prot_t 2007mac_mls_check_vnode_mmap_perms(struct ucred *cred, struct vnode *vp, 2008 struct label *label, int newmapping) 2009{ 2010 struct mac_mls *subj, *obj; 2011 vm_prot_t prot = 0; 2012 2013 if (!mac_mls_enabled || (!mac_mls_revocation_enabled && !newmapping)) 2014 return (VM_PROT_ALL); 2015 2016 subj = SLOT(&cred->cr_label); 2017 obj = SLOT(label); 2018 2019 if (mac_mls_dominate_single(subj, obj)) 2020 prot |= VM_PROT_READ | VM_PROT_EXECUTE; 2021 if (mac_mls_dominate_single(obj, subj)) 2022 prot |= VM_PROT_WRITE; 2023 return (prot); 2024} 2025 2026static struct mac_policy_op_entry mac_mls_ops[] = 2027{ 2028 { MAC_DESTROY, 2029 (macop_t)mac_mls_destroy }, 2030 { MAC_INIT, 2031 (macop_t)mac_mls_init }, 2032 { MAC_INIT_BPFDESC, 2033 (macop_t)mac_mls_init_bpfdesc }, 2034 { MAC_INIT_CRED, 2035 (macop_t)mac_mls_init_cred }, 2036 { MAC_INIT_DEVFSDIRENT, 2037 (macop_t)mac_mls_init_devfsdirent }, 2038 { MAC_INIT_IFNET, 2039 (macop_t)mac_mls_init_ifnet }, 2040 { MAC_INIT_IPQ, 2041 (macop_t)mac_mls_init_ipq }, 2042 { MAC_INIT_MBUF, 2043 (macop_t)mac_mls_init_mbuf }, 2044 { MAC_INIT_MOUNT, 2045 (macop_t)mac_mls_init_mount }, 2046 { MAC_INIT_PIPE, 2047 (macop_t)mac_mls_init_pipe }, 2048 { MAC_INIT_SOCKET, 2049 (macop_t)mac_mls_init_socket }, 2050 { MAC_INIT_TEMP, 2051 (macop_t)mac_mls_init_temp }, 2052 { MAC_INIT_VNODE, 2053 (macop_t)mac_mls_init_vnode }, 2054 { MAC_DESTROY_BPFDESC, 2055 (macop_t)mac_mls_destroy_bpfdesc }, 2056 { MAC_DESTROY_CRED, 2057 (macop_t)mac_mls_destroy_cred }, 2058 { MAC_DESTROY_DEVFSDIRENT, 2059 (macop_t)mac_mls_destroy_devfsdirent }, 2060 { MAC_DESTROY_IFNET, 2061 (macop_t)mac_mls_destroy_ifnet }, 2062 { MAC_DESTROY_IPQ, 2063 (macop_t)mac_mls_destroy_ipq }, 2064 { MAC_DESTROY_MBUF, 2065 (macop_t)mac_mls_destroy_mbuf }, 2066 { MAC_DESTROY_MOUNT, 2067 (macop_t)mac_mls_destroy_mount }, 2068 { MAC_DESTROY_PIPE, 2069 (macop_t)mac_mls_destroy_pipe }, 2070 { MAC_DESTROY_SOCKET, 2071 (macop_t)mac_mls_destroy_socket }, 2072 { MAC_DESTROY_TEMP, 2073 (macop_t)mac_mls_destroy_temp }, 2074 { MAC_DESTROY_VNODE, 2075 (macop_t)mac_mls_destroy_vnode }, 2076 { MAC_EXTERNALIZE, 2077 (macop_t)mac_mls_externalize }, 2078 { MAC_INTERNALIZE, 2079 (macop_t)mac_mls_internalize }, 2080 { MAC_CREATE_DEVFS_DEVICE, 2081 (macop_t)mac_mls_create_devfs_device }, 2082 { MAC_CREATE_DEVFS_DIRECTORY, 2083 (macop_t)mac_mls_create_devfs_directory }, 2084 { MAC_CREATE_DEVFS_VNODE, 2085 (macop_t)mac_mls_create_devfs_vnode }, 2086 { MAC_CREATE_VNODE, 2087 (macop_t)mac_mls_create_vnode }, 2088 { MAC_CREATE_MOUNT, 2089 (macop_t)mac_mls_create_mount }, 2090 { MAC_CREATE_ROOT_MOUNT, 2091 (macop_t)mac_mls_create_root_mount }, 2092 { MAC_RELABEL_VNODE, 2093 (macop_t)mac_mls_relabel_vnode }, 2094 { MAC_UPDATE_DEVFSDIRENT, 2095 (macop_t)mac_mls_update_devfsdirent }, 2096 { MAC_UPDATE_PROCFSVNODE, 2097 (macop_t)mac_mls_update_procfsvnode }, 2098 { MAC_UPDATE_VNODE_FROM_EXTERNALIZED, 2099 (macop_t)mac_mls_update_vnode_from_externalized }, 2100 { MAC_UPDATE_VNODE_FROM_MOUNT, 2101 (macop_t)mac_mls_update_vnode_from_mount }, 2102 { MAC_CREATE_MBUF_FROM_SOCKET, 2103 (macop_t)mac_mls_create_mbuf_from_socket }, 2104 { MAC_CREATE_PIPE, 2105 (macop_t)mac_mls_create_pipe }, 2106 { MAC_CREATE_SOCKET, 2107 (macop_t)mac_mls_create_socket }, 2108 { MAC_CREATE_SOCKET_FROM_SOCKET, 2109 (macop_t)mac_mls_create_socket_from_socket }, 2110 { MAC_RELABEL_PIPE, 2111 (macop_t)mac_mls_relabel_pipe }, 2112 { MAC_RELABEL_SOCKET, 2113 (macop_t)mac_mls_relabel_socket }, 2114 { MAC_SET_SOCKET_PEER_FROM_MBUF, 2115 (macop_t)mac_mls_set_socket_peer_from_mbuf }, 2116 { MAC_SET_SOCKET_PEER_FROM_SOCKET, 2117 (macop_t)mac_mls_set_socket_peer_from_socket }, 2118 { MAC_CREATE_BPFDESC, 2119 (macop_t)mac_mls_create_bpfdesc }, 2120 { MAC_CREATE_DATAGRAM_FROM_IPQ, 2121 (macop_t)mac_mls_create_datagram_from_ipq }, 2122 { MAC_CREATE_FRAGMENT, 2123 (macop_t)mac_mls_create_fragment }, 2124 { MAC_CREATE_IFNET, 2125 (macop_t)mac_mls_create_ifnet }, 2126 { MAC_CREATE_IPQ, 2127 (macop_t)mac_mls_create_ipq }, 2128 { MAC_CREATE_MBUF_FROM_MBUF, 2129 (macop_t)mac_mls_create_mbuf_from_mbuf }, 2130 { MAC_CREATE_MBUF_LINKLAYER, 2131 (macop_t)mac_mls_create_mbuf_linklayer }, 2132 { MAC_CREATE_MBUF_FROM_BPFDESC, 2133 (macop_t)mac_mls_create_mbuf_from_bpfdesc }, 2134 { MAC_CREATE_MBUF_FROM_IFNET, 2135 (macop_t)mac_mls_create_mbuf_from_ifnet }, 2136 { MAC_CREATE_MBUF_MULTICAST_ENCAP, 2137 (macop_t)mac_mls_create_mbuf_multicast_encap }, 2138 { MAC_CREATE_MBUF_NETLAYER, 2139 (macop_t)mac_mls_create_mbuf_netlayer }, 2140 { MAC_FRAGMENT_MATCH, 2141 (macop_t)mac_mls_fragment_match }, 2142 { MAC_RELABEL_IFNET, 2143 (macop_t)mac_mls_relabel_ifnet }, 2144 { MAC_UPDATE_IPQ, 2145 (macop_t)mac_mls_update_ipq }, 2146 { MAC_CREATE_CRED, 2147 (macop_t)mac_mls_create_cred }, 2148 { MAC_EXECVE_TRANSITION, 2149 (macop_t)mac_mls_execve_transition }, 2150 { MAC_EXECVE_WILL_TRANSITION, 2151 (macop_t)mac_mls_execve_will_transition }, 2152 { MAC_CREATE_PROC0, 2153 (macop_t)mac_mls_create_proc0 }, 2154 { MAC_CREATE_PROC1, 2155 (macop_t)mac_mls_create_proc1 }, 2156 { MAC_RELABEL_CRED, 2157 (macop_t)mac_mls_relabel_cred }, 2158 { MAC_CHECK_BPFDESC_RECEIVE, 2159 (macop_t)mac_mls_check_bpfdesc_receive }, 2160 { MAC_CHECK_CRED_RELABEL, 2161 (macop_t)mac_mls_check_cred_relabel }, 2162 { MAC_CHECK_CRED_VISIBLE, 2163 (macop_t)mac_mls_check_cred_visible }, 2164 { MAC_CHECK_IFNET_RELABEL, 2165 (macop_t)mac_mls_check_ifnet_relabel }, 2166 { MAC_CHECK_IFNET_TRANSMIT, 2167 (macop_t)mac_mls_check_ifnet_transmit }, 2168 { MAC_CHECK_MOUNT_STAT, 2169 (macop_t)mac_mls_check_mount_stat }, 2170 { MAC_CHECK_PIPE_IOCTL, 2171 (macop_t)mac_mls_check_pipe_ioctl }, 2172 { MAC_CHECK_PIPE_POLL, 2173 (macop_t)mac_mls_check_pipe_poll }, 2174 { MAC_CHECK_PIPE_READ, 2175 (macop_t)mac_mls_check_pipe_read }, 2176 { MAC_CHECK_PIPE_RELABEL, 2177 (macop_t)mac_mls_check_pipe_relabel }, 2178 { MAC_CHECK_PIPE_STAT, 2179 (macop_t)mac_mls_check_pipe_stat }, 2180 { MAC_CHECK_PIPE_WRITE, 2181 (macop_t)mac_mls_check_pipe_write }, 2182 { MAC_CHECK_PROC_DEBUG, 2183 (macop_t)mac_mls_check_proc_debug }, 2184 { MAC_CHECK_PROC_SCHED, 2185 (macop_t)mac_mls_check_proc_sched }, 2186 { MAC_CHECK_PROC_SIGNAL, 2187 (macop_t)mac_mls_check_proc_signal }, 2188 { MAC_CHECK_SOCKET_DELIVER, 2189 (macop_t)mac_mls_check_socket_deliver }, 2190 { MAC_CHECK_SOCKET_RELABEL, 2191 (macop_t)mac_mls_check_socket_relabel }, 2192 { MAC_CHECK_SOCKET_VISIBLE, 2193 (macop_t)mac_mls_check_socket_visible }, 2194 { MAC_CHECK_VNODE_ACCESS, 2195 (macop_t)mac_mls_check_vnode_access }, 2196 { MAC_CHECK_VNODE_CHDIR, 2197 (macop_t)mac_mls_check_vnode_chdir }, 2198 { MAC_CHECK_VNODE_CHROOT, 2199 (macop_t)mac_mls_check_vnode_chroot }, 2200 { MAC_CHECK_VNODE_CREATE, 2201 (macop_t)mac_mls_check_vnode_create }, 2202 { MAC_CHECK_VNODE_DELETE, 2203 (macop_t)mac_mls_check_vnode_delete }, 2204 { MAC_CHECK_VNODE_DELETEACL, 2205 (macop_t)mac_mls_check_vnode_deleteacl }, 2206 { MAC_CHECK_VNODE_EXEC, 2207 (macop_t)mac_mls_check_vnode_exec }, 2208 { MAC_CHECK_VNODE_GETACL, 2209 (macop_t)mac_mls_check_vnode_getacl }, 2210 { MAC_CHECK_VNODE_GETEXTATTR, 2211 (macop_t)mac_mls_check_vnode_getextattr }, 2212 { MAC_CHECK_VNODE_LOOKUP, 2213 (macop_t)mac_mls_check_vnode_lookup }, 2214 { MAC_CHECK_VNODE_OPEN, 2215 (macop_t)mac_mls_check_vnode_open }, 2216 { MAC_CHECK_VNODE_POLL, 2217 (macop_t)mac_mls_check_vnode_poll }, 2218 { MAC_CHECK_VNODE_READ, 2219 (macop_t)mac_mls_check_vnode_read }, 2220 { MAC_CHECK_VNODE_READDIR, 2221 (macop_t)mac_mls_check_vnode_readdir }, 2222 { MAC_CHECK_VNODE_READLINK, 2223 (macop_t)mac_mls_check_vnode_readlink }, 2224 { MAC_CHECK_VNODE_RELABEL, 2225 (macop_t)mac_mls_check_vnode_relabel }, 2226 { MAC_CHECK_VNODE_RENAME_FROM, 2227 (macop_t)mac_mls_check_vnode_rename_from }, 2228 { MAC_CHECK_VNODE_RENAME_TO, 2229 (macop_t)mac_mls_check_vnode_rename_to }, 2230 { MAC_CHECK_VNODE_REVOKE, 2231 (macop_t)mac_mls_check_vnode_revoke }, 2232 { MAC_CHECK_VNODE_SETACL, 2233 (macop_t)mac_mls_check_vnode_setacl }, 2234 { MAC_CHECK_VNODE_SETEXTATTR, 2235 (macop_t)mac_mls_check_vnode_setextattr }, 2236 { MAC_CHECK_VNODE_SETFLAGS, 2237 (macop_t)mac_mls_check_vnode_setflags }, 2238 { MAC_CHECK_VNODE_SETMODE, 2239 (macop_t)mac_mls_check_vnode_setmode }, 2240 { MAC_CHECK_VNODE_SETOWNER, 2241 (macop_t)mac_mls_check_vnode_setowner }, 2242 { MAC_CHECK_VNODE_SETUTIMES, 2243 (macop_t)mac_mls_check_vnode_setutimes }, 2244 { MAC_CHECK_VNODE_STAT, 2245 (macop_t)mac_mls_check_vnode_stat }, 2246 { MAC_CHECK_VNODE_WRITE, 2247 (macop_t)mac_mls_check_vnode_write }, 2248 { MAC_CHECK_VNODE_MMAP_PERMS, 2249 (macop_t)mac_mls_check_vnode_mmap_perms }, 2250 { MAC_OP_LAST, NULL } 2251}; 2252 2253MAC_POLICY_SET(mac_mls_ops, trustedbsd_mac_mls, "TrustedBSD MAC/MLS", 2254 MPC_LOADTIME_FLAG_NOTLATE, &mac_mls_slot);
|