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/malloc.h> 50#include <sys/mount.h> 51#include <sys/proc.h> 52#include <sys/systm.h> 53#include <sys/sysproto.h> 54#include <sys/sysent.h> 55#include <sys/systm.h> 56#include <sys/vnode.h> 57#include <sys/file.h> 58#include <sys/socket.h> 59#include <sys/socketvar.h> 60#include <sys/pipe.h> 61#include <sys/sysctl.h> 62 63#include <fs/devfs/devfs.h> 64 65#include <net/bpfdesc.h> 66#include <net/if.h> 67#include <net/if_types.h> 68#include <net/if_var.h> 69 70#include <netinet/in.h> 71#include <netinet/ip_var.h> 72 73#include <vm/vm.h> 74 75#include <sys/mac_policy.h> 76 77#include <security/mac_mls/mac_mls.h> 78 79SYSCTL_DECL(_security_mac); 80 81SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0, 82 "TrustedBSD mac_mls policy controls"); 83 84static int mac_mls_label_size = sizeof(struct mac_mls); 85SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD, 86 &mac_mls_label_size, 0, "Size of struct mac_mls"); 87 88static int mac_mls_enabled = 0; 89SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW, 90 &mac_mls_enabled, 0, "Enforce MAC/MLS policy"); 91TUNABLE_INT("security.mac.mls.enabled", &mac_mls_enabled); 92 93static int destroyed_not_inited; 94SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 95 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 96 97static int ptys_equal = 0; 98SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW, 99 &ptys_equal, 0, "Label pty devices as mls/equal on create"); 100TUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal); 101 102static int revocation_enabled = 0; 103SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, 104 &revocation_enabled, 0, "Revoke access to objects on relabel"); 105TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled); 106 107static int max_compartments = MAC_MLS_MAX_COMPARTMENTS; 108SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD, 109 &max_compartments, 0, "Maximum compartments the policy supports"); 110 111static int mac_mls_slot; 112#define SLOT(l) ((struct mac_mls *)LABEL_TO_SLOT((l), mac_mls_slot).l_ptr) 113 114MALLOC_DEFINE(M_MACMLS, "mls label", "MAC/MLS labels"); 115 116static __inline int 117mls_bit_set_empty(u_char *set) { 118 int i; 119 120 for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++) 121 if (set[i] != 0) 122 return (0); 123 return (1); 124} 125 126static struct mac_mls * 127mls_alloc(int flag) 128{ 129 struct mac_mls *mac_mls; 130 131 mac_mls = malloc(sizeof(struct mac_mls), M_MACMLS, M_ZERO | flag); 132 133 return (mac_mls); 134} 135 136static void 137mls_free(struct mac_mls *mac_mls) 138{ 139 140 if (mac_mls != NULL) 141 free(mac_mls, M_MACMLS); 142 else 143 atomic_add_int(&destroyed_not_inited, 1); 144} 145 146static int 147mls_atmostflags(struct mac_mls *mac_mls, int flags) 148{ 149 150 if ((mac_mls->mm_flags & flags) != mac_mls->mm_flags) 151 return (EINVAL); 152 return (0); 153} 154 155static int 156mac_mls_dominate_element(struct mac_mls_element *a, 157 struct mac_mls_element *b) 158{ 159 int bit; 160 161 switch (a->mme_type) { 162 case MAC_MLS_TYPE_EQUAL: 163 case MAC_MLS_TYPE_HIGH: 164 return (1); 165 166 case MAC_MLS_TYPE_LOW: 167 switch (b->mme_type) { 168 case MAC_MLS_TYPE_LEVEL: 169 case MAC_MLS_TYPE_HIGH: 170 return (0); 171 172 case MAC_MLS_TYPE_EQUAL: 173 case MAC_MLS_TYPE_LOW: 174 return (1); 175 176 default: 177 panic("mac_mls_dominate_element: b->mme_type invalid"); 178 } 179 180 case MAC_MLS_TYPE_LEVEL: 181 switch (b->mme_type) { 182 case MAC_MLS_TYPE_EQUAL: 183 case MAC_MLS_TYPE_LOW: 184 return (1); 185 186 case MAC_MLS_TYPE_HIGH: 187 return (0); 188 189 case MAC_MLS_TYPE_LEVEL: 190 for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) 191 if (!MAC_MLS_BIT_TEST(bit, 192 a->mme_compartments) && 193 MAC_MLS_BIT_TEST(bit, b->mme_compartments)) 194 return (0); 195 return (a->mme_level >= b->mme_level); 196 197 default: 198 panic("mac_mls_dominate_element: b->mme_type invalid"); 199 } 200 201 default: 202 panic("mac_mls_dominate_element: a->mme_type invalid"); 203 } 204 205 return (0); 206} 207 208static int 209mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) 210{ 211 212 return (mac_mls_dominate_element(&rangeb->mm_rangehigh, 213 &rangea->mm_rangehigh) && 214 mac_mls_dominate_element(&rangea->mm_rangelow, 215 &rangeb->mm_rangelow)); 216} 217 218static int 219mac_mls_single_in_range(struct mac_mls *single, struct mac_mls *range) 220{ 221 222 KASSERT((single->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 223 ("mac_mls_single_in_range: a not single")); 224 KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 225 ("mac_mls_single_in_range: b not range")); 226 227 return (mac_mls_dominate_element(&range->mm_rangehigh, 228 &single->mm_single) && 229 mac_mls_dominate_element(&single->mm_single, 230 &range->mm_rangelow)); 231 232 return (1); 233} 234 235static int 236mac_mls_dominate_single(struct mac_mls *a, struct mac_mls *b) 237{ 238 KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 239 ("mac_mls_dominate_single: a not single")); 240 KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 241 ("mac_mls_dominate_single: b not single")); 242 243 return (mac_mls_dominate_element(&a->mm_single, &b->mm_single)); 244} 245 246static int 247mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) 248{ 249 250 if (a->mme_type == MAC_MLS_TYPE_EQUAL || 251 b->mme_type == MAC_MLS_TYPE_EQUAL) 252 return (1); 253 254 return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); 255} 256 257static int 258mac_mls_equal_single(struct mac_mls *a, struct mac_mls *b) 259{ 260 261 KASSERT((a->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 262 ("mac_mls_equal_single: a not single")); 263 KASSERT((b->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 264 ("mac_mls_equal_single: b not single")); 265 266 return (mac_mls_equal_element(&a->mm_single, &b->mm_single)); 267} 268 269static int 270mac_mls_contains_equal(struct mac_mls *mac_mls) 271{ 272 273 if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE) 274 if (mac_mls->mm_single.mme_type == MAC_MLS_TYPE_EQUAL) 275 return (1); 276 277 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 278 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL) 279 return (1); 280 if (mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 281 return (1); 282 } 283 284 return (0); 285} 286 287static int 288mac_mls_subject_equal_ok(struct mac_mls *mac_mls) 289{ 290 291 KASSERT((mac_mls->mm_flags & MAC_MLS_FLAGS_BOTH) == MAC_MLS_FLAGS_BOTH, 292 ("mac_mls_subject_equal_ok: subject doesn't have both labels")); 293 294 /* If the single is EQUAL, it's ok. */ 295 if (mac_mls->mm_single.mme_type == MAC_MLS_TYPE_EQUAL) 296 return (0); 297 298 /* If either range endpoint is EQUAL, it's ok. */ 299 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL || 300 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 301 return (0); 302 303 /* If the range is low-high, it's ok. */ 304 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW && 305 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH) 306 return (0); 307 308 /* It's not ok. */ 309 return (EPERM); 310} 311 312static int 313mac_mls_valid(struct mac_mls *mac_mls) 314{ 315 316 if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE) { 317 switch (mac_mls->mm_single.mme_type) { 318 case MAC_MLS_TYPE_LEVEL: 319 break; 320 321 case MAC_MLS_TYPE_EQUAL: 322 case MAC_MLS_TYPE_HIGH: 323 case MAC_MLS_TYPE_LOW: 324 if (mac_mls->mm_single.mme_level != 0 || 325 !MAC_MLS_BIT_SET_EMPTY( 326 mac_mls->mm_single.mme_compartments)) 327 return (EINVAL); 328 break; 329 330 default: 331 return (EINVAL); 332 } 333 } else { 334 if (mac_mls->mm_single.mme_type != MAC_MLS_TYPE_UNDEF) 335 return (EINVAL); 336 } 337 338 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 339 switch (mac_mls->mm_rangelow.mme_type) { 340 case MAC_MLS_TYPE_LEVEL: 341 break; 342 343 case MAC_MLS_TYPE_EQUAL: 344 case MAC_MLS_TYPE_HIGH: 345 case MAC_MLS_TYPE_LOW: 346 if (mac_mls->mm_rangelow.mme_level != 0 || 347 !MAC_MLS_BIT_SET_EMPTY( 348 mac_mls->mm_rangelow.mme_compartments)) 349 return (EINVAL); 350 break; 351 352 default: 353 return (EINVAL); 354 } 355 356 switch (mac_mls->mm_rangehigh.mme_type) { 357 case MAC_MLS_TYPE_LEVEL: 358 break; 359 360 case MAC_MLS_TYPE_EQUAL: 361 case MAC_MLS_TYPE_HIGH: 362 case MAC_MLS_TYPE_LOW: 363 if (mac_mls->mm_rangehigh.mme_level != 0 || 364 !MAC_MLS_BIT_SET_EMPTY( 365 mac_mls->mm_rangehigh.mme_compartments)) 366 return (EINVAL); 367 break; 368 369 default: 370 return (EINVAL); 371 } 372 if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh, 373 &mac_mls->mm_rangelow)) 374 return (EINVAL); 375 } else { 376 if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || 377 mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) 378 return (EINVAL); 379 } 380 381 return (0); 382} 383 384static void 385mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow, 386 u_short levellow, u_char *compartmentslow, u_short typehigh, 387 u_short levelhigh, u_char *compartmentshigh) 388{ 389 390 mac_mls->mm_rangelow.mme_type = typelow; 391 mac_mls->mm_rangelow.mme_level = levellow; 392 if (compartmentslow != NULL) 393 memcpy(mac_mls->mm_rangelow.mme_compartments, 394 compartmentslow, 395 sizeof(mac_mls->mm_rangelow.mme_compartments)); 396 mac_mls->mm_rangehigh.mme_type = typehigh; 397 mac_mls->mm_rangehigh.mme_level = levelhigh; 398 if (compartmentshigh != NULL) 399 memcpy(mac_mls->mm_rangehigh.mme_compartments, 400 compartmentshigh, 401 sizeof(mac_mls->mm_rangehigh.mme_compartments)); 402 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 403} 404 405static void 406mac_mls_set_single(struct mac_mls *mac_mls, u_short type, u_short level, 407 u_char *compartments) 408{ 409 410 mac_mls->mm_single.mme_type = type; 411 mac_mls->mm_single.mme_level = level; 412 if (compartments != NULL) 413 memcpy(mac_mls->mm_single.mme_compartments, compartments, 414 sizeof(mac_mls->mm_single.mme_compartments)); 415 mac_mls->mm_flags |= MAC_MLS_FLAG_SINGLE; 416} 417 418static void 419mac_mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 420{ 421 422 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 423 ("mac_mls_copy_range: labelfrom not range")); 424 425 labelto->mm_rangelow = labelfrom->mm_rangelow; 426 labelto->mm_rangehigh = labelfrom->mm_rangehigh; 427 labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 428} 429 430static void 431mac_mls_copy_single(struct mac_mls *labelfrom, struct mac_mls *labelto) 432{ 433 434 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_SINGLE) != 0, 435 ("mac_mls_copy_single: labelfrom not single")); 436 437 labelto->mm_single = labelfrom->mm_single; 438 labelto->mm_flags |= MAC_MLS_FLAG_SINGLE; 439} 440 441static void 442mac_mls_copy(struct mac_mls *source, struct mac_mls *dest) 443{ 444 445 if (source->mm_flags & MAC_MLS_FLAG_SINGLE) 446 mac_mls_copy_single(source, dest); 447 if (source->mm_flags & MAC_MLS_FLAG_RANGE) 448 mac_mls_copy_range(source, dest); 449} 450 451/* 452 * Policy module operations. 453 */ 454static void 455mac_mls_destroy(struct mac_policy_conf *conf) 456{ 457 458} 459 460static void 461mac_mls_init(struct mac_policy_conf *conf) 462{ 463 464} 465 466/* 467 * Label operations. 468 */ 469static void 470mac_mls_init_label(struct label *label) 471{ 472 473 SLOT(label) = mls_alloc(M_WAITOK); 474} 475 476static int 477mac_mls_init_label_waitcheck(struct label *label, int flag) 478{ 479 480 SLOT(label) = mls_alloc(flag); 481 if (SLOT(label) == NULL) 482 return (ENOMEM); 483 484 return (0); 485} 486 487static void 488mac_mls_destroy_label(struct label *label) 489{ 490 491 mls_free(SLOT(label)); 492 SLOT(label) = NULL; 493} 494 495/* 496 * mac_mls_element_to_string() is basically an snprintf wrapper with 497 * the same properties as snprintf(). It returns the length it would 498 * have added to the string in the event the string is too short. 499 */ 500static size_t 501mac_mls_element_to_string(char *string, size_t size, 502 struct mac_mls_element *element) 503{ 504 int pos, bit = 1; 505 506 switch (element->mme_type) { 507 case MAC_MLS_TYPE_HIGH: 508 return (snprintf(string, size, "high")); 509 510 case MAC_MLS_TYPE_LOW: 511 return (snprintf(string, size, "low")); 512 513 case MAC_MLS_TYPE_EQUAL: 514 return (snprintf(string, size, "equal")); 515 516 case MAC_MLS_TYPE_LEVEL: 517 pos = snprintf(string, size, "%d:", element->mme_level); 518 for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) { 519 if (MAC_MLS_BIT_TEST(bit, element->mme_compartments)) 520 pos += snprintf(string + pos, size - pos, 521 "%d+", bit); 522 } 523 if (string[pos - 1] == '+' || string[pos - 1] == ':') 524 string[--pos] = NULL; 525 return (pos); 526 527 default: 528 panic("mac_mls_element_to_string: invalid type (%d)", 529 element->mme_type); 530 } 531} 532 533static size_t 534mac_mls_to_string(char *string, size_t size, size_t *caller_len, 535 struct mac_mls *mac_mls) 536{ 537 size_t left, len; 538 char *curptr; 539 540 bzero(string, size); 541 curptr = string; 542 left = size; 543 544 if (mac_mls->mm_flags & MAC_MLS_FLAG_SINGLE) { 545 len = mac_mls_element_to_string(curptr, left, 546 &mac_mls->mm_single); 547 if (len >= left) 548 return (EINVAL); 549 left -= len; 550 curptr += len; 551 } 552 553 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 554 len = snprintf(curptr, left, "("); 555 if (len >= left) 556 return (EINVAL); 557 left -= len; 558 curptr += len; 559 560 len = mac_mls_element_to_string(curptr, left, 561 &mac_mls->mm_rangelow); 562 if (len >= left) 563 return (EINVAL); 564 left -= len; 565 curptr += len; 566 567 len = snprintf(curptr, left, "-"); 568 if (len >= left) 569 return (EINVAL); 570 left -= len; 571 curptr += len; 572 573 len = mac_mls_element_to_string(curptr, left, 574 &mac_mls->mm_rangehigh); 575 if (len >= left) 576 return (EINVAL); 577 left -= len; 578 curptr += len; 579 580 len = snprintf(curptr, left, ")"); 581 if (len >= left) 582 return (EINVAL); 583 left -= len; 584 curptr += len; 585 } 586 587 *caller_len = strlen(string); 588 return (0); 589} 590 591static int 592mac_mls_externalize_label(struct label *label, char *element_name, 593 char *element_data, size_t size, size_t *len, int *claimed) 594{ 595 struct mac_mls *mac_mls; 596 int error; 597 598 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 599 return (0); 600 601 (*claimed)++; 602 603 mac_mls = SLOT(label); 604 605 error = mac_mls_to_string(element_data, size, len, mac_mls); 606 if (error) 607 return (error); 608 609 *len = strlen(element_data); 610 return (0); 611} 612 613static int 614mac_mls_parse_element(struct mac_mls_element *element, char *string) 615{ 616 617 if (strcmp(string, "high") == 0 || 618 strcmp(string, "hi") == 0) { 619 element->mme_type = MAC_MLS_TYPE_HIGH; 620 element->mme_level = MAC_MLS_TYPE_UNDEF; 621 } else if (strcmp(string, "low") == 0 || 622 strcmp(string, "lo") == 0) { 623 element->mme_type = MAC_MLS_TYPE_LOW; 624 element->mme_level = MAC_MLS_TYPE_UNDEF; 625 } else if (strcmp(string, "equal") == 0 || 626 strcmp(string, "eq") == 0) { 627 element->mme_type = MAC_MLS_TYPE_EQUAL; 628 element->mme_level = MAC_MLS_TYPE_UNDEF; 629 } else { 630 char *p0, *p1; 631 int d; 632 633 p0 = string; 634 d = strtol(p0, &p1, 10); 635 636 if (d < 0 || d > 65535) 637 return (EINVAL); 638 element->mme_type = MAC_MLS_TYPE_LEVEL; 639 element->mme_level = d; 640 641 if (*p1 != ':') { 642 if (p1 == p0 || *p1 != '\0') 643 return (EINVAL); 644 else 645 return (0); 646 } 647 else 648 if (*(p1 + 1) == '\0') 649 return (0); 650 651 while ((p0 = ++p1)) { 652 d = strtol(p0, &p1, 10); 653 if (d < 1 || d > MAC_MLS_MAX_COMPARTMENTS) 654 return (EINVAL); 655 656 MAC_MLS_BIT_SET(d, element->mme_compartments); 657 658 if (*p1 == '\0') 659 break; 660 if (p1 == p0 || *p1 != '+') 661 return (EINVAL); 662 } 663 } 664 665 return (0); 666} 667 668/* 669 * Note: destructively consumes the string, make a local copy before 670 * calling if that's a problem. 671 */ 672static int 673mac_mls_parse(struct mac_mls *mac_mls, char *string) 674{ 675 char *range, *rangeend, *rangehigh, *rangelow, *single; 676 int error; 677 678 /* Do we have a range? */ 679 single = string; 680 range = index(string, '('); 681 if (range == single) 682 single = NULL; 683 rangelow = rangehigh = NULL; 684 if (range != NULL) { 685 /* Nul terminate the end of the single string. */ 686 *range = '\0'; 687 range++; 688 rangelow = range; 689 rangehigh = index(rangelow, '-'); 690 if (rangehigh == NULL) 691 return (EINVAL); 692 rangehigh++; 693 if (*rangelow == '\0' || *rangehigh == '\0') 694 return (EINVAL); 695 rangeend = index(rangehigh, ')'); 696 if (rangeend == NULL) 697 return (EINVAL); 698 if (*(rangeend + 1) != '\0') 699 return (EINVAL); 700 /* Nul terminate the ends of the ranges. */ 701 *(rangehigh - 1) = '\0'; 702 *rangeend = '\0'; 703 } 704 KASSERT((rangelow != NULL && rangehigh != NULL) || 705 (rangelow == NULL && rangehigh == NULL), 706 ("mac_mls_internalize_label: range mismatch")); 707 708 bzero(mac_mls, sizeof(*mac_mls)); 709 if (single != NULL) { 710 error = mac_mls_parse_element(&mac_mls->mm_single, single); 711 if (error) 712 return (error); 713 mac_mls->mm_flags |= MAC_MLS_FLAG_SINGLE; 714 } 715 716 if (rangelow != NULL) { 717 error = mac_mls_parse_element(&mac_mls->mm_rangelow, 718 rangelow); 719 if (error) 720 return (error); 721 error = mac_mls_parse_element(&mac_mls->mm_rangehigh, 722 rangehigh); 723 if (error) 724 return (error); 725 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 726 } 727 728 error = mac_mls_valid(mac_mls); 729 if (error) 730 return (error); 731 732 return (0); 733} 734 735static int 736mac_mls_internalize_label(struct label *label, char *element_name, 737 char *element_data, int *claimed) 738{ 739 struct mac_mls *mac_mls, mac_mls_temp; 740 int error; 741 742 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 743 return (0); 744 745 (*claimed)++; 746 747 error = mac_mls_parse(&mac_mls_temp, element_data); 748 if (error) 749 return (error); 750 751 mac_mls = SLOT(label); 752 *mac_mls = mac_mls_temp; 753 754 return (0); 755} 756 757static void 758mac_mls_copy_label(struct label *src, struct label *dest) 759{ 760 761 *SLOT(dest) = *SLOT(src); 762} 763 764/* 765 * Labeling event operations: file system objects, and things that look 766 * a lot like file system objects. 767 */ 768static void 769mac_mls_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 770 struct label *label) 771{ 772 struct mac_mls *mac_mls; 773 int mls_type; 774 775 mac_mls = SLOT(label); 776 if (strcmp(dev->si_name, "null") == 0 || 777 strcmp(dev->si_name, "zero") == 0 || 778 strcmp(dev->si_name, "random") == 0 || 779 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 780 mls_type = MAC_MLS_TYPE_EQUAL; 781 else if (strcmp(dev->si_name, "kmem") == 0 || 782 strcmp(dev->si_name, "mem") == 0) 783 mls_type = MAC_MLS_TYPE_HIGH; 784 else if (ptys_equal && 785 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 786 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 787 mls_type = MAC_MLS_TYPE_EQUAL; 788 else 789 mls_type = MAC_MLS_TYPE_LOW; 790 mac_mls_set_single(mac_mls, mls_type, 0, NULL); 791} 792 793static void 794mac_mls_create_devfs_directory(char *dirname, int dirnamelen, 795 struct devfs_dirent *devfs_dirent, struct label *label) 796{ 797 struct mac_mls *mac_mls; 798 799 mac_mls = SLOT(label); 800 mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL); 801} 802 803static void 804mac_mls_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 805 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) 806{ 807 struct mac_mls *source, *dest; 808 809 source = SLOT(&cred->cr_label); 810 dest = SLOT(delabel); 811 812 mac_mls_copy_single(source, dest); 813} 814 815static void 816mac_mls_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 817 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 818{ 819 struct mac_mls *source, *dest; 820 821 source = SLOT(direntlabel); 822 dest = SLOT(vnodelabel); 823 mac_mls_copy_single(source, dest); 824} 825 826static void 827mac_mls_create_mount(struct ucred *cred, struct mount *mp, 828 struct label *mntlabel, struct label *fslabel) 829{ 830 struct mac_mls *source, *dest; 831 832 source = SLOT(&cred->cr_label); 833 dest = SLOT(mntlabel); 834 mac_mls_copy_single(source, dest); 835 dest = SLOT(fslabel); 836 mac_mls_copy_single(source, dest); 837} 838 839static void 840mac_mls_create_root_mount(struct ucred *cred, struct mount *mp, 841 struct label *mntlabel, struct label *fslabel) 842{ 843 struct mac_mls *mac_mls; 844 845 /* Always mount root as high integrity. */ 846 mac_mls = SLOT(fslabel); 847 mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL); 848 mac_mls = SLOT(mntlabel); 849 mac_mls_set_single(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL); 850} 851 852static void 853mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp, 854 struct label *vnodelabel, struct label *label) 855{ 856 struct mac_mls *source, *dest; 857 858 source = SLOT(label); 859 dest = SLOT(vnodelabel); 860 861 mac_mls_copy(source, dest); 862} 863 864static void 865mac_mls_update_devfsdirent(struct devfs_dirent *devfs_dirent, 866 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 867{ 868 struct mac_mls *source, *dest; 869 870 source = SLOT(vnodelabel); 871 dest = SLOT(direntlabel); 872 873 mac_mls_copy_single(source, dest); 874} 875 876static void 877mac_mls_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 878 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 879 struct label *vlabel) 880{ 881 struct mac_mls *source, *dest; 882 883 source = SLOT(delabel); 884 dest = SLOT(vlabel); 885 886 mac_mls_copy_single(source, dest); 887} 888 889static int 890mac_mls_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 891 struct vnode *vp, struct label *vlabel) 892{ 893 struct mac_mls temp, *source, *dest; 894 int buflen, error; 895 896 source = SLOT(fslabel); 897 dest = SLOT(vlabel); 898 899 buflen = sizeof(temp); 900 bzero(&temp, buflen); 901 902 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 903 MAC_MLS_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 904 if (error == ENOATTR || error == EOPNOTSUPP) { 905 /* Fall back to the fslabel. */ 906 mac_mls_copy_single(source, dest); 907 return (0); 908 } else if (error) 909 return (error); 910 911 if (buflen != sizeof(temp)) { 912 printf("mac_mls_associate_vnode_extattr: bad size %d\n", 913 buflen); 914 return (EPERM); 915 } 916 if (mac_mls_valid(&temp) != 0) { 917 printf("mac_mls_associate_vnode_extattr: invalid\n"); 918 return (EPERM); 919 } 920 if ((temp.mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) { 921 printf("mac_mls_associated_vnode_extattr: not single\n"); 922 return (EPERM); 923 } 924 925 mac_mls_copy_single(&temp, dest); 926 return (0); 927} 928 929static void 930mac_mls_associate_vnode_singlelabel(struct mount *mp, 931 struct label *fslabel, struct vnode *vp, struct label *vlabel) 932{ 933 struct mac_mls *source, *dest; 934 935 source = SLOT(fslabel); 936 dest = SLOT(vlabel); 937 938 mac_mls_copy_single(source, dest); 939} 940 941static int 942mac_mls_create_vnode_extattr(struct ucred *cred, struct mount *mp, 943 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 944 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 945{ 946 struct mac_mls *source, *dest, temp; 947 size_t buflen; 948 int error; 949 950 buflen = sizeof(temp); 951 bzero(&temp, buflen); 952 953 source = SLOT(&cred->cr_label); 954 dest = SLOT(vlabel); 955 mac_mls_copy_single(source, &temp); 956 957 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 958 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread); 959 if (error == 0) 960 mac_mls_copy_single(source, dest); 961 return (error); 962} 963 964static int 965mac_mls_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 966 struct label *vlabel, struct label *intlabel) 967{ 968 struct mac_mls *source, temp; 969 size_t buflen; 970 int error; 971 972 buflen = sizeof(temp); 973 bzero(&temp, buflen); 974 975 source = SLOT(intlabel); 976 if ((source->mm_flags & MAC_MLS_FLAG_SINGLE) == 0) 977 return (0); 978 979 mac_mls_copy_single(source, &temp); 980 981 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 982 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread); 983 return (error); 984} 985 986/* 987 * Labeling event operations: IPC object. 988 */ 989static void 990mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 991 struct mbuf *m, struct label *mbuflabel) 992{ 993 struct mac_mls *source, *dest; 994 995 source = SLOT(socketlabel); 996 dest = SLOT(mbuflabel); 997 998 mac_mls_copy_single(source, dest); 999} 1000 1001static void 1002mac_mls_create_socket(struct ucred *cred, struct socket *socket, 1003 struct label *socketlabel) 1004{ 1005 struct mac_mls *source, *dest; 1006 1007 source = SLOT(&cred->cr_label); 1008 dest = SLOT(socketlabel); 1009 1010 mac_mls_copy_single(source, dest); 1011} 1012 1013static void 1014mac_mls_create_pipe(struct ucred *cred, struct pipe *pipe, 1015 struct label *pipelabel) 1016{ 1017 struct mac_mls *source, *dest; 1018 1019 source = SLOT(&cred->cr_label); 1020 dest = SLOT(pipelabel); 1021 1022 mac_mls_copy_single(source, dest); 1023} 1024 1025static void 1026mac_mls_create_socket_from_socket(struct socket *oldsocket, 1027 struct label *oldsocketlabel, struct socket *newsocket, 1028 struct label *newsocketlabel) 1029{ 1030 struct mac_mls *source, *dest; 1031 1032 source = SLOT(oldsocketlabel); 1033 dest = SLOT(newsocketlabel); 1034 1035 mac_mls_copy_single(source, dest); 1036} 1037 1038static void 1039mac_mls_relabel_socket(struct ucred *cred, struct socket *socket, 1040 struct label *socketlabel, struct label *newlabel) 1041{ 1042 struct mac_mls *source, *dest; 1043 1044 source = SLOT(newlabel); 1045 dest = SLOT(socketlabel); 1046 1047 mac_mls_copy(source, dest); 1048} 1049 1050static void 1051mac_mls_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1052 struct label *pipelabel, struct label *newlabel) 1053{ 1054 struct mac_mls *source, *dest; 1055 1056 source = SLOT(newlabel); 1057 dest = SLOT(pipelabel); 1058 1059 mac_mls_copy(source, dest); 1060} 1061 1062static void 1063mac_mls_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1064 struct socket *socket, struct label *socketpeerlabel) 1065{ 1066 struct mac_mls *source, *dest; 1067 1068 source = SLOT(mbuflabel); 1069 dest = SLOT(socketpeerlabel); 1070 1071 mac_mls_copy_single(source, dest); 1072} 1073 1074/* 1075 * Labeling event operations: network objects. 1076 */ 1077static void 1078mac_mls_set_socket_peer_from_socket(struct socket *oldsocket, 1079 struct label *oldsocketlabel, struct socket *newsocket, 1080 struct label *newsocketpeerlabel) 1081{ 1082 struct mac_mls *source, *dest; 1083 1084 source = SLOT(oldsocketlabel); 1085 dest = SLOT(newsocketpeerlabel); 1086 1087 mac_mls_copy_single(source, dest); 1088} 1089 1090static void 1091mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1092 struct label *bpflabel) 1093{ 1094 struct mac_mls *source, *dest; 1095 1096 source = SLOT(&cred->cr_label); 1097 dest = SLOT(bpflabel); 1098 1099 mac_mls_copy_single(source, dest); 1100} 1101 1102static void 1103mac_mls_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1104{ 1105 struct mac_mls *dest; 1106 int level; 1107 1108 dest = SLOT(ifnetlabel); 1109 1110 if (ifnet->if_type == IFT_LOOP) 1111 level = MAC_MLS_TYPE_EQUAL; 1112 else 1113 level = MAC_MLS_TYPE_LOW; 1114 1115 mac_mls_set_single(dest, level, 0, NULL); 1116 mac_mls_set_range(dest, level, 0, NULL, level, 0, NULL); 1117} 1118 1119static void 1120mac_mls_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1121 struct ipq *ipq, struct label *ipqlabel) 1122{ 1123 struct mac_mls *source, *dest; 1124 1125 source = SLOT(fragmentlabel); 1126 dest = SLOT(ipqlabel); 1127 1128 mac_mls_copy_single(source, dest); 1129} 1130 1131static void 1132mac_mls_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1133 struct mbuf *datagram, struct label *datagramlabel) 1134{ 1135 struct mac_mls *source, *dest; 1136 1137 source = SLOT(ipqlabel); 1138 dest = SLOT(datagramlabel); 1139 1140 /* Just use the head, since we require them all to match. */ 1141 mac_mls_copy_single(source, dest); 1142} 1143 1144static void 1145mac_mls_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1146 struct mbuf *fragment, struct label *fragmentlabel) 1147{ 1148 struct mac_mls *source, *dest; 1149 1150 source = SLOT(datagramlabel); 1151 dest = SLOT(fragmentlabel); 1152 1153 mac_mls_copy_single(source, dest); 1154} 1155 1156static void 1157mac_mls_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1158 struct label *oldmbuflabel, struct mbuf *newmbuf, 1159 struct label *newmbuflabel) 1160{ 1161 struct mac_mls *source, *dest; 1162 1163 source = SLOT(oldmbuflabel); 1164 dest = SLOT(newmbuflabel); 1165 1166 /* 1167 * Because the source mbuf may not yet have been "created", 1168 * just initialized, we do a conditional copy. Since we don't 1169 * allow mbufs to have ranges, do a KASSERT to make sure that 1170 * doesn't happen. 1171 */ 1172 KASSERT((source->mm_flags & MAC_MLS_FLAG_RANGE) == 0, 1173 ("mac_mls_create_mbuf_from_mbuf: source mbuf has range")); 1174 mac_mls_copy(source, dest); 1175} 1176 1177static void 1178mac_mls_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1179 struct mbuf *mbuf, struct label *mbuflabel) 1180{ 1181 struct mac_mls *dest; 1182 1183 dest = SLOT(mbuflabel); 1184 1185 mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1186} 1187 1188static void 1189mac_mls_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1190 struct mbuf *mbuf, struct label *mbuflabel) 1191{ 1192 struct mac_mls *source, *dest; 1193 1194 source = SLOT(bpflabel); 1195 dest = SLOT(mbuflabel); 1196 1197 mac_mls_copy_single(source, dest); 1198} 1199 1200static void 1201mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1202 struct mbuf *m, struct label *mbuflabel) 1203{ 1204 struct mac_mls *source, *dest; 1205 1206 source = SLOT(ifnetlabel); 1207 dest = SLOT(mbuflabel); 1208 1209 mac_mls_copy_single(source, dest); 1210} 1211 1212static void 1213mac_mls_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1214 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1215 struct mbuf *newmbuf, struct label *newmbuflabel) 1216{ 1217 struct mac_mls *source, *dest; 1218 1219 source = SLOT(oldmbuflabel); 1220 dest = SLOT(newmbuflabel); 1221 1222 mac_mls_copy_single(source, dest); 1223} 1224 1225static void 1226mac_mls_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1227 struct mbuf *newmbuf, struct label *newmbuflabel) 1228{ 1229 struct mac_mls *source, *dest; 1230 1231 source = SLOT(oldmbuflabel); 1232 dest = SLOT(newmbuflabel); 1233 1234 mac_mls_copy_single(source, dest); 1235} 1236 1237static int 1238mac_mls_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1239 struct ipq *ipq, struct label *ipqlabel) 1240{ 1241 struct mac_mls *a, *b; 1242 1243 a = SLOT(ipqlabel); 1244 b = SLOT(fragmentlabel); 1245 1246 return (mac_mls_equal_single(a, b)); 1247} 1248 1249static void 1250mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1251 struct label *ifnetlabel, struct label *newlabel) 1252{ 1253 struct mac_mls *source, *dest; 1254 1255 source = SLOT(newlabel); 1256 dest = SLOT(ifnetlabel); 1257 1258 mac_mls_copy(source, dest); 1259} 1260 1261static void 1262mac_mls_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1263 struct ipq *ipq, struct label *ipqlabel) 1264{ 1265 1266 /* NOOP: we only accept matching labels, so no need to update */ 1267} 1268 1269/* 1270 * Labeling event operations: processes. 1271 */ 1272static void 1273mac_mls_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1274{ 1275 struct mac_mls *source, *dest; 1276 1277 source = SLOT(&cred_parent->cr_label); 1278 dest = SLOT(&cred_child->cr_label); 1279 1280 mac_mls_copy_single(source, dest); 1281 mac_mls_copy_range(source, dest); 1282} 1283 1284static void 1285mac_mls_create_proc0(struct ucred *cred) 1286{ 1287 struct mac_mls *dest; 1288 1289 dest = SLOT(&cred->cr_label); 1290 1291 mac_mls_set_single(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1292 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 1293 0, NULL); 1294} 1295 1296static void 1297mac_mls_create_proc1(struct ucred *cred) 1298{ 1299 struct mac_mls *dest; 1300 1301 dest = SLOT(&cred->cr_label); 1302 1303 mac_mls_set_single(dest, MAC_MLS_TYPE_LOW, 0, NULL); 1304 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 1305 0, NULL); 1306} 1307 1308static void 1309mac_mls_relabel_cred(struct ucred *cred, struct label *newlabel) 1310{ 1311 struct mac_mls *source, *dest; 1312 1313 source = SLOT(newlabel); 1314 dest = SLOT(&cred->cr_label); 1315 1316 mac_mls_copy(source, dest); 1317} 1318 1319/* 1320 * Access control checks. 1321 */ 1322static int 1323mac_mls_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1324 struct ifnet *ifnet, struct label *ifnetlabel) 1325{ 1326 struct mac_mls *a, *b; 1327 1328 if (!mac_mls_enabled) 1329 return (0); 1330 1331 a = SLOT(bpflabel); 1332 b = SLOT(ifnetlabel); 1333 1334 if (mac_mls_equal_single(a, b)) 1335 return (0); 1336 return (EACCES); 1337} 1338 1339static int 1340mac_mls_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1341{ 1342 struct mac_mls *subj, *new; 1343 int error; 1344 1345 subj = SLOT(&cred->cr_label); 1346 new = SLOT(newlabel); 1347 1348 /* 1349 * If there is an MLS label update for the credential, it may be 1350 * an update of single, range, or both. 1351 */ 1352 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 1353 if (error) 1354 return (error); 1355 1356 /* 1357 * If the MLS label is to be changed, authorize as appropriate. 1358 */ 1359 if (new->mm_flags & MAC_MLS_FLAGS_BOTH) { 1360 /* 1361 * To change the MLS single label on a credential, the 1362 * new single label must be in the current range. 1363 */ 1364 if (new->mm_flags & MAC_MLS_FLAG_SINGLE && 1365 !mac_mls_single_in_range(new, subj)) 1366 return (EPERM); 1367 1368 /* 1369 * To change the MLS range label on a credential, the 1370 * new range label must be in the current range. 1371 */ 1372 if (new->mm_flags & MAC_MLS_FLAG_RANGE && 1373 !mac_mls_range_in_range(new, subj)) 1374 return (EPERM); 1375 1376 /* 1377 * To have EQUAL in any component of the new credential 1378 * MLS label, the subject must already have EQUAL in 1379 * their label. 1380 */ 1381 if (mac_mls_contains_equal(new)) { 1382 error = mac_mls_subject_equal_ok(subj); 1383 if (error) 1384 return (error); 1385 } 1386 1387 /* 1388 * XXXMAC: Additional consistency tests regarding the single 1389 * and range of the new label might be performed here. 1390 */ 1391 } 1392 1393 return (0); 1394} 1395 1396static int 1397mac_mls_check_cred_visible(struct ucred *u1, struct ucred *u2) 1398{ 1399 struct mac_mls *subj, *obj; 1400 1401 if (!mac_mls_enabled) 1402 return (0); 1403 1404 subj = SLOT(&u1->cr_label); 1405 obj = SLOT(&u2->cr_label); 1406 1407 /* XXX: range */ 1408 if (!mac_mls_dominate_single(subj, obj)) 1409 return (ESRCH); 1410 1411 return (0); 1412} 1413 1414static int 1415mac_mls_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1416 struct label *ifnetlabel, struct label *newlabel) 1417{ 1418 struct mac_mls *subj, *new; 1419 int error; 1420 1421 subj = SLOT(&cred->cr_label); 1422 new = SLOT(newlabel); 1423 1424 /* 1425 * If there is an MLS label update for the interface, it may 1426 * be an update of single, range, or both. 1427 */ 1428 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 1429 if (error) 1430 return (error); 1431 1432 /* 1433 * If the MLS label is to be changed, authorize as appropriate. 1434 */ 1435 if (new->mm_flags & MAC_MLS_FLAGS_BOTH) { 1436 /* 1437 * Rely on traditional superuser status for the MLS 1438 * interface relabel requirements. XXX: This will go 1439 * away. 1440 */ 1441 error = suser_cred(cred, 0); 1442 if (error) 1443 return (EPERM); 1444 1445 /* 1446 * XXXMAC: Additional consistency tests regarding the single 1447 * and the range of the new label might be performed here. 1448 */ 1449 } 1450 1451 return (0); 1452} 1453 1454static int 1455mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1456 struct mbuf *m, struct label *mbuflabel) 1457{ 1458 struct mac_mls *p, *i; 1459 1460 if (!mac_mls_enabled) 1461 return (0); 1462 1463 p = SLOT(mbuflabel); 1464 i = SLOT(ifnetlabel); 1465 1466 return (mac_mls_single_in_range(p, i) ? 0 : EACCES); 1467} 1468 1469static int 1470mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp, 1471 struct label *mntlabel) 1472{ 1473 struct mac_mls *subj, *obj; 1474 1475 if (!mac_mls_enabled) 1476 return (0); 1477 1478 subj = SLOT(&cred->cr_label); 1479 obj = SLOT(mntlabel); 1480 1481 if (!mac_mls_dominate_single(subj, obj)) 1482 return (EACCES); 1483 1484 return (0); 1485} 1486 1487static int 1488mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1489 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1490{ 1491 1492 if(!mac_mls_enabled) 1493 return (0); 1494 1495 /* XXX: This will be implemented soon... */ 1496 1497 return (0); 1498} 1499 1500static int 1501mac_mls_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1502 struct label *pipelabel) 1503{ 1504 struct mac_mls *subj, *obj; 1505 1506 if (!mac_mls_enabled) 1507 return (0); 1508 1509 subj = SLOT(&cred->cr_label); 1510 obj = SLOT((pipelabel)); 1511 1512 if (!mac_mls_dominate_single(subj, obj)) 1513 return (EACCES); 1514 1515 return (0); 1516} 1517 1518static int 1519mac_mls_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1520 struct label *pipelabel) 1521{ 1522 struct mac_mls *subj, *obj; 1523 1524 if (!mac_mls_enabled) 1525 return (0); 1526 1527 subj = SLOT(&cred->cr_label); 1528 obj = SLOT((pipelabel)); 1529 1530 if (!mac_mls_dominate_single(subj, obj)) 1531 return (EACCES); 1532 1533 return (0); 1534} 1535 1536static int 1537mac_mls_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1538 struct label *pipelabel, struct label *newlabel) 1539{ 1540 struct mac_mls *subj, *obj, *new; 1541 int error; 1542 1543 new = SLOT(newlabel); 1544 subj = SLOT(&cred->cr_label); 1545 obj = SLOT(pipelabel); 1546 1547 /* 1548 * If there is an MLS label update for a pipe, it must be a 1549 * single update. 1550 */ 1551 error = mls_atmostflags(new, MAC_MLS_FLAG_SINGLE); 1552 if (error) 1553 return (error); 1554 1555 /* 1556 * To perform a relabel of a pipe (MLS label or not), MLS must 1557 * authorize the relabel. 1558 */ 1559 if (!mac_mls_single_in_range(obj, subj)) 1560 return (EPERM); 1561 1562 /* 1563 * If the MLS label is to be changed, authorize as appropriate. 1564 */ 1565 if (new->mm_flags & MAC_MLS_FLAG_SINGLE) { 1566 /* 1567 * To change the MLS label on a pipe, the new pipe label 1568 * must be in the subject range. 1569 */ 1570 if (!mac_mls_single_in_range(new, subj)) 1571 return (EPERM); 1572 1573 /* 1574 * To change the MLS label on a pipe to be EQUAL, the 1575 * subject must have appropriate privilege. 1576 */ 1577 if (mac_mls_contains_equal(new)) { 1578 error = mac_mls_subject_equal_ok(subj); 1579 if (error) 1580 return (error); 1581 } 1582 } 1583 1584 return (0); 1585} 1586 1587static int 1588mac_mls_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1589 struct label *pipelabel) 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((pipelabel)); 1598 1599 if (!mac_mls_dominate_single(subj, obj)) 1600 return (EACCES); 1601 1602 return (0); 1603} 1604 1605static int 1606mac_mls_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1607 struct label *pipelabel) 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((pipelabel)); 1616 1617 if (!mac_mls_dominate_single(obj, subj)) 1618 return (EACCES); 1619 1620 return (0); 1621} 1622 1623static int 1624mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc) 1625{ 1626 struct mac_mls *subj, *obj; 1627 1628 if (!mac_mls_enabled) 1629 return (0); 1630 1631 subj = SLOT(&cred->cr_label); 1632 obj = SLOT(&proc->p_ucred->cr_label); 1633 1634 /* XXX: range checks */ 1635 if (!mac_mls_dominate_single(subj, obj)) 1636 return (ESRCH); 1637 if (!mac_mls_dominate_single(obj, subj)) 1638 return (EACCES); 1639 1640 return (0); 1641} 1642 1643static int 1644mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc) 1645{ 1646 struct mac_mls *subj, *obj; 1647 1648 if (!mac_mls_enabled) 1649 return (0); 1650 1651 subj = SLOT(&cred->cr_label); 1652 obj = SLOT(&proc->p_ucred->cr_label); 1653 1654 /* XXX: range checks */ 1655 if (!mac_mls_dominate_single(subj, obj)) 1656 return (ESRCH); 1657 if (!mac_mls_dominate_single(obj, subj)) 1658 return (EACCES); 1659 1660 return (0); 1661} 1662 1663static int 1664mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1665{ 1666 struct mac_mls *subj, *obj; 1667 1668 if (!mac_mls_enabled) 1669 return (0); 1670 1671 subj = SLOT(&cred->cr_label); 1672 obj = SLOT(&proc->p_ucred->cr_label); 1673 1674 /* XXX: range checks */ 1675 if (!mac_mls_dominate_single(subj, obj)) 1676 return (ESRCH); 1677 if (!mac_mls_dominate_single(obj, subj)) 1678 return (EACCES); 1679 1680 return (0); 1681} 1682 1683static int 1684mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel, 1685 struct mbuf *m, struct label *mbuflabel) 1686{ 1687 struct mac_mls *p, *s; 1688 1689 if (!mac_mls_enabled) 1690 return (0); 1691 1692 p = SLOT(mbuflabel); 1693 s = SLOT(socketlabel); 1694 1695 return (mac_mls_equal_single(p, s) ? 0 : EACCES); 1696} 1697 1698static int 1699mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket, 1700 struct label *socketlabel, struct label *newlabel) 1701{ 1702 struct mac_mls *subj, *obj, *new; 1703 int error; 1704 1705 new = SLOT(newlabel); 1706 subj = SLOT(&cred->cr_label); 1707 obj = SLOT(socketlabel); 1708 1709 /* 1710 * If there is an MLS label update for the socket, it may be 1711 * an update of single. 1712 */ 1713 error = mls_atmostflags(new, MAC_MLS_FLAG_SINGLE); 1714 if (error) 1715 return (error); 1716 1717 /* 1718 * To relabel a socket, the old socket single must be in the subject 1719 * range. 1720 */ 1721 if (!mac_mls_single_in_range(obj, subj)) 1722 return (EPERM); 1723 1724 /* 1725 * If the MLS label is to be changed, authorize as appropriate. 1726 */ 1727 if (new->mm_flags & MAC_MLS_FLAG_SINGLE) { 1728 /* 1729 * To relabel a socket, the new socket single must be in 1730 * the subject range. 1731 */ 1732 if (!mac_mls_single_in_range(new, subj)) 1733 return (EPERM); 1734 1735 /* 1736 * To change the MLS label on the socket to contain EQUAL, 1737 * the subject must have appropriate privilege. 1738 */ 1739 if (mac_mls_contains_equal(new)) { 1740 error = mac_mls_subject_equal_ok(subj); 1741 if (error) 1742 return (error); 1743 } 1744 } 1745 1746 return (0); 1747} 1748 1749static int 1750mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket, 1751 struct label *socketlabel) 1752{ 1753 struct mac_mls *subj, *obj; 1754 1755 if (!mac_mls_enabled) 1756 return (0); 1757 1758 subj = SLOT(&cred->cr_label); 1759 obj = SLOT(socketlabel); 1760 1761 if (!mac_mls_dominate_single(subj, obj)) 1762 return (ENOENT); 1763 1764 return (0); 1765} 1766 1767static int 1768mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1769 struct label *dlabel) 1770{ 1771 struct mac_mls *subj, *obj; 1772 1773 if (!mac_mls_enabled) 1774 return (0); 1775 1776 subj = SLOT(&cred->cr_label); 1777 obj = SLOT(dlabel); 1778 1779 if (!mac_mls_dominate_single(subj, obj)) 1780 return (EACCES); 1781 1782 return (0); 1783} 1784 1785static int 1786mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1787 struct label *dlabel) 1788{ 1789 struct mac_mls *subj, *obj; 1790 1791 if (!mac_mls_enabled) 1792 return (0); 1793 1794 subj = SLOT(&cred->cr_label); 1795 obj = SLOT(dlabel); 1796 1797 if (!mac_mls_dominate_single(subj, obj)) 1798 return (EACCES); 1799 1800 return (0); 1801} 1802 1803static int 1804mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1805 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1806{ 1807 struct mac_mls *subj, *obj; 1808 1809 if (!mac_mls_enabled) 1810 return (0); 1811 1812 subj = SLOT(&cred->cr_label); 1813 obj = SLOT(dlabel); 1814 1815 if (!mac_mls_dominate_single(obj, subj)) 1816 return (EACCES); 1817 1818 return (0); 1819} 1820 1821static int 1822mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1823 struct label *dlabel, struct vnode *vp, struct label *label, 1824 struct componentname *cnp) 1825{ 1826 struct mac_mls *subj, *obj; 1827 1828 if (!mac_mls_enabled) 1829 return (0); 1830 1831 subj = SLOT(&cred->cr_label); 1832 obj = SLOT(dlabel); 1833 1834 if (!mac_mls_dominate_single(obj, subj)) 1835 return (EACCES); 1836 1837 obj = SLOT(label); 1838 1839 if (!mac_mls_dominate_single(obj, subj)) 1840 return (EACCES); 1841 1842 return (0); 1843} 1844 1845static int 1846mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1847 struct label *label, acl_type_t type) 1848{ 1849 struct mac_mls *subj, *obj; 1850 1851 if (!mac_mls_enabled) 1852 return (0); 1853 1854 subj = SLOT(&cred->cr_label); 1855 obj = SLOT(label); 1856 1857 if (!mac_mls_dominate_single(obj, subj)) 1858 return (EACCES); 1859 1860 return (0); 1861} 1862 1863static int 1864mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp,
|
1883 if (!mac_mls_enabled) 1884 return (0); 1885 1886 subj = SLOT(&cred->cr_label); 1887 obj = SLOT(label); 1888 1889 if (!mac_mls_dominate_single(subj, obj)) 1890 return (EACCES); 1891 1892 return (0); 1893} 1894 1895static int 1896mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 1897 struct label *label, acl_type_t type) 1898{ 1899 struct mac_mls *subj, *obj; 1900 1901 if (!mac_mls_enabled) 1902 return (0); 1903 1904 subj = SLOT(&cred->cr_label); 1905 obj = SLOT(label); 1906 1907 if (!mac_mls_dominate_single(subj, obj)) 1908 return (EACCES); 1909 1910 return (0); 1911} 1912 1913static int 1914mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1915 struct label *label, int attrnamespace, const char *name, struct uio *uio) 1916{ 1917 struct mac_mls *subj, *obj; 1918 1919 if (!mac_mls_enabled) 1920 return (0); 1921 1922 subj = SLOT(&cred->cr_label); 1923 obj = SLOT(label); 1924 1925 if (!mac_mls_dominate_single(subj, obj)) 1926 return (EACCES); 1927 1928 return (0); 1929} 1930 1931static int 1932mac_mls_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1933 struct label *dlabel, struct vnode *vp, struct label *label, 1934 struct componentname *cnp) 1935{ 1936 struct mac_mls *subj, *obj; 1937 1938 if (!mac_mls_enabled) 1939 return (0); 1940 1941 subj = SLOT(&cred->cr_label); 1942 obj = SLOT(dlabel); 1943 1944 if (!mac_mls_dominate_single(obj, subj)) 1945 return (EACCES); 1946 1947 obj = SLOT(dlabel); 1948 if (!mac_mls_dominate_single(obj, subj)) 1949 return (EACCES); 1950 1951 return (0); 1952} 1953 1954static int 1955mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1956 struct label *dlabel, struct componentname *cnp) 1957{ 1958 struct mac_mls *subj, *obj; 1959 1960 if (!mac_mls_enabled) 1961 return (0); 1962 1963 subj = SLOT(&cred->cr_label); 1964 obj = SLOT(dlabel); 1965 1966 if (!mac_mls_dominate_single(subj, obj)) 1967 return (EACCES); 1968 1969 return (0); 1970} 1971 1972static int 1973mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 1974 struct label *label, int prot) 1975{ 1976 struct mac_mls *subj, *obj; 1977 1978 /* 1979 * Rely on the use of open()-time protections to handle 1980 * non-revocation cases. 1981 */ 1982 if (!mac_mls_enabled || !revocation_enabled) 1983 return (0); 1984 1985 subj = SLOT(&cred->cr_label); 1986 obj = SLOT(label); 1987 1988 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 1989 if (!mac_mls_dominate_single(subj, obj)) 1990 return (EACCES); 1991 } 1992 if (prot & VM_PROT_WRITE) { 1993 if (!mac_mls_dominate_single(obj, subj)) 1994 return (EACCES); 1995 } 1996 1997 return (0); 1998} 1999 2000static int 2001mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, 2002 struct label *vnodelabel, int acc_mode) 2003{ 2004 struct mac_mls *subj, *obj; 2005 2006 if (!mac_mls_enabled) 2007 return (0); 2008 2009 subj = SLOT(&cred->cr_label); 2010 obj = SLOT(vnodelabel); 2011 2012 /* XXX privilege override for admin? */ 2013 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2014 if (!mac_mls_dominate_single(subj, obj)) 2015 return (EACCES); 2016 } 2017 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2018 if (!mac_mls_dominate_single(obj, subj)) 2019 return (EACCES); 2020 } 2021 2022 return (0); 2023} 2024 2025static int 2026mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2027 struct vnode *vp, struct label *label) 2028{ 2029 struct mac_mls *subj, *obj; 2030 2031 if (!mac_mls_enabled || !revocation_enabled) 2032 return (0); 2033 2034 subj = SLOT(&active_cred->cr_label); 2035 obj = SLOT(label); 2036 2037 if (!mac_mls_dominate_single(subj, obj)) 2038 return (EACCES); 2039 2040 return (0); 2041} 2042 2043static int 2044mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2045 struct vnode *vp, struct label *label) 2046{ 2047 struct mac_mls *subj, *obj; 2048 2049 if (!mac_mls_enabled || !revocation_enabled) 2050 return (0); 2051 2052 subj = SLOT(&active_cred->cr_label); 2053 obj = SLOT(label); 2054 2055 if (!mac_mls_dominate_single(subj, obj)) 2056 return (EACCES); 2057 2058 return (0); 2059} 2060 2061static int 2062mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2063 struct label *dlabel) 2064{ 2065 struct mac_mls *subj, *obj; 2066 2067 if (!mac_mls_enabled) 2068 return (0); 2069 2070 subj = SLOT(&cred->cr_label); 2071 obj = SLOT(dlabel); 2072 2073 if (!mac_mls_dominate_single(subj, obj)) 2074 return (EACCES); 2075 2076 return (0); 2077} 2078 2079static int 2080mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2081 struct label *vnodelabel) 2082{ 2083 struct mac_mls *subj, *obj; 2084 2085 if (!mac_mls_enabled) 2086 return (0); 2087 2088 subj = SLOT(&cred->cr_label); 2089 obj = SLOT(vnodelabel); 2090 2091 if (!mac_mls_dominate_single(subj, obj)) 2092 return (EACCES); 2093 2094 return (0); 2095} 2096 2097static int 2098mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2099 struct label *vnodelabel, struct label *newlabel) 2100{ 2101 struct mac_mls *old, *new, *subj; 2102 int error; 2103 2104 old = SLOT(vnodelabel); 2105 new = SLOT(newlabel); 2106 subj = SLOT(&cred->cr_label); 2107 2108 /* 2109 * If there is an MLS label update for the vnode, it must be a 2110 * single label. 2111 */ 2112 error = mls_atmostflags(new, MAC_MLS_FLAG_SINGLE); 2113 if (error) 2114 return (error); 2115 2116 /* 2117 * To perform a relabel of the vnode (MLS label or not), MLS must 2118 * authorize the relabel. 2119 */ 2120 if (!mac_mls_single_in_range(old, subj)) 2121 return (EPERM); 2122 2123 /* 2124 * If the MLS label is to be changed, authorize as appropriate. 2125 */ 2126 if (new->mm_flags & MAC_MLS_FLAG_SINGLE) { 2127 /* 2128 * To change the MLS label on a vnode, the new vnode label 2129 * must be in the subject range. 2130 */ 2131 if (!mac_mls_single_in_range(new, subj)) 2132 return (EPERM); 2133 2134 /* 2135 * To change the MLS label on the vnode to be EQUAL, 2136 * the subject must have appropriate privilege. 2137 */ 2138 if (mac_mls_contains_equal(new)) { 2139 error = mac_mls_subject_equal_ok(subj); 2140 if (error) 2141 return (error); 2142 } 2143 } 2144 2145 return (0); 2146} 2147 2148 2149static int 2150mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2151 struct label *dlabel, struct vnode *vp, struct label *label, 2152 struct componentname *cnp) 2153{ 2154 struct mac_mls *subj, *obj; 2155 2156 if (!mac_mls_enabled) 2157 return (0); 2158 2159 subj = SLOT(&cred->cr_label); 2160 obj = SLOT(dlabel); 2161 2162 if (!mac_mls_dominate_single(obj, subj)) 2163 return (EACCES); 2164 2165 obj = SLOT(label); 2166 2167 if (!mac_mls_dominate_single(obj, subj)) 2168 return (EACCES); 2169 2170 return (0); 2171} 2172 2173static int 2174mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2175 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2176 struct componentname *cnp) 2177{ 2178 struct mac_mls *subj, *obj; 2179 2180 if (!mac_mls_enabled) 2181 return (0); 2182 2183 subj = SLOT(&cred->cr_label); 2184 obj = SLOT(dlabel); 2185 2186 if (!mac_mls_dominate_single(obj, subj)) 2187 return (EACCES); 2188 2189 if (vp != NULL) { 2190 obj = SLOT(label); 2191 2192 if (!mac_mls_dominate_single(obj, subj)) 2193 return (EACCES); 2194 } 2195 2196 return (0); 2197} 2198 2199static int 2200mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2201 struct label *label) 2202{ 2203 struct mac_mls *subj, *obj; 2204 2205 if (!mac_mls_enabled) 2206 return (0); 2207 2208 subj = SLOT(&cred->cr_label); 2209 obj = SLOT(label); 2210 2211 if (!mac_mls_dominate_single(obj, subj)) 2212 return (EACCES); 2213 2214 return (0); 2215} 2216 2217static int 2218mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2219 struct label *label, acl_type_t type, struct acl *acl) 2220{ 2221 struct mac_mls *subj, *obj; 2222 2223 if (!mac_mls_enabled) 2224 return (0); 2225 2226 subj = SLOT(&cred->cr_label); 2227 obj = SLOT(label); 2228 2229 if (!mac_mls_dominate_single(obj, subj)) 2230 return (EACCES); 2231 2232 return (0); 2233} 2234 2235static int 2236mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2237 struct label *vnodelabel, int attrnamespace, const char *name, 2238 struct uio *uio) 2239{ 2240 struct mac_mls *subj, *obj; 2241 2242 if (!mac_mls_enabled) 2243 return (0); 2244 2245 subj = SLOT(&cred->cr_label); 2246 obj = SLOT(vnodelabel); 2247 2248 if (!mac_mls_dominate_single(obj, subj)) 2249 return (EACCES); 2250 2251 /* XXX: protect the MAC EA in a special way? */ 2252 2253 return (0); 2254} 2255 2256static int 2257mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2258 struct label *vnodelabel, u_long flags) 2259{ 2260 struct mac_mls *subj, *obj; 2261 2262 if (!mac_mls_enabled) 2263 return (0); 2264 2265 subj = SLOT(&cred->cr_label); 2266 obj = SLOT(vnodelabel); 2267 2268 if (!mac_mls_dominate_single(obj, subj)) 2269 return (EACCES); 2270 2271 return (0); 2272} 2273 2274static int 2275mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2276 struct label *vnodelabel, mode_t mode) 2277{ 2278 struct mac_mls *subj, *obj; 2279 2280 if (!mac_mls_enabled) 2281 return (0); 2282 2283 subj = SLOT(&cred->cr_label); 2284 obj = SLOT(vnodelabel); 2285 2286 if (!mac_mls_dominate_single(obj, subj)) 2287 return (EACCES); 2288 2289 return (0); 2290} 2291 2292static int 2293mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2294 struct label *vnodelabel, uid_t uid, gid_t gid) 2295{ 2296 struct mac_mls *subj, *obj; 2297 2298 if (!mac_mls_enabled) 2299 return (0); 2300 2301 subj = SLOT(&cred->cr_label); 2302 obj = SLOT(vnodelabel); 2303 2304 if (!mac_mls_dominate_single(obj, subj)) 2305 return (EACCES); 2306 2307 return (0); 2308} 2309 2310static int 2311mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2312 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2313{ 2314 struct mac_mls *subj, *obj; 2315 2316 if (!mac_mls_enabled) 2317 return (0); 2318 2319 subj = SLOT(&cred->cr_label); 2320 obj = SLOT(vnodelabel); 2321 2322 if (!mac_mls_dominate_single(obj, subj)) 2323 return (EACCES); 2324 2325 return (0); 2326} 2327 2328static int 2329mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2330 struct vnode *vp, struct label *vnodelabel) 2331{ 2332 struct mac_mls *subj, *obj; 2333 2334 if (!mac_mls_enabled) 2335 return (0); 2336 2337 subj = SLOT(&active_cred->cr_label); 2338 obj = SLOT(vnodelabel); 2339 2340 if (!mac_mls_dominate_single(subj, obj)) 2341 return (EACCES); 2342 2343 return (0); 2344} 2345 2346static int 2347mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2348 struct vnode *vp, struct label *label) 2349{ 2350 struct mac_mls *subj, *obj; 2351 2352 if (!mac_mls_enabled || !revocation_enabled) 2353 return (0); 2354 2355 subj = SLOT(&active_cred->cr_label); 2356 obj = SLOT(label); 2357 2358 if (!mac_mls_dominate_single(obj, subj)) 2359 return (EACCES); 2360 2361 return (0); 2362} 2363 2364static struct mac_policy_ops mac_mls_ops = 2365{ 2366 .mpo_destroy = mac_mls_destroy, 2367 .mpo_init = mac_mls_init, 2368 .mpo_init_bpfdesc_label = mac_mls_init_label, 2369 .mpo_init_cred_label = mac_mls_init_label, 2370 .mpo_init_devfsdirent_label = mac_mls_init_label, 2371 .mpo_init_ifnet_label = mac_mls_init_label, 2372 .mpo_init_ipq_label = mac_mls_init_label, 2373 .mpo_init_mbuf_label = mac_mls_init_label_waitcheck, 2374 .mpo_init_mount_label = mac_mls_init_label, 2375 .mpo_init_mount_fs_label = mac_mls_init_label, 2376 .mpo_init_pipe_label = mac_mls_init_label, 2377 .mpo_init_socket_label = mac_mls_init_label_waitcheck, 2378 .mpo_init_socket_peer_label = mac_mls_init_label_waitcheck, 2379 .mpo_init_vnode_label = mac_mls_init_label, 2380 .mpo_destroy_bpfdesc_label = mac_mls_destroy_label, 2381 .mpo_destroy_cred_label = mac_mls_destroy_label, 2382 .mpo_destroy_devfsdirent_label = mac_mls_destroy_label, 2383 .mpo_destroy_ifnet_label = mac_mls_destroy_label, 2384 .mpo_destroy_ipq_label = mac_mls_destroy_label, 2385 .mpo_destroy_mbuf_label = mac_mls_destroy_label, 2386 .mpo_destroy_mount_label = mac_mls_destroy_label, 2387 .mpo_destroy_mount_fs_label = mac_mls_destroy_label, 2388 .mpo_destroy_pipe_label = mac_mls_destroy_label, 2389 .mpo_destroy_socket_label = mac_mls_destroy_label, 2390 .mpo_destroy_socket_peer_label = mac_mls_destroy_label, 2391 .mpo_destroy_vnode_label = mac_mls_destroy_label, 2392 .mpo_copy_pipe_label = mac_mls_copy_label, 2393 .mpo_copy_vnode_label = mac_mls_copy_label, 2394 .mpo_externalize_cred_label = mac_mls_externalize_label, 2395 .mpo_externalize_ifnet_label = mac_mls_externalize_label, 2396 .mpo_externalize_pipe_label = mac_mls_externalize_label, 2397 .mpo_externalize_socket_label = mac_mls_externalize_label, 2398 .mpo_externalize_socket_peer_label = mac_mls_externalize_label, 2399 .mpo_externalize_vnode_label = mac_mls_externalize_label, 2400 .mpo_internalize_cred_label = mac_mls_internalize_label, 2401 .mpo_internalize_ifnet_label = mac_mls_internalize_label, 2402 .mpo_internalize_pipe_label = mac_mls_internalize_label, 2403 .mpo_internalize_socket_label = mac_mls_internalize_label, 2404 .mpo_internalize_vnode_label = mac_mls_internalize_label, 2405 .mpo_create_devfs_device = mac_mls_create_devfs_device, 2406 .mpo_create_devfs_directory = mac_mls_create_devfs_directory, 2407 .mpo_create_devfs_symlink = mac_mls_create_devfs_symlink, 2408 .mpo_create_devfs_vnode = mac_mls_create_devfs_vnode, 2409 .mpo_create_mount = mac_mls_create_mount, 2410 .mpo_create_root_mount = mac_mls_create_root_mount, 2411 .mpo_relabel_vnode = mac_mls_relabel_vnode, 2412 .mpo_update_devfsdirent = mac_mls_update_devfsdirent, 2413 .mpo_associate_vnode_devfs = mac_mls_associate_vnode_devfs, 2414 .mpo_associate_vnode_extattr = mac_mls_associate_vnode_extattr, 2415 .mpo_associate_vnode_singlelabel = mac_mls_associate_vnode_singlelabel, 2416 .mpo_create_vnode_extattr = mac_mls_create_vnode_extattr, 2417 .mpo_setlabel_vnode_extattr = mac_mls_setlabel_vnode_extattr, 2418 .mpo_create_mbuf_from_socket = mac_mls_create_mbuf_from_socket, 2419 .mpo_create_pipe = mac_mls_create_pipe, 2420 .mpo_create_socket = mac_mls_create_socket, 2421 .mpo_create_socket_from_socket = mac_mls_create_socket_from_socket, 2422 .mpo_relabel_pipe = mac_mls_relabel_pipe, 2423 .mpo_relabel_socket = mac_mls_relabel_socket, 2424 .mpo_set_socket_peer_from_mbuf = mac_mls_set_socket_peer_from_mbuf, 2425 .mpo_set_socket_peer_from_socket = mac_mls_set_socket_peer_from_socket, 2426 .mpo_create_bpfdesc = mac_mls_create_bpfdesc, 2427 .mpo_create_datagram_from_ipq = mac_mls_create_datagram_from_ipq, 2428 .mpo_create_fragment = mac_mls_create_fragment, 2429 .mpo_create_ifnet = mac_mls_create_ifnet, 2430 .mpo_create_ipq = mac_mls_create_ipq, 2431 .mpo_create_mbuf_from_mbuf = mac_mls_create_mbuf_from_mbuf, 2432 .mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer, 2433 .mpo_create_mbuf_from_bpfdesc = mac_mls_create_mbuf_from_bpfdesc, 2434 .mpo_create_mbuf_from_ifnet = mac_mls_create_mbuf_from_ifnet, 2435 .mpo_create_mbuf_multicast_encap = mac_mls_create_mbuf_multicast_encap, 2436 .mpo_create_mbuf_netlayer = mac_mls_create_mbuf_netlayer, 2437 .mpo_fragment_match = mac_mls_fragment_match, 2438 .mpo_relabel_ifnet = mac_mls_relabel_ifnet, 2439 .mpo_update_ipq = mac_mls_update_ipq, 2440 .mpo_create_cred = mac_mls_create_cred, 2441 .mpo_create_proc0 = mac_mls_create_proc0, 2442 .mpo_create_proc1 = mac_mls_create_proc1, 2443 .mpo_relabel_cred = mac_mls_relabel_cred, 2444 .mpo_check_bpfdesc_receive = mac_mls_check_bpfdesc_receive, 2445 .mpo_check_cred_relabel = mac_mls_check_cred_relabel, 2446 .mpo_check_cred_visible = mac_mls_check_cred_visible, 2447 .mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel, 2448 .mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit, 2449 .mpo_check_mount_stat = mac_mls_check_mount_stat, 2450 .mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl, 2451 .mpo_check_pipe_poll = mac_mls_check_pipe_poll, 2452 .mpo_check_pipe_read = mac_mls_check_pipe_read, 2453 .mpo_check_pipe_relabel = mac_mls_check_pipe_relabel, 2454 .mpo_check_pipe_stat = mac_mls_check_pipe_stat, 2455 .mpo_check_pipe_write = mac_mls_check_pipe_write, 2456 .mpo_check_proc_debug = mac_mls_check_proc_debug, 2457 .mpo_check_proc_sched = mac_mls_check_proc_sched, 2458 .mpo_check_proc_signal = mac_mls_check_proc_signal, 2459 .mpo_check_socket_deliver = mac_mls_check_socket_deliver, 2460 .mpo_check_socket_relabel = mac_mls_check_socket_relabel, 2461 .mpo_check_socket_visible = mac_mls_check_socket_visible, 2462 .mpo_check_vnode_access = mac_mls_check_vnode_open, 2463 .mpo_check_vnode_chdir = mac_mls_check_vnode_chdir, 2464 .mpo_check_vnode_chroot = mac_mls_check_vnode_chroot, 2465 .mpo_check_vnode_create = mac_mls_check_vnode_create, 2466 .mpo_check_vnode_delete = mac_mls_check_vnode_delete, 2467 .mpo_check_vnode_deleteacl = mac_mls_check_vnode_deleteacl, 2468 .mpo_check_vnode_exec = mac_mls_check_vnode_exec, 2469 .mpo_check_vnode_getacl = mac_mls_check_vnode_getacl, 2470 .mpo_check_vnode_getextattr = mac_mls_check_vnode_getextattr, 2471 .mpo_check_vnode_link = mac_mls_check_vnode_link, 2472 .mpo_check_vnode_lookup = mac_mls_check_vnode_lookup, 2473 .mpo_check_vnode_mmap = mac_mls_check_vnode_mmap, 2474 .mpo_check_vnode_mprotect = mac_mls_check_vnode_mmap, 2475 .mpo_check_vnode_open = mac_mls_check_vnode_open, 2476 .mpo_check_vnode_poll = mac_mls_check_vnode_poll, 2477 .mpo_check_vnode_read = mac_mls_check_vnode_read, 2478 .mpo_check_vnode_readdir = mac_mls_check_vnode_readdir, 2479 .mpo_check_vnode_readlink = mac_mls_check_vnode_readlink, 2480 .mpo_check_vnode_relabel = mac_mls_check_vnode_relabel, 2481 .mpo_check_vnode_rename_from = mac_mls_check_vnode_rename_from, 2482 .mpo_check_vnode_rename_to = mac_mls_check_vnode_rename_to, 2483 .mpo_check_vnode_revoke = mac_mls_check_vnode_revoke, 2484 .mpo_check_vnode_setacl = mac_mls_check_vnode_setacl, 2485 .mpo_check_vnode_setextattr = mac_mls_check_vnode_setextattr, 2486 .mpo_check_vnode_setflags = mac_mls_check_vnode_setflags, 2487 .mpo_check_vnode_setmode = mac_mls_check_vnode_setmode, 2488 .mpo_check_vnode_setowner = mac_mls_check_vnode_setowner, 2489 .mpo_check_vnode_setutimes = mac_mls_check_vnode_setutimes, 2490 .mpo_check_vnode_stat = mac_mls_check_vnode_stat, 2491 .mpo_check_vnode_write = mac_mls_check_vnode_write, 2492}; 2493 2494MAC_POLICY_SET(&mac_mls_ops, trustedbsd_mac_mls, "TrustedBSD MAC/MLS", 2495 MPC_LOADTIME_FLAG_NOTLATE, &mac_mls_slot);
|