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