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);
|