35 */ 36 37/* 38 * Developed by the TrustedBSD Project. 39 * MLS fixed label mandatory confidentiality policy. 40 */ 41 42#include <sys/types.h> 43#include <sys/param.h> 44#include <sys/acl.h> 45#include <sys/conf.h> 46#include <sys/extattr.h> 47#include <sys/kernel.h> 48#include <sys/mac.h> 49#include <sys/mman.h> 50#include <sys/malloc.h> 51#include <sys/mount.h> 52#include <sys/proc.h> 53#include <sys/sbuf.h> 54#include <sys/systm.h> 55#include <sys/sysproto.h> 56#include <sys/sysent.h> 57#include <sys/systm.h> 58#include <sys/vnode.h> 59#include <sys/file.h> 60#include <sys/socket.h> 61#include <sys/socketvar.h> 62#include <sys/pipe.h> 63#include <sys/sx.h> 64#include <sys/sysctl.h> 65#include <sys/msg.h> 66#include <sys/sem.h> 67#include <sys/shm.h> 68 69#include <posix4/ksem.h> 70 71#include <fs/devfs/devfs.h> 72 73#include <net/bpfdesc.h> 74#include <net/if.h> 75#include <net/if_types.h> 76#include <net/if_var.h> 77 78#include <netinet/in.h> 79#include <netinet/in_pcb.h> 80#include <netinet/ip_var.h> 81 82#include <vm/uma.h> 83#include <vm/vm.h> 84 85#include <sys/mac_policy.h> 86 87#include <security/mac_mls/mac_mls.h> 88 89SYSCTL_DECL(_security_mac); 90 91SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0, 92 "TrustedBSD mac_mls policy controls"); 93 94static int mac_mls_label_size = sizeof(struct mac_mls); 95SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD, 96 &mac_mls_label_size, 0, "Size of struct mac_mls"); 97 98static int mac_mls_enabled = 1; 99SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW, 100 &mac_mls_enabled, 0, "Enforce MAC/MLS policy"); 101TUNABLE_INT("security.mac.mls.enabled", &mac_mls_enabled); 102 103static int destroyed_not_inited; 104SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 105 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 106 107static int ptys_equal = 0; 108SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW, 109 &ptys_equal, 0, "Label pty devices as mls/equal on create"); 110TUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal); 111 112static int revocation_enabled = 0; 113SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, 114 &revocation_enabled, 0, "Revoke access to objects on relabel"); 115TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled); 116 117static int max_compartments = MAC_MLS_MAX_COMPARTMENTS; 118SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD, 119 &max_compartments, 0, "Maximum compartments the policy supports"); 120 121static int mac_mls_slot; 122#define SLOT(l) ((struct mac_mls *)LABEL_TO_SLOT((l), mac_mls_slot).l_ptr) 123#define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_mls_slot).l_ptr = (val)) 124 125static uma_zone_t zone_mls; 126 127static __inline int 128mls_bit_set_empty(u_char *set) { 129 int i; 130 131 for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++) 132 if (set[i] != 0) 133 return (0); 134 return (1); 135} 136 137static struct mac_mls * 138mls_alloc(int flag) 139{ 140 141 return (uma_zalloc(zone_mls, flag | M_ZERO)); 142} 143 144static void 145mls_free(struct mac_mls *mac_mls) 146{ 147 148 if (mac_mls != NULL) 149 uma_zfree(zone_mls, mac_mls); 150 else 151 atomic_add_int(&destroyed_not_inited, 1); 152} 153 154static int 155mls_atmostflags(struct mac_mls *mac_mls, int flags) 156{ 157 158 if ((mac_mls->mm_flags & flags) != mac_mls->mm_flags) 159 return (EINVAL); 160 return (0); 161} 162 163static int 164mac_mls_dominate_element(struct mac_mls_element *a, 165 struct mac_mls_element *b) 166{ 167 int bit; 168 169 switch (a->mme_type) { 170 case MAC_MLS_TYPE_EQUAL: 171 case MAC_MLS_TYPE_HIGH: 172 return (1); 173 174 case MAC_MLS_TYPE_LOW: 175 switch (b->mme_type) { 176 case MAC_MLS_TYPE_LEVEL: 177 case MAC_MLS_TYPE_HIGH: 178 return (0); 179 180 case MAC_MLS_TYPE_EQUAL: 181 case MAC_MLS_TYPE_LOW: 182 return (1); 183 184 default: 185 panic("mac_mls_dominate_element: b->mme_type invalid"); 186 } 187 188 case MAC_MLS_TYPE_LEVEL: 189 switch (b->mme_type) { 190 case MAC_MLS_TYPE_EQUAL: 191 case MAC_MLS_TYPE_LOW: 192 return (1); 193 194 case MAC_MLS_TYPE_HIGH: 195 return (0); 196 197 case MAC_MLS_TYPE_LEVEL: 198 for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) 199 if (!MAC_MLS_BIT_TEST(bit, 200 a->mme_compartments) && 201 MAC_MLS_BIT_TEST(bit, b->mme_compartments)) 202 return (0); 203 return (a->mme_level >= b->mme_level); 204 205 default: 206 panic("mac_mls_dominate_element: b->mme_type invalid"); 207 } 208 209 default: 210 panic("mac_mls_dominate_element: a->mme_type invalid"); 211 } 212 213 return (0); 214} 215 216static int 217mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) 218{ 219 220 return (mac_mls_dominate_element(&rangeb->mm_rangehigh, 221 &rangea->mm_rangehigh) && 222 mac_mls_dominate_element(&rangea->mm_rangelow, 223 &rangeb->mm_rangelow)); 224} 225 226static int 227mac_mls_effective_in_range(struct mac_mls *effective, struct mac_mls *range) 228{ 229 230 KASSERT((effective->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 231 ("mac_mls_effective_in_range: a not effective")); 232 KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 233 ("mac_mls_effective_in_range: b not range")); 234 235 return (mac_mls_dominate_element(&range->mm_rangehigh, 236 &effective->mm_effective) && 237 mac_mls_dominate_element(&effective->mm_effective, 238 &range->mm_rangelow)); 239 240 return (1); 241} 242 243static int 244mac_mls_dominate_effective(struct mac_mls *a, struct mac_mls *b) 245{ 246 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 247 ("mac_mls_dominate_effective: a not effective")); 248 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 249 ("mac_mls_dominate_effective: b not effective")); 250 251 return (mac_mls_dominate_element(&a->mm_effective, &b->mm_effective)); 252} 253 254static int 255mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) 256{ 257 258 if (a->mme_type == MAC_MLS_TYPE_EQUAL || 259 b->mme_type == MAC_MLS_TYPE_EQUAL) 260 return (1); 261 262 return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); 263} 264 265static int 266mac_mls_equal_effective(struct mac_mls *a, struct mac_mls *b) 267{ 268 269 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 270 ("mac_mls_equal_effective: a not effective")); 271 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 272 ("mac_mls_equal_effective: b not effective")); 273 274 return (mac_mls_equal_element(&a->mm_effective, &b->mm_effective)); 275} 276 277static int 278mac_mls_contains_equal(struct mac_mls *mac_mls) 279{ 280 281 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 282 if (mac_mls->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 283 return (1); 284 285 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 286 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL) 287 return (1); 288 if (mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 289 return (1); 290 } 291 292 return (0); 293} 294 295static int 296mac_mls_subject_privileged(struct mac_mls *mac_mls) 297{ 298 299 KASSERT((mac_mls->mm_flags & MAC_MLS_FLAGS_BOTH) == 300 MAC_MLS_FLAGS_BOTH, 301 ("mac_mls_subject_privileged: subject doesn't have both labels")); 302 303 /* If the effective is EQUAL, it's ok. */ 304 if (mac_mls->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 305 return (0); 306 307 /* If either range endpoint is EQUAL, it's ok. */ 308 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL || 309 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 310 return (0); 311 312 /* If the range is low-high, it's ok. */ 313 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW && 314 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH) 315 return (0); 316 317 /* It's not ok. */ 318 return (EPERM); 319} 320 321static int 322mac_mls_valid(struct mac_mls *mac_mls) 323{ 324 325 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 326 switch (mac_mls->mm_effective.mme_type) { 327 case MAC_MLS_TYPE_LEVEL: 328 break; 329 330 case MAC_MLS_TYPE_EQUAL: 331 case MAC_MLS_TYPE_HIGH: 332 case MAC_MLS_TYPE_LOW: 333 if (mac_mls->mm_effective.mme_level != 0 || 334 !MAC_MLS_BIT_SET_EMPTY( 335 mac_mls->mm_effective.mme_compartments)) 336 return (EINVAL); 337 break; 338 339 default: 340 return (EINVAL); 341 } 342 } else { 343 if (mac_mls->mm_effective.mme_type != MAC_MLS_TYPE_UNDEF) 344 return (EINVAL); 345 } 346 347 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 348 switch (mac_mls->mm_rangelow.mme_type) { 349 case MAC_MLS_TYPE_LEVEL: 350 break; 351 352 case MAC_MLS_TYPE_EQUAL: 353 case MAC_MLS_TYPE_HIGH: 354 case MAC_MLS_TYPE_LOW: 355 if (mac_mls->mm_rangelow.mme_level != 0 || 356 !MAC_MLS_BIT_SET_EMPTY( 357 mac_mls->mm_rangelow.mme_compartments)) 358 return (EINVAL); 359 break; 360 361 default: 362 return (EINVAL); 363 } 364 365 switch (mac_mls->mm_rangehigh.mme_type) { 366 case MAC_MLS_TYPE_LEVEL: 367 break; 368 369 case MAC_MLS_TYPE_EQUAL: 370 case MAC_MLS_TYPE_HIGH: 371 case MAC_MLS_TYPE_LOW: 372 if (mac_mls->mm_rangehigh.mme_level != 0 || 373 !MAC_MLS_BIT_SET_EMPTY( 374 mac_mls->mm_rangehigh.mme_compartments)) 375 return (EINVAL); 376 break; 377 378 default: 379 return (EINVAL); 380 } 381 if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh, 382 &mac_mls->mm_rangelow)) 383 return (EINVAL); 384 } else { 385 if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || 386 mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) 387 return (EINVAL); 388 } 389 390 return (0); 391} 392 393static void 394mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow, 395 u_short levellow, u_char *compartmentslow, u_short typehigh, 396 u_short levelhigh, u_char *compartmentshigh) 397{ 398 399 mac_mls->mm_rangelow.mme_type = typelow; 400 mac_mls->mm_rangelow.mme_level = levellow; 401 if (compartmentslow != NULL) 402 memcpy(mac_mls->mm_rangelow.mme_compartments, 403 compartmentslow, 404 sizeof(mac_mls->mm_rangelow.mme_compartments)); 405 mac_mls->mm_rangehigh.mme_type = typehigh; 406 mac_mls->mm_rangehigh.mme_level = levelhigh; 407 if (compartmentshigh != NULL) 408 memcpy(mac_mls->mm_rangehigh.mme_compartments, 409 compartmentshigh, 410 sizeof(mac_mls->mm_rangehigh.mme_compartments)); 411 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 412} 413 414static void 415mac_mls_set_effective(struct mac_mls *mac_mls, u_short type, u_short level, 416 u_char *compartments) 417{ 418 419 mac_mls->mm_effective.mme_type = type; 420 mac_mls->mm_effective.mme_level = level; 421 if (compartments != NULL) 422 memcpy(mac_mls->mm_effective.mme_compartments, compartments, 423 sizeof(mac_mls->mm_effective.mme_compartments)); 424 mac_mls->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 425} 426 427static void 428mac_mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 429{ 430 431 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 432 ("mac_mls_copy_range: labelfrom not range")); 433 434 labelto->mm_rangelow = labelfrom->mm_rangelow; 435 labelto->mm_rangehigh = labelfrom->mm_rangehigh; 436 labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 437} 438 439static void 440mac_mls_copy_effective(struct mac_mls *labelfrom, struct mac_mls *labelto) 441{ 442 443 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 444 ("mac_mls_copy_effective: labelfrom not effective")); 445 446 labelto->mm_effective = labelfrom->mm_effective; 447 labelto->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 448} 449 450static void 451mac_mls_copy(struct mac_mls *source, struct mac_mls *dest) 452{ 453 454 if (source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 455 mac_mls_copy_effective(source, dest); 456 if (source->mm_flags & MAC_MLS_FLAG_RANGE) 457 mac_mls_copy_range(source, dest); 458} 459 460/* 461 * Policy module operations. 462 */ 463static void 464mac_mls_init(struct mac_policy_conf *conf) 465{ 466 467 zone_mls = uma_zcreate("mac_mls", sizeof(struct mac_mls), NULL, 468 NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 469} 470 471/* 472 * Label operations. 473 */ 474static void 475mac_mls_init_label(struct label *label) 476{ 477 478 SLOT_SET(label, mls_alloc(M_WAITOK)); 479} 480 481static int 482mac_mls_init_label_waitcheck(struct label *label, int flag) 483{ 484 485 SLOT_SET(label, mls_alloc(flag)); 486 if (SLOT(label) == NULL) 487 return (ENOMEM); 488 489 return (0); 490} 491 492static void 493mac_mls_destroy_label(struct label *label) 494{ 495 496 mls_free(SLOT(label)); 497 SLOT_SET(label, NULL); 498} 499 500/* 501 * mac_mls_element_to_string() accepts an sbuf and MLS element. It 502 * converts the MLS element to a string and stores the result in the 503 * sbuf; if there isn't space in the sbuf, -1 is returned. 504 */ 505static int 506mac_mls_element_to_string(struct sbuf *sb, struct mac_mls_element *element) 507{ 508 int i, first; 509 510 switch (element->mme_type) { 511 case MAC_MLS_TYPE_HIGH: 512 return (sbuf_printf(sb, "high")); 513 514 case MAC_MLS_TYPE_LOW: 515 return (sbuf_printf(sb, "low")); 516 517 case MAC_MLS_TYPE_EQUAL: 518 return (sbuf_printf(sb, "equal")); 519 520 case MAC_MLS_TYPE_LEVEL: 521 if (sbuf_printf(sb, "%d", element->mme_level) == -1) 522 return (-1); 523 524 first = 1; 525 for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) { 526 if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) { 527 if (first) { 528 if (sbuf_putc(sb, ':') == -1) 529 return (-1); 530 if (sbuf_printf(sb, "%d", i) == -1) 531 return (-1); 532 first = 0; 533 } else { 534 if (sbuf_printf(sb, "+%d", i) == -1) 535 return (-1); 536 } 537 } 538 } 539 return (0); 540 541 default: 542 panic("mac_mls_element_to_string: invalid type (%d)", 543 element->mme_type); 544 } 545} 546 547/* 548 * mac_mls_to_string() converts an MLS label to a string, and places 549 * the results in the passed sbuf. It returns 0 on success, or EINVAL 550 * if there isn't room in the sbuf. Note: the sbuf will be modified 551 * even in a failure case, so the caller may need to revert the sbuf 552 * by restoring the offset if that's undesired. 553 */ 554static int 555mac_mls_to_string(struct sbuf *sb, struct mac_mls *mac_mls) 556{ 557 558 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 559 if (mac_mls_element_to_string(sb, &mac_mls->mm_effective) 560 == -1) 561 return (EINVAL); 562 } 563 564 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 565 if (sbuf_putc(sb, '(') == -1) 566 return (EINVAL); 567 568 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangelow) 569 == -1) 570 return (EINVAL); 571 572 if (sbuf_putc(sb, '-') == -1) 573 return (EINVAL); 574 575 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangehigh) 576 == -1) 577 return (EINVAL); 578 579 if (sbuf_putc(sb, ')') == -1) 580 return (EINVAL); 581 } 582 583 return (0); 584} 585 586static int 587mac_mls_externalize_label(struct label *label, char *element_name, 588 struct sbuf *sb, int *claimed) 589{ 590 struct mac_mls *mac_mls; 591 592 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 593 return (0); 594 595 (*claimed)++; 596 597 mac_mls = SLOT(label); 598 599 return (mac_mls_to_string(sb, mac_mls)); 600} 601 602static int 603mac_mls_parse_element(struct mac_mls_element *element, char *string) 604{ 605 char *compartment, *end, *level; 606 int value; 607 608 if (strcmp(string, "high") == 0 || 609 strcmp(string, "hi") == 0) { 610 element->mme_type = MAC_MLS_TYPE_HIGH; 611 element->mme_level = MAC_MLS_TYPE_UNDEF; 612 } else if (strcmp(string, "low") == 0 || 613 strcmp(string, "lo") == 0) { 614 element->mme_type = MAC_MLS_TYPE_LOW; 615 element->mme_level = MAC_MLS_TYPE_UNDEF; 616 } else if (strcmp(string, "equal") == 0 || 617 strcmp(string, "eq") == 0) { 618 element->mme_type = MAC_MLS_TYPE_EQUAL; 619 element->mme_level = MAC_MLS_TYPE_UNDEF; 620 } else { 621 element->mme_type = MAC_MLS_TYPE_LEVEL; 622 623 /* 624 * Numeric level piece of the element. 625 */ 626 level = strsep(&string, ":"); 627 value = strtol(level, &end, 10); 628 if (end == level || *end != '\0') 629 return (EINVAL); 630 if (value < 0 || value > 65535) 631 return (EINVAL); 632 element->mme_level = value; 633 634 /* 635 * Optional compartment piece of the element. If none 636 * are included, we assume that the label has no 637 * compartments. 638 */ 639 if (string == NULL) 640 return (0); 641 if (*string == '\0') 642 return (0); 643 644 while ((compartment = strsep(&string, "+")) != NULL) { 645 value = strtol(compartment, &end, 10); 646 if (compartment == end || *end != '\0') 647 return (EINVAL); 648 if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS) 649 return (EINVAL); 650 MAC_MLS_BIT_SET(value, element->mme_compartments); 651 } 652 } 653 654 return (0); 655} 656 657/* 658 * Note: destructively consumes the string, make a local copy before 659 * calling if that's a problem. 660 */ 661static int 662mac_mls_parse(struct mac_mls *mac_mls, char *string) 663{ 664 char *rangehigh, *rangelow, *effective; 665 int error; 666 667 effective = strsep(&string, "("); 668 if (*effective == '\0') 669 effective = NULL; 670 671 if (string != NULL) { 672 rangelow = strsep(&string, "-"); 673 if (string == NULL) 674 return (EINVAL); 675 rangehigh = strsep(&string, ")"); 676 if (string == NULL) 677 return (EINVAL); 678 if (*string != '\0') 679 return (EINVAL); 680 } else { 681 rangelow = NULL; 682 rangehigh = NULL; 683 } 684 685 KASSERT((rangelow != NULL && rangehigh != NULL) || 686 (rangelow == NULL && rangehigh == NULL), 687 ("mac_mls_parse: range mismatch")); 688 689 bzero(mac_mls, sizeof(*mac_mls)); 690 if (effective != NULL) { 691 error = mac_mls_parse_element(&mac_mls->mm_effective, effective); 692 if (error) 693 return (error); 694 mac_mls->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 695 } 696 697 if (rangelow != NULL) { 698 error = mac_mls_parse_element(&mac_mls->mm_rangelow, 699 rangelow); 700 if (error) 701 return (error); 702 error = mac_mls_parse_element(&mac_mls->mm_rangehigh, 703 rangehigh); 704 if (error) 705 return (error); 706 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 707 } 708 709 error = mac_mls_valid(mac_mls); 710 if (error) 711 return (error); 712 713 return (0); 714} 715 716static int 717mac_mls_internalize_label(struct label *label, char *element_name, 718 char *element_data, int *claimed) 719{ 720 struct mac_mls *mac_mls, mac_mls_temp; 721 int error; 722 723 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 724 return (0); 725 726 (*claimed)++; 727 728 error = mac_mls_parse(&mac_mls_temp, element_data); 729 if (error) 730 return (error); 731 732 mac_mls = SLOT(label); 733 *mac_mls = mac_mls_temp; 734 735 return (0); 736} 737 738static void 739mac_mls_copy_label(struct label *src, struct label *dest) 740{ 741 742 *SLOT(dest) = *SLOT(src); 743} 744 745/* 746 * Labeling event operations: file system objects, and things that look 747 * a lot like file system objects. 748 */ 749static void 750mac_mls_create_devfs_device(struct ucred *cred, struct mount *mp, 751 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label) 752{ 753 struct mac_mls *mac_mls; 754 int mls_type; 755 756 mac_mls = SLOT(label); 757 if (strcmp(dev->si_name, "null") == 0 || 758 strcmp(dev->si_name, "zero") == 0 || 759 strcmp(dev->si_name, "random") == 0 || 760 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 761 mls_type = MAC_MLS_TYPE_EQUAL; 762 else if (strcmp(dev->si_name, "kmem") == 0 || 763 strcmp(dev->si_name, "mem") == 0) 764 mls_type = MAC_MLS_TYPE_HIGH; 765 else if (ptys_equal && 766 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 767 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 768 mls_type = MAC_MLS_TYPE_EQUAL; 769 else 770 mls_type = MAC_MLS_TYPE_LOW; 771 mac_mls_set_effective(mac_mls, mls_type, 0, NULL); 772} 773 774static void 775mac_mls_create_devfs_directory(struct mount *mp, char *dirname, 776 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 777{ 778 struct mac_mls *mac_mls; 779 780 mac_mls = SLOT(label); 781 mac_mls_set_effective(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL); 782} 783 784static void 785mac_mls_create_devfs_symlink(struct ucred *cred, struct mount *mp, 786 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 787 struct label *delabel) 788{ 789 struct mac_mls *source, *dest; 790 791 source = SLOT(cred->cr_label); 792 dest = SLOT(delabel); 793 794 mac_mls_copy_effective(source, dest); 795} 796 797static void 798mac_mls_create_mount(struct ucred *cred, struct mount *mp, 799 struct label *mntlabel, struct label *fslabel) 800{ 801 struct mac_mls *source, *dest; 802 803 source = SLOT(cred->cr_label); 804 dest = SLOT(mntlabel); 805 mac_mls_copy_effective(source, dest); 806 dest = SLOT(fslabel); 807 mac_mls_copy_effective(source, dest); 808} 809 810static void 811mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp, 812 struct label *vnodelabel, struct label *label) 813{ 814 struct mac_mls *source, *dest; 815 816 source = SLOT(label); 817 dest = SLOT(vnodelabel); 818 819 mac_mls_copy(source, dest); 820} 821 822static void 823mac_mls_update_devfsdirent(struct mount *mp, 824 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 825 struct vnode *vp, struct label *vnodelabel) 826{ 827 struct mac_mls *source, *dest; 828 829 source = SLOT(vnodelabel); 830 dest = SLOT(direntlabel); 831 832 mac_mls_copy_effective(source, dest); 833} 834 835static void 836mac_mls_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 837 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 838 struct label *vlabel) 839{ 840 struct mac_mls *source, *dest; 841 842 source = SLOT(delabel); 843 dest = SLOT(vlabel); 844 845 mac_mls_copy_effective(source, dest); 846} 847 848static int 849mac_mls_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 850 struct vnode *vp, struct label *vlabel) 851{ 852 struct mac_mls temp, *source, *dest; 853 int buflen, error; 854 855 source = SLOT(fslabel); 856 dest = SLOT(vlabel); 857 858 buflen = sizeof(temp); 859 bzero(&temp, buflen); 860 861 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 862 MAC_MLS_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 863 if (error == ENOATTR || error == EOPNOTSUPP) { 864 /* Fall back to the fslabel. */ 865 mac_mls_copy_effective(source, dest); 866 return (0); 867 } else if (error) 868 return (error); 869 870 if (buflen != sizeof(temp)) { 871 printf("mac_mls_associate_vnode_extattr: bad size %d\n", 872 buflen); 873 return (EPERM); 874 } 875 if (mac_mls_valid(&temp) != 0) { 876 printf("mac_mls_associate_vnode_extattr: invalid\n"); 877 return (EPERM); 878 } 879 if ((temp.mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_EFFECTIVE) { 880 printf("mac_mls_associated_vnode_extattr: not effective\n"); 881 return (EPERM); 882 } 883 884 mac_mls_copy_effective(&temp, dest); 885 return (0); 886} 887 888static void 889mac_mls_associate_vnode_singlelabel(struct mount *mp, 890 struct label *fslabel, struct vnode *vp, struct label *vlabel) 891{ 892 struct mac_mls *source, *dest; 893 894 source = SLOT(fslabel); 895 dest = SLOT(vlabel); 896 897 mac_mls_copy_effective(source, dest); 898} 899 900static int 901mac_mls_create_vnode_extattr(struct ucred *cred, struct mount *mp, 902 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 903 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 904{ 905 struct mac_mls *source, *dest, temp; 906 size_t buflen; 907 int error; 908 909 buflen = sizeof(temp); 910 bzero(&temp, buflen); 911 912 source = SLOT(cred->cr_label); 913 dest = SLOT(vlabel); 914 mac_mls_copy_effective(source, &temp); 915 916 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 917 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread); 918 if (error == 0) 919 mac_mls_copy_effective(source, dest); 920 return (error); 921} 922 923static int 924mac_mls_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 925 struct label *vlabel, struct label *intlabel) 926{ 927 struct mac_mls *source, temp; 928 size_t buflen; 929 int error; 930 931 buflen = sizeof(temp); 932 bzero(&temp, buflen); 933 934 source = SLOT(intlabel); 935 if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 936 return (0); 937 938 mac_mls_copy_effective(source, &temp); 939 940 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 941 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread); 942 return (error); 943} 944 945/* 946 * Labeling event operations: IPC object. 947 */ 948static void 949mac_mls_create_inpcb_from_socket(struct socket *so, struct label *solabel, 950 struct inpcb *inp, struct label *inplabel) 951{ 952 struct mac_mls *source, *dest; 953 954 source = SLOT(solabel); 955 dest = SLOT(inplabel); 956 957 mac_mls_copy_effective(source, dest); 958} 959 960static void 961mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 962 struct mbuf *m, struct label *mbuflabel) 963{ 964 struct mac_mls *source, *dest; 965 966 source = SLOT(socketlabel); 967 dest = SLOT(mbuflabel); 968 969 mac_mls_copy_effective(source, dest); 970} 971 972static void 973mac_mls_create_socket(struct ucred *cred, struct socket *socket, 974 struct label *socketlabel) 975{ 976 struct mac_mls *source, *dest; 977 978 source = SLOT(cred->cr_label); 979 dest = SLOT(socketlabel); 980 981 mac_mls_copy_effective(source, dest); 982} 983 984static void 985mac_mls_create_pipe(struct ucred *cred, struct pipepair *pp, 986 struct label *pipelabel) 987{ 988 struct mac_mls *source, *dest; 989 990 source = SLOT(cred->cr_label); 991 dest = SLOT(pipelabel); 992 993 mac_mls_copy_effective(source, dest); 994} 995 996static void 997mac_mls_create_posix_sem(struct ucred *cred, struct ksem *ksemptr, 998 struct label *ks_label) 999{ 1000 struct mac_mls *source, *dest; 1001 1002 source = SLOT(cred->cr_label); 1003 dest = SLOT(ks_label); 1004 1005 mac_mls_copy_effective(source, dest); 1006} 1007 1008static void 1009mac_mls_create_socket_from_socket(struct socket *oldsocket, 1010 struct label *oldsocketlabel, struct socket *newsocket, 1011 struct label *newsocketlabel) 1012{ 1013 struct mac_mls *source, *dest; 1014 1015 source = SLOT(oldsocketlabel); 1016 dest = SLOT(newsocketlabel); 1017 1018 mac_mls_copy_effective(source, dest); 1019} 1020 1021static void 1022mac_mls_relabel_socket(struct ucred *cred, struct socket *socket, 1023 struct label *socketlabel, struct label *newlabel) 1024{ 1025 struct mac_mls *source, *dest; 1026 1027 source = SLOT(newlabel); 1028 dest = SLOT(socketlabel); 1029 1030 mac_mls_copy(source, dest); 1031} 1032 1033static void 1034mac_mls_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1035 struct label *pipelabel, struct label *newlabel) 1036{ 1037 struct mac_mls *source, *dest; 1038 1039 source = SLOT(newlabel); 1040 dest = SLOT(pipelabel); 1041 1042 mac_mls_copy(source, dest); 1043} 1044 1045static void 1046mac_mls_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1047 struct socket *socket, struct label *socketpeerlabel) 1048{ 1049 struct mac_mls *source, *dest; 1050 1051 source = SLOT(mbuflabel); 1052 dest = SLOT(socketpeerlabel); 1053 1054 mac_mls_copy_effective(source, dest); 1055} 1056 1057/* 1058 * Labeling event operations: System V IPC objects. 1059 */ 1060 1061static void 1062mac_mls_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, 1063 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1064{ 1065 struct mac_mls *source, *dest; 1066 1067 /* Ignore the msgq label */ 1068 source = SLOT(cred->cr_label); 1069 dest = SLOT(msglabel); 1070 1071 mac_mls_copy_effective(source, dest); 1072} 1073 1074static void 1075mac_mls_create_sysv_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr, 1076 struct label *msqlabel) 1077{ 1078 struct mac_mls *source, *dest; 1079 1080 source = SLOT(cred->cr_label); 1081 dest = SLOT(msqlabel); 1082 1083 mac_mls_copy_effective(source, dest); 1084} 1085 1086static void 1087mac_mls_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr, 1088 struct label *semalabel) 1089{ 1090 struct mac_mls *source, *dest; 1091 1092 source = SLOT(cred->cr_label); 1093 dest = SLOT(semalabel); 1094 1095 mac_mls_copy_effective(source, dest); 1096} 1097 1098static void 1099mac_mls_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr, 1100 struct label *shmlabel) 1101{ 1102 struct mac_mls *source, *dest; 1103 1104 source = SLOT(cred->cr_label); 1105 dest = SLOT(shmlabel); 1106 1107 mac_mls_copy_effective(source, dest); 1108} 1109 1110/* 1111 * Labeling event operations: network objects. 1112 */ 1113static void 1114mac_mls_set_socket_peer_from_socket(struct socket *oldsocket, 1115 struct label *oldsocketlabel, struct socket *newsocket, 1116 struct label *newsocketpeerlabel) 1117{ 1118 struct mac_mls *source, *dest; 1119 1120 source = SLOT(oldsocketlabel); 1121 dest = SLOT(newsocketpeerlabel); 1122 1123 mac_mls_copy_effective(source, dest); 1124} 1125 1126static void 1127mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1128 struct label *bpflabel) 1129{ 1130 struct mac_mls *source, *dest; 1131 1132 source = SLOT(cred->cr_label); 1133 dest = SLOT(bpflabel); 1134 1135 mac_mls_copy_effective(source, dest); 1136} 1137 1138static void 1139mac_mls_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1140{ 1141 struct mac_mls *dest; 1142 int type; 1143 1144 dest = SLOT(ifnetlabel); 1145 1146 if (ifnet->if_type == IFT_LOOP) 1147 type = MAC_MLS_TYPE_EQUAL; 1148 else 1149 type = MAC_MLS_TYPE_LOW; 1150 1151 mac_mls_set_effective(dest, type, 0, NULL); 1152 mac_mls_set_range(dest, type, 0, NULL, type, 0, NULL); 1153} 1154 1155static void 1156mac_mls_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1157 struct ipq *ipq, struct label *ipqlabel) 1158{ 1159 struct mac_mls *source, *dest; 1160 1161 source = SLOT(fragmentlabel); 1162 dest = SLOT(ipqlabel); 1163 1164 mac_mls_copy_effective(source, dest); 1165} 1166 1167static void 1168mac_mls_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1169 struct mbuf *datagram, struct label *datagramlabel) 1170{ 1171 struct mac_mls *source, *dest; 1172 1173 source = SLOT(ipqlabel); 1174 dest = SLOT(datagramlabel); 1175 1176 /* Just use the head, since we require them all to match. */ 1177 mac_mls_copy_effective(source, dest); 1178} 1179 1180static void 1181mac_mls_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1182 struct mbuf *fragment, struct label *fragmentlabel) 1183{ 1184 struct mac_mls *source, *dest; 1185 1186 source = SLOT(datagramlabel); 1187 dest = SLOT(fragmentlabel); 1188 1189 mac_mls_copy_effective(source, dest); 1190} 1191 1192static void 1193mac_mls_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1194 struct mbuf *m, struct label *mlabel) 1195{ 1196 struct mac_mls *source, *dest; 1197 1198 source = SLOT(inplabel); 1199 dest = SLOT(mlabel); 1200 1201 mac_mls_copy_effective(source, dest); 1202} 1203 1204static void 1205mac_mls_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1206 struct mbuf *mbuf, struct label *mbuflabel) 1207{ 1208 struct mac_mls *dest; 1209 1210 dest = SLOT(mbuflabel); 1211 1212 mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1213} 1214 1215static void 1216mac_mls_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1217 struct mbuf *mbuf, struct label *mbuflabel) 1218{ 1219 struct mac_mls *source, *dest; 1220 1221 source = SLOT(bpflabel); 1222 dest = SLOT(mbuflabel); 1223 1224 mac_mls_copy_effective(source, dest); 1225} 1226 1227static void 1228mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1229 struct mbuf *m, struct label *mbuflabel) 1230{ 1231 struct mac_mls *source, *dest; 1232 1233 source = SLOT(ifnetlabel); 1234 dest = SLOT(mbuflabel); 1235 1236 mac_mls_copy_effective(source, dest); 1237} 1238 1239static void 1240mac_mls_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1241 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1242 struct mbuf *newmbuf, struct label *newmbuflabel) 1243{ 1244 struct mac_mls *source, *dest; 1245 1246 source = SLOT(oldmbuflabel); 1247 dest = SLOT(newmbuflabel); 1248 1249 mac_mls_copy_effective(source, dest); 1250} 1251 1252static void 1253mac_mls_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1254 struct mbuf *newmbuf, struct label *newmbuflabel) 1255{ 1256 struct mac_mls *source, *dest; 1257 1258 source = SLOT(oldmbuflabel); 1259 dest = SLOT(newmbuflabel); 1260 1261 mac_mls_copy_effective(source, dest); 1262} 1263 1264static int 1265mac_mls_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1266 struct ipq *ipq, struct label *ipqlabel) 1267{ 1268 struct mac_mls *a, *b; 1269 1270 a = SLOT(ipqlabel); 1271 b = SLOT(fragmentlabel); 1272 1273 return (mac_mls_equal_effective(a, b)); 1274} 1275 1276static void 1277mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1278 struct label *ifnetlabel, struct label *newlabel) 1279{ 1280 struct mac_mls *source, *dest; 1281 1282 source = SLOT(newlabel); 1283 dest = SLOT(ifnetlabel); 1284 1285 mac_mls_copy(source, dest); 1286} 1287 1288static void 1289mac_mls_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1290 struct ipq *ipq, struct label *ipqlabel) 1291{ 1292 1293 /* NOOP: we only accept matching labels, so no need to update */ 1294} 1295 1296static void 1297mac_mls_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1298 struct inpcb *inp, struct label *inplabel) 1299{ 1300 struct mac_mls *source, *dest; 1301 1302 source = SLOT(solabel); 1303 dest = SLOT(inplabel); 1304 1305 mac_mls_copy(source, dest); 1306} 1307
| 35 */ 36 37/* 38 * Developed by the TrustedBSD Project. 39 * MLS fixed label mandatory confidentiality policy. 40 */ 41 42#include <sys/types.h> 43#include <sys/param.h> 44#include <sys/acl.h> 45#include <sys/conf.h> 46#include <sys/extattr.h> 47#include <sys/kernel.h> 48#include <sys/mac.h> 49#include <sys/mman.h> 50#include <sys/malloc.h> 51#include <sys/mount.h> 52#include <sys/proc.h> 53#include <sys/sbuf.h> 54#include <sys/systm.h> 55#include <sys/sysproto.h> 56#include <sys/sysent.h> 57#include <sys/systm.h> 58#include <sys/vnode.h> 59#include <sys/file.h> 60#include <sys/socket.h> 61#include <sys/socketvar.h> 62#include <sys/pipe.h> 63#include <sys/sx.h> 64#include <sys/sysctl.h> 65#include <sys/msg.h> 66#include <sys/sem.h> 67#include <sys/shm.h> 68 69#include <posix4/ksem.h> 70 71#include <fs/devfs/devfs.h> 72 73#include <net/bpfdesc.h> 74#include <net/if.h> 75#include <net/if_types.h> 76#include <net/if_var.h> 77 78#include <netinet/in.h> 79#include <netinet/in_pcb.h> 80#include <netinet/ip_var.h> 81 82#include <vm/uma.h> 83#include <vm/vm.h> 84 85#include <sys/mac_policy.h> 86 87#include <security/mac_mls/mac_mls.h> 88 89SYSCTL_DECL(_security_mac); 90 91SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0, 92 "TrustedBSD mac_mls policy controls"); 93 94static int mac_mls_label_size = sizeof(struct mac_mls); 95SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD, 96 &mac_mls_label_size, 0, "Size of struct mac_mls"); 97 98static int mac_mls_enabled = 1; 99SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW, 100 &mac_mls_enabled, 0, "Enforce MAC/MLS policy"); 101TUNABLE_INT("security.mac.mls.enabled", &mac_mls_enabled); 102 103static int destroyed_not_inited; 104SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 105 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 106 107static int ptys_equal = 0; 108SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW, 109 &ptys_equal, 0, "Label pty devices as mls/equal on create"); 110TUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal); 111 112static int revocation_enabled = 0; 113SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, 114 &revocation_enabled, 0, "Revoke access to objects on relabel"); 115TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled); 116 117static int max_compartments = MAC_MLS_MAX_COMPARTMENTS; 118SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD, 119 &max_compartments, 0, "Maximum compartments the policy supports"); 120 121static int mac_mls_slot; 122#define SLOT(l) ((struct mac_mls *)LABEL_TO_SLOT((l), mac_mls_slot).l_ptr) 123#define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_mls_slot).l_ptr = (val)) 124 125static uma_zone_t zone_mls; 126 127static __inline int 128mls_bit_set_empty(u_char *set) { 129 int i; 130 131 for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++) 132 if (set[i] != 0) 133 return (0); 134 return (1); 135} 136 137static struct mac_mls * 138mls_alloc(int flag) 139{ 140 141 return (uma_zalloc(zone_mls, flag | M_ZERO)); 142} 143 144static void 145mls_free(struct mac_mls *mac_mls) 146{ 147 148 if (mac_mls != NULL) 149 uma_zfree(zone_mls, mac_mls); 150 else 151 atomic_add_int(&destroyed_not_inited, 1); 152} 153 154static int 155mls_atmostflags(struct mac_mls *mac_mls, int flags) 156{ 157 158 if ((mac_mls->mm_flags & flags) != mac_mls->mm_flags) 159 return (EINVAL); 160 return (0); 161} 162 163static int 164mac_mls_dominate_element(struct mac_mls_element *a, 165 struct mac_mls_element *b) 166{ 167 int bit; 168 169 switch (a->mme_type) { 170 case MAC_MLS_TYPE_EQUAL: 171 case MAC_MLS_TYPE_HIGH: 172 return (1); 173 174 case MAC_MLS_TYPE_LOW: 175 switch (b->mme_type) { 176 case MAC_MLS_TYPE_LEVEL: 177 case MAC_MLS_TYPE_HIGH: 178 return (0); 179 180 case MAC_MLS_TYPE_EQUAL: 181 case MAC_MLS_TYPE_LOW: 182 return (1); 183 184 default: 185 panic("mac_mls_dominate_element: b->mme_type invalid"); 186 } 187 188 case MAC_MLS_TYPE_LEVEL: 189 switch (b->mme_type) { 190 case MAC_MLS_TYPE_EQUAL: 191 case MAC_MLS_TYPE_LOW: 192 return (1); 193 194 case MAC_MLS_TYPE_HIGH: 195 return (0); 196 197 case MAC_MLS_TYPE_LEVEL: 198 for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) 199 if (!MAC_MLS_BIT_TEST(bit, 200 a->mme_compartments) && 201 MAC_MLS_BIT_TEST(bit, b->mme_compartments)) 202 return (0); 203 return (a->mme_level >= b->mme_level); 204 205 default: 206 panic("mac_mls_dominate_element: b->mme_type invalid"); 207 } 208 209 default: 210 panic("mac_mls_dominate_element: a->mme_type invalid"); 211 } 212 213 return (0); 214} 215 216static int 217mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) 218{ 219 220 return (mac_mls_dominate_element(&rangeb->mm_rangehigh, 221 &rangea->mm_rangehigh) && 222 mac_mls_dominate_element(&rangea->mm_rangelow, 223 &rangeb->mm_rangelow)); 224} 225 226static int 227mac_mls_effective_in_range(struct mac_mls *effective, struct mac_mls *range) 228{ 229 230 KASSERT((effective->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 231 ("mac_mls_effective_in_range: a not effective")); 232 KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 233 ("mac_mls_effective_in_range: b not range")); 234 235 return (mac_mls_dominate_element(&range->mm_rangehigh, 236 &effective->mm_effective) && 237 mac_mls_dominate_element(&effective->mm_effective, 238 &range->mm_rangelow)); 239 240 return (1); 241} 242 243static int 244mac_mls_dominate_effective(struct mac_mls *a, struct mac_mls *b) 245{ 246 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 247 ("mac_mls_dominate_effective: a not effective")); 248 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 249 ("mac_mls_dominate_effective: b not effective")); 250 251 return (mac_mls_dominate_element(&a->mm_effective, &b->mm_effective)); 252} 253 254static int 255mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) 256{ 257 258 if (a->mme_type == MAC_MLS_TYPE_EQUAL || 259 b->mme_type == MAC_MLS_TYPE_EQUAL) 260 return (1); 261 262 return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); 263} 264 265static int 266mac_mls_equal_effective(struct mac_mls *a, struct mac_mls *b) 267{ 268 269 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 270 ("mac_mls_equal_effective: a not effective")); 271 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 272 ("mac_mls_equal_effective: b not effective")); 273 274 return (mac_mls_equal_element(&a->mm_effective, &b->mm_effective)); 275} 276 277static int 278mac_mls_contains_equal(struct mac_mls *mac_mls) 279{ 280 281 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 282 if (mac_mls->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 283 return (1); 284 285 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 286 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL) 287 return (1); 288 if (mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 289 return (1); 290 } 291 292 return (0); 293} 294 295static int 296mac_mls_subject_privileged(struct mac_mls *mac_mls) 297{ 298 299 KASSERT((mac_mls->mm_flags & MAC_MLS_FLAGS_BOTH) == 300 MAC_MLS_FLAGS_BOTH, 301 ("mac_mls_subject_privileged: subject doesn't have both labels")); 302 303 /* If the effective is EQUAL, it's ok. */ 304 if (mac_mls->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 305 return (0); 306 307 /* If either range endpoint is EQUAL, it's ok. */ 308 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL || 309 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 310 return (0); 311 312 /* If the range is low-high, it's ok. */ 313 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW && 314 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH) 315 return (0); 316 317 /* It's not ok. */ 318 return (EPERM); 319} 320 321static int 322mac_mls_valid(struct mac_mls *mac_mls) 323{ 324 325 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 326 switch (mac_mls->mm_effective.mme_type) { 327 case MAC_MLS_TYPE_LEVEL: 328 break; 329 330 case MAC_MLS_TYPE_EQUAL: 331 case MAC_MLS_TYPE_HIGH: 332 case MAC_MLS_TYPE_LOW: 333 if (mac_mls->mm_effective.mme_level != 0 || 334 !MAC_MLS_BIT_SET_EMPTY( 335 mac_mls->mm_effective.mme_compartments)) 336 return (EINVAL); 337 break; 338 339 default: 340 return (EINVAL); 341 } 342 } else { 343 if (mac_mls->mm_effective.mme_type != MAC_MLS_TYPE_UNDEF) 344 return (EINVAL); 345 } 346 347 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 348 switch (mac_mls->mm_rangelow.mme_type) { 349 case MAC_MLS_TYPE_LEVEL: 350 break; 351 352 case MAC_MLS_TYPE_EQUAL: 353 case MAC_MLS_TYPE_HIGH: 354 case MAC_MLS_TYPE_LOW: 355 if (mac_mls->mm_rangelow.mme_level != 0 || 356 !MAC_MLS_BIT_SET_EMPTY( 357 mac_mls->mm_rangelow.mme_compartments)) 358 return (EINVAL); 359 break; 360 361 default: 362 return (EINVAL); 363 } 364 365 switch (mac_mls->mm_rangehigh.mme_type) { 366 case MAC_MLS_TYPE_LEVEL: 367 break; 368 369 case MAC_MLS_TYPE_EQUAL: 370 case MAC_MLS_TYPE_HIGH: 371 case MAC_MLS_TYPE_LOW: 372 if (mac_mls->mm_rangehigh.mme_level != 0 || 373 !MAC_MLS_BIT_SET_EMPTY( 374 mac_mls->mm_rangehigh.mme_compartments)) 375 return (EINVAL); 376 break; 377 378 default: 379 return (EINVAL); 380 } 381 if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh, 382 &mac_mls->mm_rangelow)) 383 return (EINVAL); 384 } else { 385 if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || 386 mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) 387 return (EINVAL); 388 } 389 390 return (0); 391} 392 393static void 394mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow, 395 u_short levellow, u_char *compartmentslow, u_short typehigh, 396 u_short levelhigh, u_char *compartmentshigh) 397{ 398 399 mac_mls->mm_rangelow.mme_type = typelow; 400 mac_mls->mm_rangelow.mme_level = levellow; 401 if (compartmentslow != NULL) 402 memcpy(mac_mls->mm_rangelow.mme_compartments, 403 compartmentslow, 404 sizeof(mac_mls->mm_rangelow.mme_compartments)); 405 mac_mls->mm_rangehigh.mme_type = typehigh; 406 mac_mls->mm_rangehigh.mme_level = levelhigh; 407 if (compartmentshigh != NULL) 408 memcpy(mac_mls->mm_rangehigh.mme_compartments, 409 compartmentshigh, 410 sizeof(mac_mls->mm_rangehigh.mme_compartments)); 411 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 412} 413 414static void 415mac_mls_set_effective(struct mac_mls *mac_mls, u_short type, u_short level, 416 u_char *compartments) 417{ 418 419 mac_mls->mm_effective.mme_type = type; 420 mac_mls->mm_effective.mme_level = level; 421 if (compartments != NULL) 422 memcpy(mac_mls->mm_effective.mme_compartments, compartments, 423 sizeof(mac_mls->mm_effective.mme_compartments)); 424 mac_mls->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 425} 426 427static void 428mac_mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 429{ 430 431 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 432 ("mac_mls_copy_range: labelfrom not range")); 433 434 labelto->mm_rangelow = labelfrom->mm_rangelow; 435 labelto->mm_rangehigh = labelfrom->mm_rangehigh; 436 labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 437} 438 439static void 440mac_mls_copy_effective(struct mac_mls *labelfrom, struct mac_mls *labelto) 441{ 442 443 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 444 ("mac_mls_copy_effective: labelfrom not effective")); 445 446 labelto->mm_effective = labelfrom->mm_effective; 447 labelto->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 448} 449 450static void 451mac_mls_copy(struct mac_mls *source, struct mac_mls *dest) 452{ 453 454 if (source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 455 mac_mls_copy_effective(source, dest); 456 if (source->mm_flags & MAC_MLS_FLAG_RANGE) 457 mac_mls_copy_range(source, dest); 458} 459 460/* 461 * Policy module operations. 462 */ 463static void 464mac_mls_init(struct mac_policy_conf *conf) 465{ 466 467 zone_mls = uma_zcreate("mac_mls", sizeof(struct mac_mls), NULL, 468 NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 469} 470 471/* 472 * Label operations. 473 */ 474static void 475mac_mls_init_label(struct label *label) 476{ 477 478 SLOT_SET(label, mls_alloc(M_WAITOK)); 479} 480 481static int 482mac_mls_init_label_waitcheck(struct label *label, int flag) 483{ 484 485 SLOT_SET(label, mls_alloc(flag)); 486 if (SLOT(label) == NULL) 487 return (ENOMEM); 488 489 return (0); 490} 491 492static void 493mac_mls_destroy_label(struct label *label) 494{ 495 496 mls_free(SLOT(label)); 497 SLOT_SET(label, NULL); 498} 499 500/* 501 * mac_mls_element_to_string() accepts an sbuf and MLS element. It 502 * converts the MLS element to a string and stores the result in the 503 * sbuf; if there isn't space in the sbuf, -1 is returned. 504 */ 505static int 506mac_mls_element_to_string(struct sbuf *sb, struct mac_mls_element *element) 507{ 508 int i, first; 509 510 switch (element->mme_type) { 511 case MAC_MLS_TYPE_HIGH: 512 return (sbuf_printf(sb, "high")); 513 514 case MAC_MLS_TYPE_LOW: 515 return (sbuf_printf(sb, "low")); 516 517 case MAC_MLS_TYPE_EQUAL: 518 return (sbuf_printf(sb, "equal")); 519 520 case MAC_MLS_TYPE_LEVEL: 521 if (sbuf_printf(sb, "%d", element->mme_level) == -1) 522 return (-1); 523 524 first = 1; 525 for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) { 526 if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) { 527 if (first) { 528 if (sbuf_putc(sb, ':') == -1) 529 return (-1); 530 if (sbuf_printf(sb, "%d", i) == -1) 531 return (-1); 532 first = 0; 533 } else { 534 if (sbuf_printf(sb, "+%d", i) == -1) 535 return (-1); 536 } 537 } 538 } 539 return (0); 540 541 default: 542 panic("mac_mls_element_to_string: invalid type (%d)", 543 element->mme_type); 544 } 545} 546 547/* 548 * mac_mls_to_string() converts an MLS label to a string, and places 549 * the results in the passed sbuf. It returns 0 on success, or EINVAL 550 * if there isn't room in the sbuf. Note: the sbuf will be modified 551 * even in a failure case, so the caller may need to revert the sbuf 552 * by restoring the offset if that's undesired. 553 */ 554static int 555mac_mls_to_string(struct sbuf *sb, struct mac_mls *mac_mls) 556{ 557 558 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 559 if (mac_mls_element_to_string(sb, &mac_mls->mm_effective) 560 == -1) 561 return (EINVAL); 562 } 563 564 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 565 if (sbuf_putc(sb, '(') == -1) 566 return (EINVAL); 567 568 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangelow) 569 == -1) 570 return (EINVAL); 571 572 if (sbuf_putc(sb, '-') == -1) 573 return (EINVAL); 574 575 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangehigh) 576 == -1) 577 return (EINVAL); 578 579 if (sbuf_putc(sb, ')') == -1) 580 return (EINVAL); 581 } 582 583 return (0); 584} 585 586static int 587mac_mls_externalize_label(struct label *label, char *element_name, 588 struct sbuf *sb, int *claimed) 589{ 590 struct mac_mls *mac_mls; 591 592 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 593 return (0); 594 595 (*claimed)++; 596 597 mac_mls = SLOT(label); 598 599 return (mac_mls_to_string(sb, mac_mls)); 600} 601 602static int 603mac_mls_parse_element(struct mac_mls_element *element, char *string) 604{ 605 char *compartment, *end, *level; 606 int value; 607 608 if (strcmp(string, "high") == 0 || 609 strcmp(string, "hi") == 0) { 610 element->mme_type = MAC_MLS_TYPE_HIGH; 611 element->mme_level = MAC_MLS_TYPE_UNDEF; 612 } else if (strcmp(string, "low") == 0 || 613 strcmp(string, "lo") == 0) { 614 element->mme_type = MAC_MLS_TYPE_LOW; 615 element->mme_level = MAC_MLS_TYPE_UNDEF; 616 } else if (strcmp(string, "equal") == 0 || 617 strcmp(string, "eq") == 0) { 618 element->mme_type = MAC_MLS_TYPE_EQUAL; 619 element->mme_level = MAC_MLS_TYPE_UNDEF; 620 } else { 621 element->mme_type = MAC_MLS_TYPE_LEVEL; 622 623 /* 624 * Numeric level piece of the element. 625 */ 626 level = strsep(&string, ":"); 627 value = strtol(level, &end, 10); 628 if (end == level || *end != '\0') 629 return (EINVAL); 630 if (value < 0 || value > 65535) 631 return (EINVAL); 632 element->mme_level = value; 633 634 /* 635 * Optional compartment piece of the element. If none 636 * are included, we assume that the label has no 637 * compartments. 638 */ 639 if (string == NULL) 640 return (0); 641 if (*string == '\0') 642 return (0); 643 644 while ((compartment = strsep(&string, "+")) != NULL) { 645 value = strtol(compartment, &end, 10); 646 if (compartment == end || *end != '\0') 647 return (EINVAL); 648 if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS) 649 return (EINVAL); 650 MAC_MLS_BIT_SET(value, element->mme_compartments); 651 } 652 } 653 654 return (0); 655} 656 657/* 658 * Note: destructively consumes the string, make a local copy before 659 * calling if that's a problem. 660 */ 661static int 662mac_mls_parse(struct mac_mls *mac_mls, char *string) 663{ 664 char *rangehigh, *rangelow, *effective; 665 int error; 666 667 effective = strsep(&string, "("); 668 if (*effective == '\0') 669 effective = NULL; 670 671 if (string != NULL) { 672 rangelow = strsep(&string, "-"); 673 if (string == NULL) 674 return (EINVAL); 675 rangehigh = strsep(&string, ")"); 676 if (string == NULL) 677 return (EINVAL); 678 if (*string != '\0') 679 return (EINVAL); 680 } else { 681 rangelow = NULL; 682 rangehigh = NULL; 683 } 684 685 KASSERT((rangelow != NULL && rangehigh != NULL) || 686 (rangelow == NULL && rangehigh == NULL), 687 ("mac_mls_parse: range mismatch")); 688 689 bzero(mac_mls, sizeof(*mac_mls)); 690 if (effective != NULL) { 691 error = mac_mls_parse_element(&mac_mls->mm_effective, effective); 692 if (error) 693 return (error); 694 mac_mls->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 695 } 696 697 if (rangelow != NULL) { 698 error = mac_mls_parse_element(&mac_mls->mm_rangelow, 699 rangelow); 700 if (error) 701 return (error); 702 error = mac_mls_parse_element(&mac_mls->mm_rangehigh, 703 rangehigh); 704 if (error) 705 return (error); 706 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 707 } 708 709 error = mac_mls_valid(mac_mls); 710 if (error) 711 return (error); 712 713 return (0); 714} 715 716static int 717mac_mls_internalize_label(struct label *label, char *element_name, 718 char *element_data, int *claimed) 719{ 720 struct mac_mls *mac_mls, mac_mls_temp; 721 int error; 722 723 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 724 return (0); 725 726 (*claimed)++; 727 728 error = mac_mls_parse(&mac_mls_temp, element_data); 729 if (error) 730 return (error); 731 732 mac_mls = SLOT(label); 733 *mac_mls = mac_mls_temp; 734 735 return (0); 736} 737 738static void 739mac_mls_copy_label(struct label *src, struct label *dest) 740{ 741 742 *SLOT(dest) = *SLOT(src); 743} 744 745/* 746 * Labeling event operations: file system objects, and things that look 747 * a lot like file system objects. 748 */ 749static void 750mac_mls_create_devfs_device(struct ucred *cred, struct mount *mp, 751 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label) 752{ 753 struct mac_mls *mac_mls; 754 int mls_type; 755 756 mac_mls = SLOT(label); 757 if (strcmp(dev->si_name, "null") == 0 || 758 strcmp(dev->si_name, "zero") == 0 || 759 strcmp(dev->si_name, "random") == 0 || 760 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 761 mls_type = MAC_MLS_TYPE_EQUAL; 762 else if (strcmp(dev->si_name, "kmem") == 0 || 763 strcmp(dev->si_name, "mem") == 0) 764 mls_type = MAC_MLS_TYPE_HIGH; 765 else if (ptys_equal && 766 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 767 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 768 mls_type = MAC_MLS_TYPE_EQUAL; 769 else 770 mls_type = MAC_MLS_TYPE_LOW; 771 mac_mls_set_effective(mac_mls, mls_type, 0, NULL); 772} 773 774static void 775mac_mls_create_devfs_directory(struct mount *mp, char *dirname, 776 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 777{ 778 struct mac_mls *mac_mls; 779 780 mac_mls = SLOT(label); 781 mac_mls_set_effective(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL); 782} 783 784static void 785mac_mls_create_devfs_symlink(struct ucred *cred, struct mount *mp, 786 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 787 struct label *delabel) 788{ 789 struct mac_mls *source, *dest; 790 791 source = SLOT(cred->cr_label); 792 dest = SLOT(delabel); 793 794 mac_mls_copy_effective(source, dest); 795} 796 797static void 798mac_mls_create_mount(struct ucred *cred, struct mount *mp, 799 struct label *mntlabel, struct label *fslabel) 800{ 801 struct mac_mls *source, *dest; 802 803 source = SLOT(cred->cr_label); 804 dest = SLOT(mntlabel); 805 mac_mls_copy_effective(source, dest); 806 dest = SLOT(fslabel); 807 mac_mls_copy_effective(source, dest); 808} 809 810static void 811mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp, 812 struct label *vnodelabel, struct label *label) 813{ 814 struct mac_mls *source, *dest; 815 816 source = SLOT(label); 817 dest = SLOT(vnodelabel); 818 819 mac_mls_copy(source, dest); 820} 821 822static void 823mac_mls_update_devfsdirent(struct mount *mp, 824 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 825 struct vnode *vp, struct label *vnodelabel) 826{ 827 struct mac_mls *source, *dest; 828 829 source = SLOT(vnodelabel); 830 dest = SLOT(direntlabel); 831 832 mac_mls_copy_effective(source, dest); 833} 834 835static void 836mac_mls_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 837 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 838 struct label *vlabel) 839{ 840 struct mac_mls *source, *dest; 841 842 source = SLOT(delabel); 843 dest = SLOT(vlabel); 844 845 mac_mls_copy_effective(source, dest); 846} 847 848static int 849mac_mls_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 850 struct vnode *vp, struct label *vlabel) 851{ 852 struct mac_mls temp, *source, *dest; 853 int buflen, error; 854 855 source = SLOT(fslabel); 856 dest = SLOT(vlabel); 857 858 buflen = sizeof(temp); 859 bzero(&temp, buflen); 860 861 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 862 MAC_MLS_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 863 if (error == ENOATTR || error == EOPNOTSUPP) { 864 /* Fall back to the fslabel. */ 865 mac_mls_copy_effective(source, dest); 866 return (0); 867 } else if (error) 868 return (error); 869 870 if (buflen != sizeof(temp)) { 871 printf("mac_mls_associate_vnode_extattr: bad size %d\n", 872 buflen); 873 return (EPERM); 874 } 875 if (mac_mls_valid(&temp) != 0) { 876 printf("mac_mls_associate_vnode_extattr: invalid\n"); 877 return (EPERM); 878 } 879 if ((temp.mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_EFFECTIVE) { 880 printf("mac_mls_associated_vnode_extattr: not effective\n"); 881 return (EPERM); 882 } 883 884 mac_mls_copy_effective(&temp, dest); 885 return (0); 886} 887 888static void 889mac_mls_associate_vnode_singlelabel(struct mount *mp, 890 struct label *fslabel, struct vnode *vp, struct label *vlabel) 891{ 892 struct mac_mls *source, *dest; 893 894 source = SLOT(fslabel); 895 dest = SLOT(vlabel); 896 897 mac_mls_copy_effective(source, dest); 898} 899 900static int 901mac_mls_create_vnode_extattr(struct ucred *cred, struct mount *mp, 902 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 903 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 904{ 905 struct mac_mls *source, *dest, temp; 906 size_t buflen; 907 int error; 908 909 buflen = sizeof(temp); 910 bzero(&temp, buflen); 911 912 source = SLOT(cred->cr_label); 913 dest = SLOT(vlabel); 914 mac_mls_copy_effective(source, &temp); 915 916 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 917 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread); 918 if (error == 0) 919 mac_mls_copy_effective(source, dest); 920 return (error); 921} 922 923static int 924mac_mls_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 925 struct label *vlabel, struct label *intlabel) 926{ 927 struct mac_mls *source, temp; 928 size_t buflen; 929 int error; 930 931 buflen = sizeof(temp); 932 bzero(&temp, buflen); 933 934 source = SLOT(intlabel); 935 if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 936 return (0); 937 938 mac_mls_copy_effective(source, &temp); 939 940 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 941 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread); 942 return (error); 943} 944 945/* 946 * Labeling event operations: IPC object. 947 */ 948static void 949mac_mls_create_inpcb_from_socket(struct socket *so, struct label *solabel, 950 struct inpcb *inp, struct label *inplabel) 951{ 952 struct mac_mls *source, *dest; 953 954 source = SLOT(solabel); 955 dest = SLOT(inplabel); 956 957 mac_mls_copy_effective(source, dest); 958} 959 960static void 961mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 962 struct mbuf *m, struct label *mbuflabel) 963{ 964 struct mac_mls *source, *dest; 965 966 source = SLOT(socketlabel); 967 dest = SLOT(mbuflabel); 968 969 mac_mls_copy_effective(source, dest); 970} 971 972static void 973mac_mls_create_socket(struct ucred *cred, struct socket *socket, 974 struct label *socketlabel) 975{ 976 struct mac_mls *source, *dest; 977 978 source = SLOT(cred->cr_label); 979 dest = SLOT(socketlabel); 980 981 mac_mls_copy_effective(source, dest); 982} 983 984static void 985mac_mls_create_pipe(struct ucred *cred, struct pipepair *pp, 986 struct label *pipelabel) 987{ 988 struct mac_mls *source, *dest; 989 990 source = SLOT(cred->cr_label); 991 dest = SLOT(pipelabel); 992 993 mac_mls_copy_effective(source, dest); 994} 995 996static void 997mac_mls_create_posix_sem(struct ucred *cred, struct ksem *ksemptr, 998 struct label *ks_label) 999{ 1000 struct mac_mls *source, *dest; 1001 1002 source = SLOT(cred->cr_label); 1003 dest = SLOT(ks_label); 1004 1005 mac_mls_copy_effective(source, dest); 1006} 1007 1008static void 1009mac_mls_create_socket_from_socket(struct socket *oldsocket, 1010 struct label *oldsocketlabel, struct socket *newsocket, 1011 struct label *newsocketlabel) 1012{ 1013 struct mac_mls *source, *dest; 1014 1015 source = SLOT(oldsocketlabel); 1016 dest = SLOT(newsocketlabel); 1017 1018 mac_mls_copy_effective(source, dest); 1019} 1020 1021static void 1022mac_mls_relabel_socket(struct ucred *cred, struct socket *socket, 1023 struct label *socketlabel, struct label *newlabel) 1024{ 1025 struct mac_mls *source, *dest; 1026 1027 source = SLOT(newlabel); 1028 dest = SLOT(socketlabel); 1029 1030 mac_mls_copy(source, dest); 1031} 1032 1033static void 1034mac_mls_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1035 struct label *pipelabel, struct label *newlabel) 1036{ 1037 struct mac_mls *source, *dest; 1038 1039 source = SLOT(newlabel); 1040 dest = SLOT(pipelabel); 1041 1042 mac_mls_copy(source, dest); 1043} 1044 1045static void 1046mac_mls_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1047 struct socket *socket, struct label *socketpeerlabel) 1048{ 1049 struct mac_mls *source, *dest; 1050 1051 source = SLOT(mbuflabel); 1052 dest = SLOT(socketpeerlabel); 1053 1054 mac_mls_copy_effective(source, dest); 1055} 1056 1057/* 1058 * Labeling event operations: System V IPC objects. 1059 */ 1060 1061static void 1062mac_mls_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, 1063 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1064{ 1065 struct mac_mls *source, *dest; 1066 1067 /* Ignore the msgq label */ 1068 source = SLOT(cred->cr_label); 1069 dest = SLOT(msglabel); 1070 1071 mac_mls_copy_effective(source, dest); 1072} 1073 1074static void 1075mac_mls_create_sysv_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr, 1076 struct label *msqlabel) 1077{ 1078 struct mac_mls *source, *dest; 1079 1080 source = SLOT(cred->cr_label); 1081 dest = SLOT(msqlabel); 1082 1083 mac_mls_copy_effective(source, dest); 1084} 1085 1086static void 1087mac_mls_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr, 1088 struct label *semalabel) 1089{ 1090 struct mac_mls *source, *dest; 1091 1092 source = SLOT(cred->cr_label); 1093 dest = SLOT(semalabel); 1094 1095 mac_mls_copy_effective(source, dest); 1096} 1097 1098static void 1099mac_mls_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr, 1100 struct label *shmlabel) 1101{ 1102 struct mac_mls *source, *dest; 1103 1104 source = SLOT(cred->cr_label); 1105 dest = SLOT(shmlabel); 1106 1107 mac_mls_copy_effective(source, dest); 1108} 1109 1110/* 1111 * Labeling event operations: network objects. 1112 */ 1113static void 1114mac_mls_set_socket_peer_from_socket(struct socket *oldsocket, 1115 struct label *oldsocketlabel, struct socket *newsocket, 1116 struct label *newsocketpeerlabel) 1117{ 1118 struct mac_mls *source, *dest; 1119 1120 source = SLOT(oldsocketlabel); 1121 dest = SLOT(newsocketpeerlabel); 1122 1123 mac_mls_copy_effective(source, dest); 1124} 1125 1126static void 1127mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1128 struct label *bpflabel) 1129{ 1130 struct mac_mls *source, *dest; 1131 1132 source = SLOT(cred->cr_label); 1133 dest = SLOT(bpflabel); 1134 1135 mac_mls_copy_effective(source, dest); 1136} 1137 1138static void 1139mac_mls_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1140{ 1141 struct mac_mls *dest; 1142 int type; 1143 1144 dest = SLOT(ifnetlabel); 1145 1146 if (ifnet->if_type == IFT_LOOP) 1147 type = MAC_MLS_TYPE_EQUAL; 1148 else 1149 type = MAC_MLS_TYPE_LOW; 1150 1151 mac_mls_set_effective(dest, type, 0, NULL); 1152 mac_mls_set_range(dest, type, 0, NULL, type, 0, NULL); 1153} 1154 1155static void 1156mac_mls_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1157 struct ipq *ipq, struct label *ipqlabel) 1158{ 1159 struct mac_mls *source, *dest; 1160 1161 source = SLOT(fragmentlabel); 1162 dest = SLOT(ipqlabel); 1163 1164 mac_mls_copy_effective(source, dest); 1165} 1166 1167static void 1168mac_mls_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1169 struct mbuf *datagram, struct label *datagramlabel) 1170{ 1171 struct mac_mls *source, *dest; 1172 1173 source = SLOT(ipqlabel); 1174 dest = SLOT(datagramlabel); 1175 1176 /* Just use the head, since we require them all to match. */ 1177 mac_mls_copy_effective(source, dest); 1178} 1179 1180static void 1181mac_mls_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1182 struct mbuf *fragment, struct label *fragmentlabel) 1183{ 1184 struct mac_mls *source, *dest; 1185 1186 source = SLOT(datagramlabel); 1187 dest = SLOT(fragmentlabel); 1188 1189 mac_mls_copy_effective(source, dest); 1190} 1191 1192static void 1193mac_mls_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1194 struct mbuf *m, struct label *mlabel) 1195{ 1196 struct mac_mls *source, *dest; 1197 1198 source = SLOT(inplabel); 1199 dest = SLOT(mlabel); 1200 1201 mac_mls_copy_effective(source, dest); 1202} 1203 1204static void 1205mac_mls_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1206 struct mbuf *mbuf, struct label *mbuflabel) 1207{ 1208 struct mac_mls *dest; 1209 1210 dest = SLOT(mbuflabel); 1211 1212 mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1213} 1214 1215static void 1216mac_mls_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1217 struct mbuf *mbuf, struct label *mbuflabel) 1218{ 1219 struct mac_mls *source, *dest; 1220 1221 source = SLOT(bpflabel); 1222 dest = SLOT(mbuflabel); 1223 1224 mac_mls_copy_effective(source, dest); 1225} 1226 1227static void 1228mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1229 struct mbuf *m, struct label *mbuflabel) 1230{ 1231 struct mac_mls *source, *dest; 1232 1233 source = SLOT(ifnetlabel); 1234 dest = SLOT(mbuflabel); 1235 1236 mac_mls_copy_effective(source, dest); 1237} 1238 1239static void 1240mac_mls_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1241 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1242 struct mbuf *newmbuf, struct label *newmbuflabel) 1243{ 1244 struct mac_mls *source, *dest; 1245 1246 source = SLOT(oldmbuflabel); 1247 dest = SLOT(newmbuflabel); 1248 1249 mac_mls_copy_effective(source, dest); 1250} 1251 1252static void 1253mac_mls_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1254 struct mbuf *newmbuf, struct label *newmbuflabel) 1255{ 1256 struct mac_mls *source, *dest; 1257 1258 source = SLOT(oldmbuflabel); 1259 dest = SLOT(newmbuflabel); 1260 1261 mac_mls_copy_effective(source, dest); 1262} 1263 1264static int 1265mac_mls_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1266 struct ipq *ipq, struct label *ipqlabel) 1267{ 1268 struct mac_mls *a, *b; 1269 1270 a = SLOT(ipqlabel); 1271 b = SLOT(fragmentlabel); 1272 1273 return (mac_mls_equal_effective(a, b)); 1274} 1275 1276static void 1277mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1278 struct label *ifnetlabel, struct label *newlabel) 1279{ 1280 struct mac_mls *source, *dest; 1281 1282 source = SLOT(newlabel); 1283 dest = SLOT(ifnetlabel); 1284 1285 mac_mls_copy(source, dest); 1286} 1287 1288static void 1289mac_mls_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1290 struct ipq *ipq, struct label *ipqlabel) 1291{ 1292 1293 /* NOOP: we only accept matching labels, so no need to update */ 1294} 1295 1296static void 1297mac_mls_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1298 struct inpcb *inp, struct label *inplabel) 1299{ 1300 struct mac_mls *source, *dest; 1301 1302 source = SLOT(solabel); 1303 dest = SLOT(inplabel); 1304 1305 mac_mls_copy(source, dest); 1306} 1307
|
1308/* 1309 * Labeling event operations: processes. 1310 */ 1311static void 1312mac_mls_create_proc0(struct ucred *cred) 1313{ 1314 struct mac_mls *dest; 1315 1316 dest = SLOT(cred->cr_label); 1317 1318 mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1319 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 1320 0, NULL); 1321} 1322 1323static void 1324mac_mls_create_proc1(struct ucred *cred) 1325{ 1326 struct mac_mls *dest; 1327 1328 dest = SLOT(cred->cr_label); 1329 1330 mac_mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL); 1331 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 1332 0, NULL); 1333} 1334 1335static void 1336mac_mls_relabel_cred(struct ucred *cred, struct label *newlabel) 1337{ 1338 struct mac_mls *source, *dest; 1339 1340 source = SLOT(newlabel); 1341 dest = SLOT(cred->cr_label); 1342 1343 mac_mls_copy(source, dest); 1344} 1345 1346/* 1347 * Label cleanup/flush operations. 1348 */ 1349static void 1350mac_mls_cleanup_sysv_msgmsg(struct label *msglabel) 1351{ 1352 1353 bzero(SLOT(msglabel), sizeof(struct mac_mls)); 1354} 1355 1356static void 1357mac_mls_cleanup_sysv_msgqueue(struct label *msqlabel) 1358{ 1359 1360 bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 1361} 1362 1363static void 1364mac_mls_cleanup_sysv_sem(struct label *semalabel) 1365{ 1366 1367 bzero(SLOT(semalabel), sizeof(struct mac_mls)); 1368} 1369 1370static void 1371mac_mls_cleanup_sysv_shm(struct label *shmlabel) 1372{ 1373 1374 bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 1375} 1376 1377/* 1378 * Access control checks. 1379 */ 1380static int 1381mac_mls_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1382 struct ifnet *ifnet, struct label *ifnetlabel) 1383{ 1384 struct mac_mls *a, *b; 1385 1386 if (!mac_mls_enabled) 1387 return (0); 1388 1389 a = SLOT(bpflabel); 1390 b = SLOT(ifnetlabel); 1391 1392 if (mac_mls_equal_effective(a, b)) 1393 return (0); 1394 return (EACCES); 1395} 1396 1397static int 1398mac_mls_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1399{ 1400 struct mac_mls *subj, *new; 1401 int error; 1402 1403 subj = SLOT(cred->cr_label); 1404 new = SLOT(newlabel); 1405 1406 /* 1407 * If there is an MLS label update for the credential, it may be 1408 * an update of effective, range, or both. 1409 */ 1410 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 1411 if (error) 1412 return (error); 1413 1414 /* 1415 * If the MLS label is to be changed, authorize as appropriate. 1416 */ 1417 if (new->mm_flags & MAC_MLS_FLAGS_BOTH) { 1418 /* 1419 * If the change request modifies both the MLS label effective 1420 * and range, check that the new effective will be in the 1421 * new range. 1422 */ 1423 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) == 1424 MAC_MLS_FLAGS_BOTH && 1425 !mac_mls_effective_in_range(new, new)) 1426 return (EINVAL); 1427 1428 /* 1429 * To change the MLS effective label on a credential, the 1430 * new effective label must be in the current range. 1431 */ 1432 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE && 1433 !mac_mls_effective_in_range(new, subj)) 1434 return (EPERM); 1435 1436 /* 1437 * To change the MLS range label on a credential, the 1438 * new range must be in the current range. 1439 */ 1440 if (new->mm_flags & MAC_MLS_FLAG_RANGE && 1441 !mac_mls_range_in_range(new, subj)) 1442 return (EPERM); 1443 1444 /* 1445 * To have EQUAL in any component of the new credential 1446 * MLS label, the subject must already have EQUAL in 1447 * their label. 1448 */ 1449 if (mac_mls_contains_equal(new)) { 1450 error = mac_mls_subject_privileged(subj); 1451 if (error) 1452 return (error); 1453 } 1454 } 1455 1456 return (0); 1457} 1458 1459static int 1460mac_mls_check_cred_visible(struct ucred *u1, struct ucred *u2) 1461{ 1462 struct mac_mls *subj, *obj; 1463 1464 if (!mac_mls_enabled) 1465 return (0); 1466 1467 subj = SLOT(u1->cr_label); 1468 obj = SLOT(u2->cr_label); 1469 1470 /* XXX: range */ 1471 if (!mac_mls_dominate_effective(subj, obj)) 1472 return (ESRCH); 1473 1474 return (0); 1475} 1476 1477static int 1478mac_mls_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1479 struct label *ifnetlabel, struct label *newlabel) 1480{ 1481 struct mac_mls *subj, *new; 1482 int error; 1483 1484 subj = SLOT(cred->cr_label); 1485 new = SLOT(newlabel); 1486 1487 /* 1488 * If there is an MLS label update for the interface, it may 1489 * be an update of effective, range, or both. 1490 */ 1491 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 1492 if (error) 1493 return (error); 1494 1495 /* 1496 * Relabeling network interfaces requires MLS privilege. 1497 */ 1498 error = mac_mls_subject_privileged(subj); 1499 1500 return (0); 1501} 1502 1503static int 1504mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1505 struct mbuf *m, struct label *mbuflabel) 1506{ 1507 struct mac_mls *p, *i; 1508 1509 if (!mac_mls_enabled) 1510 return (0); 1511 1512 p = SLOT(mbuflabel); 1513 i = SLOT(ifnetlabel); 1514 1515 return (mac_mls_effective_in_range(p, i) ? 0 : EACCES); 1516} 1517 1518static int 1519mac_mls_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1520 struct mbuf *m, struct label *mlabel) 1521{ 1522 struct mac_mls *p, *i; 1523 1524 if (!mac_mls_enabled) 1525 return (0); 1526 1527 p = SLOT(mlabel); 1528 i = SLOT(inplabel); 1529 1530 return (mac_mls_equal_effective(p, i) ? 0 : EACCES); 1531} 1532 1533static int 1534mac_mls_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr, 1535 struct label *msglabel) 1536{ 1537 struct mac_mls *subj, *obj; 1538 1539 if (!mac_mls_enabled) 1540 return (0); 1541 1542 subj = SLOT(cred->cr_label); 1543 obj = SLOT(msglabel); 1544 1545 if (!mac_mls_dominate_effective(subj, obj)) 1546 return (EACCES); 1547 1548 return (0); 1549} 1550 1551static int 1552mac_mls_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr, 1553 struct label *msglabel) 1554{ 1555 struct mac_mls *subj, *obj; 1556 1557 if (!mac_mls_enabled) 1558 return (0); 1559 1560 subj = SLOT(cred->cr_label); 1561 obj = SLOT(msglabel); 1562 1563 if (!mac_mls_dominate_effective(obj, subj)) 1564 return (EACCES); 1565 1566 return (0); 1567} 1568 1569static int 1570mac_mls_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1571 struct label *msqklabel) 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(msqklabel); 1580 1581 if (!mac_mls_dominate_effective(subj, obj)) 1582 return (EACCES); 1583 1584 return (0); 1585} 1586 1587static int 1588mac_mls_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1589 struct label *msqklabel) 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(msqklabel); 1598 1599 if (!mac_mls_dominate_effective(obj, subj)) 1600 return (EACCES); 1601 1602 return (0); 1603} 1604 1605static int 1606mac_mls_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1607 struct label *msqklabel) 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(msqklabel); 1616 1617 if (!mac_mls_dominate_effective(subj, obj)) 1618 return (EACCES); 1619 1620 return (0); 1621} 1622 1623static int 1624mac_mls_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1625 struct label *msqklabel, int cmd) 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(msqklabel); 1634 1635 switch(cmd) { 1636 case IPC_RMID: 1637 case IPC_SET: 1638 if (!mac_mls_dominate_effective(obj, subj)) 1639 return (EACCES); 1640 break; 1641 1642 case IPC_STAT: 1643 if (!mac_mls_dominate_effective(subj, obj)) 1644 return (EACCES); 1645 break; 1646 1647 default: 1648 return (EACCES); 1649 } 1650 1651 return (0); 1652} 1653 1654static int 1655mac_mls_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1656 struct label *semaklabel, int cmd) 1657{ 1658 struct mac_mls *subj, *obj; 1659 1660 if (!mac_mls_enabled) 1661 return (0); 1662 1663 subj = SLOT(cred->cr_label); 1664 obj = SLOT(semaklabel); 1665 1666 switch(cmd) { 1667 case IPC_RMID: 1668 case IPC_SET: 1669 case SETVAL: 1670 case SETALL: 1671 if (!mac_mls_dominate_effective(obj, subj)) 1672 return (EACCES); 1673 break; 1674 1675 case IPC_STAT: 1676 case GETVAL: 1677 case GETPID: 1678 case GETNCNT: 1679 case GETZCNT: 1680 case GETALL: 1681 if (!mac_mls_dominate_effective(subj, obj)) 1682 return (EACCES); 1683 break; 1684 1685 default: 1686 return (EACCES); 1687 } 1688 1689 return (0); 1690} 1691 1692static int 1693mac_mls_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr, 1694 struct label *semaklabel) 1695{ 1696 struct mac_mls *subj, *obj; 1697 1698 if (!mac_mls_enabled) 1699 return (0); 1700 1701 subj = SLOT(cred->cr_label); 1702 obj = SLOT(semaklabel); 1703 1704 if (!mac_mls_dominate_effective(subj, obj)) 1705 return (EACCES); 1706 1707 return (0); 1708} 1709 1710static int 1711mac_mls_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr, 1712 struct label *semaklabel, size_t accesstype) 1713{ 1714 struct mac_mls *subj, *obj; 1715 1716 if (!mac_mls_enabled) 1717 return (0); 1718 1719 subj = SLOT(cred->cr_label); 1720 obj = SLOT(semaklabel); 1721 1722 if( accesstype & SEM_R ) 1723 if (!mac_mls_dominate_effective(subj, obj)) 1724 return (EACCES); 1725 1726 if( accesstype & SEM_A ) 1727 if (!mac_mls_dominate_effective(obj, subj)) 1728 return (EACCES); 1729 1730 return (0); 1731} 1732 1733static int 1734mac_mls_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 1735 struct label *shmseglabel, int shmflg) 1736{ 1737 struct mac_mls *subj, *obj; 1738 1739 if (!mac_mls_enabled) 1740 return (0); 1741 1742 subj = SLOT(cred->cr_label); 1743 obj = SLOT(shmseglabel); 1744 1745 if (!mac_mls_dominate_effective(subj, obj)) 1746 return (EACCES); 1747 if ((shmflg & SHM_RDONLY) == 0) 1748 if (!mac_mls_dominate_effective(obj, subj)) 1749 return (EACCES); 1750 1751 return (0); 1752} 1753 1754static int 1755mac_mls_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 1756 struct label *shmseglabel, int cmd) 1757{ 1758 struct mac_mls *subj, *obj; 1759 1760 if (!mac_mls_enabled) 1761 return (0); 1762 1763 subj = SLOT(cred->cr_label); 1764 obj = SLOT(shmseglabel); 1765 1766 switch(cmd) { 1767 case IPC_RMID: 1768 case IPC_SET: 1769 if (!mac_mls_dominate_effective(obj, subj)) 1770 return (EACCES); 1771 break; 1772 1773 case IPC_STAT: 1774 case SHM_STAT: 1775 if (!mac_mls_dominate_effective(subj, obj)) 1776 return (EACCES); 1777 break; 1778 1779 default: 1780 return (EACCES); 1781 } 1782 1783 return (0); 1784} 1785 1786static int 1787mac_mls_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 1788 struct label *shmseglabel, int shmflg) 1789{ 1790 struct mac_mls *subj, *obj; 1791 1792 if (!mac_mls_enabled) 1793 return (0); 1794 1795 subj = SLOT(cred->cr_label); 1796 obj = SLOT(shmseglabel); 1797 1798 if (!mac_mls_dominate_effective(obj, subj)) 1799 return (EACCES); 1800 1801 return (0); 1802} 1803 1804static int 1805mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp, 1806 struct label *mntlabel) 1807{ 1808 struct mac_mls *subj, *obj; 1809 1810 if (!mac_mls_enabled) 1811 return (0); 1812 1813 subj = SLOT(cred->cr_label); 1814 obj = SLOT(mntlabel); 1815 1816 if (!mac_mls_dominate_effective(subj, obj)) 1817 return (EACCES); 1818 1819 return (0); 1820} 1821 1822static int 1823mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1824 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1825{ 1826 1827 if(!mac_mls_enabled) 1828 return (0); 1829 1830 /* XXX: This will be implemented soon... */ 1831 1832 return (0); 1833} 1834 1835static int 1836mac_mls_check_pipe_poll(struct ucred *cred, struct pipepair *pp, 1837 struct label *pipelabel) 1838{ 1839 struct mac_mls *subj, *obj; 1840 1841 if (!mac_mls_enabled) 1842 return (0); 1843 1844 subj = SLOT(cred->cr_label); 1845 obj = SLOT((pipelabel)); 1846 1847 if (!mac_mls_dominate_effective(subj, obj)) 1848 return (EACCES); 1849 1850 return (0); 1851} 1852 1853static int 1854mac_mls_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1855 struct label *pipelabel) 1856{ 1857 struct mac_mls *subj, *obj; 1858 1859 if (!mac_mls_enabled) 1860 return (0); 1861 1862 subj = SLOT(cred->cr_label); 1863 obj = SLOT((pipelabel)); 1864 1865 if (!mac_mls_dominate_effective(subj, obj)) 1866 return (EACCES); 1867 1868 return (0); 1869} 1870 1871static int 1872mac_mls_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1873 struct label *pipelabel, struct label *newlabel) 1874{ 1875 struct mac_mls *subj, *obj, *new; 1876 int error; 1877 1878 new = SLOT(newlabel); 1879 subj = SLOT(cred->cr_label); 1880 obj = SLOT(pipelabel); 1881 1882 /* 1883 * If there is an MLS label update for a pipe, it must be a 1884 * effective update. 1885 */ 1886 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1887 if (error) 1888 return (error); 1889 1890 /* 1891 * To perform a relabel of a pipe (MLS label or not), MLS must 1892 * authorize the relabel. 1893 */ 1894 if (!mac_mls_effective_in_range(obj, subj)) 1895 return (EPERM); 1896 1897 /* 1898 * If the MLS label is to be changed, authorize as appropriate. 1899 */ 1900 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1901 /* 1902 * To change the MLS label on a pipe, the new pipe label 1903 * must be in the subject range. 1904 */ 1905 if (!mac_mls_effective_in_range(new, subj)) 1906 return (EPERM); 1907 1908 /* 1909 * To change the MLS label on a pipe to be EQUAL, the 1910 * subject must have appropriate privilege. 1911 */ 1912 if (mac_mls_contains_equal(new)) { 1913 error = mac_mls_subject_privileged(subj); 1914 if (error) 1915 return (error); 1916 } 1917 } 1918 1919 return (0); 1920} 1921 1922static int 1923mac_mls_check_pipe_stat(struct ucred *cred, struct pipepair *pp, 1924 struct label *pipelabel) 1925{ 1926 struct mac_mls *subj, *obj; 1927 1928 if (!mac_mls_enabled) 1929 return (0); 1930 1931 subj = SLOT(cred->cr_label); 1932 obj = SLOT((pipelabel)); 1933 1934 if (!mac_mls_dominate_effective(subj, obj)) 1935 return (EACCES); 1936 1937 return (0); 1938} 1939 1940static int 1941mac_mls_check_pipe_write(struct ucred *cred, struct pipepair *pp, 1942 struct label *pipelabel) 1943{ 1944 struct mac_mls *subj, *obj; 1945 1946 if (!mac_mls_enabled) 1947 return (0); 1948 1949 subj = SLOT(cred->cr_label); 1950 obj = SLOT((pipelabel)); 1951 1952 if (!mac_mls_dominate_effective(obj, subj)) 1953 return (EACCES); 1954 1955 return (0); 1956} 1957 1958static int 1959mac_mls_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr, 1960 struct label *ks_label) 1961{ 1962 struct mac_mls *subj, *obj; 1963 1964 if (!mac_mls_enabled) 1965 return (0); 1966 1967 subj = SLOT(cred->cr_label); 1968 obj = SLOT(ks_label); 1969 1970 if (!mac_mls_dominate_effective(obj, subj)) 1971 return (EACCES); 1972 1973 return (0); 1974} 1975 1976static int 1977mac_mls_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr, 1978 struct label *ks_label) 1979{ 1980 struct mac_mls *subj, *obj; 1981 1982 if (!mac_mls_enabled) 1983 return (0); 1984 1985 subj = SLOT(cred->cr_label); 1986 obj = SLOT(ks_label); 1987 1988 if (!mac_mls_dominate_effective(subj, obj)) 1989 return (EACCES); 1990 1991 return (0); 1992} 1993 1994static int 1995mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc) 1996{ 1997 struct mac_mls *subj, *obj; 1998 1999 if (!mac_mls_enabled) 2000 return (0); 2001 2002 subj = SLOT(cred->cr_label); 2003 obj = SLOT(proc->p_ucred->cr_label); 2004 2005 /* XXX: range checks */ 2006 if (!mac_mls_dominate_effective(subj, obj)) 2007 return (ESRCH); 2008 if (!mac_mls_dominate_effective(obj, subj)) 2009 return (EACCES); 2010 2011 return (0); 2012} 2013 2014static int 2015mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc) 2016{ 2017 struct mac_mls *subj, *obj; 2018 2019 if (!mac_mls_enabled) 2020 return (0); 2021 2022 subj = SLOT(cred->cr_label); 2023 obj = SLOT(proc->p_ucred->cr_label); 2024 2025 /* XXX: range checks */ 2026 if (!mac_mls_dominate_effective(subj, obj)) 2027 return (ESRCH); 2028 if (!mac_mls_dominate_effective(obj, subj)) 2029 return (EACCES); 2030 2031 return (0); 2032} 2033 2034static int 2035mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2036{ 2037 struct mac_mls *subj, *obj; 2038 2039 if (!mac_mls_enabled) 2040 return (0); 2041 2042 subj = SLOT(cred->cr_label); 2043 obj = SLOT(proc->p_ucred->cr_label); 2044 2045 /* XXX: range checks */ 2046 if (!mac_mls_dominate_effective(subj, obj)) 2047 return (ESRCH); 2048 if (!mac_mls_dominate_effective(obj, subj)) 2049 return (EACCES); 2050 2051 return (0); 2052} 2053 2054static int 2055mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel, 2056 struct mbuf *m, struct label *mbuflabel) 2057{ 2058 struct mac_mls *p, *s; 2059 2060 if (!mac_mls_enabled) 2061 return (0); 2062 2063 p = SLOT(mbuflabel); 2064 s = SLOT(socketlabel); 2065 2066 return (mac_mls_equal_effective(p, s) ? 0 : EACCES); 2067} 2068 2069static int 2070mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket, 2071 struct label *socketlabel, struct label *newlabel) 2072{ 2073 struct mac_mls *subj, *obj, *new; 2074 int error; 2075 2076 new = SLOT(newlabel); 2077 subj = SLOT(cred->cr_label); 2078 obj = SLOT(socketlabel); 2079 2080 /* 2081 * If there is an MLS label update for the socket, it may be 2082 * an update of effective. 2083 */ 2084 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2085 if (error) 2086 return (error); 2087 2088 /* 2089 * To relabel a socket, the old socket effective must be in the subject 2090 * range. 2091 */ 2092 if (!mac_mls_effective_in_range(obj, subj)) 2093 return (EPERM); 2094 2095 /* 2096 * If the MLS label is to be changed, authorize as appropriate. 2097 */ 2098 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2099 /* 2100 * To relabel a socket, the new socket effective must be in 2101 * the subject range. 2102 */ 2103 if (!mac_mls_effective_in_range(new, subj)) 2104 return (EPERM); 2105 2106 /* 2107 * To change the MLS label on the socket to contain EQUAL, 2108 * the subject must have appropriate privilege. 2109 */ 2110 if (mac_mls_contains_equal(new)) { 2111 error = mac_mls_subject_privileged(subj); 2112 if (error) 2113 return (error); 2114 } 2115 } 2116 2117 return (0); 2118} 2119 2120static int 2121mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket, 2122 struct label *socketlabel) 2123{ 2124 struct mac_mls *subj, *obj; 2125 2126 if (!mac_mls_enabled) 2127 return (0); 2128 2129 subj = SLOT(cred->cr_label); 2130 obj = SLOT(socketlabel); 2131 2132 if (!mac_mls_dominate_effective(subj, obj)) 2133 return (ENOENT); 2134 2135 return (0); 2136} 2137 2138static int 2139mac_mls_check_system_swapon(struct ucred *cred, struct vnode *vp, 2140 struct label *label) 2141{ 2142 struct mac_mls *subj, *obj; 2143 2144 if (!mac_mls_enabled) 2145 return (0); 2146 2147 subj = SLOT(cred->cr_label); 2148 obj = SLOT(label); 2149 2150 if (!mac_mls_dominate_effective(obj, subj) || 2151 !mac_mls_dominate_effective(subj, obj)) 2152 return (EACCES); 2153 2154 return (0); 2155} 2156 2157static int 2158mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2159 struct label *dlabel) 2160{ 2161 struct mac_mls *subj, *obj; 2162 2163 if (!mac_mls_enabled) 2164 return (0); 2165 2166 subj = SLOT(cred->cr_label); 2167 obj = SLOT(dlabel); 2168 2169 if (!mac_mls_dominate_effective(subj, obj)) 2170 return (EACCES); 2171 2172 return (0); 2173} 2174 2175static int 2176mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2177 struct label *dlabel) 2178{ 2179 struct mac_mls *subj, *obj; 2180 2181 if (!mac_mls_enabled) 2182 return (0); 2183 2184 subj = SLOT(cred->cr_label); 2185 obj = SLOT(dlabel); 2186 2187 if (!mac_mls_dominate_effective(subj, obj)) 2188 return (EACCES); 2189 2190 return (0); 2191} 2192 2193static int 2194mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2195 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2196{ 2197 struct mac_mls *subj, *obj; 2198 2199 if (!mac_mls_enabled) 2200 return (0); 2201 2202 subj = SLOT(cred->cr_label); 2203 obj = SLOT(dlabel); 2204 2205 if (!mac_mls_dominate_effective(obj, subj)) 2206 return (EACCES); 2207 2208 return (0); 2209} 2210 2211static int 2212mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2213 struct label *dlabel, struct vnode *vp, struct label *label, 2214 struct componentname *cnp) 2215{ 2216 struct mac_mls *subj, *obj; 2217 2218 if (!mac_mls_enabled) 2219 return (0); 2220 2221 subj = SLOT(cred->cr_label); 2222 obj = SLOT(dlabel); 2223 2224 if (!mac_mls_dominate_effective(obj, subj)) 2225 return (EACCES); 2226 2227 obj = SLOT(label); 2228 2229 if (!mac_mls_dominate_effective(obj, subj)) 2230 return (EACCES); 2231 2232 return (0); 2233} 2234 2235static int 2236mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2237 struct label *label, acl_type_t type) 2238{ 2239 struct mac_mls *subj, *obj; 2240 2241 if (!mac_mls_enabled) 2242 return (0); 2243 2244 subj = SLOT(cred->cr_label); 2245 obj = SLOT(label); 2246 2247 if (!mac_mls_dominate_effective(obj, subj)) 2248 return (EACCES); 2249 2250 return (0); 2251} 2252 2253static int 2254mac_mls_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2255 struct label *label, int attrnamespace, const char *name) 2256{ 2257 struct mac_mls *subj, *obj; 2258 2259 if (!mac_mls_enabled) 2260 return (0); 2261 2262 subj = SLOT(cred->cr_label); 2263 obj = SLOT(label); 2264 2265 if (!mac_mls_dominate_effective(obj, subj)) 2266 return (EACCES); 2267 2268 return (0); 2269} 2270 2271static int 2272mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2273 struct label *label, struct image_params *imgp, 2274 struct label *execlabel) 2275{ 2276 struct mac_mls *subj, *obj, *exec; 2277 int error; 2278 2279 if (execlabel != NULL) { 2280 /* 2281 * We currently don't permit labels to be changed at 2282 * exec-time as part of MLS, so disallow non-NULL 2283 * MLS label elements in the execlabel. 2284 */ 2285 exec = SLOT(execlabel); 2286 error = mls_atmostflags(exec, 0); 2287 if (error) 2288 return (error); 2289 } 2290 2291 if (!mac_mls_enabled) 2292 return (0); 2293 2294 subj = SLOT(cred->cr_label); 2295 obj = SLOT(label); 2296 2297 if (!mac_mls_dominate_effective(subj, obj)) 2298 return (EACCES); 2299 2300 return (0); 2301} 2302 2303static int 2304mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2305 struct label *label, acl_type_t type) 2306{ 2307 struct mac_mls *subj, *obj; 2308 2309 if (!mac_mls_enabled) 2310 return (0); 2311 2312 subj = SLOT(cred->cr_label); 2313 obj = SLOT(label); 2314 2315 if (!mac_mls_dominate_effective(subj, obj)) 2316 return (EACCES); 2317 2318 return (0); 2319} 2320 2321static int 2322mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2323 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2324{ 2325 struct mac_mls *subj, *obj; 2326 2327 if (!mac_mls_enabled) 2328 return (0); 2329 2330 subj = SLOT(cred->cr_label); 2331 obj = SLOT(label); 2332 2333 if (!mac_mls_dominate_effective(subj, obj)) 2334 return (EACCES); 2335 2336 return (0); 2337} 2338 2339static int 2340mac_mls_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2341 struct label *dlabel, struct vnode *vp, struct label *label, 2342 struct componentname *cnp) 2343{ 2344 struct mac_mls *subj, *obj; 2345 2346 if (!mac_mls_enabled) 2347 return (0); 2348 2349 subj = SLOT(cred->cr_label); 2350 obj = SLOT(dlabel); 2351 2352 if (!mac_mls_dominate_effective(obj, subj)) 2353 return (EACCES); 2354 2355 obj = SLOT(dlabel); 2356 if (!mac_mls_dominate_effective(obj, subj)) 2357 return (EACCES); 2358 2359 return (0); 2360} 2361 2362static int 2363mac_mls_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2364 struct label *label, int attrnamespace) 2365{ 2366 2367 struct mac_mls *subj, *obj; 2368 2369 if (!mac_mls_enabled) 2370 return (0); 2371 2372 subj = SLOT(cred->cr_label); 2373 obj = SLOT(label); 2374 2375 if (!mac_mls_dominate_effective(subj, obj)) 2376 return (EACCES); 2377 2378 return (0); 2379} 2380 2381static int 2382mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2383 struct label *dlabel, struct componentname *cnp) 2384{ 2385 struct mac_mls *subj, *obj; 2386 2387 if (!mac_mls_enabled) 2388 return (0); 2389 2390 subj = SLOT(cred->cr_label); 2391 obj = SLOT(dlabel); 2392 2393 if (!mac_mls_dominate_effective(subj, obj)) 2394 return (EACCES); 2395 2396 return (0); 2397} 2398 2399static int 2400mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2401 struct label *label, int prot, int flags) 2402{ 2403 struct mac_mls *subj, *obj; 2404 2405 /* 2406 * Rely on the use of open()-time protections to handle 2407 * non-revocation cases. 2408 */ 2409 if (!mac_mls_enabled || !revocation_enabled) 2410 return (0); 2411 2412 subj = SLOT(cred->cr_label); 2413 obj = SLOT(label); 2414 2415 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2416 if (!mac_mls_dominate_effective(subj, obj)) 2417 return (EACCES); 2418 } 2419 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2420 if (!mac_mls_dominate_effective(obj, subj)) 2421 return (EACCES); 2422 } 2423 2424 return (0); 2425} 2426 2427static int 2428mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, 2429 struct label *vnodelabel, int acc_mode) 2430{ 2431 struct mac_mls *subj, *obj; 2432 2433 if (!mac_mls_enabled) 2434 return (0); 2435 2436 subj = SLOT(cred->cr_label); 2437 obj = SLOT(vnodelabel); 2438 2439 /* XXX privilege override for admin? */ 2440 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2441 if (!mac_mls_dominate_effective(subj, obj)) 2442 return (EACCES); 2443 } 2444 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2445 if (!mac_mls_dominate_effective(obj, subj)) 2446 return (EACCES); 2447 } 2448 2449 return (0); 2450} 2451 2452static int 2453mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2454 struct vnode *vp, struct label *label) 2455{ 2456 struct mac_mls *subj, *obj; 2457 2458 if (!mac_mls_enabled || !revocation_enabled) 2459 return (0); 2460 2461 subj = SLOT(active_cred->cr_label); 2462 obj = SLOT(label); 2463 2464 if (!mac_mls_dominate_effective(subj, obj)) 2465 return (EACCES); 2466 2467 return (0); 2468} 2469 2470static int 2471mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2472 struct vnode *vp, struct label *label) 2473{ 2474 struct mac_mls *subj, *obj; 2475 2476 if (!mac_mls_enabled || !revocation_enabled) 2477 return (0); 2478 2479 subj = SLOT(active_cred->cr_label); 2480 obj = SLOT(label); 2481 2482 if (!mac_mls_dominate_effective(subj, obj)) 2483 return (EACCES); 2484 2485 return (0); 2486} 2487 2488static int 2489mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2490 struct label *dlabel) 2491{ 2492 struct mac_mls *subj, *obj; 2493 2494 if (!mac_mls_enabled) 2495 return (0); 2496 2497 subj = SLOT(cred->cr_label); 2498 obj = SLOT(dlabel); 2499 2500 if (!mac_mls_dominate_effective(subj, obj)) 2501 return (EACCES); 2502 2503 return (0); 2504} 2505 2506static int 2507mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2508 struct label *vnodelabel) 2509{ 2510 struct mac_mls *subj, *obj; 2511 2512 if (!mac_mls_enabled) 2513 return (0); 2514 2515 subj = SLOT(cred->cr_label); 2516 obj = SLOT(vnodelabel); 2517 2518 if (!mac_mls_dominate_effective(subj, obj)) 2519 return (EACCES); 2520 2521 return (0); 2522} 2523 2524static int 2525mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2526 struct label *vnodelabel, struct label *newlabel) 2527{ 2528 struct mac_mls *old, *new, *subj; 2529 int error; 2530 2531 old = SLOT(vnodelabel); 2532 new = SLOT(newlabel); 2533 subj = SLOT(cred->cr_label); 2534 2535 /* 2536 * If there is an MLS label update for the vnode, it must be a 2537 * effective label. 2538 */ 2539 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2540 if (error) 2541 return (error); 2542 2543 /* 2544 * To perform a relabel of the vnode (MLS label or not), MLS must 2545 * authorize the relabel. 2546 */ 2547 if (!mac_mls_effective_in_range(old, subj)) 2548 return (EPERM); 2549 2550 /* 2551 * If the MLS label is to be changed, authorize as appropriate. 2552 */ 2553 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2554 /* 2555 * To change the MLS label on a vnode, the new vnode label 2556 * must be in the subject range. 2557 */ 2558 if (!mac_mls_effective_in_range(new, subj)) 2559 return (EPERM); 2560 2561 /* 2562 * To change the MLS label on the vnode to be EQUAL, 2563 * the subject must have appropriate privilege. 2564 */ 2565 if (mac_mls_contains_equal(new)) { 2566 error = mac_mls_subject_privileged(subj); 2567 if (error) 2568 return (error); 2569 } 2570 } 2571 2572 return (0); 2573} 2574 2575 2576static int 2577mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2578 struct label *dlabel, struct vnode *vp, struct label *label, 2579 struct componentname *cnp) 2580{ 2581 struct mac_mls *subj, *obj; 2582 2583 if (!mac_mls_enabled) 2584 return (0); 2585 2586 subj = SLOT(cred->cr_label); 2587 obj = SLOT(dlabel); 2588 2589 if (!mac_mls_dominate_effective(obj, subj)) 2590 return (EACCES); 2591 2592 obj = SLOT(label); 2593 2594 if (!mac_mls_dominate_effective(obj, subj)) 2595 return (EACCES); 2596 2597 return (0); 2598} 2599 2600static int 2601mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2602 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2603 struct componentname *cnp) 2604{ 2605 struct mac_mls *subj, *obj; 2606 2607 if (!mac_mls_enabled) 2608 return (0); 2609 2610 subj = SLOT(cred->cr_label); 2611 obj = SLOT(dlabel); 2612 2613 if (!mac_mls_dominate_effective(obj, subj)) 2614 return (EACCES); 2615 2616 if (vp != NULL) { 2617 obj = SLOT(label); 2618 2619 if (!mac_mls_dominate_effective(obj, subj)) 2620 return (EACCES); 2621 } 2622 2623 return (0); 2624} 2625 2626static int 2627mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2628 struct label *label) 2629{ 2630 struct mac_mls *subj, *obj; 2631 2632 if (!mac_mls_enabled) 2633 return (0); 2634 2635 subj = SLOT(cred->cr_label); 2636 obj = SLOT(label); 2637 2638 if (!mac_mls_dominate_effective(obj, subj)) 2639 return (EACCES); 2640 2641 return (0); 2642} 2643 2644static int 2645mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2646 struct label *label, acl_type_t type, struct acl *acl) 2647{ 2648 struct mac_mls *subj, *obj; 2649 2650 if (!mac_mls_enabled) 2651 return (0); 2652 2653 subj = SLOT(cred->cr_label); 2654 obj = SLOT(label); 2655 2656 if (!mac_mls_dominate_effective(obj, subj)) 2657 return (EACCES); 2658 2659 return (0); 2660} 2661 2662static int 2663mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2664 struct label *vnodelabel, int attrnamespace, const char *name, 2665 struct uio *uio) 2666{ 2667 struct mac_mls *subj, *obj; 2668 2669 if (!mac_mls_enabled) 2670 return (0); 2671 2672 subj = SLOT(cred->cr_label); 2673 obj = SLOT(vnodelabel); 2674 2675 if (!mac_mls_dominate_effective(obj, subj)) 2676 return (EACCES); 2677 2678 /* XXX: protect the MAC EA in a special way? */ 2679 2680 return (0); 2681} 2682 2683static int 2684mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2685 struct label *vnodelabel, u_long flags) 2686{ 2687 struct mac_mls *subj, *obj; 2688 2689 if (!mac_mls_enabled) 2690 return (0); 2691 2692 subj = SLOT(cred->cr_label); 2693 obj = SLOT(vnodelabel); 2694 2695 if (!mac_mls_dominate_effective(obj, subj)) 2696 return (EACCES); 2697 2698 return (0); 2699} 2700 2701static int 2702mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2703 struct label *vnodelabel, mode_t mode) 2704{ 2705 struct mac_mls *subj, *obj; 2706 2707 if (!mac_mls_enabled) 2708 return (0); 2709 2710 subj = SLOT(cred->cr_label); 2711 obj = SLOT(vnodelabel); 2712 2713 if (!mac_mls_dominate_effective(obj, subj)) 2714 return (EACCES); 2715 2716 return (0); 2717} 2718 2719static int 2720mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2721 struct label *vnodelabel, uid_t uid, gid_t gid) 2722{ 2723 struct mac_mls *subj, *obj; 2724 2725 if (!mac_mls_enabled) 2726 return (0); 2727 2728 subj = SLOT(cred->cr_label); 2729 obj = SLOT(vnodelabel); 2730 2731 if (!mac_mls_dominate_effective(obj, subj)) 2732 return (EACCES); 2733 2734 return (0); 2735} 2736 2737static int 2738mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2739 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2740{ 2741 struct mac_mls *subj, *obj; 2742 2743 if (!mac_mls_enabled) 2744 return (0); 2745 2746 subj = SLOT(cred->cr_label); 2747 obj = SLOT(vnodelabel); 2748 2749 if (!mac_mls_dominate_effective(obj, subj)) 2750 return (EACCES); 2751 2752 return (0); 2753} 2754 2755static int 2756mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2757 struct vnode *vp, struct label *vnodelabel) 2758{ 2759 struct mac_mls *subj, *obj; 2760 2761 if (!mac_mls_enabled) 2762 return (0); 2763 2764 subj = SLOT(active_cred->cr_label); 2765 obj = SLOT(vnodelabel); 2766 2767 if (!mac_mls_dominate_effective(subj, obj)) 2768 return (EACCES); 2769 2770 return (0); 2771} 2772 2773static int 2774mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2775 struct vnode *vp, struct label *label) 2776{ 2777 struct mac_mls *subj, *obj; 2778 2779 if (!mac_mls_enabled || !revocation_enabled) 2780 return (0); 2781 2782 subj = SLOT(active_cred->cr_label); 2783 obj = SLOT(label); 2784 2785 if (!mac_mls_dominate_effective(obj, subj)) 2786 return (EACCES); 2787 2788 return (0); 2789} 2790 2791static void 2792mac_mls_associate_nfsd_label(struct ucred *cred) 2793{ 2794 struct mac_mls *label; 2795 2796 label = SLOT(cred->cr_label); 2797 mac_mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL); 2798 mac_mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL, 2799 MAC_MLS_TYPE_HIGH, 0, NULL); 2800} 2801 2802static struct mac_policy_ops mac_mls_ops = 2803{ 2804 .mpo_init = mac_mls_init, 2805 .mpo_init_bpfdesc_label = mac_mls_init_label, 2806 .mpo_init_cred_label = mac_mls_init_label, 2807 .mpo_init_devfsdirent_label = mac_mls_init_label, 2808 .mpo_init_ifnet_label = mac_mls_init_label, 2809 .mpo_init_inpcb_label = mac_mls_init_label_waitcheck, 2810 .mpo_init_sysv_msgmsg_label = mac_mls_init_label, 2811 .mpo_init_sysv_msgqueue_label = mac_mls_init_label, 2812 .mpo_init_sysv_sem_label = mac_mls_init_label, 2813 .mpo_init_sysv_shm_label = mac_mls_init_label, 2814 .mpo_init_ipq_label = mac_mls_init_label_waitcheck, 2815 .mpo_init_mbuf_label = mac_mls_init_label_waitcheck, 2816 .mpo_init_mount_label = mac_mls_init_label, 2817 .mpo_init_mount_fs_label = mac_mls_init_label, 2818 .mpo_init_pipe_label = mac_mls_init_label, 2819 .mpo_init_posix_sem_label = mac_mls_init_label, 2820 .mpo_init_socket_label = mac_mls_init_label_waitcheck, 2821 .mpo_init_socket_peer_label = mac_mls_init_label_waitcheck, 2822 .mpo_init_vnode_label = mac_mls_init_label, 2823 .mpo_destroy_bpfdesc_label = mac_mls_destroy_label, 2824 .mpo_destroy_cred_label = mac_mls_destroy_label, 2825 .mpo_destroy_devfsdirent_label = mac_mls_destroy_label, 2826 .mpo_destroy_ifnet_label = mac_mls_destroy_label, 2827 .mpo_destroy_inpcb_label = mac_mls_destroy_label, 2828 .mpo_destroy_sysv_msgmsg_label = mac_mls_destroy_label, 2829 .mpo_destroy_sysv_msgqueue_label = mac_mls_destroy_label, 2830 .mpo_destroy_sysv_sem_label = mac_mls_destroy_label, 2831 .mpo_destroy_sysv_shm_label = mac_mls_destroy_label, 2832 .mpo_destroy_ipq_label = mac_mls_destroy_label, 2833 .mpo_destroy_mbuf_label = mac_mls_destroy_label, 2834 .mpo_destroy_mount_label = mac_mls_destroy_label, 2835 .mpo_destroy_mount_fs_label = mac_mls_destroy_label, 2836 .mpo_destroy_pipe_label = mac_mls_destroy_label, 2837 .mpo_destroy_posix_sem_label = mac_mls_destroy_label, 2838 .mpo_destroy_socket_label = mac_mls_destroy_label, 2839 .mpo_destroy_socket_peer_label = mac_mls_destroy_label, 2840 .mpo_destroy_vnode_label = mac_mls_destroy_label, 2841 .mpo_copy_cred_label = mac_mls_copy_label, 2842 .mpo_copy_ifnet_label = mac_mls_copy_label, 2843 .mpo_copy_mbuf_label = mac_mls_copy_label, 2844 .mpo_copy_pipe_label = mac_mls_copy_label, 2845 .mpo_copy_socket_label = mac_mls_copy_label, 2846 .mpo_copy_vnode_label = mac_mls_copy_label, 2847 .mpo_externalize_cred_label = mac_mls_externalize_label, 2848 .mpo_externalize_ifnet_label = mac_mls_externalize_label, 2849 .mpo_externalize_pipe_label = mac_mls_externalize_label, 2850 .mpo_externalize_socket_label = mac_mls_externalize_label, 2851 .mpo_externalize_socket_peer_label = mac_mls_externalize_label, 2852 .mpo_externalize_vnode_label = mac_mls_externalize_label, 2853 .mpo_internalize_cred_label = mac_mls_internalize_label, 2854 .mpo_internalize_ifnet_label = mac_mls_internalize_label, 2855 .mpo_internalize_pipe_label = mac_mls_internalize_label, 2856 .mpo_internalize_socket_label = mac_mls_internalize_label, 2857 .mpo_internalize_vnode_label = mac_mls_internalize_label, 2858 .mpo_create_devfs_device = mac_mls_create_devfs_device, 2859 .mpo_create_devfs_directory = mac_mls_create_devfs_directory, 2860 .mpo_create_devfs_symlink = mac_mls_create_devfs_symlink, 2861 .mpo_create_mount = mac_mls_create_mount, 2862 .mpo_relabel_vnode = mac_mls_relabel_vnode, 2863 .mpo_update_devfsdirent = mac_mls_update_devfsdirent, 2864 .mpo_associate_vnode_devfs = mac_mls_associate_vnode_devfs, 2865 .mpo_associate_vnode_extattr = mac_mls_associate_vnode_extattr, 2866 .mpo_associate_vnode_singlelabel = mac_mls_associate_vnode_singlelabel, 2867 .mpo_create_vnode_extattr = mac_mls_create_vnode_extattr, 2868 .mpo_setlabel_vnode_extattr = mac_mls_setlabel_vnode_extattr, 2869 .mpo_create_mbuf_from_socket = mac_mls_create_mbuf_from_socket, 2870 .mpo_create_pipe = mac_mls_create_pipe, 2871 .mpo_create_posix_sem = mac_mls_create_posix_sem, 2872 .mpo_create_socket = mac_mls_create_socket, 2873 .mpo_create_socket_from_socket = mac_mls_create_socket_from_socket, 2874 .mpo_relabel_pipe = mac_mls_relabel_pipe, 2875 .mpo_relabel_socket = mac_mls_relabel_socket, 2876 .mpo_set_socket_peer_from_mbuf = mac_mls_set_socket_peer_from_mbuf, 2877 .mpo_set_socket_peer_from_socket = mac_mls_set_socket_peer_from_socket, 2878 .mpo_create_bpfdesc = mac_mls_create_bpfdesc, 2879 .mpo_create_datagram_from_ipq = mac_mls_create_datagram_from_ipq, 2880 .mpo_create_fragment = mac_mls_create_fragment, 2881 .mpo_create_ifnet = mac_mls_create_ifnet, 2882 .mpo_create_inpcb_from_socket = mac_mls_create_inpcb_from_socket, 2883 .mpo_create_ipq = mac_mls_create_ipq, 2884 .mpo_create_sysv_msgmsg = mac_mls_create_sysv_msgmsg, 2885 .mpo_create_sysv_msgqueue = mac_mls_create_sysv_msgqueue, 2886 .mpo_create_sysv_sem = mac_mls_create_sysv_sem, 2887 .mpo_create_sysv_shm = mac_mls_create_sysv_shm, 2888 .mpo_create_mbuf_from_inpcb = mac_mls_create_mbuf_from_inpcb, 2889 .mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer, 2890 .mpo_create_mbuf_from_bpfdesc = mac_mls_create_mbuf_from_bpfdesc, 2891 .mpo_create_mbuf_from_ifnet = mac_mls_create_mbuf_from_ifnet, 2892 .mpo_create_mbuf_multicast_encap = mac_mls_create_mbuf_multicast_encap, 2893 .mpo_create_mbuf_netlayer = mac_mls_create_mbuf_netlayer, 2894 .mpo_fragment_match = mac_mls_fragment_match, 2895 .mpo_relabel_ifnet = mac_mls_relabel_ifnet, 2896 .mpo_update_ipq = mac_mls_update_ipq, 2897 .mpo_inpcb_sosetlabel = mac_mls_inpcb_sosetlabel, 2898 .mpo_create_proc0 = mac_mls_create_proc0, 2899 .mpo_create_proc1 = mac_mls_create_proc1, 2900 .mpo_relabel_cred = mac_mls_relabel_cred, 2901 .mpo_cleanup_sysv_msgmsg = mac_mls_cleanup_sysv_msgmsg, 2902 .mpo_cleanup_sysv_msgqueue = mac_mls_cleanup_sysv_msgqueue, 2903 .mpo_cleanup_sysv_sem = mac_mls_cleanup_sysv_sem, 2904 .mpo_cleanup_sysv_shm = mac_mls_cleanup_sysv_shm, 2905 .mpo_check_bpfdesc_receive = mac_mls_check_bpfdesc_receive, 2906 .mpo_check_cred_relabel = mac_mls_check_cred_relabel, 2907 .mpo_check_cred_visible = mac_mls_check_cred_visible, 2908 .mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel, 2909 .mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit, 2910 .mpo_check_inpcb_deliver = mac_mls_check_inpcb_deliver, 2911 .mpo_check_sysv_msgrcv = mac_mls_check_sysv_msgrcv, 2912 .mpo_check_sysv_msgrmid = mac_mls_check_sysv_msgrmid, 2913 .mpo_check_sysv_msqget = mac_mls_check_sysv_msqget, 2914 .mpo_check_sysv_msqsnd = mac_mls_check_sysv_msqsnd, 2915 .mpo_check_sysv_msqrcv = mac_mls_check_sysv_msqrcv, 2916 .mpo_check_sysv_msqctl = mac_mls_check_sysv_msqctl, 2917 .mpo_check_sysv_semctl = mac_mls_check_sysv_semctl, 2918 .mpo_check_sysv_semget = mac_mls_check_sysv_semget, 2919 .mpo_check_sysv_semop = mac_mls_check_sysv_semop, 2920 .mpo_check_sysv_shmat = mac_mls_check_sysv_shmat, 2921 .mpo_check_sysv_shmctl = mac_mls_check_sysv_shmctl, 2922 .mpo_check_sysv_shmget = mac_mls_check_sysv_shmget, 2923 .mpo_check_mount_stat = mac_mls_check_mount_stat, 2924 .mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl, 2925 .mpo_check_pipe_poll = mac_mls_check_pipe_poll, 2926 .mpo_check_pipe_read = mac_mls_check_pipe_read, 2927 .mpo_check_pipe_relabel = mac_mls_check_pipe_relabel, 2928 .mpo_check_pipe_stat = mac_mls_check_pipe_stat, 2929 .mpo_check_pipe_write = mac_mls_check_pipe_write, 2930 .mpo_check_posix_sem_destroy = mac_mls_check_posix_sem_write, 2931 .mpo_check_posix_sem_getvalue = mac_mls_check_posix_sem_rdonly, 2932 .mpo_check_posix_sem_open = mac_mls_check_posix_sem_write, 2933 .mpo_check_posix_sem_post = mac_mls_check_posix_sem_write, 2934 .mpo_check_posix_sem_unlink = mac_mls_check_posix_sem_write, 2935 .mpo_check_posix_sem_wait = mac_mls_check_posix_sem_write, 2936 .mpo_check_proc_debug = mac_mls_check_proc_debug, 2937 .mpo_check_proc_sched = mac_mls_check_proc_sched, 2938 .mpo_check_proc_signal = mac_mls_check_proc_signal, 2939 .mpo_check_socket_deliver = mac_mls_check_socket_deliver, 2940 .mpo_check_socket_relabel = mac_mls_check_socket_relabel, 2941 .mpo_check_socket_visible = mac_mls_check_socket_visible, 2942 .mpo_check_system_swapon = mac_mls_check_system_swapon, 2943 .mpo_check_vnode_access = mac_mls_check_vnode_open, 2944 .mpo_check_vnode_chdir = mac_mls_check_vnode_chdir, 2945 .mpo_check_vnode_chroot = mac_mls_check_vnode_chroot, 2946 .mpo_check_vnode_create = mac_mls_check_vnode_create, 2947 .mpo_check_vnode_delete = mac_mls_check_vnode_delete, 2948 .mpo_check_vnode_deleteacl = mac_mls_check_vnode_deleteacl, 2949 .mpo_check_vnode_deleteextattr = mac_mls_check_vnode_deleteextattr, 2950 .mpo_check_vnode_exec = mac_mls_check_vnode_exec, 2951 .mpo_check_vnode_getacl = mac_mls_check_vnode_getacl, 2952 .mpo_check_vnode_getextattr = mac_mls_check_vnode_getextattr, 2953 .mpo_check_vnode_link = mac_mls_check_vnode_link, 2954 .mpo_check_vnode_listextattr = mac_mls_check_vnode_listextattr, 2955 .mpo_check_vnode_lookup = mac_mls_check_vnode_lookup, 2956 .mpo_check_vnode_mmap = mac_mls_check_vnode_mmap, 2957 .mpo_check_vnode_open = mac_mls_check_vnode_open, 2958 .mpo_check_vnode_poll = mac_mls_check_vnode_poll, 2959 .mpo_check_vnode_read = mac_mls_check_vnode_read, 2960 .mpo_check_vnode_readdir = mac_mls_check_vnode_readdir, 2961 .mpo_check_vnode_readlink = mac_mls_check_vnode_readlink, 2962 .mpo_check_vnode_relabel = mac_mls_check_vnode_relabel, 2963 .mpo_check_vnode_rename_from = mac_mls_check_vnode_rename_from, 2964 .mpo_check_vnode_rename_to = mac_mls_check_vnode_rename_to, 2965 .mpo_check_vnode_revoke = mac_mls_check_vnode_revoke, 2966 .mpo_check_vnode_setacl = mac_mls_check_vnode_setacl, 2967 .mpo_check_vnode_setextattr = mac_mls_check_vnode_setextattr, 2968 .mpo_check_vnode_setflags = mac_mls_check_vnode_setflags, 2969 .mpo_check_vnode_setmode = mac_mls_check_vnode_setmode, 2970 .mpo_check_vnode_setowner = mac_mls_check_vnode_setowner, 2971 .mpo_check_vnode_setutimes = mac_mls_check_vnode_setutimes, 2972 .mpo_check_vnode_stat = mac_mls_check_vnode_stat, 2973 .mpo_check_vnode_write = mac_mls_check_vnode_write, 2974 .mpo_associate_nfsd_label = mac_mls_associate_nfsd_label,
| 1319/* 1320 * Labeling event operations: processes. 1321 */ 1322static void 1323mac_mls_create_proc0(struct ucred *cred) 1324{ 1325 struct mac_mls *dest; 1326 1327 dest = SLOT(cred->cr_label); 1328 1329 mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1330 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 1331 0, NULL); 1332} 1333 1334static void 1335mac_mls_create_proc1(struct ucred *cred) 1336{ 1337 struct mac_mls *dest; 1338 1339 dest = SLOT(cred->cr_label); 1340 1341 mac_mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL); 1342 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 1343 0, NULL); 1344} 1345 1346static void 1347mac_mls_relabel_cred(struct ucred *cred, struct label *newlabel) 1348{ 1349 struct mac_mls *source, *dest; 1350 1351 source = SLOT(newlabel); 1352 dest = SLOT(cred->cr_label); 1353 1354 mac_mls_copy(source, dest); 1355} 1356 1357/* 1358 * Label cleanup/flush operations. 1359 */ 1360static void 1361mac_mls_cleanup_sysv_msgmsg(struct label *msglabel) 1362{ 1363 1364 bzero(SLOT(msglabel), sizeof(struct mac_mls)); 1365} 1366 1367static void 1368mac_mls_cleanup_sysv_msgqueue(struct label *msqlabel) 1369{ 1370 1371 bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 1372} 1373 1374static void 1375mac_mls_cleanup_sysv_sem(struct label *semalabel) 1376{ 1377 1378 bzero(SLOT(semalabel), sizeof(struct mac_mls)); 1379} 1380 1381static void 1382mac_mls_cleanup_sysv_shm(struct label *shmlabel) 1383{ 1384 1385 bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 1386} 1387 1388/* 1389 * Access control checks. 1390 */ 1391static int 1392mac_mls_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1393 struct ifnet *ifnet, struct label *ifnetlabel) 1394{ 1395 struct mac_mls *a, *b; 1396 1397 if (!mac_mls_enabled) 1398 return (0); 1399 1400 a = SLOT(bpflabel); 1401 b = SLOT(ifnetlabel); 1402 1403 if (mac_mls_equal_effective(a, b)) 1404 return (0); 1405 return (EACCES); 1406} 1407 1408static int 1409mac_mls_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1410{ 1411 struct mac_mls *subj, *new; 1412 int error; 1413 1414 subj = SLOT(cred->cr_label); 1415 new = SLOT(newlabel); 1416 1417 /* 1418 * If there is an MLS label update for the credential, it may be 1419 * an update of effective, range, or both. 1420 */ 1421 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 1422 if (error) 1423 return (error); 1424 1425 /* 1426 * If the MLS label is to be changed, authorize as appropriate. 1427 */ 1428 if (new->mm_flags & MAC_MLS_FLAGS_BOTH) { 1429 /* 1430 * If the change request modifies both the MLS label effective 1431 * and range, check that the new effective will be in the 1432 * new range. 1433 */ 1434 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) == 1435 MAC_MLS_FLAGS_BOTH && 1436 !mac_mls_effective_in_range(new, new)) 1437 return (EINVAL); 1438 1439 /* 1440 * To change the MLS effective label on a credential, the 1441 * new effective label must be in the current range. 1442 */ 1443 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE && 1444 !mac_mls_effective_in_range(new, subj)) 1445 return (EPERM); 1446 1447 /* 1448 * To change the MLS range label on a credential, the 1449 * new range must be in the current range. 1450 */ 1451 if (new->mm_flags & MAC_MLS_FLAG_RANGE && 1452 !mac_mls_range_in_range(new, subj)) 1453 return (EPERM); 1454 1455 /* 1456 * To have EQUAL in any component of the new credential 1457 * MLS label, the subject must already have EQUAL in 1458 * their label. 1459 */ 1460 if (mac_mls_contains_equal(new)) { 1461 error = mac_mls_subject_privileged(subj); 1462 if (error) 1463 return (error); 1464 } 1465 } 1466 1467 return (0); 1468} 1469 1470static int 1471mac_mls_check_cred_visible(struct ucred *u1, struct ucred *u2) 1472{ 1473 struct mac_mls *subj, *obj; 1474 1475 if (!mac_mls_enabled) 1476 return (0); 1477 1478 subj = SLOT(u1->cr_label); 1479 obj = SLOT(u2->cr_label); 1480 1481 /* XXX: range */ 1482 if (!mac_mls_dominate_effective(subj, obj)) 1483 return (ESRCH); 1484 1485 return (0); 1486} 1487 1488static int 1489mac_mls_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1490 struct label *ifnetlabel, struct label *newlabel) 1491{ 1492 struct mac_mls *subj, *new; 1493 int error; 1494 1495 subj = SLOT(cred->cr_label); 1496 new = SLOT(newlabel); 1497 1498 /* 1499 * If there is an MLS label update for the interface, it may 1500 * be an update of effective, range, or both. 1501 */ 1502 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 1503 if (error) 1504 return (error); 1505 1506 /* 1507 * Relabeling network interfaces requires MLS privilege. 1508 */ 1509 error = mac_mls_subject_privileged(subj); 1510 1511 return (0); 1512} 1513 1514static int 1515mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1516 struct mbuf *m, struct label *mbuflabel) 1517{ 1518 struct mac_mls *p, *i; 1519 1520 if (!mac_mls_enabled) 1521 return (0); 1522 1523 p = SLOT(mbuflabel); 1524 i = SLOT(ifnetlabel); 1525 1526 return (mac_mls_effective_in_range(p, i) ? 0 : EACCES); 1527} 1528 1529static int 1530mac_mls_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1531 struct mbuf *m, struct label *mlabel) 1532{ 1533 struct mac_mls *p, *i; 1534 1535 if (!mac_mls_enabled) 1536 return (0); 1537 1538 p = SLOT(mlabel); 1539 i = SLOT(inplabel); 1540 1541 return (mac_mls_equal_effective(p, i) ? 0 : EACCES); 1542} 1543 1544static int 1545mac_mls_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr, 1546 struct label *msglabel) 1547{ 1548 struct mac_mls *subj, *obj; 1549 1550 if (!mac_mls_enabled) 1551 return (0); 1552 1553 subj = SLOT(cred->cr_label); 1554 obj = SLOT(msglabel); 1555 1556 if (!mac_mls_dominate_effective(subj, obj)) 1557 return (EACCES); 1558 1559 return (0); 1560} 1561 1562static int 1563mac_mls_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr, 1564 struct label *msglabel) 1565{ 1566 struct mac_mls *subj, *obj; 1567 1568 if (!mac_mls_enabled) 1569 return (0); 1570 1571 subj = SLOT(cred->cr_label); 1572 obj = SLOT(msglabel); 1573 1574 if (!mac_mls_dominate_effective(obj, subj)) 1575 return (EACCES); 1576 1577 return (0); 1578} 1579 1580static int 1581mac_mls_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1582 struct label *msqklabel) 1583{ 1584 struct mac_mls *subj, *obj; 1585 1586 if (!mac_mls_enabled) 1587 return (0); 1588 1589 subj = SLOT(cred->cr_label); 1590 obj = SLOT(msqklabel); 1591 1592 if (!mac_mls_dominate_effective(subj, obj)) 1593 return (EACCES); 1594 1595 return (0); 1596} 1597 1598static int 1599mac_mls_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1600 struct label *msqklabel) 1601{ 1602 struct mac_mls *subj, *obj; 1603 1604 if (!mac_mls_enabled) 1605 return (0); 1606 1607 subj = SLOT(cred->cr_label); 1608 obj = SLOT(msqklabel); 1609 1610 if (!mac_mls_dominate_effective(obj, subj)) 1611 return (EACCES); 1612 1613 return (0); 1614} 1615 1616static int 1617mac_mls_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1618 struct label *msqklabel) 1619{ 1620 struct mac_mls *subj, *obj; 1621 1622 if (!mac_mls_enabled) 1623 return (0); 1624 1625 subj = SLOT(cred->cr_label); 1626 obj = SLOT(msqklabel); 1627 1628 if (!mac_mls_dominate_effective(subj, obj)) 1629 return (EACCES); 1630 1631 return (0); 1632} 1633 1634static int 1635mac_mls_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1636 struct label *msqklabel, int cmd) 1637{ 1638 struct mac_mls *subj, *obj; 1639 1640 if (!mac_mls_enabled) 1641 return (0); 1642 1643 subj = SLOT(cred->cr_label); 1644 obj = SLOT(msqklabel); 1645 1646 switch(cmd) { 1647 case IPC_RMID: 1648 case IPC_SET: 1649 if (!mac_mls_dominate_effective(obj, subj)) 1650 return (EACCES); 1651 break; 1652 1653 case IPC_STAT: 1654 if (!mac_mls_dominate_effective(subj, obj)) 1655 return (EACCES); 1656 break; 1657 1658 default: 1659 return (EACCES); 1660 } 1661 1662 return (0); 1663} 1664 1665static int 1666mac_mls_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1667 struct label *semaklabel, int cmd) 1668{ 1669 struct mac_mls *subj, *obj; 1670 1671 if (!mac_mls_enabled) 1672 return (0); 1673 1674 subj = SLOT(cred->cr_label); 1675 obj = SLOT(semaklabel); 1676 1677 switch(cmd) { 1678 case IPC_RMID: 1679 case IPC_SET: 1680 case SETVAL: 1681 case SETALL: 1682 if (!mac_mls_dominate_effective(obj, subj)) 1683 return (EACCES); 1684 break; 1685 1686 case IPC_STAT: 1687 case GETVAL: 1688 case GETPID: 1689 case GETNCNT: 1690 case GETZCNT: 1691 case GETALL: 1692 if (!mac_mls_dominate_effective(subj, obj)) 1693 return (EACCES); 1694 break; 1695 1696 default: 1697 return (EACCES); 1698 } 1699 1700 return (0); 1701} 1702 1703static int 1704mac_mls_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr, 1705 struct label *semaklabel) 1706{ 1707 struct mac_mls *subj, *obj; 1708 1709 if (!mac_mls_enabled) 1710 return (0); 1711 1712 subj = SLOT(cred->cr_label); 1713 obj = SLOT(semaklabel); 1714 1715 if (!mac_mls_dominate_effective(subj, obj)) 1716 return (EACCES); 1717 1718 return (0); 1719} 1720 1721static int 1722mac_mls_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr, 1723 struct label *semaklabel, size_t accesstype) 1724{ 1725 struct mac_mls *subj, *obj; 1726 1727 if (!mac_mls_enabled) 1728 return (0); 1729 1730 subj = SLOT(cred->cr_label); 1731 obj = SLOT(semaklabel); 1732 1733 if( accesstype & SEM_R ) 1734 if (!mac_mls_dominate_effective(subj, obj)) 1735 return (EACCES); 1736 1737 if( accesstype & SEM_A ) 1738 if (!mac_mls_dominate_effective(obj, subj)) 1739 return (EACCES); 1740 1741 return (0); 1742} 1743 1744static int 1745mac_mls_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 1746 struct label *shmseglabel, int shmflg) 1747{ 1748 struct mac_mls *subj, *obj; 1749 1750 if (!mac_mls_enabled) 1751 return (0); 1752 1753 subj = SLOT(cred->cr_label); 1754 obj = SLOT(shmseglabel); 1755 1756 if (!mac_mls_dominate_effective(subj, obj)) 1757 return (EACCES); 1758 if ((shmflg & SHM_RDONLY) == 0) 1759 if (!mac_mls_dominate_effective(obj, subj)) 1760 return (EACCES); 1761 1762 return (0); 1763} 1764 1765static int 1766mac_mls_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 1767 struct label *shmseglabel, int cmd) 1768{ 1769 struct mac_mls *subj, *obj; 1770 1771 if (!mac_mls_enabled) 1772 return (0); 1773 1774 subj = SLOT(cred->cr_label); 1775 obj = SLOT(shmseglabel); 1776 1777 switch(cmd) { 1778 case IPC_RMID: 1779 case IPC_SET: 1780 if (!mac_mls_dominate_effective(obj, subj)) 1781 return (EACCES); 1782 break; 1783 1784 case IPC_STAT: 1785 case SHM_STAT: 1786 if (!mac_mls_dominate_effective(subj, obj)) 1787 return (EACCES); 1788 break; 1789 1790 default: 1791 return (EACCES); 1792 } 1793 1794 return (0); 1795} 1796 1797static int 1798mac_mls_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 1799 struct label *shmseglabel, int shmflg) 1800{ 1801 struct mac_mls *subj, *obj; 1802 1803 if (!mac_mls_enabled) 1804 return (0); 1805 1806 subj = SLOT(cred->cr_label); 1807 obj = SLOT(shmseglabel); 1808 1809 if (!mac_mls_dominate_effective(obj, subj)) 1810 return (EACCES); 1811 1812 return (0); 1813} 1814 1815static int 1816mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp, 1817 struct label *mntlabel) 1818{ 1819 struct mac_mls *subj, *obj; 1820 1821 if (!mac_mls_enabled) 1822 return (0); 1823 1824 subj = SLOT(cred->cr_label); 1825 obj = SLOT(mntlabel); 1826 1827 if (!mac_mls_dominate_effective(subj, obj)) 1828 return (EACCES); 1829 1830 return (0); 1831} 1832 1833static int 1834mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1835 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1836{ 1837 1838 if(!mac_mls_enabled) 1839 return (0); 1840 1841 /* XXX: This will be implemented soon... */ 1842 1843 return (0); 1844} 1845 1846static int 1847mac_mls_check_pipe_poll(struct ucred *cred, struct pipepair *pp, 1848 struct label *pipelabel) 1849{ 1850 struct mac_mls *subj, *obj; 1851 1852 if (!mac_mls_enabled) 1853 return (0); 1854 1855 subj = SLOT(cred->cr_label); 1856 obj = SLOT((pipelabel)); 1857 1858 if (!mac_mls_dominate_effective(subj, obj)) 1859 return (EACCES); 1860 1861 return (0); 1862} 1863 1864static int 1865mac_mls_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1866 struct label *pipelabel) 1867{ 1868 struct mac_mls *subj, *obj; 1869 1870 if (!mac_mls_enabled) 1871 return (0); 1872 1873 subj = SLOT(cred->cr_label); 1874 obj = SLOT((pipelabel)); 1875 1876 if (!mac_mls_dominate_effective(subj, obj)) 1877 return (EACCES); 1878 1879 return (0); 1880} 1881 1882static int 1883mac_mls_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1884 struct label *pipelabel, struct label *newlabel) 1885{ 1886 struct mac_mls *subj, *obj, *new; 1887 int error; 1888 1889 new = SLOT(newlabel); 1890 subj = SLOT(cred->cr_label); 1891 obj = SLOT(pipelabel); 1892 1893 /* 1894 * If there is an MLS label update for a pipe, it must be a 1895 * effective update. 1896 */ 1897 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1898 if (error) 1899 return (error); 1900 1901 /* 1902 * To perform a relabel of a pipe (MLS label or not), MLS must 1903 * authorize the relabel. 1904 */ 1905 if (!mac_mls_effective_in_range(obj, subj)) 1906 return (EPERM); 1907 1908 /* 1909 * If the MLS label is to be changed, authorize as appropriate. 1910 */ 1911 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1912 /* 1913 * To change the MLS label on a pipe, the new pipe label 1914 * must be in the subject range. 1915 */ 1916 if (!mac_mls_effective_in_range(new, subj)) 1917 return (EPERM); 1918 1919 /* 1920 * To change the MLS label on a pipe to be EQUAL, the 1921 * subject must have appropriate privilege. 1922 */ 1923 if (mac_mls_contains_equal(new)) { 1924 error = mac_mls_subject_privileged(subj); 1925 if (error) 1926 return (error); 1927 } 1928 } 1929 1930 return (0); 1931} 1932 1933static int 1934mac_mls_check_pipe_stat(struct ucred *cred, struct pipepair *pp, 1935 struct label *pipelabel) 1936{ 1937 struct mac_mls *subj, *obj; 1938 1939 if (!mac_mls_enabled) 1940 return (0); 1941 1942 subj = SLOT(cred->cr_label); 1943 obj = SLOT((pipelabel)); 1944 1945 if (!mac_mls_dominate_effective(subj, obj)) 1946 return (EACCES); 1947 1948 return (0); 1949} 1950 1951static int 1952mac_mls_check_pipe_write(struct ucred *cred, struct pipepair *pp, 1953 struct label *pipelabel) 1954{ 1955 struct mac_mls *subj, *obj; 1956 1957 if (!mac_mls_enabled) 1958 return (0); 1959 1960 subj = SLOT(cred->cr_label); 1961 obj = SLOT((pipelabel)); 1962 1963 if (!mac_mls_dominate_effective(obj, subj)) 1964 return (EACCES); 1965 1966 return (0); 1967} 1968 1969static int 1970mac_mls_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr, 1971 struct label *ks_label) 1972{ 1973 struct mac_mls *subj, *obj; 1974 1975 if (!mac_mls_enabled) 1976 return (0); 1977 1978 subj = SLOT(cred->cr_label); 1979 obj = SLOT(ks_label); 1980 1981 if (!mac_mls_dominate_effective(obj, subj)) 1982 return (EACCES); 1983 1984 return (0); 1985} 1986 1987static int 1988mac_mls_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr, 1989 struct label *ks_label) 1990{ 1991 struct mac_mls *subj, *obj; 1992 1993 if (!mac_mls_enabled) 1994 return (0); 1995 1996 subj = SLOT(cred->cr_label); 1997 obj = SLOT(ks_label); 1998 1999 if (!mac_mls_dominate_effective(subj, obj)) 2000 return (EACCES); 2001 2002 return (0); 2003} 2004 2005static int 2006mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc) 2007{ 2008 struct mac_mls *subj, *obj; 2009 2010 if (!mac_mls_enabled) 2011 return (0); 2012 2013 subj = SLOT(cred->cr_label); 2014 obj = SLOT(proc->p_ucred->cr_label); 2015 2016 /* XXX: range checks */ 2017 if (!mac_mls_dominate_effective(subj, obj)) 2018 return (ESRCH); 2019 if (!mac_mls_dominate_effective(obj, subj)) 2020 return (EACCES); 2021 2022 return (0); 2023} 2024 2025static int 2026mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc) 2027{ 2028 struct mac_mls *subj, *obj; 2029 2030 if (!mac_mls_enabled) 2031 return (0); 2032 2033 subj = SLOT(cred->cr_label); 2034 obj = SLOT(proc->p_ucred->cr_label); 2035 2036 /* XXX: range checks */ 2037 if (!mac_mls_dominate_effective(subj, obj)) 2038 return (ESRCH); 2039 if (!mac_mls_dominate_effective(obj, subj)) 2040 return (EACCES); 2041 2042 return (0); 2043} 2044 2045static int 2046mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2047{ 2048 struct mac_mls *subj, *obj; 2049 2050 if (!mac_mls_enabled) 2051 return (0); 2052 2053 subj = SLOT(cred->cr_label); 2054 obj = SLOT(proc->p_ucred->cr_label); 2055 2056 /* XXX: range checks */ 2057 if (!mac_mls_dominate_effective(subj, obj)) 2058 return (ESRCH); 2059 if (!mac_mls_dominate_effective(obj, subj)) 2060 return (EACCES); 2061 2062 return (0); 2063} 2064 2065static int 2066mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel, 2067 struct mbuf *m, struct label *mbuflabel) 2068{ 2069 struct mac_mls *p, *s; 2070 2071 if (!mac_mls_enabled) 2072 return (0); 2073 2074 p = SLOT(mbuflabel); 2075 s = SLOT(socketlabel); 2076 2077 return (mac_mls_equal_effective(p, s) ? 0 : EACCES); 2078} 2079 2080static int 2081mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket, 2082 struct label *socketlabel, struct label *newlabel) 2083{ 2084 struct mac_mls *subj, *obj, *new; 2085 int error; 2086 2087 new = SLOT(newlabel); 2088 subj = SLOT(cred->cr_label); 2089 obj = SLOT(socketlabel); 2090 2091 /* 2092 * If there is an MLS label update for the socket, it may be 2093 * an update of effective. 2094 */ 2095 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2096 if (error) 2097 return (error); 2098 2099 /* 2100 * To relabel a socket, the old socket effective must be in the subject 2101 * range. 2102 */ 2103 if (!mac_mls_effective_in_range(obj, subj)) 2104 return (EPERM); 2105 2106 /* 2107 * If the MLS label is to be changed, authorize as appropriate. 2108 */ 2109 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2110 /* 2111 * To relabel a socket, the new socket effective must be in 2112 * the subject range. 2113 */ 2114 if (!mac_mls_effective_in_range(new, subj)) 2115 return (EPERM); 2116 2117 /* 2118 * To change the MLS label on the socket to contain EQUAL, 2119 * the subject must have appropriate privilege. 2120 */ 2121 if (mac_mls_contains_equal(new)) { 2122 error = mac_mls_subject_privileged(subj); 2123 if (error) 2124 return (error); 2125 } 2126 } 2127 2128 return (0); 2129} 2130 2131static int 2132mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket, 2133 struct label *socketlabel) 2134{ 2135 struct mac_mls *subj, *obj; 2136 2137 if (!mac_mls_enabled) 2138 return (0); 2139 2140 subj = SLOT(cred->cr_label); 2141 obj = SLOT(socketlabel); 2142 2143 if (!mac_mls_dominate_effective(subj, obj)) 2144 return (ENOENT); 2145 2146 return (0); 2147} 2148 2149static int 2150mac_mls_check_system_swapon(struct ucred *cred, struct vnode *vp, 2151 struct label *label) 2152{ 2153 struct mac_mls *subj, *obj; 2154 2155 if (!mac_mls_enabled) 2156 return (0); 2157 2158 subj = SLOT(cred->cr_label); 2159 obj = SLOT(label); 2160 2161 if (!mac_mls_dominate_effective(obj, subj) || 2162 !mac_mls_dominate_effective(subj, obj)) 2163 return (EACCES); 2164 2165 return (0); 2166} 2167 2168static int 2169mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2170 struct label *dlabel) 2171{ 2172 struct mac_mls *subj, *obj; 2173 2174 if (!mac_mls_enabled) 2175 return (0); 2176 2177 subj = SLOT(cred->cr_label); 2178 obj = SLOT(dlabel); 2179 2180 if (!mac_mls_dominate_effective(subj, obj)) 2181 return (EACCES); 2182 2183 return (0); 2184} 2185 2186static int 2187mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2188 struct label *dlabel) 2189{ 2190 struct mac_mls *subj, *obj; 2191 2192 if (!mac_mls_enabled) 2193 return (0); 2194 2195 subj = SLOT(cred->cr_label); 2196 obj = SLOT(dlabel); 2197 2198 if (!mac_mls_dominate_effective(subj, obj)) 2199 return (EACCES); 2200 2201 return (0); 2202} 2203 2204static int 2205mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2206 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2207{ 2208 struct mac_mls *subj, *obj; 2209 2210 if (!mac_mls_enabled) 2211 return (0); 2212 2213 subj = SLOT(cred->cr_label); 2214 obj = SLOT(dlabel); 2215 2216 if (!mac_mls_dominate_effective(obj, subj)) 2217 return (EACCES); 2218 2219 return (0); 2220} 2221 2222static int 2223mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2224 struct label *dlabel, struct vnode *vp, struct label *label, 2225 struct componentname *cnp) 2226{ 2227 struct mac_mls *subj, *obj; 2228 2229 if (!mac_mls_enabled) 2230 return (0); 2231 2232 subj = SLOT(cred->cr_label); 2233 obj = SLOT(dlabel); 2234 2235 if (!mac_mls_dominate_effective(obj, subj)) 2236 return (EACCES); 2237 2238 obj = SLOT(label); 2239 2240 if (!mac_mls_dominate_effective(obj, subj)) 2241 return (EACCES); 2242 2243 return (0); 2244} 2245 2246static int 2247mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2248 struct label *label, acl_type_t type) 2249{ 2250 struct mac_mls *subj, *obj; 2251 2252 if (!mac_mls_enabled) 2253 return (0); 2254 2255 subj = SLOT(cred->cr_label); 2256 obj = SLOT(label); 2257 2258 if (!mac_mls_dominate_effective(obj, subj)) 2259 return (EACCES); 2260 2261 return (0); 2262} 2263 2264static int 2265mac_mls_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2266 struct label *label, int attrnamespace, const char *name) 2267{ 2268 struct mac_mls *subj, *obj; 2269 2270 if (!mac_mls_enabled) 2271 return (0); 2272 2273 subj = SLOT(cred->cr_label); 2274 obj = SLOT(label); 2275 2276 if (!mac_mls_dominate_effective(obj, subj)) 2277 return (EACCES); 2278 2279 return (0); 2280} 2281 2282static int 2283mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2284 struct label *label, struct image_params *imgp, 2285 struct label *execlabel) 2286{ 2287 struct mac_mls *subj, *obj, *exec; 2288 int error; 2289 2290 if (execlabel != NULL) { 2291 /* 2292 * We currently don't permit labels to be changed at 2293 * exec-time as part of MLS, so disallow non-NULL 2294 * MLS label elements in the execlabel. 2295 */ 2296 exec = SLOT(execlabel); 2297 error = mls_atmostflags(exec, 0); 2298 if (error) 2299 return (error); 2300 } 2301 2302 if (!mac_mls_enabled) 2303 return (0); 2304 2305 subj = SLOT(cred->cr_label); 2306 obj = SLOT(label); 2307 2308 if (!mac_mls_dominate_effective(subj, obj)) 2309 return (EACCES); 2310 2311 return (0); 2312} 2313 2314static int 2315mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2316 struct label *label, acl_type_t type) 2317{ 2318 struct mac_mls *subj, *obj; 2319 2320 if (!mac_mls_enabled) 2321 return (0); 2322 2323 subj = SLOT(cred->cr_label); 2324 obj = SLOT(label); 2325 2326 if (!mac_mls_dominate_effective(subj, obj)) 2327 return (EACCES); 2328 2329 return (0); 2330} 2331 2332static int 2333mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2334 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2335{ 2336 struct mac_mls *subj, *obj; 2337 2338 if (!mac_mls_enabled) 2339 return (0); 2340 2341 subj = SLOT(cred->cr_label); 2342 obj = SLOT(label); 2343 2344 if (!mac_mls_dominate_effective(subj, obj)) 2345 return (EACCES); 2346 2347 return (0); 2348} 2349 2350static int 2351mac_mls_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2352 struct label *dlabel, struct vnode *vp, struct label *label, 2353 struct componentname *cnp) 2354{ 2355 struct mac_mls *subj, *obj; 2356 2357 if (!mac_mls_enabled) 2358 return (0); 2359 2360 subj = SLOT(cred->cr_label); 2361 obj = SLOT(dlabel); 2362 2363 if (!mac_mls_dominate_effective(obj, subj)) 2364 return (EACCES); 2365 2366 obj = SLOT(dlabel); 2367 if (!mac_mls_dominate_effective(obj, subj)) 2368 return (EACCES); 2369 2370 return (0); 2371} 2372 2373static int 2374mac_mls_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2375 struct label *label, int attrnamespace) 2376{ 2377 2378 struct mac_mls *subj, *obj; 2379 2380 if (!mac_mls_enabled) 2381 return (0); 2382 2383 subj = SLOT(cred->cr_label); 2384 obj = SLOT(label); 2385 2386 if (!mac_mls_dominate_effective(subj, obj)) 2387 return (EACCES); 2388 2389 return (0); 2390} 2391 2392static int 2393mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2394 struct label *dlabel, struct componentname *cnp) 2395{ 2396 struct mac_mls *subj, *obj; 2397 2398 if (!mac_mls_enabled) 2399 return (0); 2400 2401 subj = SLOT(cred->cr_label); 2402 obj = SLOT(dlabel); 2403 2404 if (!mac_mls_dominate_effective(subj, obj)) 2405 return (EACCES); 2406 2407 return (0); 2408} 2409 2410static int 2411mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2412 struct label *label, int prot, int flags) 2413{ 2414 struct mac_mls *subj, *obj; 2415 2416 /* 2417 * Rely on the use of open()-time protections to handle 2418 * non-revocation cases. 2419 */ 2420 if (!mac_mls_enabled || !revocation_enabled) 2421 return (0); 2422 2423 subj = SLOT(cred->cr_label); 2424 obj = SLOT(label); 2425 2426 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2427 if (!mac_mls_dominate_effective(subj, obj)) 2428 return (EACCES); 2429 } 2430 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2431 if (!mac_mls_dominate_effective(obj, subj)) 2432 return (EACCES); 2433 } 2434 2435 return (0); 2436} 2437 2438static int 2439mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, 2440 struct label *vnodelabel, int acc_mode) 2441{ 2442 struct mac_mls *subj, *obj; 2443 2444 if (!mac_mls_enabled) 2445 return (0); 2446 2447 subj = SLOT(cred->cr_label); 2448 obj = SLOT(vnodelabel); 2449 2450 /* XXX privilege override for admin? */ 2451 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2452 if (!mac_mls_dominate_effective(subj, obj)) 2453 return (EACCES); 2454 } 2455 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2456 if (!mac_mls_dominate_effective(obj, subj)) 2457 return (EACCES); 2458 } 2459 2460 return (0); 2461} 2462 2463static int 2464mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2465 struct vnode *vp, struct label *label) 2466{ 2467 struct mac_mls *subj, *obj; 2468 2469 if (!mac_mls_enabled || !revocation_enabled) 2470 return (0); 2471 2472 subj = SLOT(active_cred->cr_label); 2473 obj = SLOT(label); 2474 2475 if (!mac_mls_dominate_effective(subj, obj)) 2476 return (EACCES); 2477 2478 return (0); 2479} 2480 2481static int 2482mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2483 struct vnode *vp, struct label *label) 2484{ 2485 struct mac_mls *subj, *obj; 2486 2487 if (!mac_mls_enabled || !revocation_enabled) 2488 return (0); 2489 2490 subj = SLOT(active_cred->cr_label); 2491 obj = SLOT(label); 2492 2493 if (!mac_mls_dominate_effective(subj, obj)) 2494 return (EACCES); 2495 2496 return (0); 2497} 2498 2499static int 2500mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2501 struct label *dlabel) 2502{ 2503 struct mac_mls *subj, *obj; 2504 2505 if (!mac_mls_enabled) 2506 return (0); 2507 2508 subj = SLOT(cred->cr_label); 2509 obj = SLOT(dlabel); 2510 2511 if (!mac_mls_dominate_effective(subj, obj)) 2512 return (EACCES); 2513 2514 return (0); 2515} 2516 2517static int 2518mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2519 struct label *vnodelabel) 2520{ 2521 struct mac_mls *subj, *obj; 2522 2523 if (!mac_mls_enabled) 2524 return (0); 2525 2526 subj = SLOT(cred->cr_label); 2527 obj = SLOT(vnodelabel); 2528 2529 if (!mac_mls_dominate_effective(subj, obj)) 2530 return (EACCES); 2531 2532 return (0); 2533} 2534 2535static int 2536mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2537 struct label *vnodelabel, struct label *newlabel) 2538{ 2539 struct mac_mls *old, *new, *subj; 2540 int error; 2541 2542 old = SLOT(vnodelabel); 2543 new = SLOT(newlabel); 2544 subj = SLOT(cred->cr_label); 2545 2546 /* 2547 * If there is an MLS label update for the vnode, it must be a 2548 * effective label. 2549 */ 2550 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2551 if (error) 2552 return (error); 2553 2554 /* 2555 * To perform a relabel of the vnode (MLS label or not), MLS must 2556 * authorize the relabel. 2557 */ 2558 if (!mac_mls_effective_in_range(old, subj)) 2559 return (EPERM); 2560 2561 /* 2562 * If the MLS label is to be changed, authorize as appropriate. 2563 */ 2564 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2565 /* 2566 * To change the MLS label on a vnode, the new vnode label 2567 * must be in the subject range. 2568 */ 2569 if (!mac_mls_effective_in_range(new, subj)) 2570 return (EPERM); 2571 2572 /* 2573 * To change the MLS label on the vnode to be EQUAL, 2574 * the subject must have appropriate privilege. 2575 */ 2576 if (mac_mls_contains_equal(new)) { 2577 error = mac_mls_subject_privileged(subj); 2578 if (error) 2579 return (error); 2580 } 2581 } 2582 2583 return (0); 2584} 2585 2586 2587static int 2588mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2589 struct label *dlabel, struct vnode *vp, struct label *label, 2590 struct componentname *cnp) 2591{ 2592 struct mac_mls *subj, *obj; 2593 2594 if (!mac_mls_enabled) 2595 return (0); 2596 2597 subj = SLOT(cred->cr_label); 2598 obj = SLOT(dlabel); 2599 2600 if (!mac_mls_dominate_effective(obj, subj)) 2601 return (EACCES); 2602 2603 obj = SLOT(label); 2604 2605 if (!mac_mls_dominate_effective(obj, subj)) 2606 return (EACCES); 2607 2608 return (0); 2609} 2610 2611static int 2612mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2613 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2614 struct componentname *cnp) 2615{ 2616 struct mac_mls *subj, *obj; 2617 2618 if (!mac_mls_enabled) 2619 return (0); 2620 2621 subj = SLOT(cred->cr_label); 2622 obj = SLOT(dlabel); 2623 2624 if (!mac_mls_dominate_effective(obj, subj)) 2625 return (EACCES); 2626 2627 if (vp != NULL) { 2628 obj = SLOT(label); 2629 2630 if (!mac_mls_dominate_effective(obj, subj)) 2631 return (EACCES); 2632 } 2633 2634 return (0); 2635} 2636 2637static int 2638mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2639 struct label *label) 2640{ 2641 struct mac_mls *subj, *obj; 2642 2643 if (!mac_mls_enabled) 2644 return (0); 2645 2646 subj = SLOT(cred->cr_label); 2647 obj = SLOT(label); 2648 2649 if (!mac_mls_dominate_effective(obj, subj)) 2650 return (EACCES); 2651 2652 return (0); 2653} 2654 2655static int 2656mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2657 struct label *label, acl_type_t type, struct acl *acl) 2658{ 2659 struct mac_mls *subj, *obj; 2660 2661 if (!mac_mls_enabled) 2662 return (0); 2663 2664 subj = SLOT(cred->cr_label); 2665 obj = SLOT(label); 2666 2667 if (!mac_mls_dominate_effective(obj, subj)) 2668 return (EACCES); 2669 2670 return (0); 2671} 2672 2673static int 2674mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2675 struct label *vnodelabel, int attrnamespace, const char *name, 2676 struct uio *uio) 2677{ 2678 struct mac_mls *subj, *obj; 2679 2680 if (!mac_mls_enabled) 2681 return (0); 2682 2683 subj = SLOT(cred->cr_label); 2684 obj = SLOT(vnodelabel); 2685 2686 if (!mac_mls_dominate_effective(obj, subj)) 2687 return (EACCES); 2688 2689 /* XXX: protect the MAC EA in a special way? */ 2690 2691 return (0); 2692} 2693 2694static int 2695mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2696 struct label *vnodelabel, u_long flags) 2697{ 2698 struct mac_mls *subj, *obj; 2699 2700 if (!mac_mls_enabled) 2701 return (0); 2702 2703 subj = SLOT(cred->cr_label); 2704 obj = SLOT(vnodelabel); 2705 2706 if (!mac_mls_dominate_effective(obj, subj)) 2707 return (EACCES); 2708 2709 return (0); 2710} 2711 2712static int 2713mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2714 struct label *vnodelabel, mode_t mode) 2715{ 2716 struct mac_mls *subj, *obj; 2717 2718 if (!mac_mls_enabled) 2719 return (0); 2720 2721 subj = SLOT(cred->cr_label); 2722 obj = SLOT(vnodelabel); 2723 2724 if (!mac_mls_dominate_effective(obj, subj)) 2725 return (EACCES); 2726 2727 return (0); 2728} 2729 2730static int 2731mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2732 struct label *vnodelabel, uid_t uid, gid_t gid) 2733{ 2734 struct mac_mls *subj, *obj; 2735 2736 if (!mac_mls_enabled) 2737 return (0); 2738 2739 subj = SLOT(cred->cr_label); 2740 obj = SLOT(vnodelabel); 2741 2742 if (!mac_mls_dominate_effective(obj, subj)) 2743 return (EACCES); 2744 2745 return (0); 2746} 2747 2748static int 2749mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2750 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2751{ 2752 struct mac_mls *subj, *obj; 2753 2754 if (!mac_mls_enabled) 2755 return (0); 2756 2757 subj = SLOT(cred->cr_label); 2758 obj = SLOT(vnodelabel); 2759 2760 if (!mac_mls_dominate_effective(obj, subj)) 2761 return (EACCES); 2762 2763 return (0); 2764} 2765 2766static int 2767mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2768 struct vnode *vp, struct label *vnodelabel) 2769{ 2770 struct mac_mls *subj, *obj; 2771 2772 if (!mac_mls_enabled) 2773 return (0); 2774 2775 subj = SLOT(active_cred->cr_label); 2776 obj = SLOT(vnodelabel); 2777 2778 if (!mac_mls_dominate_effective(subj, obj)) 2779 return (EACCES); 2780 2781 return (0); 2782} 2783 2784static int 2785mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2786 struct vnode *vp, struct label *label) 2787{ 2788 struct mac_mls *subj, *obj; 2789 2790 if (!mac_mls_enabled || !revocation_enabled) 2791 return (0); 2792 2793 subj = SLOT(active_cred->cr_label); 2794 obj = SLOT(label); 2795 2796 if (!mac_mls_dominate_effective(obj, subj)) 2797 return (EACCES); 2798 2799 return (0); 2800} 2801 2802static void 2803mac_mls_associate_nfsd_label(struct ucred *cred) 2804{ 2805 struct mac_mls *label; 2806 2807 label = SLOT(cred->cr_label); 2808 mac_mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL); 2809 mac_mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL, 2810 MAC_MLS_TYPE_HIGH, 0, NULL); 2811} 2812 2813static struct mac_policy_ops mac_mls_ops = 2814{ 2815 .mpo_init = mac_mls_init, 2816 .mpo_init_bpfdesc_label = mac_mls_init_label, 2817 .mpo_init_cred_label = mac_mls_init_label, 2818 .mpo_init_devfsdirent_label = mac_mls_init_label, 2819 .mpo_init_ifnet_label = mac_mls_init_label, 2820 .mpo_init_inpcb_label = mac_mls_init_label_waitcheck, 2821 .mpo_init_sysv_msgmsg_label = mac_mls_init_label, 2822 .mpo_init_sysv_msgqueue_label = mac_mls_init_label, 2823 .mpo_init_sysv_sem_label = mac_mls_init_label, 2824 .mpo_init_sysv_shm_label = mac_mls_init_label, 2825 .mpo_init_ipq_label = mac_mls_init_label_waitcheck, 2826 .mpo_init_mbuf_label = mac_mls_init_label_waitcheck, 2827 .mpo_init_mount_label = mac_mls_init_label, 2828 .mpo_init_mount_fs_label = mac_mls_init_label, 2829 .mpo_init_pipe_label = mac_mls_init_label, 2830 .mpo_init_posix_sem_label = mac_mls_init_label, 2831 .mpo_init_socket_label = mac_mls_init_label_waitcheck, 2832 .mpo_init_socket_peer_label = mac_mls_init_label_waitcheck, 2833 .mpo_init_vnode_label = mac_mls_init_label, 2834 .mpo_destroy_bpfdesc_label = mac_mls_destroy_label, 2835 .mpo_destroy_cred_label = mac_mls_destroy_label, 2836 .mpo_destroy_devfsdirent_label = mac_mls_destroy_label, 2837 .mpo_destroy_ifnet_label = mac_mls_destroy_label, 2838 .mpo_destroy_inpcb_label = mac_mls_destroy_label, 2839 .mpo_destroy_sysv_msgmsg_label = mac_mls_destroy_label, 2840 .mpo_destroy_sysv_msgqueue_label = mac_mls_destroy_label, 2841 .mpo_destroy_sysv_sem_label = mac_mls_destroy_label, 2842 .mpo_destroy_sysv_shm_label = mac_mls_destroy_label, 2843 .mpo_destroy_ipq_label = mac_mls_destroy_label, 2844 .mpo_destroy_mbuf_label = mac_mls_destroy_label, 2845 .mpo_destroy_mount_label = mac_mls_destroy_label, 2846 .mpo_destroy_mount_fs_label = mac_mls_destroy_label, 2847 .mpo_destroy_pipe_label = mac_mls_destroy_label, 2848 .mpo_destroy_posix_sem_label = mac_mls_destroy_label, 2849 .mpo_destroy_socket_label = mac_mls_destroy_label, 2850 .mpo_destroy_socket_peer_label = mac_mls_destroy_label, 2851 .mpo_destroy_vnode_label = mac_mls_destroy_label, 2852 .mpo_copy_cred_label = mac_mls_copy_label, 2853 .mpo_copy_ifnet_label = mac_mls_copy_label, 2854 .mpo_copy_mbuf_label = mac_mls_copy_label, 2855 .mpo_copy_pipe_label = mac_mls_copy_label, 2856 .mpo_copy_socket_label = mac_mls_copy_label, 2857 .mpo_copy_vnode_label = mac_mls_copy_label, 2858 .mpo_externalize_cred_label = mac_mls_externalize_label, 2859 .mpo_externalize_ifnet_label = mac_mls_externalize_label, 2860 .mpo_externalize_pipe_label = mac_mls_externalize_label, 2861 .mpo_externalize_socket_label = mac_mls_externalize_label, 2862 .mpo_externalize_socket_peer_label = mac_mls_externalize_label, 2863 .mpo_externalize_vnode_label = mac_mls_externalize_label, 2864 .mpo_internalize_cred_label = mac_mls_internalize_label, 2865 .mpo_internalize_ifnet_label = mac_mls_internalize_label, 2866 .mpo_internalize_pipe_label = mac_mls_internalize_label, 2867 .mpo_internalize_socket_label = mac_mls_internalize_label, 2868 .mpo_internalize_vnode_label = mac_mls_internalize_label, 2869 .mpo_create_devfs_device = mac_mls_create_devfs_device, 2870 .mpo_create_devfs_directory = mac_mls_create_devfs_directory, 2871 .mpo_create_devfs_symlink = mac_mls_create_devfs_symlink, 2872 .mpo_create_mount = mac_mls_create_mount, 2873 .mpo_relabel_vnode = mac_mls_relabel_vnode, 2874 .mpo_update_devfsdirent = mac_mls_update_devfsdirent, 2875 .mpo_associate_vnode_devfs = mac_mls_associate_vnode_devfs, 2876 .mpo_associate_vnode_extattr = mac_mls_associate_vnode_extattr, 2877 .mpo_associate_vnode_singlelabel = mac_mls_associate_vnode_singlelabel, 2878 .mpo_create_vnode_extattr = mac_mls_create_vnode_extattr, 2879 .mpo_setlabel_vnode_extattr = mac_mls_setlabel_vnode_extattr, 2880 .mpo_create_mbuf_from_socket = mac_mls_create_mbuf_from_socket, 2881 .mpo_create_pipe = mac_mls_create_pipe, 2882 .mpo_create_posix_sem = mac_mls_create_posix_sem, 2883 .mpo_create_socket = mac_mls_create_socket, 2884 .mpo_create_socket_from_socket = mac_mls_create_socket_from_socket, 2885 .mpo_relabel_pipe = mac_mls_relabel_pipe, 2886 .mpo_relabel_socket = mac_mls_relabel_socket, 2887 .mpo_set_socket_peer_from_mbuf = mac_mls_set_socket_peer_from_mbuf, 2888 .mpo_set_socket_peer_from_socket = mac_mls_set_socket_peer_from_socket, 2889 .mpo_create_bpfdesc = mac_mls_create_bpfdesc, 2890 .mpo_create_datagram_from_ipq = mac_mls_create_datagram_from_ipq, 2891 .mpo_create_fragment = mac_mls_create_fragment, 2892 .mpo_create_ifnet = mac_mls_create_ifnet, 2893 .mpo_create_inpcb_from_socket = mac_mls_create_inpcb_from_socket, 2894 .mpo_create_ipq = mac_mls_create_ipq, 2895 .mpo_create_sysv_msgmsg = mac_mls_create_sysv_msgmsg, 2896 .mpo_create_sysv_msgqueue = mac_mls_create_sysv_msgqueue, 2897 .mpo_create_sysv_sem = mac_mls_create_sysv_sem, 2898 .mpo_create_sysv_shm = mac_mls_create_sysv_shm, 2899 .mpo_create_mbuf_from_inpcb = mac_mls_create_mbuf_from_inpcb, 2900 .mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer, 2901 .mpo_create_mbuf_from_bpfdesc = mac_mls_create_mbuf_from_bpfdesc, 2902 .mpo_create_mbuf_from_ifnet = mac_mls_create_mbuf_from_ifnet, 2903 .mpo_create_mbuf_multicast_encap = mac_mls_create_mbuf_multicast_encap, 2904 .mpo_create_mbuf_netlayer = mac_mls_create_mbuf_netlayer, 2905 .mpo_fragment_match = mac_mls_fragment_match, 2906 .mpo_relabel_ifnet = mac_mls_relabel_ifnet, 2907 .mpo_update_ipq = mac_mls_update_ipq, 2908 .mpo_inpcb_sosetlabel = mac_mls_inpcb_sosetlabel, 2909 .mpo_create_proc0 = mac_mls_create_proc0, 2910 .mpo_create_proc1 = mac_mls_create_proc1, 2911 .mpo_relabel_cred = mac_mls_relabel_cred, 2912 .mpo_cleanup_sysv_msgmsg = mac_mls_cleanup_sysv_msgmsg, 2913 .mpo_cleanup_sysv_msgqueue = mac_mls_cleanup_sysv_msgqueue, 2914 .mpo_cleanup_sysv_sem = mac_mls_cleanup_sysv_sem, 2915 .mpo_cleanup_sysv_shm = mac_mls_cleanup_sysv_shm, 2916 .mpo_check_bpfdesc_receive = mac_mls_check_bpfdesc_receive, 2917 .mpo_check_cred_relabel = mac_mls_check_cred_relabel, 2918 .mpo_check_cred_visible = mac_mls_check_cred_visible, 2919 .mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel, 2920 .mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit, 2921 .mpo_check_inpcb_deliver = mac_mls_check_inpcb_deliver, 2922 .mpo_check_sysv_msgrcv = mac_mls_check_sysv_msgrcv, 2923 .mpo_check_sysv_msgrmid = mac_mls_check_sysv_msgrmid, 2924 .mpo_check_sysv_msqget = mac_mls_check_sysv_msqget, 2925 .mpo_check_sysv_msqsnd = mac_mls_check_sysv_msqsnd, 2926 .mpo_check_sysv_msqrcv = mac_mls_check_sysv_msqrcv, 2927 .mpo_check_sysv_msqctl = mac_mls_check_sysv_msqctl, 2928 .mpo_check_sysv_semctl = mac_mls_check_sysv_semctl, 2929 .mpo_check_sysv_semget = mac_mls_check_sysv_semget, 2930 .mpo_check_sysv_semop = mac_mls_check_sysv_semop, 2931 .mpo_check_sysv_shmat = mac_mls_check_sysv_shmat, 2932 .mpo_check_sysv_shmctl = mac_mls_check_sysv_shmctl, 2933 .mpo_check_sysv_shmget = mac_mls_check_sysv_shmget, 2934 .mpo_check_mount_stat = mac_mls_check_mount_stat, 2935 .mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl, 2936 .mpo_check_pipe_poll = mac_mls_check_pipe_poll, 2937 .mpo_check_pipe_read = mac_mls_check_pipe_read, 2938 .mpo_check_pipe_relabel = mac_mls_check_pipe_relabel, 2939 .mpo_check_pipe_stat = mac_mls_check_pipe_stat, 2940 .mpo_check_pipe_write = mac_mls_check_pipe_write, 2941 .mpo_check_posix_sem_destroy = mac_mls_check_posix_sem_write, 2942 .mpo_check_posix_sem_getvalue = mac_mls_check_posix_sem_rdonly, 2943 .mpo_check_posix_sem_open = mac_mls_check_posix_sem_write, 2944 .mpo_check_posix_sem_post = mac_mls_check_posix_sem_write, 2945 .mpo_check_posix_sem_unlink = mac_mls_check_posix_sem_write, 2946 .mpo_check_posix_sem_wait = mac_mls_check_posix_sem_write, 2947 .mpo_check_proc_debug = mac_mls_check_proc_debug, 2948 .mpo_check_proc_sched = mac_mls_check_proc_sched, 2949 .mpo_check_proc_signal = mac_mls_check_proc_signal, 2950 .mpo_check_socket_deliver = mac_mls_check_socket_deliver, 2951 .mpo_check_socket_relabel = mac_mls_check_socket_relabel, 2952 .mpo_check_socket_visible = mac_mls_check_socket_visible, 2953 .mpo_check_system_swapon = mac_mls_check_system_swapon, 2954 .mpo_check_vnode_access = mac_mls_check_vnode_open, 2955 .mpo_check_vnode_chdir = mac_mls_check_vnode_chdir, 2956 .mpo_check_vnode_chroot = mac_mls_check_vnode_chroot, 2957 .mpo_check_vnode_create = mac_mls_check_vnode_create, 2958 .mpo_check_vnode_delete = mac_mls_check_vnode_delete, 2959 .mpo_check_vnode_deleteacl = mac_mls_check_vnode_deleteacl, 2960 .mpo_check_vnode_deleteextattr = mac_mls_check_vnode_deleteextattr, 2961 .mpo_check_vnode_exec = mac_mls_check_vnode_exec, 2962 .mpo_check_vnode_getacl = mac_mls_check_vnode_getacl, 2963 .mpo_check_vnode_getextattr = mac_mls_check_vnode_getextattr, 2964 .mpo_check_vnode_link = mac_mls_check_vnode_link, 2965 .mpo_check_vnode_listextattr = mac_mls_check_vnode_listextattr, 2966 .mpo_check_vnode_lookup = mac_mls_check_vnode_lookup, 2967 .mpo_check_vnode_mmap = mac_mls_check_vnode_mmap, 2968 .mpo_check_vnode_open = mac_mls_check_vnode_open, 2969 .mpo_check_vnode_poll = mac_mls_check_vnode_poll, 2970 .mpo_check_vnode_read = mac_mls_check_vnode_read, 2971 .mpo_check_vnode_readdir = mac_mls_check_vnode_readdir, 2972 .mpo_check_vnode_readlink = mac_mls_check_vnode_readlink, 2973 .mpo_check_vnode_relabel = mac_mls_check_vnode_relabel, 2974 .mpo_check_vnode_rename_from = mac_mls_check_vnode_rename_from, 2975 .mpo_check_vnode_rename_to = mac_mls_check_vnode_rename_to, 2976 .mpo_check_vnode_revoke = mac_mls_check_vnode_revoke, 2977 .mpo_check_vnode_setacl = mac_mls_check_vnode_setacl, 2978 .mpo_check_vnode_setextattr = mac_mls_check_vnode_setextattr, 2979 .mpo_check_vnode_setflags = mac_mls_check_vnode_setflags, 2980 .mpo_check_vnode_setmode = mac_mls_check_vnode_setmode, 2981 .mpo_check_vnode_setowner = mac_mls_check_vnode_setowner, 2982 .mpo_check_vnode_setutimes = mac_mls_check_vnode_setutimes, 2983 .mpo_check_vnode_stat = mac_mls_check_vnode_stat, 2984 .mpo_check_vnode_write = mac_mls_check_vnode_write, 2985 .mpo_associate_nfsd_label = mac_mls_associate_nfsd_label,
|