38 */ 39 40/* 41 * Developed by the TrustedBSD Project. 42 * Biba fixed label mandatory integrity policy. 43 */ 44 45#include <sys/types.h> 46#include <sys/param.h> 47#include <sys/acl.h> 48#include <sys/conf.h> 49#include <sys/extattr.h> 50#include <sys/kernel.h> 51#include <sys/mac.h> 52#include <sys/malloc.h> 53#include <sys/mount.h> 54#include <sys/proc.h> 55#include <sys/systm.h> 56#include <sys/sysproto.h> 57#include <sys/sysent.h> 58#include <sys/systm.h> 59#include <sys/vnode.h> 60#include <sys/file.h> 61#include <sys/socket.h> 62#include <sys/socketvar.h> 63#include <sys/pipe.h> 64#include <sys/sysctl.h> 65 66#include <fs/devfs/devfs.h> 67 68#include <net/bpfdesc.h> 69#include <net/if.h> 70#include <net/if_types.h> 71#include <net/if_var.h> 72 73#include <netinet/in.h> 74#include <netinet/ip_var.h> 75 76#include <vm/vm.h> 77 78#include <sys/mac_policy.h> 79 80#include <security/mac_biba/mac_biba.h> 81 82SYSCTL_DECL(_security_mac); 83 84SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 85 "TrustedBSD mac_biba policy controls"); 86 87static int mac_biba_label_size = sizeof(struct mac_biba); 88SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 89 &mac_biba_label_size, 0, "Size of struct mac_biba"); 90 91static int mac_biba_enabled = 0; 92SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 93 &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 94TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 95 96static int destroyed_not_inited; 97SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 98 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 99 100static int trust_all_interfaces = 0; 101SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 102 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 103TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 104 105static char trusted_interfaces[128]; 106SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 107 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 108TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 109 sizeof(trusted_interfaces)); 110 111static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 112SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 113 &max_compartments, 0, "Maximum supported compartments"); 114 115static int ptys_equal = 0; 116SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 117 &ptys_equal, 0, "Label pty devices as biba/equal on create"); 118TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 119 120static int revocation_enabled = 0; 121SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 122 &revocation_enabled, 0, "Revoke access to objects on relabel"); 123TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 124 125static int mac_biba_slot; 126#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 127 128MALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels"); 129 130static __inline int 131biba_bit_set_empty(u_char *set) { 132 int i; 133 134 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 135 if (set[i] != 0) 136 return (0); 137 return (1); 138} 139 140static struct mac_biba * 141biba_alloc(int flag) 142{ 143 struct mac_biba *mac_biba; 144 145 mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag); 146 147 return (mac_biba); 148} 149 150static void 151biba_free(struct mac_biba *mac_biba) 152{ 153 154 if (mac_biba != NULL) 155 free(mac_biba, M_MACBIBA); 156 else 157 atomic_add_int(&destroyed_not_inited, 1); 158} 159 160static int 161biba_atmostflags(struct mac_biba *mac_biba, int flags) 162{ 163 164 if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 165 return (EINVAL); 166 return (0); 167} 168 169static int 170mac_biba_dominate_element(struct mac_biba_element *a, 171 struct mac_biba_element *b) 172{ 173 int bit; 174 175 switch (a->mbe_type) { 176 case MAC_BIBA_TYPE_EQUAL: 177 case MAC_BIBA_TYPE_HIGH: 178 return (1); 179 180 case MAC_BIBA_TYPE_LOW: 181 switch (b->mbe_type) { 182 case MAC_BIBA_TYPE_GRADE: 183 case MAC_BIBA_TYPE_HIGH: 184 return (0); 185 186 case MAC_BIBA_TYPE_EQUAL: 187 case MAC_BIBA_TYPE_LOW: 188 return (1); 189 190 default: 191 panic("mac_biba_dominate_element: b->mbe_type invalid"); 192 } 193 194 case MAC_BIBA_TYPE_GRADE: 195 switch (b->mbe_type) { 196 case MAC_BIBA_TYPE_EQUAL: 197 case MAC_BIBA_TYPE_LOW: 198 return (1); 199 200 case MAC_BIBA_TYPE_HIGH: 201 return (0); 202 203 case MAC_BIBA_TYPE_GRADE: 204 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 205 if (!MAC_BIBA_BIT_TEST(bit, 206 a->mbe_compartments) && 207 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 208 return (0); 209 return (a->mbe_grade >= b->mbe_grade); 210 211 default: 212 panic("mac_biba_dominate_element: b->mbe_type invalid"); 213 } 214 215 default: 216 panic("mac_biba_dominate_element: a->mbe_type invalid"); 217 } 218 219 return (0); 220} 221 222static int 223mac_biba_subject_dominate_high(struct mac_biba *mac_biba) 224{ 225 struct mac_biba_element *element; 226 227 KASSERT((mac_biba->mb_single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 228 ("mac_biba_single_in_range: mac_biba not single")); 229 element = &mac_biba->mb_single; 230 231 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 232 element->mbe_type == MAC_BIBA_TYPE_HIGH); 233} 234 235static int 236mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 237{ 238 239 return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 240 &rangea->mb_rangehigh) && 241 mac_biba_dominate_element(&rangea->mb_rangelow, 242 &rangeb->mb_rangelow)); 243} 244 245static int 246mac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range) 247{ 248 249 KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 250 ("mac_biba_single_in_range: a not single")); 251 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 252 ("mac_biba_single_in_range: b not range")); 253 254 return (mac_biba_dominate_element(&range->mb_rangehigh, 255 &single->mb_single) && 256 mac_biba_dominate_element(&single->mb_single, 257 &range->mb_rangelow)); 258 259 return (1); 260} 261 262static int 263mac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b) 264{ 265 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 266 ("mac_biba_dominate_single: a not single")); 267 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 268 ("mac_biba_dominate_single: b not single")); 269 270 return (mac_biba_dominate_element(&a->mb_single, &b->mb_single)); 271} 272 273static int 274mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 275{ 276 277 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 278 b->mbe_type == MAC_BIBA_TYPE_EQUAL) 279 return (1); 280 281 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 282} 283 284static int 285mac_biba_equal_single(struct mac_biba *a, struct mac_biba *b) 286{ 287 288 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 289 ("mac_biba_equal_single: a not single")); 290 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 291 ("mac_biba_equal_single: b not single")); 292 293 return (mac_biba_equal_element(&a->mb_single, &b->mb_single)); 294} 295 296static int 297mac_biba_contains_equal(struct mac_biba *mac_biba) 298{ 299 300 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) 301 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 302 return (1); 303 304 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 305 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 306 return (1); 307 if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 308 return (1); 309 } 310 311 return (0); 312} 313 314static int 315mac_biba_subject_equal_ok(struct mac_biba *mac_biba) 316{ 317 318 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 319 MAC_BIBA_FLAGS_BOTH, 320 ("mac_biba_subject_equal_ok: subject doesn't have both labels")); 321 322 /* If the single is EQUAL, it's ok. */ 323 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 324 return (0); 325 326 /* If either range endpoint is EQUAL, it's ok. */ 327 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 328 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 329 return (0); 330 331 /* If the range is low-high, it's ok. */ 332 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 333 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 334 return (0); 335 336 /* It's not ok. */ 337 return (EPERM); 338} 339 340mac_biba_high_single(struct mac_biba *mac_biba) 341{ 342 343 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 344 ("mac_biba_equal_single: mac_biba not single")); 345 346 return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH); 347} 348 349static int 350mac_biba_valid(struct mac_biba *mac_biba) 351{ 352 353 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 354 switch (mac_biba->mb_single.mbe_type) { 355 case MAC_BIBA_TYPE_GRADE: 356 break; 357 358 case MAC_BIBA_TYPE_EQUAL: 359 case MAC_BIBA_TYPE_HIGH: 360 case MAC_BIBA_TYPE_LOW: 361 if (mac_biba->mb_single.mbe_grade != 0 || 362 !MAC_BIBA_BIT_SET_EMPTY( 363 mac_biba->mb_single.mbe_compartments)) 364 return (EINVAL); 365 break; 366 367 default: 368 return (EINVAL); 369 } 370 } else { 371 if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 372 return (EINVAL); 373 } 374 375 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 376 switch (mac_biba->mb_rangelow.mbe_type) { 377 case MAC_BIBA_TYPE_GRADE: 378 break; 379 380 case MAC_BIBA_TYPE_EQUAL: 381 case MAC_BIBA_TYPE_HIGH: 382 case MAC_BIBA_TYPE_LOW: 383 if (mac_biba->mb_rangelow.mbe_grade != 0 || 384 !MAC_BIBA_BIT_SET_EMPTY( 385 mac_biba->mb_rangelow.mbe_compartments)) 386 return (EINVAL); 387 break; 388 389 default: 390 return (EINVAL); 391 } 392 393 switch (mac_biba->mb_rangehigh.mbe_type) { 394 case MAC_BIBA_TYPE_GRADE: 395 break; 396 397 case MAC_BIBA_TYPE_EQUAL: 398 case MAC_BIBA_TYPE_HIGH: 399 case MAC_BIBA_TYPE_LOW: 400 if (mac_biba->mb_rangehigh.mbe_grade != 0 || 401 !MAC_BIBA_BIT_SET_EMPTY( 402 mac_biba->mb_rangehigh.mbe_compartments)) 403 return (EINVAL); 404 break; 405 406 default: 407 return (EINVAL); 408 } 409 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 410 &mac_biba->mb_rangelow)) 411 return (EINVAL); 412 } else { 413 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 414 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 415 return (EINVAL); 416 } 417 418 return (0); 419} 420 421static void 422mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 423 u_short gradelow, u_char *compartmentslow, u_short typehigh, 424 u_short gradehigh, u_char *compartmentshigh) 425{ 426 427 mac_biba->mb_rangelow.mbe_type = typelow; 428 mac_biba->mb_rangelow.mbe_grade = gradelow; 429 if (compartmentslow != NULL) 430 memcpy(mac_biba->mb_rangelow.mbe_compartments, 431 compartmentslow, 432 sizeof(mac_biba->mb_rangelow.mbe_compartments)); 433 mac_biba->mb_rangehigh.mbe_type = typehigh; 434 mac_biba->mb_rangehigh.mbe_grade = gradehigh; 435 if (compartmentshigh != NULL) 436 memcpy(mac_biba->mb_rangehigh.mbe_compartments, 437 compartmentshigh, 438 sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 439 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 440} 441 442static void 443mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 444 u_char *compartments) 445{ 446 447 mac_biba->mb_single.mbe_type = type; 448 mac_biba->mb_single.mbe_grade = grade; 449 if (compartments != NULL) 450 memcpy(mac_biba->mb_single.mbe_compartments, compartments, 451 sizeof(mac_biba->mb_single.mbe_compartments)); 452 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 453} 454 455static void 456mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 457{ 458 459 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 460 ("mac_biba_copy_range: labelfrom not range")); 461 462 labelto->mb_rangelow = labelfrom->mb_rangelow; 463 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 464 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 465} 466 467static void 468mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 469{ 470 471 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 472 ("mac_biba_copy_single: labelfrom not single")); 473 474 labelto->mb_single = labelfrom->mb_single; 475 labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 476} 477 478static void 479mac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 480{ 481 482 if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 483 mac_biba_copy_single(source, dest); 484 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 485 mac_biba_copy_range(source, dest); 486} 487 488/* 489 * Policy module operations. 490 */ 491static void 492mac_biba_destroy(struct mac_policy_conf *conf) 493{ 494 495} 496 497static void 498mac_biba_init(struct mac_policy_conf *conf) 499{ 500 501} 502 503/* 504 * Label operations. 505 */ 506static void 507mac_biba_init_label(struct label *label) 508{ 509 510 SLOT(label) = biba_alloc(M_WAITOK); 511} 512 513static int 514mac_biba_init_label_waitcheck(struct label *label, int flag) 515{ 516 517 SLOT(label) = biba_alloc(flag); 518 if (SLOT(label) == NULL) 519 return (ENOMEM); 520 521 return (0); 522} 523 524static void 525mac_biba_destroy_label(struct label *label) 526{ 527 528 biba_free(SLOT(label)); 529 SLOT(label) = NULL; 530} 531 532/* 533 * mac_biba_element_to_string() is basically an snprintf wrapper with 534 * the same properties as snprintf(). It returns the length it would 535 * have added to the string in the event the string is too short. 536 */ 537static size_t 538mac_biba_element_to_string(char *string, size_t size, 539 struct mac_biba_element *element) 540{ 541 int pos, bit = 1; 542 543 switch (element->mbe_type) { 544 case MAC_BIBA_TYPE_HIGH: 545 return (snprintf(string, size, "high")); 546 547 case MAC_BIBA_TYPE_LOW: 548 return (snprintf(string, size, "low")); 549 550 case MAC_BIBA_TYPE_EQUAL: 551 return (snprintf(string, size, "equal")); 552 553 case MAC_BIBA_TYPE_GRADE: 554 pos = snprintf(string, size, "%d:", element->mbe_grade); 555 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) { 556 if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments)) 557 pos += snprintf(string + pos, size - pos, 558 "%d+", bit); 559 } 560 if (string[pos - 1] == '+' || string[pos - 1] == ':') 561 string[--pos] = NULL; 562 return (pos); 563 564 default: 565 panic("mac_biba_element_to_string: invalid type (%d)", 566 element->mbe_type); 567 } 568} 569 570static int 571mac_biba_to_string(char *string, size_t size, size_t *caller_len, 572 struct mac_biba *mac_biba) 573{ 574 size_t left, len; 575 char *curptr; 576 577 bzero(string, size); 578 curptr = string; 579 left = size; 580 581 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 582 len = mac_biba_element_to_string(curptr, left, 583 &mac_biba->mb_single); 584 if (len >= left) 585 return (EINVAL); 586 left -= len; 587 curptr += len; 588 } 589 590 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 591 len = snprintf(curptr, left, "("); 592 if (len >= left) 593 return (EINVAL); 594 left -= len; 595 curptr += len; 596 597 len = mac_biba_element_to_string(curptr, left, 598 &mac_biba->mb_rangelow); 599 if (len >= left) 600 return (EINVAL); 601 left -= len; 602 curptr += len; 603 604 len = snprintf(curptr, left, "-"); 605 if (len >= left) 606 return (EINVAL); 607 left -= len; 608 curptr += len; 609 610 len = mac_biba_element_to_string(curptr, left, 611 &mac_biba->mb_rangehigh); 612 if (len >= left) 613 return (EINVAL); 614 left -= len; 615 curptr += len; 616 617 len = snprintf(curptr, left, ")"); 618 if (len >= left) 619 return (EINVAL); 620 left -= len; 621 curptr += len; 622 } 623 624 *caller_len = strlen(string); 625 return (0); 626} 627 628static int 629mac_biba_externalize_label(struct label *label, char *element_name, 630 char *element_data, size_t size, size_t *len, int *claimed) 631{ 632 struct mac_biba *mac_biba; 633 int error; 634 635 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 636 return (0); 637 638 (*claimed)++; 639 640 mac_biba = SLOT(label); 641 error = mac_biba_to_string(element_data, size, len, mac_biba); 642 if (error) 643 return (error); 644 645 *len = strlen(element_data); 646 return (0); 647} 648 649static int 650mac_biba_parse_element(struct mac_biba_element *element, char *string) 651{ 652 653 if (strcmp(string, "high") == 0 || 654 strcmp(string, "hi") == 0) { 655 element->mbe_type = MAC_BIBA_TYPE_HIGH; 656 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 657 } else if (strcmp(string, "low") == 0 || 658 strcmp(string, "lo") == 0) { 659 element->mbe_type = MAC_BIBA_TYPE_LOW; 660 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 661 } else if (strcmp(string, "equal") == 0 || 662 strcmp(string, "eq") == 0) { 663 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 664 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 665 } else { 666 char *p0, *p1; 667 int d; 668 669 p0 = string; 670 d = strtol(p0, &p1, 10); 671 672 if (d < 0 || d > 65535) 673 return (EINVAL); 674 element->mbe_type = MAC_BIBA_TYPE_GRADE; 675 element->mbe_grade = d; 676 677 if (*p1 != ':') { 678 if (p1 == p0 || *p1 != '\0') 679 return (EINVAL); 680 else 681 return (0); 682 } 683 else 684 if (*(p1 + 1) == '\0') 685 return (0); 686 687 while ((p0 = ++p1)) { 688 d = strtol(p0, &p1, 10); 689 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS) 690 return (EINVAL); 691 692 MAC_BIBA_BIT_SET(d, element->mbe_compartments); 693 694 if (*p1 == '\0') 695 break; 696 if (p1 == p0 || *p1 != '+') 697 return (EINVAL); 698 } 699 } 700 701 return (0); 702} 703 704/* 705 * Note: destructively consumes the string, make a local copy before 706 * calling if that's a problem. 707 */ 708static int 709mac_biba_parse(struct mac_biba *mac_biba, char *string) 710{ 711 char *range, *rangeend, *rangehigh, *rangelow, *single; 712 int error; 713 714 /* Do we have a range? */ 715 single = string; 716 range = index(string, '('); 717 if (range == single) 718 single = NULL; 719 rangelow = rangehigh = NULL; 720 if (range != NULL) { 721 /* Nul terminate the end of the single string. */ 722 *range = '\0'; 723 range++; 724 rangelow = range; 725 rangehigh = index(rangelow, '-'); 726 if (rangehigh == NULL) 727 return (EINVAL); 728 rangehigh++; 729 if (*rangelow == '\0' || *rangehigh == '\0') 730 return (EINVAL); 731 rangeend = index(rangehigh, ')'); 732 if (rangeend == NULL) 733 return (EINVAL); 734 if (*(rangeend + 1) != '\0') 735 return (EINVAL); 736 /* Nul terminate the ends of the ranges. */ 737 *(rangehigh - 1) = '\0'; 738 *rangeend = '\0'; 739 } 740 KASSERT((rangelow != NULL && rangehigh != NULL) || 741 (rangelow == NULL && rangehigh == NULL), 742 ("mac_biba_internalize_label: range mismatch")); 743 744 bzero(mac_biba, sizeof(*mac_biba)); 745 if (single != NULL) { 746 error = mac_biba_parse_element(&mac_biba->mb_single, single); 747 if (error) 748 return (error); 749 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 750 } 751 752 if (rangelow != NULL) { 753 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 754 rangelow); 755 if (error) 756 return (error); 757 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 758 rangehigh); 759 if (error) 760 return (error); 761 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 762 } 763 764 error = mac_biba_valid(mac_biba); 765 if (error) 766 return (error); 767 768 return (0); 769} 770 771static int 772mac_biba_internalize_label(struct label *label, char *element_name, 773 char *element_data, int *claimed) 774{ 775 struct mac_biba *mac_biba, mac_biba_temp; 776 int error; 777 778 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 779 return (0); 780 781 (*claimed)++; 782 783 error = mac_biba_parse(&mac_biba_temp, element_data); 784 if (error) 785 return (error); 786 787 mac_biba = SLOT(label); 788 *mac_biba = mac_biba_temp; 789 790 return (0); 791} 792 793static void 794mac_biba_copy_label(struct label *src, struct label *dest) 795{ 796 797 *SLOT(dest) = *SLOT(src); 798} 799 800/* 801 * Labeling event operations: file system objects, and things that look 802 * a lot like file system objects. 803 */ 804static void 805mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 806 struct label *label) 807{ 808 struct mac_biba *mac_biba; 809 int biba_type; 810 811 mac_biba = SLOT(label); 812 if (strcmp(dev->si_name, "null") == 0 || 813 strcmp(dev->si_name, "zero") == 0 || 814 strcmp(dev->si_name, "random") == 0 || 815 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 816 biba_type = MAC_BIBA_TYPE_EQUAL; 817 else if (ptys_equal && 818 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 819 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 820 biba_type = MAC_BIBA_TYPE_EQUAL; 821 else 822 biba_type = MAC_BIBA_TYPE_HIGH; 823 mac_biba_set_single(mac_biba, biba_type, 0, NULL); 824} 825 826static void 827mac_biba_create_devfs_directory(char *dirname, int dirnamelen, 828 struct devfs_dirent *devfs_dirent, struct label *label) 829{ 830 struct mac_biba *mac_biba; 831 832 mac_biba = SLOT(label); 833 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 834} 835 836static void 837mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 838 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) 839{ 840 struct mac_biba *source, *dest; 841 842 source = SLOT(&cred->cr_label); 843 dest = SLOT(delabel); 844 845 mac_biba_copy_single(source, dest); 846} 847 848static void 849mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 850 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 851{ 852 struct mac_biba *source, *dest; 853 854 source = SLOT(direntlabel); 855 dest = SLOT(vnodelabel); 856 mac_biba_copy_single(source, dest); 857} 858 859static void 860mac_biba_create_mount(struct ucred *cred, struct mount *mp, 861 struct label *mntlabel, struct label *fslabel) 862{ 863 struct mac_biba *source, *dest; 864 865 source = SLOT(&cred->cr_label); 866 dest = SLOT(mntlabel); 867 mac_biba_copy_single(source, dest); 868 dest = SLOT(fslabel); 869 mac_biba_copy_single(source, dest); 870} 871 872static void 873mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 874 struct label *mntlabel, struct label *fslabel) 875{ 876 struct mac_biba *mac_biba; 877 878 /* Always mount root as high integrity. */ 879 mac_biba = SLOT(fslabel); 880 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 881 mac_biba = SLOT(mntlabel); 882 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 883} 884 885static void 886mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 887 struct label *vnodelabel, struct label *label) 888{ 889 struct mac_biba *source, *dest; 890 891 source = SLOT(label); 892 dest = SLOT(vnodelabel); 893 894 mac_biba_copy(source, dest); 895} 896 897static void 898mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent, 899 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 900{ 901 struct mac_biba *source, *dest; 902 903 source = SLOT(vnodelabel); 904 dest = SLOT(direntlabel); 905 906 mac_biba_copy(source, dest); 907} 908 909static void 910mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 911 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 912 struct label *vlabel) 913{ 914 struct mac_biba *source, *dest; 915 916 source = SLOT(delabel); 917 dest = SLOT(vlabel); 918 919 mac_biba_copy_single(source, dest); 920} 921 922static int 923mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 924 struct vnode *vp, struct label *vlabel) 925{ 926 struct mac_biba temp, *source, *dest; 927 size_t buflen; 928 int error; 929 930 source = SLOT(fslabel); 931 dest = SLOT(vlabel); 932 933 buflen = sizeof(temp); 934 bzero(&temp, buflen); 935 936 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 937 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 938 if (error == ENOATTR || error == EOPNOTSUPP) { 939 /* Fall back to the fslabel. */ 940 mac_biba_copy_single(source, dest); 941 return (0); 942 } else if (error) 943 return (error); 944 945 if (buflen != sizeof(temp)) { 946 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 947 buflen); 948 return (EPERM); 949 } 950 if (mac_biba_valid(&temp) != 0) { 951 printf("mac_biba_associate_vnode_extattr: invalid\n"); 952 return (EPERM); 953 } 954 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 955 printf("mac_biba_associate_vnode_extattr: not single\n"); 956 return (EPERM); 957 } 958 959 mac_biba_copy_single(&temp, dest); 960 return (0); 961} 962 963static void 964mac_biba_associate_vnode_singlelabel(struct mount *mp, 965 struct label *fslabel, struct vnode *vp, struct label *vlabel) 966{ 967 struct mac_biba *source, *dest; 968 969 source = SLOT(fslabel); 970 dest = SLOT(vlabel); 971 972 mac_biba_copy_single(source, dest); 973} 974 975static int 976mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 977 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 978 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 979{ 980 struct mac_biba *source, *dest, temp; 981 size_t buflen; 982 int error; 983 984 buflen = sizeof(temp); 985 bzero(&temp, buflen); 986 987 source = SLOT(&cred->cr_label); 988 dest = SLOT(vlabel); 989 mac_biba_copy_single(source, &temp); 990 991 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 992 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 993 if (error == 0) 994 mac_biba_copy_single(source, dest); 995 return (error); 996} 997 998static int 999mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1000 struct label *vlabel, struct label *intlabel) 1001{ 1002 struct mac_biba *source, temp; 1003 size_t buflen; 1004 int error; 1005 1006 buflen = sizeof(temp); 1007 bzero(&temp, buflen); 1008 1009 source = SLOT(intlabel); 1010 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 1011 return (0); 1012 1013 mac_biba_copy_single(source, &temp); 1014 1015 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 1016 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 1017 return (error); 1018} 1019 1020/* 1021 * Labeling event operations: IPC object. 1022 */ 1023static void 1024mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1025 struct mbuf *m, struct label *mbuflabel) 1026{ 1027 struct mac_biba *source, *dest; 1028 1029 source = SLOT(socketlabel); 1030 dest = SLOT(mbuflabel); 1031 1032 mac_biba_copy_single(source, dest); 1033} 1034 1035static void 1036mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1037 struct label *socketlabel) 1038{ 1039 struct mac_biba *source, *dest; 1040 1041 source = SLOT(&cred->cr_label); 1042 dest = SLOT(socketlabel); 1043 1044 mac_biba_copy_single(source, dest); 1045} 1046 1047static void 1048mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1049 struct label *pipelabel) 1050{ 1051 struct mac_biba *source, *dest; 1052 1053 source = SLOT(&cred->cr_label); 1054 dest = SLOT(pipelabel); 1055 1056 mac_biba_copy_single(source, dest); 1057} 1058 1059static void 1060mac_biba_create_socket_from_socket(struct socket *oldsocket, 1061 struct label *oldsocketlabel, struct socket *newsocket, 1062 struct label *newsocketlabel) 1063{ 1064 struct mac_biba *source, *dest; 1065 1066 source = SLOT(oldsocketlabel); 1067 dest = SLOT(newsocketlabel); 1068 1069 mac_biba_copy_single(source, dest); 1070} 1071 1072static void 1073mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1074 struct label *socketlabel, struct label *newlabel) 1075{ 1076 struct mac_biba *source, *dest; 1077 1078 source = SLOT(newlabel); 1079 dest = SLOT(socketlabel); 1080 1081 mac_biba_copy(source, dest); 1082} 1083 1084static void 1085mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1086 struct label *pipelabel, struct label *newlabel) 1087{ 1088 struct mac_biba *source, *dest; 1089 1090 source = SLOT(newlabel); 1091 dest = SLOT(pipelabel); 1092 1093 mac_biba_copy(source, dest); 1094} 1095 1096static void 1097mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1098 struct socket *socket, struct label *socketpeerlabel) 1099{ 1100 struct mac_biba *source, *dest; 1101 1102 source = SLOT(mbuflabel); 1103 dest = SLOT(socketpeerlabel); 1104 1105 mac_biba_copy_single(source, dest); 1106} 1107 1108/* 1109 * Labeling event operations: network objects. 1110 */ 1111static void 1112mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1113 struct label *oldsocketlabel, struct socket *newsocket, 1114 struct label *newsocketpeerlabel) 1115{ 1116 struct mac_biba *source, *dest; 1117 1118 source = SLOT(oldsocketlabel); 1119 dest = SLOT(newsocketpeerlabel); 1120 1121 mac_biba_copy_single(source, dest); 1122} 1123 1124static void 1125mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1126 struct label *bpflabel) 1127{ 1128 struct mac_biba *source, *dest; 1129 1130 source = SLOT(&cred->cr_label); 1131 dest = SLOT(bpflabel); 1132 1133 mac_biba_copy_single(source, dest); 1134} 1135 1136static void 1137mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1138{ 1139 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1140 char tiflist[sizeof(trusted_interfaces)]; 1141 struct mac_biba *dest; 1142 int len, grade; 1143 1144 dest = SLOT(ifnetlabel); 1145 1146 if (ifnet->if_type == IFT_LOOP) { 1147 grade = MAC_BIBA_TYPE_EQUAL; 1148 goto set; 1149 } 1150 1151 if (trust_all_interfaces) { 1152 grade = MAC_BIBA_TYPE_HIGH; 1153 goto set; 1154 } 1155 1156 grade = MAC_BIBA_TYPE_LOW; 1157 1158 if (trusted_interfaces[0] == '\0' || 1159 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1160 goto set; 1161
| 38 */ 39 40/* 41 * Developed by the TrustedBSD Project. 42 * Biba fixed label mandatory integrity policy. 43 */ 44 45#include <sys/types.h> 46#include <sys/param.h> 47#include <sys/acl.h> 48#include <sys/conf.h> 49#include <sys/extattr.h> 50#include <sys/kernel.h> 51#include <sys/mac.h> 52#include <sys/malloc.h> 53#include <sys/mount.h> 54#include <sys/proc.h> 55#include <sys/systm.h> 56#include <sys/sysproto.h> 57#include <sys/sysent.h> 58#include <sys/systm.h> 59#include <sys/vnode.h> 60#include <sys/file.h> 61#include <sys/socket.h> 62#include <sys/socketvar.h> 63#include <sys/pipe.h> 64#include <sys/sysctl.h> 65 66#include <fs/devfs/devfs.h> 67 68#include <net/bpfdesc.h> 69#include <net/if.h> 70#include <net/if_types.h> 71#include <net/if_var.h> 72 73#include <netinet/in.h> 74#include <netinet/ip_var.h> 75 76#include <vm/vm.h> 77 78#include <sys/mac_policy.h> 79 80#include <security/mac_biba/mac_biba.h> 81 82SYSCTL_DECL(_security_mac); 83 84SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 85 "TrustedBSD mac_biba policy controls"); 86 87static int mac_biba_label_size = sizeof(struct mac_biba); 88SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 89 &mac_biba_label_size, 0, "Size of struct mac_biba"); 90 91static int mac_biba_enabled = 0; 92SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 93 &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 94TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 95 96static int destroyed_not_inited; 97SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 98 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 99 100static int trust_all_interfaces = 0; 101SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 102 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 103TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 104 105static char trusted_interfaces[128]; 106SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 107 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 108TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 109 sizeof(trusted_interfaces)); 110 111static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 112SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 113 &max_compartments, 0, "Maximum supported compartments"); 114 115static int ptys_equal = 0; 116SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 117 &ptys_equal, 0, "Label pty devices as biba/equal on create"); 118TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 119 120static int revocation_enabled = 0; 121SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 122 &revocation_enabled, 0, "Revoke access to objects on relabel"); 123TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 124 125static int mac_biba_slot; 126#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 127 128MALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels"); 129 130static __inline int 131biba_bit_set_empty(u_char *set) { 132 int i; 133 134 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 135 if (set[i] != 0) 136 return (0); 137 return (1); 138} 139 140static struct mac_biba * 141biba_alloc(int flag) 142{ 143 struct mac_biba *mac_biba; 144 145 mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag); 146 147 return (mac_biba); 148} 149 150static void 151biba_free(struct mac_biba *mac_biba) 152{ 153 154 if (mac_biba != NULL) 155 free(mac_biba, M_MACBIBA); 156 else 157 atomic_add_int(&destroyed_not_inited, 1); 158} 159 160static int 161biba_atmostflags(struct mac_biba *mac_biba, int flags) 162{ 163 164 if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 165 return (EINVAL); 166 return (0); 167} 168 169static int 170mac_biba_dominate_element(struct mac_biba_element *a, 171 struct mac_biba_element *b) 172{ 173 int bit; 174 175 switch (a->mbe_type) { 176 case MAC_BIBA_TYPE_EQUAL: 177 case MAC_BIBA_TYPE_HIGH: 178 return (1); 179 180 case MAC_BIBA_TYPE_LOW: 181 switch (b->mbe_type) { 182 case MAC_BIBA_TYPE_GRADE: 183 case MAC_BIBA_TYPE_HIGH: 184 return (0); 185 186 case MAC_BIBA_TYPE_EQUAL: 187 case MAC_BIBA_TYPE_LOW: 188 return (1); 189 190 default: 191 panic("mac_biba_dominate_element: b->mbe_type invalid"); 192 } 193 194 case MAC_BIBA_TYPE_GRADE: 195 switch (b->mbe_type) { 196 case MAC_BIBA_TYPE_EQUAL: 197 case MAC_BIBA_TYPE_LOW: 198 return (1); 199 200 case MAC_BIBA_TYPE_HIGH: 201 return (0); 202 203 case MAC_BIBA_TYPE_GRADE: 204 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 205 if (!MAC_BIBA_BIT_TEST(bit, 206 a->mbe_compartments) && 207 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 208 return (0); 209 return (a->mbe_grade >= b->mbe_grade); 210 211 default: 212 panic("mac_biba_dominate_element: b->mbe_type invalid"); 213 } 214 215 default: 216 panic("mac_biba_dominate_element: a->mbe_type invalid"); 217 } 218 219 return (0); 220} 221 222static int 223mac_biba_subject_dominate_high(struct mac_biba *mac_biba) 224{ 225 struct mac_biba_element *element; 226 227 KASSERT((mac_biba->mb_single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 228 ("mac_biba_single_in_range: mac_biba not single")); 229 element = &mac_biba->mb_single; 230 231 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 232 element->mbe_type == MAC_BIBA_TYPE_HIGH); 233} 234 235static int 236mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 237{ 238 239 return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 240 &rangea->mb_rangehigh) && 241 mac_biba_dominate_element(&rangea->mb_rangelow, 242 &rangeb->mb_rangelow)); 243} 244 245static int 246mac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range) 247{ 248 249 KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 250 ("mac_biba_single_in_range: a not single")); 251 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 252 ("mac_biba_single_in_range: b not range")); 253 254 return (mac_biba_dominate_element(&range->mb_rangehigh, 255 &single->mb_single) && 256 mac_biba_dominate_element(&single->mb_single, 257 &range->mb_rangelow)); 258 259 return (1); 260} 261 262static int 263mac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b) 264{ 265 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 266 ("mac_biba_dominate_single: a not single")); 267 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 268 ("mac_biba_dominate_single: b not single")); 269 270 return (mac_biba_dominate_element(&a->mb_single, &b->mb_single)); 271} 272 273static int 274mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 275{ 276 277 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 278 b->mbe_type == MAC_BIBA_TYPE_EQUAL) 279 return (1); 280 281 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 282} 283 284static int 285mac_biba_equal_single(struct mac_biba *a, struct mac_biba *b) 286{ 287 288 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 289 ("mac_biba_equal_single: a not single")); 290 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 291 ("mac_biba_equal_single: b not single")); 292 293 return (mac_biba_equal_element(&a->mb_single, &b->mb_single)); 294} 295 296static int 297mac_biba_contains_equal(struct mac_biba *mac_biba) 298{ 299 300 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) 301 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 302 return (1); 303 304 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 305 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 306 return (1); 307 if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 308 return (1); 309 } 310 311 return (0); 312} 313 314static int 315mac_biba_subject_equal_ok(struct mac_biba *mac_biba) 316{ 317 318 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 319 MAC_BIBA_FLAGS_BOTH, 320 ("mac_biba_subject_equal_ok: subject doesn't have both labels")); 321 322 /* If the single is EQUAL, it's ok. */ 323 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 324 return (0); 325 326 /* If either range endpoint is EQUAL, it's ok. */ 327 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 328 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 329 return (0); 330 331 /* If the range is low-high, it's ok. */ 332 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 333 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 334 return (0); 335 336 /* It's not ok. */ 337 return (EPERM); 338} 339 340mac_biba_high_single(struct mac_biba *mac_biba) 341{ 342 343 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 344 ("mac_biba_equal_single: mac_biba not single")); 345 346 return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH); 347} 348 349static int 350mac_biba_valid(struct mac_biba *mac_biba) 351{ 352 353 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 354 switch (mac_biba->mb_single.mbe_type) { 355 case MAC_BIBA_TYPE_GRADE: 356 break; 357 358 case MAC_BIBA_TYPE_EQUAL: 359 case MAC_BIBA_TYPE_HIGH: 360 case MAC_BIBA_TYPE_LOW: 361 if (mac_biba->mb_single.mbe_grade != 0 || 362 !MAC_BIBA_BIT_SET_EMPTY( 363 mac_biba->mb_single.mbe_compartments)) 364 return (EINVAL); 365 break; 366 367 default: 368 return (EINVAL); 369 } 370 } else { 371 if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 372 return (EINVAL); 373 } 374 375 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 376 switch (mac_biba->mb_rangelow.mbe_type) { 377 case MAC_BIBA_TYPE_GRADE: 378 break; 379 380 case MAC_BIBA_TYPE_EQUAL: 381 case MAC_BIBA_TYPE_HIGH: 382 case MAC_BIBA_TYPE_LOW: 383 if (mac_biba->mb_rangelow.mbe_grade != 0 || 384 !MAC_BIBA_BIT_SET_EMPTY( 385 mac_biba->mb_rangelow.mbe_compartments)) 386 return (EINVAL); 387 break; 388 389 default: 390 return (EINVAL); 391 } 392 393 switch (mac_biba->mb_rangehigh.mbe_type) { 394 case MAC_BIBA_TYPE_GRADE: 395 break; 396 397 case MAC_BIBA_TYPE_EQUAL: 398 case MAC_BIBA_TYPE_HIGH: 399 case MAC_BIBA_TYPE_LOW: 400 if (mac_biba->mb_rangehigh.mbe_grade != 0 || 401 !MAC_BIBA_BIT_SET_EMPTY( 402 mac_biba->mb_rangehigh.mbe_compartments)) 403 return (EINVAL); 404 break; 405 406 default: 407 return (EINVAL); 408 } 409 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 410 &mac_biba->mb_rangelow)) 411 return (EINVAL); 412 } else { 413 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 414 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 415 return (EINVAL); 416 } 417 418 return (0); 419} 420 421static void 422mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 423 u_short gradelow, u_char *compartmentslow, u_short typehigh, 424 u_short gradehigh, u_char *compartmentshigh) 425{ 426 427 mac_biba->mb_rangelow.mbe_type = typelow; 428 mac_biba->mb_rangelow.mbe_grade = gradelow; 429 if (compartmentslow != NULL) 430 memcpy(mac_biba->mb_rangelow.mbe_compartments, 431 compartmentslow, 432 sizeof(mac_biba->mb_rangelow.mbe_compartments)); 433 mac_biba->mb_rangehigh.mbe_type = typehigh; 434 mac_biba->mb_rangehigh.mbe_grade = gradehigh; 435 if (compartmentshigh != NULL) 436 memcpy(mac_biba->mb_rangehigh.mbe_compartments, 437 compartmentshigh, 438 sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 439 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 440} 441 442static void 443mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 444 u_char *compartments) 445{ 446 447 mac_biba->mb_single.mbe_type = type; 448 mac_biba->mb_single.mbe_grade = grade; 449 if (compartments != NULL) 450 memcpy(mac_biba->mb_single.mbe_compartments, compartments, 451 sizeof(mac_biba->mb_single.mbe_compartments)); 452 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 453} 454 455static void 456mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 457{ 458 459 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 460 ("mac_biba_copy_range: labelfrom not range")); 461 462 labelto->mb_rangelow = labelfrom->mb_rangelow; 463 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 464 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 465} 466 467static void 468mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 469{ 470 471 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 472 ("mac_biba_copy_single: labelfrom not single")); 473 474 labelto->mb_single = labelfrom->mb_single; 475 labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 476} 477 478static void 479mac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 480{ 481 482 if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 483 mac_biba_copy_single(source, dest); 484 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 485 mac_biba_copy_range(source, dest); 486} 487 488/* 489 * Policy module operations. 490 */ 491static void 492mac_biba_destroy(struct mac_policy_conf *conf) 493{ 494 495} 496 497static void 498mac_biba_init(struct mac_policy_conf *conf) 499{ 500 501} 502 503/* 504 * Label operations. 505 */ 506static void 507mac_biba_init_label(struct label *label) 508{ 509 510 SLOT(label) = biba_alloc(M_WAITOK); 511} 512 513static int 514mac_biba_init_label_waitcheck(struct label *label, int flag) 515{ 516 517 SLOT(label) = biba_alloc(flag); 518 if (SLOT(label) == NULL) 519 return (ENOMEM); 520 521 return (0); 522} 523 524static void 525mac_biba_destroy_label(struct label *label) 526{ 527 528 biba_free(SLOT(label)); 529 SLOT(label) = NULL; 530} 531 532/* 533 * mac_biba_element_to_string() is basically an snprintf wrapper with 534 * the same properties as snprintf(). It returns the length it would 535 * have added to the string in the event the string is too short. 536 */ 537static size_t 538mac_biba_element_to_string(char *string, size_t size, 539 struct mac_biba_element *element) 540{ 541 int pos, bit = 1; 542 543 switch (element->mbe_type) { 544 case MAC_BIBA_TYPE_HIGH: 545 return (snprintf(string, size, "high")); 546 547 case MAC_BIBA_TYPE_LOW: 548 return (snprintf(string, size, "low")); 549 550 case MAC_BIBA_TYPE_EQUAL: 551 return (snprintf(string, size, "equal")); 552 553 case MAC_BIBA_TYPE_GRADE: 554 pos = snprintf(string, size, "%d:", element->mbe_grade); 555 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) { 556 if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments)) 557 pos += snprintf(string + pos, size - pos, 558 "%d+", bit); 559 } 560 if (string[pos - 1] == '+' || string[pos - 1] == ':') 561 string[--pos] = NULL; 562 return (pos); 563 564 default: 565 panic("mac_biba_element_to_string: invalid type (%d)", 566 element->mbe_type); 567 } 568} 569 570static int 571mac_biba_to_string(char *string, size_t size, size_t *caller_len, 572 struct mac_biba *mac_biba) 573{ 574 size_t left, len; 575 char *curptr; 576 577 bzero(string, size); 578 curptr = string; 579 left = size; 580 581 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 582 len = mac_biba_element_to_string(curptr, left, 583 &mac_biba->mb_single); 584 if (len >= left) 585 return (EINVAL); 586 left -= len; 587 curptr += len; 588 } 589 590 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 591 len = snprintf(curptr, left, "("); 592 if (len >= left) 593 return (EINVAL); 594 left -= len; 595 curptr += len; 596 597 len = mac_biba_element_to_string(curptr, left, 598 &mac_biba->mb_rangelow); 599 if (len >= left) 600 return (EINVAL); 601 left -= len; 602 curptr += len; 603 604 len = snprintf(curptr, left, "-"); 605 if (len >= left) 606 return (EINVAL); 607 left -= len; 608 curptr += len; 609 610 len = mac_biba_element_to_string(curptr, left, 611 &mac_biba->mb_rangehigh); 612 if (len >= left) 613 return (EINVAL); 614 left -= len; 615 curptr += len; 616 617 len = snprintf(curptr, left, ")"); 618 if (len >= left) 619 return (EINVAL); 620 left -= len; 621 curptr += len; 622 } 623 624 *caller_len = strlen(string); 625 return (0); 626} 627 628static int 629mac_biba_externalize_label(struct label *label, char *element_name, 630 char *element_data, size_t size, size_t *len, int *claimed) 631{ 632 struct mac_biba *mac_biba; 633 int error; 634 635 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 636 return (0); 637 638 (*claimed)++; 639 640 mac_biba = SLOT(label); 641 error = mac_biba_to_string(element_data, size, len, mac_biba); 642 if (error) 643 return (error); 644 645 *len = strlen(element_data); 646 return (0); 647} 648 649static int 650mac_biba_parse_element(struct mac_biba_element *element, char *string) 651{ 652 653 if (strcmp(string, "high") == 0 || 654 strcmp(string, "hi") == 0) { 655 element->mbe_type = MAC_BIBA_TYPE_HIGH; 656 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 657 } else if (strcmp(string, "low") == 0 || 658 strcmp(string, "lo") == 0) { 659 element->mbe_type = MAC_BIBA_TYPE_LOW; 660 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 661 } else if (strcmp(string, "equal") == 0 || 662 strcmp(string, "eq") == 0) { 663 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 664 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 665 } else { 666 char *p0, *p1; 667 int d; 668 669 p0 = string; 670 d = strtol(p0, &p1, 10); 671 672 if (d < 0 || d > 65535) 673 return (EINVAL); 674 element->mbe_type = MAC_BIBA_TYPE_GRADE; 675 element->mbe_grade = d; 676 677 if (*p1 != ':') { 678 if (p1 == p0 || *p1 != '\0') 679 return (EINVAL); 680 else 681 return (0); 682 } 683 else 684 if (*(p1 + 1) == '\0') 685 return (0); 686 687 while ((p0 = ++p1)) { 688 d = strtol(p0, &p1, 10); 689 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS) 690 return (EINVAL); 691 692 MAC_BIBA_BIT_SET(d, element->mbe_compartments); 693 694 if (*p1 == '\0') 695 break; 696 if (p1 == p0 || *p1 != '+') 697 return (EINVAL); 698 } 699 } 700 701 return (0); 702} 703 704/* 705 * Note: destructively consumes the string, make a local copy before 706 * calling if that's a problem. 707 */ 708static int 709mac_biba_parse(struct mac_biba *mac_biba, char *string) 710{ 711 char *range, *rangeend, *rangehigh, *rangelow, *single; 712 int error; 713 714 /* Do we have a range? */ 715 single = string; 716 range = index(string, '('); 717 if (range == single) 718 single = NULL; 719 rangelow = rangehigh = NULL; 720 if (range != NULL) { 721 /* Nul terminate the end of the single string. */ 722 *range = '\0'; 723 range++; 724 rangelow = range; 725 rangehigh = index(rangelow, '-'); 726 if (rangehigh == NULL) 727 return (EINVAL); 728 rangehigh++; 729 if (*rangelow == '\0' || *rangehigh == '\0') 730 return (EINVAL); 731 rangeend = index(rangehigh, ')'); 732 if (rangeend == NULL) 733 return (EINVAL); 734 if (*(rangeend + 1) != '\0') 735 return (EINVAL); 736 /* Nul terminate the ends of the ranges. */ 737 *(rangehigh - 1) = '\0'; 738 *rangeend = '\0'; 739 } 740 KASSERT((rangelow != NULL && rangehigh != NULL) || 741 (rangelow == NULL && rangehigh == NULL), 742 ("mac_biba_internalize_label: range mismatch")); 743 744 bzero(mac_biba, sizeof(*mac_biba)); 745 if (single != NULL) { 746 error = mac_biba_parse_element(&mac_biba->mb_single, single); 747 if (error) 748 return (error); 749 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 750 } 751 752 if (rangelow != NULL) { 753 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 754 rangelow); 755 if (error) 756 return (error); 757 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 758 rangehigh); 759 if (error) 760 return (error); 761 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 762 } 763 764 error = mac_biba_valid(mac_biba); 765 if (error) 766 return (error); 767 768 return (0); 769} 770 771static int 772mac_biba_internalize_label(struct label *label, char *element_name, 773 char *element_data, int *claimed) 774{ 775 struct mac_biba *mac_biba, mac_biba_temp; 776 int error; 777 778 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 779 return (0); 780 781 (*claimed)++; 782 783 error = mac_biba_parse(&mac_biba_temp, element_data); 784 if (error) 785 return (error); 786 787 mac_biba = SLOT(label); 788 *mac_biba = mac_biba_temp; 789 790 return (0); 791} 792 793static void 794mac_biba_copy_label(struct label *src, struct label *dest) 795{ 796 797 *SLOT(dest) = *SLOT(src); 798} 799 800/* 801 * Labeling event operations: file system objects, and things that look 802 * a lot like file system objects. 803 */ 804static void 805mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 806 struct label *label) 807{ 808 struct mac_biba *mac_biba; 809 int biba_type; 810 811 mac_biba = SLOT(label); 812 if (strcmp(dev->si_name, "null") == 0 || 813 strcmp(dev->si_name, "zero") == 0 || 814 strcmp(dev->si_name, "random") == 0 || 815 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 816 biba_type = MAC_BIBA_TYPE_EQUAL; 817 else if (ptys_equal && 818 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 819 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 820 biba_type = MAC_BIBA_TYPE_EQUAL; 821 else 822 biba_type = MAC_BIBA_TYPE_HIGH; 823 mac_biba_set_single(mac_biba, biba_type, 0, NULL); 824} 825 826static void 827mac_biba_create_devfs_directory(char *dirname, int dirnamelen, 828 struct devfs_dirent *devfs_dirent, struct label *label) 829{ 830 struct mac_biba *mac_biba; 831 832 mac_biba = SLOT(label); 833 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 834} 835 836static void 837mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 838 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) 839{ 840 struct mac_biba *source, *dest; 841 842 source = SLOT(&cred->cr_label); 843 dest = SLOT(delabel); 844 845 mac_biba_copy_single(source, dest); 846} 847 848static void 849mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 850 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 851{ 852 struct mac_biba *source, *dest; 853 854 source = SLOT(direntlabel); 855 dest = SLOT(vnodelabel); 856 mac_biba_copy_single(source, dest); 857} 858 859static void 860mac_biba_create_mount(struct ucred *cred, struct mount *mp, 861 struct label *mntlabel, struct label *fslabel) 862{ 863 struct mac_biba *source, *dest; 864 865 source = SLOT(&cred->cr_label); 866 dest = SLOT(mntlabel); 867 mac_biba_copy_single(source, dest); 868 dest = SLOT(fslabel); 869 mac_biba_copy_single(source, dest); 870} 871 872static void 873mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 874 struct label *mntlabel, struct label *fslabel) 875{ 876 struct mac_biba *mac_biba; 877 878 /* Always mount root as high integrity. */ 879 mac_biba = SLOT(fslabel); 880 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 881 mac_biba = SLOT(mntlabel); 882 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 883} 884 885static void 886mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 887 struct label *vnodelabel, struct label *label) 888{ 889 struct mac_biba *source, *dest; 890 891 source = SLOT(label); 892 dest = SLOT(vnodelabel); 893 894 mac_biba_copy(source, dest); 895} 896 897static void 898mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent, 899 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 900{ 901 struct mac_biba *source, *dest; 902 903 source = SLOT(vnodelabel); 904 dest = SLOT(direntlabel); 905 906 mac_biba_copy(source, dest); 907} 908 909static void 910mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 911 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 912 struct label *vlabel) 913{ 914 struct mac_biba *source, *dest; 915 916 source = SLOT(delabel); 917 dest = SLOT(vlabel); 918 919 mac_biba_copy_single(source, dest); 920} 921 922static int 923mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 924 struct vnode *vp, struct label *vlabel) 925{ 926 struct mac_biba temp, *source, *dest; 927 size_t buflen; 928 int error; 929 930 source = SLOT(fslabel); 931 dest = SLOT(vlabel); 932 933 buflen = sizeof(temp); 934 bzero(&temp, buflen); 935 936 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 937 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 938 if (error == ENOATTR || error == EOPNOTSUPP) { 939 /* Fall back to the fslabel. */ 940 mac_biba_copy_single(source, dest); 941 return (0); 942 } else if (error) 943 return (error); 944 945 if (buflen != sizeof(temp)) { 946 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 947 buflen); 948 return (EPERM); 949 } 950 if (mac_biba_valid(&temp) != 0) { 951 printf("mac_biba_associate_vnode_extattr: invalid\n"); 952 return (EPERM); 953 } 954 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 955 printf("mac_biba_associate_vnode_extattr: not single\n"); 956 return (EPERM); 957 } 958 959 mac_biba_copy_single(&temp, dest); 960 return (0); 961} 962 963static void 964mac_biba_associate_vnode_singlelabel(struct mount *mp, 965 struct label *fslabel, struct vnode *vp, struct label *vlabel) 966{ 967 struct mac_biba *source, *dest; 968 969 source = SLOT(fslabel); 970 dest = SLOT(vlabel); 971 972 mac_biba_copy_single(source, dest); 973} 974 975static int 976mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 977 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 978 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 979{ 980 struct mac_biba *source, *dest, temp; 981 size_t buflen; 982 int error; 983 984 buflen = sizeof(temp); 985 bzero(&temp, buflen); 986 987 source = SLOT(&cred->cr_label); 988 dest = SLOT(vlabel); 989 mac_biba_copy_single(source, &temp); 990 991 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 992 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 993 if (error == 0) 994 mac_biba_copy_single(source, dest); 995 return (error); 996} 997 998static int 999mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1000 struct label *vlabel, struct label *intlabel) 1001{ 1002 struct mac_biba *source, temp; 1003 size_t buflen; 1004 int error; 1005 1006 buflen = sizeof(temp); 1007 bzero(&temp, buflen); 1008 1009 source = SLOT(intlabel); 1010 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 1011 return (0); 1012 1013 mac_biba_copy_single(source, &temp); 1014 1015 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 1016 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 1017 return (error); 1018} 1019 1020/* 1021 * Labeling event operations: IPC object. 1022 */ 1023static void 1024mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1025 struct mbuf *m, struct label *mbuflabel) 1026{ 1027 struct mac_biba *source, *dest; 1028 1029 source = SLOT(socketlabel); 1030 dest = SLOT(mbuflabel); 1031 1032 mac_biba_copy_single(source, dest); 1033} 1034 1035static void 1036mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1037 struct label *socketlabel) 1038{ 1039 struct mac_biba *source, *dest; 1040 1041 source = SLOT(&cred->cr_label); 1042 dest = SLOT(socketlabel); 1043 1044 mac_biba_copy_single(source, dest); 1045} 1046 1047static void 1048mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1049 struct label *pipelabel) 1050{ 1051 struct mac_biba *source, *dest; 1052 1053 source = SLOT(&cred->cr_label); 1054 dest = SLOT(pipelabel); 1055 1056 mac_biba_copy_single(source, dest); 1057} 1058 1059static void 1060mac_biba_create_socket_from_socket(struct socket *oldsocket, 1061 struct label *oldsocketlabel, struct socket *newsocket, 1062 struct label *newsocketlabel) 1063{ 1064 struct mac_biba *source, *dest; 1065 1066 source = SLOT(oldsocketlabel); 1067 dest = SLOT(newsocketlabel); 1068 1069 mac_biba_copy_single(source, dest); 1070} 1071 1072static void 1073mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1074 struct label *socketlabel, struct label *newlabel) 1075{ 1076 struct mac_biba *source, *dest; 1077 1078 source = SLOT(newlabel); 1079 dest = SLOT(socketlabel); 1080 1081 mac_biba_copy(source, dest); 1082} 1083 1084static void 1085mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1086 struct label *pipelabel, struct label *newlabel) 1087{ 1088 struct mac_biba *source, *dest; 1089 1090 source = SLOT(newlabel); 1091 dest = SLOT(pipelabel); 1092 1093 mac_biba_copy(source, dest); 1094} 1095 1096static void 1097mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1098 struct socket *socket, struct label *socketpeerlabel) 1099{ 1100 struct mac_biba *source, *dest; 1101 1102 source = SLOT(mbuflabel); 1103 dest = SLOT(socketpeerlabel); 1104 1105 mac_biba_copy_single(source, dest); 1106} 1107 1108/* 1109 * Labeling event operations: network objects. 1110 */ 1111static void 1112mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1113 struct label *oldsocketlabel, struct socket *newsocket, 1114 struct label *newsocketpeerlabel) 1115{ 1116 struct mac_biba *source, *dest; 1117 1118 source = SLOT(oldsocketlabel); 1119 dest = SLOT(newsocketpeerlabel); 1120 1121 mac_biba_copy_single(source, dest); 1122} 1123 1124static void 1125mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1126 struct label *bpflabel) 1127{ 1128 struct mac_biba *source, *dest; 1129 1130 source = SLOT(&cred->cr_label); 1131 dest = SLOT(bpflabel); 1132 1133 mac_biba_copy_single(source, dest); 1134} 1135 1136static void 1137mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1138{ 1139 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1140 char tiflist[sizeof(trusted_interfaces)]; 1141 struct mac_biba *dest; 1142 int len, grade; 1143 1144 dest = SLOT(ifnetlabel); 1145 1146 if (ifnet->if_type == IFT_LOOP) { 1147 grade = MAC_BIBA_TYPE_EQUAL; 1148 goto set; 1149 } 1150 1151 if (trust_all_interfaces) { 1152 grade = MAC_BIBA_TYPE_HIGH; 1153 goto set; 1154 } 1155 1156 grade = MAC_BIBA_TYPE_LOW; 1157 1158 if (trusted_interfaces[0] == '\0' || 1159 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1160 goto set; 1161
|
1178 } 1179 if (*p == '\0') 1180 break; 1181 q = p + 1; 1182 } 1183 } 1184set: 1185 mac_biba_set_single(dest, grade, 0, NULL); 1186 mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL); 1187} 1188 1189static void 1190mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1191 struct ipq *ipq, struct label *ipqlabel) 1192{ 1193 struct mac_biba *source, *dest; 1194 1195 source = SLOT(fragmentlabel); 1196 dest = SLOT(ipqlabel); 1197 1198 mac_biba_copy_single(source, dest); 1199} 1200 1201static void 1202mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1203 struct mbuf *datagram, struct label *datagramlabel) 1204{ 1205 struct mac_biba *source, *dest; 1206 1207 source = SLOT(ipqlabel); 1208 dest = SLOT(datagramlabel); 1209 1210 /* Just use the head, since we require them all to match. */ 1211 mac_biba_copy_single(source, dest); 1212} 1213 1214static void 1215mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1216 struct mbuf *fragment, struct label *fragmentlabel) 1217{ 1218 struct mac_biba *source, *dest; 1219 1220 source = SLOT(datagramlabel); 1221 dest = SLOT(fragmentlabel); 1222 1223 mac_biba_copy_single(source, dest); 1224} 1225 1226static void 1227mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1228 struct label *oldmbuflabel, struct mbuf *newmbuf, 1229 struct label *newmbuflabel) 1230{ 1231 struct mac_biba *source, *dest; 1232 1233 source = SLOT(oldmbuflabel); 1234 dest = SLOT(newmbuflabel); 1235 1236 /* 1237 * Because the source mbuf may not yet have been "created", 1238 * just initialized, we do a conditional copy. Since we don't 1239 * allow mbufs to have ranges, do a KASSERT to make sure that 1240 * doesn't happen. 1241 */ 1242 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1243 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1244 mac_biba_copy(source, dest); 1245} 1246 1247static void 1248mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1249 struct mbuf *mbuf, struct label *mbuflabel) 1250{ 1251 struct mac_biba *dest; 1252 1253 dest = SLOT(mbuflabel); 1254 1255 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1256} 1257 1258static void 1259mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1260 struct mbuf *mbuf, struct label *mbuflabel) 1261{ 1262 struct mac_biba *source, *dest; 1263 1264 source = SLOT(bpflabel); 1265 dest = SLOT(mbuflabel); 1266 1267 mac_biba_copy_single(source, dest); 1268} 1269 1270static void 1271mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1272 struct mbuf *m, struct label *mbuflabel) 1273{ 1274 struct mac_biba *source, *dest; 1275 1276 source = SLOT(ifnetlabel); 1277 dest = SLOT(mbuflabel); 1278 1279 mac_biba_copy_single(source, dest); 1280} 1281 1282static void 1283mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1284 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1285 struct mbuf *newmbuf, struct label *newmbuflabel) 1286{ 1287 struct mac_biba *source, *dest; 1288 1289 source = SLOT(oldmbuflabel); 1290 dest = SLOT(newmbuflabel); 1291 1292 mac_biba_copy_single(source, dest); 1293} 1294 1295static void 1296mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1297 struct mbuf *newmbuf, struct label *newmbuflabel) 1298{ 1299 struct mac_biba *source, *dest; 1300 1301 source = SLOT(oldmbuflabel); 1302 dest = SLOT(newmbuflabel); 1303 1304 mac_biba_copy_single(source, dest); 1305} 1306 1307static int 1308mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1309 struct ipq *ipq, struct label *ipqlabel) 1310{ 1311 struct mac_biba *a, *b; 1312 1313 a = SLOT(ipqlabel); 1314 b = SLOT(fragmentlabel); 1315 1316 return (mac_biba_equal_single(a, b)); 1317} 1318 1319static void 1320mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1321 struct label *ifnetlabel, struct label *newlabel) 1322{ 1323 struct mac_biba *source, *dest; 1324 1325 source = SLOT(newlabel); 1326 dest = SLOT(ifnetlabel); 1327 1328 mac_biba_copy(source, dest); 1329} 1330 1331static void 1332mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1333 struct ipq *ipq, struct label *ipqlabel) 1334{ 1335 1336 /* NOOP: we only accept matching labels, so no need to update */ 1337} 1338 1339/* 1340 * Labeling event operations: processes. 1341 */ 1342static void 1343mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1344{ 1345 struct mac_biba *source, *dest; 1346 1347 source = SLOT(&cred_parent->cr_label); 1348 dest = SLOT(&cred_child->cr_label); 1349 1350 mac_biba_copy_single(source, dest); 1351 mac_biba_copy_range(source, dest); 1352} 1353 1354static void 1355mac_biba_execve_transition(struct ucred *old, struct ucred *new, 1356 struct vnode *vp, struct mac *vnodelabel) 1357{ 1358 struct mac_biba *source, *dest; 1359 1360 source = SLOT(&old->cr_label); 1361 dest = SLOT(&new->cr_label); 1362 1363 mac_biba_copy_single(source, dest); 1364 mac_biba_copy_range(source, dest); 1365} 1366 1367static int 1368mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp, 1369 struct mac *vnodelabel) 1370{ 1371 1372 return (0); 1373} 1374 1375static void 1376mac_biba_create_proc0(struct ucred *cred) 1377{ 1378 struct mac_biba *dest; 1379 1380 dest = SLOT(&cred->cr_label); 1381 1382 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1383 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1384 MAC_BIBA_TYPE_HIGH, 0, NULL); 1385} 1386 1387static void 1388mac_biba_create_proc1(struct ucred *cred) 1389{ 1390 struct mac_biba *dest; 1391 1392 dest = SLOT(&cred->cr_label); 1393 1394 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1395 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1396 MAC_BIBA_TYPE_HIGH, 0, NULL); 1397} 1398 1399static void 1400mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1401{ 1402 struct mac_biba *source, *dest; 1403 1404 source = SLOT(newlabel); 1405 dest = SLOT(&cred->cr_label); 1406 1407 mac_biba_copy(source, dest); 1408} 1409 1410/* 1411 * Access control checks. 1412 */ 1413static int 1414mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1415 struct ifnet *ifnet, struct label *ifnetlabel) 1416{ 1417 struct mac_biba *a, *b; 1418 1419 if (!mac_biba_enabled) 1420 return (0); 1421 1422 a = SLOT(bpflabel); 1423 b = SLOT(ifnetlabel); 1424 1425 if (mac_biba_equal_single(a, b)) 1426 return (0); 1427 return (EACCES); 1428} 1429 1430static int 1431mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1432{ 1433 struct mac_biba *subj, *new; 1434 int error; 1435 1436 subj = SLOT(&cred->cr_label); 1437 new = SLOT(newlabel); 1438 1439 /* 1440 * If there is a Biba label update for the credential, it may 1441 * be an update of the single, range, or both. 1442 */ 1443 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1444 if (error) 1445 return (error); 1446 1447 /* 1448 * If the Biba label is to be changed, authorize as appropriate. 1449 */ 1450 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1451 /* 1452 * To change the Biba single label on a credential, the 1453 * new single label must be in the current range. 1454 */ 1455 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1456 !mac_biba_single_in_range(new, subj)) 1457 return (EPERM); 1458 1459 /* 1460 * To change the Biba range on a credential, the new 1461 * range label must be in the current range. 1462 */ 1463 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1464 !mac_biba_range_in_range(new, subj)) 1465 return (EPERM); 1466 1467 /* 1468 * To have EQUAL in any component of the new credential 1469 * Biba label, the subject must already have EQUAL in 1470 * their label. 1471 */ 1472 if (mac_biba_contains_equal(new)) { 1473 error = mac_biba_subject_equal_ok(subj); 1474 if (error) 1475 return (error); 1476 } 1477 1478 /* 1479 * XXXMAC: Additional consistency tests regarding the 1480 * single and range of the new label might be performed 1481 * here. 1482 */ 1483 } 1484 1485 return (0); 1486} 1487 1488static int 1489mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1490{ 1491 struct mac_biba *subj, *obj; 1492 1493 if (!mac_biba_enabled) 1494 return (0); 1495 1496 subj = SLOT(&u1->cr_label); 1497 obj = SLOT(&u2->cr_label); 1498 1499 /* XXX: range */ 1500 if (!mac_biba_dominate_single(obj, subj)) 1501 return (ESRCH); 1502 1503 return (0); 1504} 1505 1506static int 1507mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1508 struct label *ifnetlabel, struct label *newlabel) 1509{ 1510 struct mac_biba *subj, *new; 1511 int error; 1512 1513 subj = SLOT(&cred->cr_label); 1514 new = SLOT(newlabel); 1515 1516 /* 1517 * If there is a Biba label update for the interface, it may 1518 * be an update of the single, range, or both. 1519 */ 1520 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1521 if (error) 1522 return (error); 1523 1524 /* 1525 * If the Biba label is to be changed, authorize as appropriate. 1526 */ 1527 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1528 /* 1529 * Rely on the traditional superuser status for the Biba 1530 * interface relabel requirements. XXXMAC: This will go 1531 * away. 1532 */ 1533 error = suser_cred(cred, 0); 1534 if (error) 1535 return (EPERM); 1536 1537 /* 1538 * XXXMAC: Additional consistency tests regarding the single 1539 * and the range of the new label might be performed here. 1540 */ 1541 } 1542 1543 return (0); 1544} 1545 1546static int 1547mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1548 struct mbuf *m, struct label *mbuflabel) 1549{ 1550 struct mac_biba *p, *i; 1551 1552 if (!mac_biba_enabled) 1553 return (0); 1554 1555 p = SLOT(mbuflabel); 1556 i = SLOT(ifnetlabel); 1557 1558 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1559} 1560 1561static int 1562mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1563 struct label *mntlabel) 1564{ 1565 struct mac_biba *subj, *obj; 1566 1567 if (!mac_biba_enabled) 1568 return (0); 1569 1570 subj = SLOT(&cred->cr_label); 1571 obj = SLOT(mntlabel); 1572 1573 if (!mac_biba_dominate_single(obj, subj)) 1574 return (EACCES); 1575 1576 return (0); 1577} 1578 1579static int 1580mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1581 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1582{ 1583 1584 if(!mac_biba_enabled) 1585 return (0); 1586 1587 /* XXX: This will be implemented soon... */ 1588 1589 return (0); 1590} 1591 1592static int 1593mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1594 struct label *pipelabel) 1595{ 1596 struct mac_biba *subj, *obj; 1597 1598 if (!mac_biba_enabled) 1599 return (0); 1600 1601 subj = SLOT(&cred->cr_label); 1602 obj = SLOT((pipelabel)); 1603 1604 if (!mac_biba_dominate_single(obj, subj)) 1605 return (EACCES); 1606 1607 return (0); 1608} 1609 1610static int 1611mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1612 struct label *pipelabel) 1613{ 1614 struct mac_biba *subj, *obj; 1615 1616 if (!mac_biba_enabled) 1617 return (0); 1618 1619 subj = SLOT(&cred->cr_label); 1620 obj = SLOT((pipelabel)); 1621 1622 if (!mac_biba_dominate_single(obj, subj)) 1623 return (EACCES); 1624 1625 return (0); 1626} 1627 1628static int 1629mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1630 struct label *pipelabel, struct label *newlabel) 1631{ 1632 struct mac_biba *subj, *obj, *new; 1633 int error; 1634 1635 new = SLOT(newlabel); 1636 subj = SLOT(&cred->cr_label); 1637 obj = SLOT(pipelabel); 1638 1639 /* 1640 * If there is a Biba label update for a pipe, it must be a 1641 * single update. 1642 */ 1643 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1644 if (error) 1645 return (error); 1646 1647 /* 1648 * To perform a relabel of a pipe (Biba label or not), Biba must 1649 * authorize the relabel. 1650 */ 1651 if (!mac_biba_single_in_range(obj, subj)) 1652 return (EPERM); 1653 1654 /* 1655 * If the Biba label is to be changed, authorize as appropriate. 1656 */ 1657 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1658 /* 1659 * To change the Biba label on a pipe, the new pipe label 1660 * must be in the subject range. 1661 */ 1662 if (!mac_biba_single_in_range(new, subj)) 1663 return (EPERM); 1664 1665 /* 1666 * To change the Biba label on a pipe to be EQUAL, the 1667 * subject must have appropriate privilege. 1668 */ 1669 if (mac_biba_contains_equal(new)) { 1670 error = mac_biba_subject_equal_ok(subj); 1671 if (error) 1672 return (error); 1673 } 1674 } 1675 1676 return (0); 1677} 1678 1679static int 1680mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1681 struct label *pipelabel) 1682{ 1683 struct mac_biba *subj, *obj; 1684 1685 if (!mac_biba_enabled) 1686 return (0); 1687 1688 subj = SLOT(&cred->cr_label); 1689 obj = SLOT((pipelabel)); 1690 1691 if (!mac_biba_dominate_single(obj, subj)) 1692 return (EACCES); 1693 1694 return (0); 1695} 1696 1697static int 1698mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1699 struct label *pipelabel) 1700{ 1701 struct mac_biba *subj, *obj; 1702 1703 if (!mac_biba_enabled) 1704 return (0); 1705 1706 subj = SLOT(&cred->cr_label); 1707 obj = SLOT((pipelabel)); 1708 1709 if (!mac_biba_dominate_single(subj, obj)) 1710 return (EACCES); 1711 1712 return (0); 1713} 1714 1715static int 1716mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1717{ 1718 struct mac_biba *subj, *obj; 1719 1720 if (!mac_biba_enabled) 1721 return (0); 1722 1723 subj = SLOT(&cred->cr_label); 1724 obj = SLOT(&proc->p_ucred->cr_label); 1725 1726 /* XXX: range checks */ 1727 if (!mac_biba_dominate_single(obj, subj)) 1728 return (ESRCH); 1729 if (!mac_biba_dominate_single(subj, obj)) 1730 return (EACCES); 1731 1732 return (0); 1733} 1734 1735static int 1736mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1737{ 1738 struct mac_biba *subj, *obj; 1739 1740 if (!mac_biba_enabled) 1741 return (0); 1742 1743 subj = SLOT(&cred->cr_label); 1744 obj = SLOT(&proc->p_ucred->cr_label); 1745 1746 /* XXX: range checks */ 1747 if (!mac_biba_dominate_single(obj, subj)) 1748 return (ESRCH); 1749 if (!mac_biba_dominate_single(subj, obj)) 1750 return (EACCES); 1751 1752 return (0); 1753} 1754 1755static int 1756mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1757{ 1758 struct mac_biba *subj, *obj; 1759 1760 if (!mac_biba_enabled) 1761 return (0); 1762 1763 subj = SLOT(&cred->cr_label); 1764 obj = SLOT(&proc->p_ucred->cr_label); 1765 1766 /* XXX: range checks */ 1767 if (!mac_biba_dominate_single(obj, subj)) 1768 return (ESRCH); 1769 if (!mac_biba_dominate_single(subj, obj)) 1770 return (EACCES); 1771 1772 return (0); 1773} 1774 1775static int 1776mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1777 struct mbuf *m, struct label *mbuflabel) 1778{ 1779 struct mac_biba *p, *s; 1780 1781 if (!mac_biba_enabled) 1782 return (0); 1783 1784 p = SLOT(mbuflabel); 1785 s = SLOT(socketlabel); 1786 1787 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1788} 1789 1790static int 1791mac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket, 1792 struct label *socketlabel, struct label *newlabel) 1793{ 1794 struct mac_biba *subj, *obj, *new; 1795 int error; 1796 1797 new = SLOT(newlabel); 1798 subj = SLOT(&cred->cr_label); 1799 obj = SLOT(socketlabel); 1800 1801 /* 1802 * If there is a Biba label update for the socket, it may be 1803 * an update of single. 1804 */ 1805 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1806 if (error) 1807 return (error); 1808 1809 /* 1810 * To relabel a socket, the old socket single must be in the subject 1811 * range. 1812 */ 1813 if (!mac_biba_single_in_range(obj, subj)) 1814 return (EPERM); 1815 1816 /* 1817 * If the Biba label is to be changed, authorize as appropriate. 1818 */ 1819 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1820 /* 1821 * To relabel a socket, the new socket single must be in 1822 * the subject range. 1823 */ 1824 if (!mac_biba_single_in_range(new, subj)) 1825 return (EPERM); 1826 1827 /* 1828 * To change the Biba label on the socket to contain EQUAL, 1829 * the subject must have appropriate privilege. 1830 */ 1831 if (mac_biba_contains_equal(new)) { 1832 error = mac_biba_subject_equal_ok(subj); 1833 if (error) 1834 return (error); 1835 } 1836 } 1837 1838 return (0); 1839} 1840 1841static int 1842mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1843 struct label *socketlabel) 1844{ 1845 struct mac_biba *subj, *obj; 1846 1847 if (!mac_biba_enabled) 1848 return (0); 1849 1850 subj = SLOT(&cred->cr_label); 1851 obj = SLOT(socketlabel); 1852 1853 if (!mac_biba_dominate_single(obj, subj)) 1854 return (ENOENT); 1855 1856 return (0); 1857} 1858 1859static int 1860mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1861 struct label *dlabel) 1862{ 1863 struct mac_biba *subj, *obj; 1864 1865 if (!mac_biba_enabled) 1866 return (0); 1867 1868 subj = SLOT(&cred->cr_label); 1869 obj = SLOT(dlabel); 1870 1871 if (!mac_biba_dominate_single(obj, subj)) 1872 return (EACCES); 1873 1874 return (0); 1875} 1876 1877static int 1878mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1879 struct label *dlabel) 1880{ 1881 struct mac_biba *subj, *obj; 1882 1883 if (!mac_biba_enabled) 1884 return (0); 1885 1886 subj = SLOT(&cred->cr_label); 1887 obj = SLOT(dlabel); 1888 1889 if (!mac_biba_dominate_single(obj, subj)) 1890 return (EACCES); 1891 1892 return (0); 1893} 1894 1895static int 1896mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1897 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1898{ 1899 struct mac_biba *subj, *obj; 1900 1901 if (!mac_biba_enabled) 1902 return (0); 1903 1904 subj = SLOT(&cred->cr_label); 1905 obj = SLOT(dlabel); 1906 1907 if (!mac_biba_dominate_single(subj, obj)) 1908 return (EACCES); 1909 1910 return (0); 1911} 1912 1913static int 1914mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1915 struct label *dlabel, struct vnode *vp, struct label *label, 1916 struct componentname *cnp) 1917{ 1918 struct mac_biba *subj, *obj; 1919 1920 if (!mac_biba_enabled) 1921 return (0); 1922 1923 subj = SLOT(&cred->cr_label); 1924 obj = SLOT(dlabel); 1925 1926 if (!mac_biba_dominate_single(subj, obj)) 1927 return (EACCES); 1928 1929 obj = SLOT(label); 1930 1931 if (!mac_biba_dominate_single(subj, obj)) 1932 return (EACCES); 1933 1934 return (0); 1935} 1936 1937static int 1938mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1939 struct label *label, acl_type_t type) 1940{ 1941 struct mac_biba *subj, *obj; 1942 1943 if (!mac_biba_enabled) 1944 return (0); 1945 1946 subj = SLOT(&cred->cr_label); 1947 obj = SLOT(label); 1948 1949 if (!mac_biba_dominate_single(subj, obj)) 1950 return (EACCES); 1951 1952 return (0); 1953} 1954 1955static int 1956mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1957 struct label *label) 1958{ 1959 struct mac_biba *subj, *obj; 1960 1961 if (!mac_biba_enabled) 1962 return (0); 1963 1964 subj = SLOT(&cred->cr_label); 1965 obj = SLOT(label); 1966 1967 if (!mac_biba_dominate_single(obj, subj)) 1968 return (EACCES); 1969 1970 return (0); 1971} 1972 1973static int 1974mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 1975 struct label *label, acl_type_t type) 1976{ 1977 struct mac_biba *subj, *obj; 1978 1979 if (!mac_biba_enabled) 1980 return (0); 1981 1982 subj = SLOT(&cred->cr_label); 1983 obj = SLOT(label); 1984 1985 if (!mac_biba_dominate_single(obj, subj)) 1986 return (EACCES); 1987 1988 return (0); 1989} 1990 1991static int 1992mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1993 struct label *label, int attrnamespace, const char *name, struct uio *uio) 1994{ 1995 struct mac_biba *subj, *obj; 1996 1997 if (!mac_biba_enabled) 1998 return (0); 1999 2000 subj = SLOT(&cred->cr_label); 2001 obj = SLOT(label); 2002 2003 if (!mac_biba_dominate_single(obj, subj)) 2004 return (EACCES); 2005 2006 return (0); 2007} 2008 2009static int 2010mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2011 struct label *dlabel, struct vnode *vp, struct label *label, 2012 struct componentname *cnp) 2013{ 2014 struct mac_biba *subj, *obj; 2015 2016 if (!mac_biba_enabled) 2017 return (0); 2018 2019 subj = SLOT(&cred->cr_label); 2020 obj = SLOT(dlabel); 2021 2022 if (!mac_biba_dominate_single(subj, obj)) 2023 return (EACCES); 2024 2025 obj = SLOT(label); 2026 2027 if (!mac_biba_dominate_single(subj, obj)) 2028 return (EACCES); 2029 2030 return (0); 2031} 2032 2033static int 2034mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2035 struct label *dlabel, struct componentname *cnp) 2036{ 2037 struct mac_biba *subj, *obj; 2038 2039 if (!mac_biba_enabled) 2040 return (0); 2041 2042 subj = SLOT(&cred->cr_label); 2043 obj = SLOT(dlabel); 2044 2045 if (!mac_biba_dominate_single(obj, subj)) 2046 return (EACCES); 2047 2048 return (0); 2049} 2050 2051static int 2052mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2053 struct label *label, int prot) 2054{ 2055 struct mac_biba *subj, *obj; 2056 2057 /* 2058 * Rely on the use of open()-time protections to handle 2059 * non-revocation cases. 2060 */ 2061 if (!mac_biba_enabled || !revocation_enabled) 2062 return (0); 2063 2064 subj = SLOT(&cred->cr_label); 2065 obj = SLOT(label); 2066 2067 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2068 if (!mac_biba_dominate_single(obj, subj)) 2069 return (EACCES); 2070 } 2071 if (prot & VM_PROT_WRITE) { 2072 if (!mac_biba_dominate_single(subj, obj)) 2073 return (EACCES); 2074 } 2075 2076 return (0); 2077} 2078 2079static int 2080mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2081 struct label *vnodelabel, mode_t acc_mode) 2082{ 2083 struct mac_biba *subj, *obj; 2084 2085 if (!mac_biba_enabled) 2086 return (0); 2087 2088 subj = SLOT(&cred->cr_label); 2089 obj = SLOT(vnodelabel); 2090 2091 /* XXX privilege override for admin? */ 2092 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2093 if (!mac_biba_dominate_single(obj, subj)) 2094 return (EACCES); 2095 } 2096 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2097 if (!mac_biba_dominate_single(subj, obj)) 2098 return (EACCES); 2099 } 2100 2101 return (0); 2102} 2103 2104static int 2105mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2106 struct vnode *vp, struct label *label) 2107{ 2108 struct mac_biba *subj, *obj; 2109 2110 if (!mac_biba_enabled || !revocation_enabled) 2111 return (0); 2112 2113 subj = SLOT(&active_cred->cr_label); 2114 obj = SLOT(label); 2115 2116 if (!mac_biba_dominate_single(obj, subj)) 2117 return (EACCES); 2118 2119 return (0); 2120} 2121 2122static int 2123mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2124 struct vnode *vp, struct label *label) 2125{ 2126 struct mac_biba *subj, *obj; 2127 2128 if (!mac_biba_enabled || !revocation_enabled) 2129 return (0); 2130 2131 subj = SLOT(&active_cred->cr_label); 2132 obj = SLOT(label); 2133 2134 if (!mac_biba_dominate_single(obj, subj)) 2135 return (EACCES); 2136 2137 return (0); 2138} 2139 2140static int 2141mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2142 struct label *dlabel) 2143{ 2144 struct mac_biba *subj, *obj; 2145 2146 if (!mac_biba_enabled) 2147 return (0); 2148 2149 subj = SLOT(&cred->cr_label); 2150 obj = SLOT(dlabel); 2151 2152 if (!mac_biba_dominate_single(obj, subj)) 2153 return (EACCES); 2154 2155 return (0); 2156} 2157 2158static int 2159mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2160 struct label *label) 2161{ 2162 struct mac_biba *subj, *obj; 2163 2164 if (!mac_biba_enabled) 2165 return (0); 2166 2167 subj = SLOT(&cred->cr_label); 2168 obj = SLOT(label); 2169 2170 if (!mac_biba_dominate_single(obj, subj)) 2171 return (EACCES); 2172 2173 return (0); 2174} 2175 2176static int 2177mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2178 struct label *vnodelabel, struct label *newlabel) 2179{ 2180 struct mac_biba *old, *new, *subj; 2181 int error; 2182 2183 old = SLOT(vnodelabel); 2184 new = SLOT(newlabel); 2185 subj = SLOT(&cred->cr_label); 2186 2187 /* 2188 * If there is a Biba label update for the vnode, it must be a 2189 * single label. 2190 */ 2191 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2192 if (error) 2193 return (error); 2194 2195 /* 2196 * To perform a relabel of the vnode (Biba label or not), Biba must 2197 * authorize the relabel. 2198 */ 2199 if (!mac_biba_single_in_range(old, subj)) 2200 return (EPERM); 2201 2202 /* 2203 * If the Biba label is to be changed, authorize as appropriate. 2204 */ 2205 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2206 /* 2207 * To change the Biba label on a vnode, the new vnode label 2208 * must be in the subject range. 2209 */ 2210 if (!mac_biba_single_in_range(new, subj)) 2211 return (EPERM); 2212 2213 /* 2214 * To change the Biba label on the vnode to be EQUAL, 2215 * the subject must have appropriate privilege. 2216 */ 2217 if (mac_biba_contains_equal(new)) { 2218 error = mac_biba_subject_equal_ok(subj); 2219 if (error) 2220 return (error); 2221 } 2222 } 2223 2224 return (0); 2225} 2226 2227static int 2228mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2229 struct label *dlabel, struct vnode *vp, struct label *label, 2230 struct componentname *cnp) 2231{ 2232 struct mac_biba *subj, *obj; 2233 2234 if (!mac_biba_enabled) 2235 return (0); 2236 2237 subj = SLOT(&cred->cr_label); 2238 obj = SLOT(dlabel); 2239 2240 if (!mac_biba_dominate_single(subj, obj)) 2241 return (EACCES); 2242 2243 obj = SLOT(label); 2244 2245 if (!mac_biba_dominate_single(subj, obj)) 2246 return (EACCES); 2247 2248 return (0); 2249} 2250 2251static int 2252mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2253 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2254 struct componentname *cnp) 2255{ 2256 struct mac_biba *subj, *obj; 2257 2258 if (!mac_biba_enabled) 2259 return (0); 2260 2261 subj = SLOT(&cred->cr_label); 2262 obj = SLOT(dlabel); 2263 2264 if (!mac_biba_dominate_single(subj, obj)) 2265 return (EACCES); 2266 2267 if (vp != NULL) { 2268 obj = SLOT(label); 2269 2270 if (!mac_biba_dominate_single(subj, obj)) 2271 return (EACCES); 2272 } 2273 2274 return (0); 2275} 2276 2277static int 2278mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2279 struct label *label) 2280{ 2281 struct mac_biba *subj, *obj; 2282 2283 if (!mac_biba_enabled) 2284 return (0); 2285 2286 subj = SLOT(&cred->cr_label); 2287 obj = SLOT(label); 2288 2289 if (!mac_biba_dominate_single(subj, obj)) 2290 return (EACCES); 2291 2292 return (0); 2293} 2294 2295static int 2296mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2297 struct label *label, acl_type_t type, struct acl *acl) 2298{ 2299 struct mac_biba *subj, *obj; 2300 2301 if (!mac_biba_enabled) 2302 return (0); 2303 2304 subj = SLOT(&cred->cr_label); 2305 obj = SLOT(label); 2306 2307 if (!mac_biba_dominate_single(subj, obj)) 2308 return (EACCES); 2309 2310 return (0); 2311} 2312 2313static int 2314mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2315 struct label *vnodelabel, int attrnamespace, const char *name, 2316 struct uio *uio) 2317{ 2318 struct mac_biba *subj, *obj; 2319 2320 if (!mac_biba_enabled) 2321 return (0); 2322 2323 subj = SLOT(&cred->cr_label); 2324 obj = SLOT(vnodelabel); 2325 2326 if (!mac_biba_dominate_single(subj, obj)) 2327 return (EACCES); 2328 2329 /* XXX: protect the MAC EA in a special way? */ 2330 2331 return (0); 2332} 2333 2334static int 2335mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2336 struct label *vnodelabel, u_long flags) 2337{ 2338 struct mac_biba *subj, *obj; 2339 2340 if (!mac_biba_enabled) 2341 return (0); 2342 2343 subj = SLOT(&cred->cr_label); 2344 obj = SLOT(vnodelabel); 2345 2346 if (!mac_biba_dominate_single(subj, obj)) 2347 return (EACCES); 2348 2349 return (0); 2350} 2351 2352static int 2353mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2354 struct label *vnodelabel, mode_t mode) 2355{ 2356 struct mac_biba *subj, *obj; 2357 2358 if (!mac_biba_enabled) 2359 return (0); 2360 2361 subj = SLOT(&cred->cr_label); 2362 obj = SLOT(vnodelabel); 2363 2364 if (!mac_biba_dominate_single(subj, obj)) 2365 return (EACCES); 2366 2367 return (0); 2368} 2369 2370static int 2371mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2372 struct label *vnodelabel, uid_t uid, gid_t gid) 2373{ 2374 struct mac_biba *subj, *obj; 2375 2376 if (!mac_biba_enabled) 2377 return (0); 2378 2379 subj = SLOT(&cred->cr_label); 2380 obj = SLOT(vnodelabel); 2381 2382 if (!mac_biba_dominate_single(subj, obj)) 2383 return (EACCES); 2384 2385 return (0); 2386} 2387 2388static int 2389mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2390 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2391{ 2392 struct mac_biba *subj, *obj; 2393 2394 if (!mac_biba_enabled) 2395 return (0); 2396 2397 subj = SLOT(&cred->cr_label); 2398 obj = SLOT(vnodelabel); 2399 2400 if (!mac_biba_dominate_single(subj, obj)) 2401 return (EACCES); 2402 2403 return (0); 2404} 2405 2406static int 2407mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2408 struct vnode *vp, struct label *vnodelabel) 2409{ 2410 struct mac_biba *subj, *obj; 2411 2412 if (!mac_biba_enabled) 2413 return (0); 2414 2415 subj = SLOT(&active_cred->cr_label); 2416 obj = SLOT(vnodelabel); 2417 2418 if (!mac_biba_dominate_single(obj, subj)) 2419 return (EACCES); 2420 2421 return (0); 2422} 2423 2424static int 2425mac_biba_check_vnode_write(struct ucred *active_cred, 2426 struct ucred *file_cred, struct vnode *vp, struct label *label) 2427{ 2428 struct mac_biba *subj, *obj; 2429 2430 if (!mac_biba_enabled || !revocation_enabled) 2431 return (0); 2432 2433 subj = SLOT(&active_cred->cr_label); 2434 obj = SLOT(label); 2435 2436 if (!mac_biba_dominate_single(subj, obj)) 2437 return (EACCES); 2438 2439 return (0); 2440} 2441 2442static struct mac_policy_op_entry mac_biba_ops[] = 2443{ 2444 { MAC_DESTROY, 2445 (macop_t)mac_biba_destroy }, 2446 { MAC_INIT, 2447 (macop_t)mac_biba_init }, 2448 { MAC_INIT_BPFDESC_LABEL, 2449 (macop_t)mac_biba_init_label }, 2450 { MAC_INIT_CRED_LABEL, 2451 (macop_t)mac_biba_init_label }, 2452 { MAC_INIT_DEVFSDIRENT_LABEL, 2453 (macop_t)mac_biba_init_label }, 2454 { MAC_INIT_IFNET_LABEL, 2455 (macop_t)mac_biba_init_label }, 2456 { MAC_INIT_IPQ_LABEL, 2457 (macop_t)mac_biba_init_label }, 2458 { MAC_INIT_MBUF_LABEL, 2459 (macop_t)mac_biba_init_label_waitcheck }, 2460 { MAC_INIT_MOUNT_LABEL, 2461 (macop_t)mac_biba_init_label }, 2462 { MAC_INIT_MOUNT_FS_LABEL, 2463 (macop_t)mac_biba_init_label }, 2464 { MAC_INIT_PIPE_LABEL, 2465 (macop_t)mac_biba_init_label }, 2466 { MAC_INIT_SOCKET_LABEL, 2467 (macop_t)mac_biba_init_label_waitcheck }, 2468 { MAC_INIT_SOCKET_PEER_LABEL, 2469 (macop_t)mac_biba_init_label_waitcheck }, 2470 { MAC_INIT_VNODE_LABEL, 2471 (macop_t)mac_biba_init_label }, 2472 { MAC_DESTROY_BPFDESC_LABEL, 2473 (macop_t)mac_biba_destroy_label }, 2474 { MAC_DESTROY_CRED_LABEL, 2475 (macop_t)mac_biba_destroy_label }, 2476 { MAC_DESTROY_DEVFSDIRENT_LABEL, 2477 (macop_t)mac_biba_destroy_label }, 2478 { MAC_DESTROY_IFNET_LABEL, 2479 (macop_t)mac_biba_destroy_label }, 2480 { MAC_DESTROY_IPQ_LABEL, 2481 (macop_t)mac_biba_destroy_label }, 2482 { MAC_DESTROY_MBUF_LABEL, 2483 (macop_t)mac_biba_destroy_label }, 2484 { MAC_DESTROY_MOUNT_LABEL, 2485 (macop_t)mac_biba_destroy_label }, 2486 { MAC_DESTROY_MOUNT_FS_LABEL, 2487 (macop_t)mac_biba_destroy_label }, 2488 { MAC_DESTROY_PIPE_LABEL, 2489 (macop_t)mac_biba_destroy_label }, 2490 { MAC_DESTROY_SOCKET_LABEL, 2491 (macop_t)mac_biba_destroy_label }, 2492 { MAC_DESTROY_SOCKET_PEER_LABEL, 2493 (macop_t)mac_biba_destroy_label }, 2494 { MAC_DESTROY_VNODE_LABEL, 2495 (macop_t)mac_biba_destroy_label }, 2496 { MAC_COPY_PIPE_LABEL, 2497 (macop_t)mac_biba_copy_label }, 2498 { MAC_COPY_VNODE_LABEL, 2499 (macop_t)mac_biba_copy_label }, 2500 { MAC_EXTERNALIZE_CRED_LABEL, 2501 (macop_t)mac_biba_externalize_label }, 2502 { MAC_EXTERNALIZE_IFNET_LABEL, 2503 (macop_t)mac_biba_externalize_label }, 2504 { MAC_EXTERNALIZE_PIPE_LABEL, 2505 (macop_t)mac_biba_externalize_label }, 2506 { MAC_EXTERNALIZE_SOCKET_LABEL, 2507 (macop_t)mac_biba_externalize_label }, 2508 { MAC_EXTERNALIZE_SOCKET_PEER_LABEL, 2509 (macop_t)mac_biba_externalize_label }, 2510 { MAC_EXTERNALIZE_VNODE_LABEL, 2511 (macop_t)mac_biba_externalize_label }, 2512 { MAC_INTERNALIZE_CRED_LABEL, 2513 (macop_t)mac_biba_internalize_label }, 2514 { MAC_INTERNALIZE_IFNET_LABEL, 2515 (macop_t)mac_biba_internalize_label }, 2516 { MAC_INTERNALIZE_PIPE_LABEL, 2517 (macop_t)mac_biba_internalize_label }, 2518 { MAC_INTERNALIZE_SOCKET_LABEL, 2519 (macop_t)mac_biba_internalize_label }, 2520 { MAC_INTERNALIZE_VNODE_LABEL, 2521 (macop_t)mac_biba_internalize_label }, 2522 { MAC_CREATE_DEVFS_DEVICE, 2523 (macop_t)mac_biba_create_devfs_device }, 2524 { MAC_CREATE_DEVFS_DIRECTORY, 2525 (macop_t)mac_biba_create_devfs_directory }, 2526 { MAC_CREATE_DEVFS_SYMLINK, 2527 (macop_t)mac_biba_create_devfs_symlink }, 2528 { MAC_CREATE_DEVFS_VNODE, 2529 (macop_t)mac_biba_create_devfs_vnode }, 2530 { MAC_CREATE_MOUNT, 2531 (macop_t)mac_biba_create_mount }, 2532 { MAC_CREATE_ROOT_MOUNT, 2533 (macop_t)mac_biba_create_root_mount }, 2534 { MAC_RELABEL_VNODE, 2535 (macop_t)mac_biba_relabel_vnode }, 2536 { MAC_UPDATE_DEVFSDIRENT, 2537 (macop_t)mac_biba_update_devfsdirent }, 2538 { MAC_ASSOCIATE_VNODE_DEVFS, 2539 (macop_t)mac_biba_associate_vnode_devfs }, 2540 { MAC_ASSOCIATE_VNODE_EXTATTR, 2541 (macop_t)mac_biba_associate_vnode_extattr }, 2542 { MAC_ASSOCIATE_VNODE_SINGLELABEL, 2543 (macop_t)mac_biba_associate_vnode_singlelabel }, 2544 { MAC_CREATE_VNODE_EXTATTR, 2545 (macop_t)mac_biba_create_vnode_extattr }, 2546 { MAC_SETLABEL_VNODE_EXTATTR, 2547 (macop_t)mac_biba_setlabel_vnode_extattr }, 2548 { MAC_CREATE_MBUF_FROM_SOCKET, 2549 (macop_t)mac_biba_create_mbuf_from_socket }, 2550 { MAC_CREATE_PIPE, 2551 (macop_t)mac_biba_create_pipe }, 2552 { MAC_CREATE_SOCKET, 2553 (macop_t)mac_biba_create_socket }, 2554 { MAC_CREATE_SOCKET_FROM_SOCKET, 2555 (macop_t)mac_biba_create_socket_from_socket }, 2556 { MAC_RELABEL_PIPE, 2557 (macop_t)mac_biba_relabel_pipe }, 2558 { MAC_RELABEL_SOCKET, 2559 (macop_t)mac_biba_relabel_socket }, 2560 { MAC_SET_SOCKET_PEER_FROM_MBUF, 2561 (macop_t)mac_biba_set_socket_peer_from_mbuf }, 2562 { MAC_SET_SOCKET_PEER_FROM_SOCKET, 2563 (macop_t)mac_biba_set_socket_peer_from_socket }, 2564 { MAC_CREATE_BPFDESC, 2565 (macop_t)mac_biba_create_bpfdesc }, 2566 { MAC_CREATE_DATAGRAM_FROM_IPQ, 2567 (macop_t)mac_biba_create_datagram_from_ipq }, 2568 { MAC_CREATE_FRAGMENT, 2569 (macop_t)mac_biba_create_fragment }, 2570 { MAC_CREATE_IFNET, 2571 (macop_t)mac_biba_create_ifnet }, 2572 { MAC_CREATE_IPQ, 2573 (macop_t)mac_biba_create_ipq }, 2574 { MAC_CREATE_MBUF_FROM_MBUF, 2575 (macop_t)mac_biba_create_mbuf_from_mbuf }, 2576 { MAC_CREATE_MBUF_LINKLAYER, 2577 (macop_t)mac_biba_create_mbuf_linklayer }, 2578 { MAC_CREATE_MBUF_FROM_BPFDESC, 2579 (macop_t)mac_biba_create_mbuf_from_bpfdesc }, 2580 { MAC_CREATE_MBUF_FROM_IFNET, 2581 (macop_t)mac_biba_create_mbuf_from_ifnet }, 2582 { MAC_CREATE_MBUF_MULTICAST_ENCAP, 2583 (macop_t)mac_biba_create_mbuf_multicast_encap }, 2584 { MAC_CREATE_MBUF_NETLAYER, 2585 (macop_t)mac_biba_create_mbuf_netlayer }, 2586 { MAC_FRAGMENT_MATCH, 2587 (macop_t)mac_biba_fragment_match }, 2588 { MAC_RELABEL_IFNET, 2589 (macop_t)mac_biba_relabel_ifnet }, 2590 { MAC_UPDATE_IPQ, 2591 (macop_t)mac_biba_update_ipq }, 2592 { MAC_CREATE_CRED, 2593 (macop_t)mac_biba_create_cred }, 2594 { MAC_EXECVE_TRANSITION, 2595 (macop_t)mac_biba_execve_transition }, 2596 { MAC_EXECVE_WILL_TRANSITION, 2597 (macop_t)mac_biba_execve_will_transition }, 2598 { MAC_CREATE_PROC0, 2599 (macop_t)mac_biba_create_proc0 }, 2600 { MAC_CREATE_PROC1, 2601 (macop_t)mac_biba_create_proc1 }, 2602 { MAC_RELABEL_CRED, 2603 (macop_t)mac_biba_relabel_cred }, 2604 { MAC_CHECK_BPFDESC_RECEIVE, 2605 (macop_t)mac_biba_check_bpfdesc_receive }, 2606 { MAC_CHECK_CRED_RELABEL, 2607 (macop_t)mac_biba_check_cred_relabel }, 2608 { MAC_CHECK_CRED_VISIBLE, 2609 (macop_t)mac_biba_check_cred_visible }, 2610 { MAC_CHECK_IFNET_RELABEL, 2611 (macop_t)mac_biba_check_ifnet_relabel }, 2612 { MAC_CHECK_IFNET_TRANSMIT, 2613 (macop_t)mac_biba_check_ifnet_transmit }, 2614 { MAC_CHECK_MOUNT_STAT, 2615 (macop_t)mac_biba_check_mount_stat }, 2616 { MAC_CHECK_PIPE_IOCTL, 2617 (macop_t)mac_biba_check_pipe_ioctl }, 2618 { MAC_CHECK_PIPE_POLL, 2619 (macop_t)mac_biba_check_pipe_poll }, 2620 { MAC_CHECK_PIPE_READ, 2621 (macop_t)mac_biba_check_pipe_read }, 2622 { MAC_CHECK_PIPE_RELABEL, 2623 (macop_t)mac_biba_check_pipe_relabel }, 2624 { MAC_CHECK_PIPE_STAT, 2625 (macop_t)mac_biba_check_pipe_stat }, 2626 { MAC_CHECK_PIPE_WRITE, 2627 (macop_t)mac_biba_check_pipe_write }, 2628 { MAC_CHECK_PROC_DEBUG, 2629 (macop_t)mac_biba_check_proc_debug }, 2630 { MAC_CHECK_PROC_SCHED, 2631 (macop_t)mac_biba_check_proc_sched }, 2632 { MAC_CHECK_PROC_SIGNAL, 2633 (macop_t)mac_biba_check_proc_signal }, 2634 { MAC_CHECK_SOCKET_DELIVER, 2635 (macop_t)mac_biba_check_socket_deliver }, 2636 { MAC_CHECK_SOCKET_RELABEL, 2637 (macop_t)mac_biba_check_socket_relabel }, 2638 { MAC_CHECK_SOCKET_VISIBLE, 2639 (macop_t)mac_biba_check_socket_visible }, 2640 { MAC_CHECK_VNODE_ACCESS, 2641 (macop_t)mac_biba_check_vnode_open }, 2642 { MAC_CHECK_VNODE_CHDIR, 2643 (macop_t)mac_biba_check_vnode_chdir }, 2644 { MAC_CHECK_VNODE_CHROOT, 2645 (macop_t)mac_biba_check_vnode_chroot }, 2646 { MAC_CHECK_VNODE_CREATE, 2647 (macop_t)mac_biba_check_vnode_create }, 2648 { MAC_CHECK_VNODE_DELETE, 2649 (macop_t)mac_biba_check_vnode_delete }, 2650 { MAC_CHECK_VNODE_DELETEACL, 2651 (macop_t)mac_biba_check_vnode_deleteacl }, 2652 { MAC_CHECK_VNODE_EXEC, 2653 (macop_t)mac_biba_check_vnode_exec }, 2654 { MAC_CHECK_VNODE_GETACL, 2655 (macop_t)mac_biba_check_vnode_getacl }, 2656 { MAC_CHECK_VNODE_GETEXTATTR, 2657 (macop_t)mac_biba_check_vnode_getextattr }, 2658 { MAC_CHECK_VNODE_LINK, 2659 (macop_t)mac_biba_check_vnode_link }, 2660 { MAC_CHECK_VNODE_LOOKUP, 2661 (macop_t)mac_biba_check_vnode_lookup }, 2662 { MAC_CHECK_VNODE_MMAP, 2663 (macop_t)mac_biba_check_vnode_mmap }, 2664 { MAC_CHECK_VNODE_MPROTECT, 2665 (macop_t)mac_biba_check_vnode_mmap }, 2666 { MAC_CHECK_VNODE_OPEN, 2667 (macop_t)mac_biba_check_vnode_open }, 2668 { MAC_CHECK_VNODE_POLL, 2669 (macop_t)mac_biba_check_vnode_poll }, 2670 { MAC_CHECK_VNODE_READ, 2671 (macop_t)mac_biba_check_vnode_read }, 2672 { MAC_CHECK_VNODE_READDIR, 2673 (macop_t)mac_biba_check_vnode_readdir }, 2674 { MAC_CHECK_VNODE_READLINK, 2675 (macop_t)mac_biba_check_vnode_readlink }, 2676 { MAC_CHECK_VNODE_RELABEL, 2677 (macop_t)mac_biba_check_vnode_relabel }, 2678 { MAC_CHECK_VNODE_RENAME_FROM, 2679 (macop_t)mac_biba_check_vnode_rename_from }, 2680 { MAC_CHECK_VNODE_RENAME_TO, 2681 (macop_t)mac_biba_check_vnode_rename_to }, 2682 { MAC_CHECK_VNODE_REVOKE, 2683 (macop_t)mac_biba_check_vnode_revoke }, 2684 { MAC_CHECK_VNODE_SETACL, 2685 (macop_t)mac_biba_check_vnode_setacl }, 2686 { MAC_CHECK_VNODE_SETEXTATTR, 2687 (macop_t)mac_biba_check_vnode_setextattr }, 2688 { MAC_CHECK_VNODE_SETFLAGS, 2689 (macop_t)mac_biba_check_vnode_setflags }, 2690 { MAC_CHECK_VNODE_SETMODE, 2691 (macop_t)mac_biba_check_vnode_setmode }, 2692 { MAC_CHECK_VNODE_SETOWNER, 2693 (macop_t)mac_biba_check_vnode_setowner }, 2694 { MAC_CHECK_VNODE_SETUTIMES, 2695 (macop_t)mac_biba_check_vnode_setutimes }, 2696 { MAC_CHECK_VNODE_STAT, 2697 (macop_t)mac_biba_check_vnode_stat }, 2698 { MAC_CHECK_VNODE_WRITE, 2699 (macop_t)mac_biba_check_vnode_write }, 2700 { MAC_OP_LAST, NULL } 2701}; 2702 2703MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2704 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
| 1184 } 1185 if (*p == '\0') 1186 break; 1187 q = p + 1; 1188 } 1189 } 1190set: 1191 mac_biba_set_single(dest, grade, 0, NULL); 1192 mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL); 1193} 1194 1195static void 1196mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1197 struct ipq *ipq, struct label *ipqlabel) 1198{ 1199 struct mac_biba *source, *dest; 1200 1201 source = SLOT(fragmentlabel); 1202 dest = SLOT(ipqlabel); 1203 1204 mac_biba_copy_single(source, dest); 1205} 1206 1207static void 1208mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1209 struct mbuf *datagram, struct label *datagramlabel) 1210{ 1211 struct mac_biba *source, *dest; 1212 1213 source = SLOT(ipqlabel); 1214 dest = SLOT(datagramlabel); 1215 1216 /* Just use the head, since we require them all to match. */ 1217 mac_biba_copy_single(source, dest); 1218} 1219 1220static void 1221mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1222 struct mbuf *fragment, struct label *fragmentlabel) 1223{ 1224 struct mac_biba *source, *dest; 1225 1226 source = SLOT(datagramlabel); 1227 dest = SLOT(fragmentlabel); 1228 1229 mac_biba_copy_single(source, dest); 1230} 1231 1232static void 1233mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1234 struct label *oldmbuflabel, struct mbuf *newmbuf, 1235 struct label *newmbuflabel) 1236{ 1237 struct mac_biba *source, *dest; 1238 1239 source = SLOT(oldmbuflabel); 1240 dest = SLOT(newmbuflabel); 1241 1242 /* 1243 * Because the source mbuf may not yet have been "created", 1244 * just initialized, we do a conditional copy. Since we don't 1245 * allow mbufs to have ranges, do a KASSERT to make sure that 1246 * doesn't happen. 1247 */ 1248 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1249 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1250 mac_biba_copy(source, dest); 1251} 1252 1253static void 1254mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1255 struct mbuf *mbuf, struct label *mbuflabel) 1256{ 1257 struct mac_biba *dest; 1258 1259 dest = SLOT(mbuflabel); 1260 1261 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1262} 1263 1264static void 1265mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1266 struct mbuf *mbuf, struct label *mbuflabel) 1267{ 1268 struct mac_biba *source, *dest; 1269 1270 source = SLOT(bpflabel); 1271 dest = SLOT(mbuflabel); 1272 1273 mac_biba_copy_single(source, dest); 1274} 1275 1276static void 1277mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1278 struct mbuf *m, struct label *mbuflabel) 1279{ 1280 struct mac_biba *source, *dest; 1281 1282 source = SLOT(ifnetlabel); 1283 dest = SLOT(mbuflabel); 1284 1285 mac_biba_copy_single(source, dest); 1286} 1287 1288static void 1289mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1290 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1291 struct mbuf *newmbuf, struct label *newmbuflabel) 1292{ 1293 struct mac_biba *source, *dest; 1294 1295 source = SLOT(oldmbuflabel); 1296 dest = SLOT(newmbuflabel); 1297 1298 mac_biba_copy_single(source, dest); 1299} 1300 1301static void 1302mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1303 struct mbuf *newmbuf, struct label *newmbuflabel) 1304{ 1305 struct mac_biba *source, *dest; 1306 1307 source = SLOT(oldmbuflabel); 1308 dest = SLOT(newmbuflabel); 1309 1310 mac_biba_copy_single(source, dest); 1311} 1312 1313static int 1314mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1315 struct ipq *ipq, struct label *ipqlabel) 1316{ 1317 struct mac_biba *a, *b; 1318 1319 a = SLOT(ipqlabel); 1320 b = SLOT(fragmentlabel); 1321 1322 return (mac_biba_equal_single(a, b)); 1323} 1324 1325static void 1326mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1327 struct label *ifnetlabel, struct label *newlabel) 1328{ 1329 struct mac_biba *source, *dest; 1330 1331 source = SLOT(newlabel); 1332 dest = SLOT(ifnetlabel); 1333 1334 mac_biba_copy(source, dest); 1335} 1336 1337static void 1338mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1339 struct ipq *ipq, struct label *ipqlabel) 1340{ 1341 1342 /* NOOP: we only accept matching labels, so no need to update */ 1343} 1344 1345/* 1346 * Labeling event operations: processes. 1347 */ 1348static void 1349mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1350{ 1351 struct mac_biba *source, *dest; 1352 1353 source = SLOT(&cred_parent->cr_label); 1354 dest = SLOT(&cred_child->cr_label); 1355 1356 mac_biba_copy_single(source, dest); 1357 mac_biba_copy_range(source, dest); 1358} 1359 1360static void 1361mac_biba_execve_transition(struct ucred *old, struct ucred *new, 1362 struct vnode *vp, struct mac *vnodelabel) 1363{ 1364 struct mac_biba *source, *dest; 1365 1366 source = SLOT(&old->cr_label); 1367 dest = SLOT(&new->cr_label); 1368 1369 mac_biba_copy_single(source, dest); 1370 mac_biba_copy_range(source, dest); 1371} 1372 1373static int 1374mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp, 1375 struct mac *vnodelabel) 1376{ 1377 1378 return (0); 1379} 1380 1381static void 1382mac_biba_create_proc0(struct ucred *cred) 1383{ 1384 struct mac_biba *dest; 1385 1386 dest = SLOT(&cred->cr_label); 1387 1388 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1389 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1390 MAC_BIBA_TYPE_HIGH, 0, NULL); 1391} 1392 1393static void 1394mac_biba_create_proc1(struct ucred *cred) 1395{ 1396 struct mac_biba *dest; 1397 1398 dest = SLOT(&cred->cr_label); 1399 1400 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1401 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1402 MAC_BIBA_TYPE_HIGH, 0, NULL); 1403} 1404 1405static void 1406mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1407{ 1408 struct mac_biba *source, *dest; 1409 1410 source = SLOT(newlabel); 1411 dest = SLOT(&cred->cr_label); 1412 1413 mac_biba_copy(source, dest); 1414} 1415 1416/* 1417 * Access control checks. 1418 */ 1419static int 1420mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1421 struct ifnet *ifnet, struct label *ifnetlabel) 1422{ 1423 struct mac_biba *a, *b; 1424 1425 if (!mac_biba_enabled) 1426 return (0); 1427 1428 a = SLOT(bpflabel); 1429 b = SLOT(ifnetlabel); 1430 1431 if (mac_biba_equal_single(a, b)) 1432 return (0); 1433 return (EACCES); 1434} 1435 1436static int 1437mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1438{ 1439 struct mac_biba *subj, *new; 1440 int error; 1441 1442 subj = SLOT(&cred->cr_label); 1443 new = SLOT(newlabel); 1444 1445 /* 1446 * If there is a Biba label update for the credential, it may 1447 * be an update of the single, range, or both. 1448 */ 1449 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1450 if (error) 1451 return (error); 1452 1453 /* 1454 * If the Biba label is to be changed, authorize as appropriate. 1455 */ 1456 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1457 /* 1458 * To change the Biba single label on a credential, the 1459 * new single label must be in the current range. 1460 */ 1461 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1462 !mac_biba_single_in_range(new, subj)) 1463 return (EPERM); 1464 1465 /* 1466 * To change the Biba range on a credential, the new 1467 * range label must be in the current range. 1468 */ 1469 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1470 !mac_biba_range_in_range(new, subj)) 1471 return (EPERM); 1472 1473 /* 1474 * To have EQUAL in any component of the new credential 1475 * Biba label, the subject must already have EQUAL in 1476 * their label. 1477 */ 1478 if (mac_biba_contains_equal(new)) { 1479 error = mac_biba_subject_equal_ok(subj); 1480 if (error) 1481 return (error); 1482 } 1483 1484 /* 1485 * XXXMAC: Additional consistency tests regarding the 1486 * single and range of the new label might be performed 1487 * here. 1488 */ 1489 } 1490 1491 return (0); 1492} 1493 1494static int 1495mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1496{ 1497 struct mac_biba *subj, *obj; 1498 1499 if (!mac_biba_enabled) 1500 return (0); 1501 1502 subj = SLOT(&u1->cr_label); 1503 obj = SLOT(&u2->cr_label); 1504 1505 /* XXX: range */ 1506 if (!mac_biba_dominate_single(obj, subj)) 1507 return (ESRCH); 1508 1509 return (0); 1510} 1511 1512static int 1513mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1514 struct label *ifnetlabel, struct label *newlabel) 1515{ 1516 struct mac_biba *subj, *new; 1517 int error; 1518 1519 subj = SLOT(&cred->cr_label); 1520 new = SLOT(newlabel); 1521 1522 /* 1523 * If there is a Biba label update for the interface, it may 1524 * be an update of the single, range, or both. 1525 */ 1526 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1527 if (error) 1528 return (error); 1529 1530 /* 1531 * If the Biba label is to be changed, authorize as appropriate. 1532 */ 1533 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1534 /* 1535 * Rely on the traditional superuser status for the Biba 1536 * interface relabel requirements. XXXMAC: This will go 1537 * away. 1538 */ 1539 error = suser_cred(cred, 0); 1540 if (error) 1541 return (EPERM); 1542 1543 /* 1544 * XXXMAC: Additional consistency tests regarding the single 1545 * and the range of the new label might be performed here. 1546 */ 1547 } 1548 1549 return (0); 1550} 1551 1552static int 1553mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1554 struct mbuf *m, struct label *mbuflabel) 1555{ 1556 struct mac_biba *p, *i; 1557 1558 if (!mac_biba_enabled) 1559 return (0); 1560 1561 p = SLOT(mbuflabel); 1562 i = SLOT(ifnetlabel); 1563 1564 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1565} 1566 1567static int 1568mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1569 struct label *mntlabel) 1570{ 1571 struct mac_biba *subj, *obj; 1572 1573 if (!mac_biba_enabled) 1574 return (0); 1575 1576 subj = SLOT(&cred->cr_label); 1577 obj = SLOT(mntlabel); 1578 1579 if (!mac_biba_dominate_single(obj, subj)) 1580 return (EACCES); 1581 1582 return (0); 1583} 1584 1585static int 1586mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1587 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1588{ 1589 1590 if(!mac_biba_enabled) 1591 return (0); 1592 1593 /* XXX: This will be implemented soon... */ 1594 1595 return (0); 1596} 1597 1598static int 1599mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1600 struct label *pipelabel) 1601{ 1602 struct mac_biba *subj, *obj; 1603 1604 if (!mac_biba_enabled) 1605 return (0); 1606 1607 subj = SLOT(&cred->cr_label); 1608 obj = SLOT((pipelabel)); 1609 1610 if (!mac_biba_dominate_single(obj, subj)) 1611 return (EACCES); 1612 1613 return (0); 1614} 1615 1616static int 1617mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1618 struct label *pipelabel) 1619{ 1620 struct mac_biba *subj, *obj; 1621 1622 if (!mac_biba_enabled) 1623 return (0); 1624 1625 subj = SLOT(&cred->cr_label); 1626 obj = SLOT((pipelabel)); 1627 1628 if (!mac_biba_dominate_single(obj, subj)) 1629 return (EACCES); 1630 1631 return (0); 1632} 1633 1634static int 1635mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1636 struct label *pipelabel, struct label *newlabel) 1637{ 1638 struct mac_biba *subj, *obj, *new; 1639 int error; 1640 1641 new = SLOT(newlabel); 1642 subj = SLOT(&cred->cr_label); 1643 obj = SLOT(pipelabel); 1644 1645 /* 1646 * If there is a Biba label update for a pipe, it must be a 1647 * single update. 1648 */ 1649 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1650 if (error) 1651 return (error); 1652 1653 /* 1654 * To perform a relabel of a pipe (Biba label or not), Biba must 1655 * authorize the relabel. 1656 */ 1657 if (!mac_biba_single_in_range(obj, subj)) 1658 return (EPERM); 1659 1660 /* 1661 * If the Biba label is to be changed, authorize as appropriate. 1662 */ 1663 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1664 /* 1665 * To change the Biba label on a pipe, the new pipe label 1666 * must be in the subject range. 1667 */ 1668 if (!mac_biba_single_in_range(new, subj)) 1669 return (EPERM); 1670 1671 /* 1672 * To change the Biba label on a pipe to be EQUAL, the 1673 * subject must have appropriate privilege. 1674 */ 1675 if (mac_biba_contains_equal(new)) { 1676 error = mac_biba_subject_equal_ok(subj); 1677 if (error) 1678 return (error); 1679 } 1680 } 1681 1682 return (0); 1683} 1684 1685static int 1686mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1687 struct label *pipelabel) 1688{ 1689 struct mac_biba *subj, *obj; 1690 1691 if (!mac_biba_enabled) 1692 return (0); 1693 1694 subj = SLOT(&cred->cr_label); 1695 obj = SLOT((pipelabel)); 1696 1697 if (!mac_biba_dominate_single(obj, subj)) 1698 return (EACCES); 1699 1700 return (0); 1701} 1702 1703static int 1704mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1705 struct label *pipelabel) 1706{ 1707 struct mac_biba *subj, *obj; 1708 1709 if (!mac_biba_enabled) 1710 return (0); 1711 1712 subj = SLOT(&cred->cr_label); 1713 obj = SLOT((pipelabel)); 1714 1715 if (!mac_biba_dominate_single(subj, obj)) 1716 return (EACCES); 1717 1718 return (0); 1719} 1720 1721static int 1722mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1723{ 1724 struct mac_biba *subj, *obj; 1725 1726 if (!mac_biba_enabled) 1727 return (0); 1728 1729 subj = SLOT(&cred->cr_label); 1730 obj = SLOT(&proc->p_ucred->cr_label); 1731 1732 /* XXX: range checks */ 1733 if (!mac_biba_dominate_single(obj, subj)) 1734 return (ESRCH); 1735 if (!mac_biba_dominate_single(subj, obj)) 1736 return (EACCES); 1737 1738 return (0); 1739} 1740 1741static int 1742mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1743{ 1744 struct mac_biba *subj, *obj; 1745 1746 if (!mac_biba_enabled) 1747 return (0); 1748 1749 subj = SLOT(&cred->cr_label); 1750 obj = SLOT(&proc->p_ucred->cr_label); 1751 1752 /* XXX: range checks */ 1753 if (!mac_biba_dominate_single(obj, subj)) 1754 return (ESRCH); 1755 if (!mac_biba_dominate_single(subj, obj)) 1756 return (EACCES); 1757 1758 return (0); 1759} 1760 1761static int 1762mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1763{ 1764 struct mac_biba *subj, *obj; 1765 1766 if (!mac_biba_enabled) 1767 return (0); 1768 1769 subj = SLOT(&cred->cr_label); 1770 obj = SLOT(&proc->p_ucred->cr_label); 1771 1772 /* XXX: range checks */ 1773 if (!mac_biba_dominate_single(obj, subj)) 1774 return (ESRCH); 1775 if (!mac_biba_dominate_single(subj, obj)) 1776 return (EACCES); 1777 1778 return (0); 1779} 1780 1781static int 1782mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1783 struct mbuf *m, struct label *mbuflabel) 1784{ 1785 struct mac_biba *p, *s; 1786 1787 if (!mac_biba_enabled) 1788 return (0); 1789 1790 p = SLOT(mbuflabel); 1791 s = SLOT(socketlabel); 1792 1793 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1794} 1795 1796static int 1797mac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket, 1798 struct label *socketlabel, struct label *newlabel) 1799{ 1800 struct mac_biba *subj, *obj, *new; 1801 int error; 1802 1803 new = SLOT(newlabel); 1804 subj = SLOT(&cred->cr_label); 1805 obj = SLOT(socketlabel); 1806 1807 /* 1808 * If there is a Biba label update for the socket, it may be 1809 * an update of single. 1810 */ 1811 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1812 if (error) 1813 return (error); 1814 1815 /* 1816 * To relabel a socket, the old socket single must be in the subject 1817 * range. 1818 */ 1819 if (!mac_biba_single_in_range(obj, subj)) 1820 return (EPERM); 1821 1822 /* 1823 * If the Biba label is to be changed, authorize as appropriate. 1824 */ 1825 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1826 /* 1827 * To relabel a socket, the new socket single must be in 1828 * the subject range. 1829 */ 1830 if (!mac_biba_single_in_range(new, subj)) 1831 return (EPERM); 1832 1833 /* 1834 * To change the Biba label on the socket to contain EQUAL, 1835 * the subject must have appropriate privilege. 1836 */ 1837 if (mac_biba_contains_equal(new)) { 1838 error = mac_biba_subject_equal_ok(subj); 1839 if (error) 1840 return (error); 1841 } 1842 } 1843 1844 return (0); 1845} 1846 1847static int 1848mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1849 struct label *socketlabel) 1850{ 1851 struct mac_biba *subj, *obj; 1852 1853 if (!mac_biba_enabled) 1854 return (0); 1855 1856 subj = SLOT(&cred->cr_label); 1857 obj = SLOT(socketlabel); 1858 1859 if (!mac_biba_dominate_single(obj, subj)) 1860 return (ENOENT); 1861 1862 return (0); 1863} 1864 1865static int 1866mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1867 struct label *dlabel) 1868{ 1869 struct mac_biba *subj, *obj; 1870 1871 if (!mac_biba_enabled) 1872 return (0); 1873 1874 subj = SLOT(&cred->cr_label); 1875 obj = SLOT(dlabel); 1876 1877 if (!mac_biba_dominate_single(obj, subj)) 1878 return (EACCES); 1879 1880 return (0); 1881} 1882 1883static int 1884mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1885 struct label *dlabel) 1886{ 1887 struct mac_biba *subj, *obj; 1888 1889 if (!mac_biba_enabled) 1890 return (0); 1891 1892 subj = SLOT(&cred->cr_label); 1893 obj = SLOT(dlabel); 1894 1895 if (!mac_biba_dominate_single(obj, subj)) 1896 return (EACCES); 1897 1898 return (0); 1899} 1900 1901static int 1902mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1903 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1904{ 1905 struct mac_biba *subj, *obj; 1906 1907 if (!mac_biba_enabled) 1908 return (0); 1909 1910 subj = SLOT(&cred->cr_label); 1911 obj = SLOT(dlabel); 1912 1913 if (!mac_biba_dominate_single(subj, obj)) 1914 return (EACCES); 1915 1916 return (0); 1917} 1918 1919static int 1920mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1921 struct label *dlabel, struct vnode *vp, struct label *label, 1922 struct componentname *cnp) 1923{ 1924 struct mac_biba *subj, *obj; 1925 1926 if (!mac_biba_enabled) 1927 return (0); 1928 1929 subj = SLOT(&cred->cr_label); 1930 obj = SLOT(dlabel); 1931 1932 if (!mac_biba_dominate_single(subj, obj)) 1933 return (EACCES); 1934 1935 obj = SLOT(label); 1936 1937 if (!mac_biba_dominate_single(subj, obj)) 1938 return (EACCES); 1939 1940 return (0); 1941} 1942 1943static int 1944mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1945 struct label *label, acl_type_t type) 1946{ 1947 struct mac_biba *subj, *obj; 1948 1949 if (!mac_biba_enabled) 1950 return (0); 1951 1952 subj = SLOT(&cred->cr_label); 1953 obj = SLOT(label); 1954 1955 if (!mac_biba_dominate_single(subj, obj)) 1956 return (EACCES); 1957 1958 return (0); 1959} 1960 1961static int 1962mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1963 struct label *label) 1964{ 1965 struct mac_biba *subj, *obj; 1966 1967 if (!mac_biba_enabled) 1968 return (0); 1969 1970 subj = SLOT(&cred->cr_label); 1971 obj = SLOT(label); 1972 1973 if (!mac_biba_dominate_single(obj, subj)) 1974 return (EACCES); 1975 1976 return (0); 1977} 1978 1979static int 1980mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 1981 struct label *label, acl_type_t type) 1982{ 1983 struct mac_biba *subj, *obj; 1984 1985 if (!mac_biba_enabled) 1986 return (0); 1987 1988 subj = SLOT(&cred->cr_label); 1989 obj = SLOT(label); 1990 1991 if (!mac_biba_dominate_single(obj, subj)) 1992 return (EACCES); 1993 1994 return (0); 1995} 1996 1997static int 1998mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1999 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2000{ 2001 struct mac_biba *subj, *obj; 2002 2003 if (!mac_biba_enabled) 2004 return (0); 2005 2006 subj = SLOT(&cred->cr_label); 2007 obj = SLOT(label); 2008 2009 if (!mac_biba_dominate_single(obj, subj)) 2010 return (EACCES); 2011 2012 return (0); 2013} 2014 2015static int 2016mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2017 struct label *dlabel, struct vnode *vp, struct label *label, 2018 struct componentname *cnp) 2019{ 2020 struct mac_biba *subj, *obj; 2021 2022 if (!mac_biba_enabled) 2023 return (0); 2024 2025 subj = SLOT(&cred->cr_label); 2026 obj = SLOT(dlabel); 2027 2028 if (!mac_biba_dominate_single(subj, obj)) 2029 return (EACCES); 2030 2031 obj = SLOT(label); 2032 2033 if (!mac_biba_dominate_single(subj, obj)) 2034 return (EACCES); 2035 2036 return (0); 2037} 2038 2039static int 2040mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2041 struct label *dlabel, struct componentname *cnp) 2042{ 2043 struct mac_biba *subj, *obj; 2044 2045 if (!mac_biba_enabled) 2046 return (0); 2047 2048 subj = SLOT(&cred->cr_label); 2049 obj = SLOT(dlabel); 2050 2051 if (!mac_biba_dominate_single(obj, subj)) 2052 return (EACCES); 2053 2054 return (0); 2055} 2056 2057static int 2058mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2059 struct label *label, int prot) 2060{ 2061 struct mac_biba *subj, *obj; 2062 2063 /* 2064 * Rely on the use of open()-time protections to handle 2065 * non-revocation cases. 2066 */ 2067 if (!mac_biba_enabled || !revocation_enabled) 2068 return (0); 2069 2070 subj = SLOT(&cred->cr_label); 2071 obj = SLOT(label); 2072 2073 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2074 if (!mac_biba_dominate_single(obj, subj)) 2075 return (EACCES); 2076 } 2077 if (prot & VM_PROT_WRITE) { 2078 if (!mac_biba_dominate_single(subj, obj)) 2079 return (EACCES); 2080 } 2081 2082 return (0); 2083} 2084 2085static int 2086mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2087 struct label *vnodelabel, mode_t acc_mode) 2088{ 2089 struct mac_biba *subj, *obj; 2090 2091 if (!mac_biba_enabled) 2092 return (0); 2093 2094 subj = SLOT(&cred->cr_label); 2095 obj = SLOT(vnodelabel); 2096 2097 /* XXX privilege override for admin? */ 2098 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2099 if (!mac_biba_dominate_single(obj, subj)) 2100 return (EACCES); 2101 } 2102 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2103 if (!mac_biba_dominate_single(subj, obj)) 2104 return (EACCES); 2105 } 2106 2107 return (0); 2108} 2109 2110static int 2111mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2112 struct vnode *vp, struct label *label) 2113{ 2114 struct mac_biba *subj, *obj; 2115 2116 if (!mac_biba_enabled || !revocation_enabled) 2117 return (0); 2118 2119 subj = SLOT(&active_cred->cr_label); 2120 obj = SLOT(label); 2121 2122 if (!mac_biba_dominate_single(obj, subj)) 2123 return (EACCES); 2124 2125 return (0); 2126} 2127 2128static int 2129mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2130 struct vnode *vp, struct label *label) 2131{ 2132 struct mac_biba *subj, *obj; 2133 2134 if (!mac_biba_enabled || !revocation_enabled) 2135 return (0); 2136 2137 subj = SLOT(&active_cred->cr_label); 2138 obj = SLOT(label); 2139 2140 if (!mac_biba_dominate_single(obj, subj)) 2141 return (EACCES); 2142 2143 return (0); 2144} 2145 2146static int 2147mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2148 struct label *dlabel) 2149{ 2150 struct mac_biba *subj, *obj; 2151 2152 if (!mac_biba_enabled) 2153 return (0); 2154 2155 subj = SLOT(&cred->cr_label); 2156 obj = SLOT(dlabel); 2157 2158 if (!mac_biba_dominate_single(obj, subj)) 2159 return (EACCES); 2160 2161 return (0); 2162} 2163 2164static int 2165mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2166 struct label *label) 2167{ 2168 struct mac_biba *subj, *obj; 2169 2170 if (!mac_biba_enabled) 2171 return (0); 2172 2173 subj = SLOT(&cred->cr_label); 2174 obj = SLOT(label); 2175 2176 if (!mac_biba_dominate_single(obj, subj)) 2177 return (EACCES); 2178 2179 return (0); 2180} 2181 2182static int 2183mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2184 struct label *vnodelabel, struct label *newlabel) 2185{ 2186 struct mac_biba *old, *new, *subj; 2187 int error; 2188 2189 old = SLOT(vnodelabel); 2190 new = SLOT(newlabel); 2191 subj = SLOT(&cred->cr_label); 2192 2193 /* 2194 * If there is a Biba label update for the vnode, it must be a 2195 * single label. 2196 */ 2197 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2198 if (error) 2199 return (error); 2200 2201 /* 2202 * To perform a relabel of the vnode (Biba label or not), Biba must 2203 * authorize the relabel. 2204 */ 2205 if (!mac_biba_single_in_range(old, subj)) 2206 return (EPERM); 2207 2208 /* 2209 * If the Biba label is to be changed, authorize as appropriate. 2210 */ 2211 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2212 /* 2213 * To change the Biba label on a vnode, the new vnode label 2214 * must be in the subject range. 2215 */ 2216 if (!mac_biba_single_in_range(new, subj)) 2217 return (EPERM); 2218 2219 /* 2220 * To change the Biba label on the vnode to be EQUAL, 2221 * the subject must have appropriate privilege. 2222 */ 2223 if (mac_biba_contains_equal(new)) { 2224 error = mac_biba_subject_equal_ok(subj); 2225 if (error) 2226 return (error); 2227 } 2228 } 2229 2230 return (0); 2231} 2232 2233static int 2234mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2235 struct label *dlabel, struct vnode *vp, struct label *label, 2236 struct componentname *cnp) 2237{ 2238 struct mac_biba *subj, *obj; 2239 2240 if (!mac_biba_enabled) 2241 return (0); 2242 2243 subj = SLOT(&cred->cr_label); 2244 obj = SLOT(dlabel); 2245 2246 if (!mac_biba_dominate_single(subj, obj)) 2247 return (EACCES); 2248 2249 obj = SLOT(label); 2250 2251 if (!mac_biba_dominate_single(subj, obj)) 2252 return (EACCES); 2253 2254 return (0); 2255} 2256 2257static int 2258mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2259 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2260 struct componentname *cnp) 2261{ 2262 struct mac_biba *subj, *obj; 2263 2264 if (!mac_biba_enabled) 2265 return (0); 2266 2267 subj = SLOT(&cred->cr_label); 2268 obj = SLOT(dlabel); 2269 2270 if (!mac_biba_dominate_single(subj, obj)) 2271 return (EACCES); 2272 2273 if (vp != NULL) { 2274 obj = SLOT(label); 2275 2276 if (!mac_biba_dominate_single(subj, obj)) 2277 return (EACCES); 2278 } 2279 2280 return (0); 2281} 2282 2283static int 2284mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2285 struct label *label) 2286{ 2287 struct mac_biba *subj, *obj; 2288 2289 if (!mac_biba_enabled) 2290 return (0); 2291 2292 subj = SLOT(&cred->cr_label); 2293 obj = SLOT(label); 2294 2295 if (!mac_biba_dominate_single(subj, obj)) 2296 return (EACCES); 2297 2298 return (0); 2299} 2300 2301static int 2302mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2303 struct label *label, acl_type_t type, struct acl *acl) 2304{ 2305 struct mac_biba *subj, *obj; 2306 2307 if (!mac_biba_enabled) 2308 return (0); 2309 2310 subj = SLOT(&cred->cr_label); 2311 obj = SLOT(label); 2312 2313 if (!mac_biba_dominate_single(subj, obj)) 2314 return (EACCES); 2315 2316 return (0); 2317} 2318 2319static int 2320mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2321 struct label *vnodelabel, int attrnamespace, const char *name, 2322 struct uio *uio) 2323{ 2324 struct mac_biba *subj, *obj; 2325 2326 if (!mac_biba_enabled) 2327 return (0); 2328 2329 subj = SLOT(&cred->cr_label); 2330 obj = SLOT(vnodelabel); 2331 2332 if (!mac_biba_dominate_single(subj, obj)) 2333 return (EACCES); 2334 2335 /* XXX: protect the MAC EA in a special way? */ 2336 2337 return (0); 2338} 2339 2340static int 2341mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2342 struct label *vnodelabel, u_long flags) 2343{ 2344 struct mac_biba *subj, *obj; 2345 2346 if (!mac_biba_enabled) 2347 return (0); 2348 2349 subj = SLOT(&cred->cr_label); 2350 obj = SLOT(vnodelabel); 2351 2352 if (!mac_biba_dominate_single(subj, obj)) 2353 return (EACCES); 2354 2355 return (0); 2356} 2357 2358static int 2359mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2360 struct label *vnodelabel, mode_t mode) 2361{ 2362 struct mac_biba *subj, *obj; 2363 2364 if (!mac_biba_enabled) 2365 return (0); 2366 2367 subj = SLOT(&cred->cr_label); 2368 obj = SLOT(vnodelabel); 2369 2370 if (!mac_biba_dominate_single(subj, obj)) 2371 return (EACCES); 2372 2373 return (0); 2374} 2375 2376static int 2377mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2378 struct label *vnodelabel, uid_t uid, gid_t gid) 2379{ 2380 struct mac_biba *subj, *obj; 2381 2382 if (!mac_biba_enabled) 2383 return (0); 2384 2385 subj = SLOT(&cred->cr_label); 2386 obj = SLOT(vnodelabel); 2387 2388 if (!mac_biba_dominate_single(subj, obj)) 2389 return (EACCES); 2390 2391 return (0); 2392} 2393 2394static int 2395mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2396 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2397{ 2398 struct mac_biba *subj, *obj; 2399 2400 if (!mac_biba_enabled) 2401 return (0); 2402 2403 subj = SLOT(&cred->cr_label); 2404 obj = SLOT(vnodelabel); 2405 2406 if (!mac_biba_dominate_single(subj, obj)) 2407 return (EACCES); 2408 2409 return (0); 2410} 2411 2412static int 2413mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2414 struct vnode *vp, struct label *vnodelabel) 2415{ 2416 struct mac_biba *subj, *obj; 2417 2418 if (!mac_biba_enabled) 2419 return (0); 2420 2421 subj = SLOT(&active_cred->cr_label); 2422 obj = SLOT(vnodelabel); 2423 2424 if (!mac_biba_dominate_single(obj, subj)) 2425 return (EACCES); 2426 2427 return (0); 2428} 2429 2430static int 2431mac_biba_check_vnode_write(struct ucred *active_cred, 2432 struct ucred *file_cred, struct vnode *vp, struct label *label) 2433{ 2434 struct mac_biba *subj, *obj; 2435 2436 if (!mac_biba_enabled || !revocation_enabled) 2437 return (0); 2438 2439 subj = SLOT(&active_cred->cr_label); 2440 obj = SLOT(label); 2441 2442 if (!mac_biba_dominate_single(subj, obj)) 2443 return (EACCES); 2444 2445 return (0); 2446} 2447 2448static struct mac_policy_op_entry mac_biba_ops[] = 2449{ 2450 { MAC_DESTROY, 2451 (macop_t)mac_biba_destroy }, 2452 { MAC_INIT, 2453 (macop_t)mac_biba_init }, 2454 { MAC_INIT_BPFDESC_LABEL, 2455 (macop_t)mac_biba_init_label }, 2456 { MAC_INIT_CRED_LABEL, 2457 (macop_t)mac_biba_init_label }, 2458 { MAC_INIT_DEVFSDIRENT_LABEL, 2459 (macop_t)mac_biba_init_label }, 2460 { MAC_INIT_IFNET_LABEL, 2461 (macop_t)mac_biba_init_label }, 2462 { MAC_INIT_IPQ_LABEL, 2463 (macop_t)mac_biba_init_label }, 2464 { MAC_INIT_MBUF_LABEL, 2465 (macop_t)mac_biba_init_label_waitcheck }, 2466 { MAC_INIT_MOUNT_LABEL, 2467 (macop_t)mac_biba_init_label }, 2468 { MAC_INIT_MOUNT_FS_LABEL, 2469 (macop_t)mac_biba_init_label }, 2470 { MAC_INIT_PIPE_LABEL, 2471 (macop_t)mac_biba_init_label }, 2472 { MAC_INIT_SOCKET_LABEL, 2473 (macop_t)mac_biba_init_label_waitcheck }, 2474 { MAC_INIT_SOCKET_PEER_LABEL, 2475 (macop_t)mac_biba_init_label_waitcheck }, 2476 { MAC_INIT_VNODE_LABEL, 2477 (macop_t)mac_biba_init_label }, 2478 { MAC_DESTROY_BPFDESC_LABEL, 2479 (macop_t)mac_biba_destroy_label }, 2480 { MAC_DESTROY_CRED_LABEL, 2481 (macop_t)mac_biba_destroy_label }, 2482 { MAC_DESTROY_DEVFSDIRENT_LABEL, 2483 (macop_t)mac_biba_destroy_label }, 2484 { MAC_DESTROY_IFNET_LABEL, 2485 (macop_t)mac_biba_destroy_label }, 2486 { MAC_DESTROY_IPQ_LABEL, 2487 (macop_t)mac_biba_destroy_label }, 2488 { MAC_DESTROY_MBUF_LABEL, 2489 (macop_t)mac_biba_destroy_label }, 2490 { MAC_DESTROY_MOUNT_LABEL, 2491 (macop_t)mac_biba_destroy_label }, 2492 { MAC_DESTROY_MOUNT_FS_LABEL, 2493 (macop_t)mac_biba_destroy_label }, 2494 { MAC_DESTROY_PIPE_LABEL, 2495 (macop_t)mac_biba_destroy_label }, 2496 { MAC_DESTROY_SOCKET_LABEL, 2497 (macop_t)mac_biba_destroy_label }, 2498 { MAC_DESTROY_SOCKET_PEER_LABEL, 2499 (macop_t)mac_biba_destroy_label }, 2500 { MAC_DESTROY_VNODE_LABEL, 2501 (macop_t)mac_biba_destroy_label }, 2502 { MAC_COPY_PIPE_LABEL, 2503 (macop_t)mac_biba_copy_label }, 2504 { MAC_COPY_VNODE_LABEL, 2505 (macop_t)mac_biba_copy_label }, 2506 { MAC_EXTERNALIZE_CRED_LABEL, 2507 (macop_t)mac_biba_externalize_label }, 2508 { MAC_EXTERNALIZE_IFNET_LABEL, 2509 (macop_t)mac_biba_externalize_label }, 2510 { MAC_EXTERNALIZE_PIPE_LABEL, 2511 (macop_t)mac_biba_externalize_label }, 2512 { MAC_EXTERNALIZE_SOCKET_LABEL, 2513 (macop_t)mac_biba_externalize_label }, 2514 { MAC_EXTERNALIZE_SOCKET_PEER_LABEL, 2515 (macop_t)mac_biba_externalize_label }, 2516 { MAC_EXTERNALIZE_VNODE_LABEL, 2517 (macop_t)mac_biba_externalize_label }, 2518 { MAC_INTERNALIZE_CRED_LABEL, 2519 (macop_t)mac_biba_internalize_label }, 2520 { MAC_INTERNALIZE_IFNET_LABEL, 2521 (macop_t)mac_biba_internalize_label }, 2522 { MAC_INTERNALIZE_PIPE_LABEL, 2523 (macop_t)mac_biba_internalize_label }, 2524 { MAC_INTERNALIZE_SOCKET_LABEL, 2525 (macop_t)mac_biba_internalize_label }, 2526 { MAC_INTERNALIZE_VNODE_LABEL, 2527 (macop_t)mac_biba_internalize_label }, 2528 { MAC_CREATE_DEVFS_DEVICE, 2529 (macop_t)mac_biba_create_devfs_device }, 2530 { MAC_CREATE_DEVFS_DIRECTORY, 2531 (macop_t)mac_biba_create_devfs_directory }, 2532 { MAC_CREATE_DEVFS_SYMLINK, 2533 (macop_t)mac_biba_create_devfs_symlink }, 2534 { MAC_CREATE_DEVFS_VNODE, 2535 (macop_t)mac_biba_create_devfs_vnode }, 2536 { MAC_CREATE_MOUNT, 2537 (macop_t)mac_biba_create_mount }, 2538 { MAC_CREATE_ROOT_MOUNT, 2539 (macop_t)mac_biba_create_root_mount }, 2540 { MAC_RELABEL_VNODE, 2541 (macop_t)mac_biba_relabel_vnode }, 2542 { MAC_UPDATE_DEVFSDIRENT, 2543 (macop_t)mac_biba_update_devfsdirent }, 2544 { MAC_ASSOCIATE_VNODE_DEVFS, 2545 (macop_t)mac_biba_associate_vnode_devfs }, 2546 { MAC_ASSOCIATE_VNODE_EXTATTR, 2547 (macop_t)mac_biba_associate_vnode_extattr }, 2548 { MAC_ASSOCIATE_VNODE_SINGLELABEL, 2549 (macop_t)mac_biba_associate_vnode_singlelabel }, 2550 { MAC_CREATE_VNODE_EXTATTR, 2551 (macop_t)mac_biba_create_vnode_extattr }, 2552 { MAC_SETLABEL_VNODE_EXTATTR, 2553 (macop_t)mac_biba_setlabel_vnode_extattr }, 2554 { MAC_CREATE_MBUF_FROM_SOCKET, 2555 (macop_t)mac_biba_create_mbuf_from_socket }, 2556 { MAC_CREATE_PIPE, 2557 (macop_t)mac_biba_create_pipe }, 2558 { MAC_CREATE_SOCKET, 2559 (macop_t)mac_biba_create_socket }, 2560 { MAC_CREATE_SOCKET_FROM_SOCKET, 2561 (macop_t)mac_biba_create_socket_from_socket }, 2562 { MAC_RELABEL_PIPE, 2563 (macop_t)mac_biba_relabel_pipe }, 2564 { MAC_RELABEL_SOCKET, 2565 (macop_t)mac_biba_relabel_socket }, 2566 { MAC_SET_SOCKET_PEER_FROM_MBUF, 2567 (macop_t)mac_biba_set_socket_peer_from_mbuf }, 2568 { MAC_SET_SOCKET_PEER_FROM_SOCKET, 2569 (macop_t)mac_biba_set_socket_peer_from_socket }, 2570 { MAC_CREATE_BPFDESC, 2571 (macop_t)mac_biba_create_bpfdesc }, 2572 { MAC_CREATE_DATAGRAM_FROM_IPQ, 2573 (macop_t)mac_biba_create_datagram_from_ipq }, 2574 { MAC_CREATE_FRAGMENT, 2575 (macop_t)mac_biba_create_fragment }, 2576 { MAC_CREATE_IFNET, 2577 (macop_t)mac_biba_create_ifnet }, 2578 { MAC_CREATE_IPQ, 2579 (macop_t)mac_biba_create_ipq }, 2580 { MAC_CREATE_MBUF_FROM_MBUF, 2581 (macop_t)mac_biba_create_mbuf_from_mbuf }, 2582 { MAC_CREATE_MBUF_LINKLAYER, 2583 (macop_t)mac_biba_create_mbuf_linklayer }, 2584 { MAC_CREATE_MBUF_FROM_BPFDESC, 2585 (macop_t)mac_biba_create_mbuf_from_bpfdesc }, 2586 { MAC_CREATE_MBUF_FROM_IFNET, 2587 (macop_t)mac_biba_create_mbuf_from_ifnet }, 2588 { MAC_CREATE_MBUF_MULTICAST_ENCAP, 2589 (macop_t)mac_biba_create_mbuf_multicast_encap }, 2590 { MAC_CREATE_MBUF_NETLAYER, 2591 (macop_t)mac_biba_create_mbuf_netlayer }, 2592 { MAC_FRAGMENT_MATCH, 2593 (macop_t)mac_biba_fragment_match }, 2594 { MAC_RELABEL_IFNET, 2595 (macop_t)mac_biba_relabel_ifnet }, 2596 { MAC_UPDATE_IPQ, 2597 (macop_t)mac_biba_update_ipq }, 2598 { MAC_CREATE_CRED, 2599 (macop_t)mac_biba_create_cred }, 2600 { MAC_EXECVE_TRANSITION, 2601 (macop_t)mac_biba_execve_transition }, 2602 { MAC_EXECVE_WILL_TRANSITION, 2603 (macop_t)mac_biba_execve_will_transition }, 2604 { MAC_CREATE_PROC0, 2605 (macop_t)mac_biba_create_proc0 }, 2606 { MAC_CREATE_PROC1, 2607 (macop_t)mac_biba_create_proc1 }, 2608 { MAC_RELABEL_CRED, 2609 (macop_t)mac_biba_relabel_cred }, 2610 { MAC_CHECK_BPFDESC_RECEIVE, 2611 (macop_t)mac_biba_check_bpfdesc_receive }, 2612 { MAC_CHECK_CRED_RELABEL, 2613 (macop_t)mac_biba_check_cred_relabel }, 2614 { MAC_CHECK_CRED_VISIBLE, 2615 (macop_t)mac_biba_check_cred_visible }, 2616 { MAC_CHECK_IFNET_RELABEL, 2617 (macop_t)mac_biba_check_ifnet_relabel }, 2618 { MAC_CHECK_IFNET_TRANSMIT, 2619 (macop_t)mac_biba_check_ifnet_transmit }, 2620 { MAC_CHECK_MOUNT_STAT, 2621 (macop_t)mac_biba_check_mount_stat }, 2622 { MAC_CHECK_PIPE_IOCTL, 2623 (macop_t)mac_biba_check_pipe_ioctl }, 2624 { MAC_CHECK_PIPE_POLL, 2625 (macop_t)mac_biba_check_pipe_poll }, 2626 { MAC_CHECK_PIPE_READ, 2627 (macop_t)mac_biba_check_pipe_read }, 2628 { MAC_CHECK_PIPE_RELABEL, 2629 (macop_t)mac_biba_check_pipe_relabel }, 2630 { MAC_CHECK_PIPE_STAT, 2631 (macop_t)mac_biba_check_pipe_stat }, 2632 { MAC_CHECK_PIPE_WRITE, 2633 (macop_t)mac_biba_check_pipe_write }, 2634 { MAC_CHECK_PROC_DEBUG, 2635 (macop_t)mac_biba_check_proc_debug }, 2636 { MAC_CHECK_PROC_SCHED, 2637 (macop_t)mac_biba_check_proc_sched }, 2638 { MAC_CHECK_PROC_SIGNAL, 2639 (macop_t)mac_biba_check_proc_signal }, 2640 { MAC_CHECK_SOCKET_DELIVER, 2641 (macop_t)mac_biba_check_socket_deliver }, 2642 { MAC_CHECK_SOCKET_RELABEL, 2643 (macop_t)mac_biba_check_socket_relabel }, 2644 { MAC_CHECK_SOCKET_VISIBLE, 2645 (macop_t)mac_biba_check_socket_visible }, 2646 { MAC_CHECK_VNODE_ACCESS, 2647 (macop_t)mac_biba_check_vnode_open }, 2648 { MAC_CHECK_VNODE_CHDIR, 2649 (macop_t)mac_biba_check_vnode_chdir }, 2650 { MAC_CHECK_VNODE_CHROOT, 2651 (macop_t)mac_biba_check_vnode_chroot }, 2652 { MAC_CHECK_VNODE_CREATE, 2653 (macop_t)mac_biba_check_vnode_create }, 2654 { MAC_CHECK_VNODE_DELETE, 2655 (macop_t)mac_biba_check_vnode_delete }, 2656 { MAC_CHECK_VNODE_DELETEACL, 2657 (macop_t)mac_biba_check_vnode_deleteacl }, 2658 { MAC_CHECK_VNODE_EXEC, 2659 (macop_t)mac_biba_check_vnode_exec }, 2660 { MAC_CHECK_VNODE_GETACL, 2661 (macop_t)mac_biba_check_vnode_getacl }, 2662 { MAC_CHECK_VNODE_GETEXTATTR, 2663 (macop_t)mac_biba_check_vnode_getextattr }, 2664 { MAC_CHECK_VNODE_LINK, 2665 (macop_t)mac_biba_check_vnode_link }, 2666 { MAC_CHECK_VNODE_LOOKUP, 2667 (macop_t)mac_biba_check_vnode_lookup }, 2668 { MAC_CHECK_VNODE_MMAP, 2669 (macop_t)mac_biba_check_vnode_mmap }, 2670 { MAC_CHECK_VNODE_MPROTECT, 2671 (macop_t)mac_biba_check_vnode_mmap }, 2672 { MAC_CHECK_VNODE_OPEN, 2673 (macop_t)mac_biba_check_vnode_open }, 2674 { MAC_CHECK_VNODE_POLL, 2675 (macop_t)mac_biba_check_vnode_poll }, 2676 { MAC_CHECK_VNODE_READ, 2677 (macop_t)mac_biba_check_vnode_read }, 2678 { MAC_CHECK_VNODE_READDIR, 2679 (macop_t)mac_biba_check_vnode_readdir }, 2680 { MAC_CHECK_VNODE_READLINK, 2681 (macop_t)mac_biba_check_vnode_readlink }, 2682 { MAC_CHECK_VNODE_RELABEL, 2683 (macop_t)mac_biba_check_vnode_relabel }, 2684 { MAC_CHECK_VNODE_RENAME_FROM, 2685 (macop_t)mac_biba_check_vnode_rename_from }, 2686 { MAC_CHECK_VNODE_RENAME_TO, 2687 (macop_t)mac_biba_check_vnode_rename_to }, 2688 { MAC_CHECK_VNODE_REVOKE, 2689 (macop_t)mac_biba_check_vnode_revoke }, 2690 { MAC_CHECK_VNODE_SETACL, 2691 (macop_t)mac_biba_check_vnode_setacl }, 2692 { MAC_CHECK_VNODE_SETEXTATTR, 2693 (macop_t)mac_biba_check_vnode_setextattr }, 2694 { MAC_CHECK_VNODE_SETFLAGS, 2695 (macop_t)mac_biba_check_vnode_setflags }, 2696 { MAC_CHECK_VNODE_SETMODE, 2697 (macop_t)mac_biba_check_vnode_setmode }, 2698 { MAC_CHECK_VNODE_SETOWNER, 2699 (macop_t)mac_biba_check_vnode_setowner }, 2700 { MAC_CHECK_VNODE_SETUTIMES, 2701 (macop_t)mac_biba_check_vnode_setutimes }, 2702 { MAC_CHECK_VNODE_STAT, 2703 (macop_t)mac_biba_check_vnode_stat }, 2704 { MAC_CHECK_VNODE_WRITE, 2705 (macop_t)mac_biba_check_vnode_write }, 2706 { MAC_OP_LAST, NULL } 2707}; 2708 2709MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2710 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
|