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_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_privileged(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_privileged: 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 340static int 341mac_biba_high_single(struct mac_biba *mac_biba) 342{ 343 344 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 345 ("mac_biba_equal_single: mac_biba not single")); 346 347 return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH); 348} 349 350static int 351mac_biba_valid(struct mac_biba *mac_biba) 352{ 353 354 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 355 switch (mac_biba->mb_single.mbe_type) { 356 case MAC_BIBA_TYPE_GRADE: 357 break; 358 359 case MAC_BIBA_TYPE_EQUAL: 360 case MAC_BIBA_TYPE_HIGH: 361 case MAC_BIBA_TYPE_LOW: 362 if (mac_biba->mb_single.mbe_grade != 0 || 363 !MAC_BIBA_BIT_SET_EMPTY( 364 mac_biba->mb_single.mbe_compartments)) 365 return (EINVAL); 366 break; 367 368 default: 369 return (EINVAL); 370 } 371 } else { 372 if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 373 return (EINVAL); 374 } 375 376 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 377 switch (mac_biba->mb_rangelow.mbe_type) { 378 case MAC_BIBA_TYPE_GRADE: 379 break; 380 381 case MAC_BIBA_TYPE_EQUAL: 382 case MAC_BIBA_TYPE_HIGH: 383 case MAC_BIBA_TYPE_LOW: 384 if (mac_biba->mb_rangelow.mbe_grade != 0 || 385 !MAC_BIBA_BIT_SET_EMPTY( 386 mac_biba->mb_rangelow.mbe_compartments)) 387 return (EINVAL); 388 break; 389 390 default: 391 return (EINVAL); 392 } 393 394 switch (mac_biba->mb_rangehigh.mbe_type) { 395 case MAC_BIBA_TYPE_GRADE: 396 break; 397 398 case MAC_BIBA_TYPE_EQUAL: 399 case MAC_BIBA_TYPE_HIGH: 400 case MAC_BIBA_TYPE_LOW: 401 if (mac_biba->mb_rangehigh.mbe_grade != 0 || 402 !MAC_BIBA_BIT_SET_EMPTY( 403 mac_biba->mb_rangehigh.mbe_compartments)) 404 return (EINVAL); 405 break; 406 407 default: 408 return (EINVAL); 409 } 410 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 411 &mac_biba->mb_rangelow)) 412 return (EINVAL); 413 } else { 414 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 415 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 416 return (EINVAL); 417 } 418 419 return (0); 420} 421 422static void 423mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 424 u_short gradelow, u_char *compartmentslow, u_short typehigh, 425 u_short gradehigh, u_char *compartmentshigh) 426{ 427 428 mac_biba->mb_rangelow.mbe_type = typelow; 429 mac_biba->mb_rangelow.mbe_grade = gradelow; 430 if (compartmentslow != NULL) 431 memcpy(mac_biba->mb_rangelow.mbe_compartments, 432 compartmentslow, 433 sizeof(mac_biba->mb_rangelow.mbe_compartments)); 434 mac_biba->mb_rangehigh.mbe_type = typehigh; 435 mac_biba->mb_rangehigh.mbe_grade = gradehigh; 436 if (compartmentshigh != NULL) 437 memcpy(mac_biba->mb_rangehigh.mbe_compartments, 438 compartmentshigh, 439 sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 440 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 441} 442 443static void 444mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 445 u_char *compartments) 446{ 447 448 mac_biba->mb_single.mbe_type = type; 449 mac_biba->mb_single.mbe_grade = grade; 450 if (compartments != NULL) 451 memcpy(mac_biba->mb_single.mbe_compartments, compartments, 452 sizeof(mac_biba->mb_single.mbe_compartments)); 453 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 454} 455 456static void 457mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 458{ 459 460 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 461 ("mac_biba_copy_range: labelfrom not range")); 462 463 labelto->mb_rangelow = labelfrom->mb_rangelow; 464 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 465 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 466} 467 468static void 469mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 470{ 471 472 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 473 ("mac_biba_copy_single: labelfrom not single")); 474 475 labelto->mb_single = labelfrom->mb_single; 476 labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 477} 478 479static void 480mac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 481{ 482 483 if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 484 mac_biba_copy_single(source, dest); 485 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 486 mac_biba_copy_range(source, dest); 487} 488 489/* 490 * Policy module operations. 491 */ 492static void 493mac_biba_destroy(struct mac_policy_conf *conf) 494{ 495 496} 497 498static void 499mac_biba_init(struct mac_policy_conf *conf) 500{ 501 502} 503 504/* 505 * Label operations. 506 */ 507static void 508mac_biba_init_label(struct label *label) 509{ 510 511 SLOT(label) = biba_alloc(M_WAITOK); 512} 513 514static int 515mac_biba_init_label_waitcheck(struct label *label, int flag) 516{ 517 518 SLOT(label) = biba_alloc(flag); 519 if (SLOT(label) == NULL) 520 return (ENOMEM); 521 522 return (0); 523} 524 525static void 526mac_biba_destroy_label(struct label *label) 527{ 528 529 biba_free(SLOT(label)); 530 SLOT(label) = NULL; 531} 532 533/* 534 * mac_biba_element_to_string() is basically an snprintf wrapper with 535 * the same properties as snprintf(). It returns the length it would 536 * have added to the string in the event the string is too short. 537 */ 538static size_t 539mac_biba_element_to_string(char *string, size_t size, 540 struct mac_biba_element *element) 541{ 542 int pos, bit = 1; 543 544 switch (element->mbe_type) { 545 case MAC_BIBA_TYPE_HIGH: 546 return (snprintf(string, size, "high")); 547 548 case MAC_BIBA_TYPE_LOW: 549 return (snprintf(string, size, "low")); 550 551 case MAC_BIBA_TYPE_EQUAL: 552 return (snprintf(string, size, "equal")); 553 554 case MAC_BIBA_TYPE_GRADE: 555 pos = snprintf(string, size, "%d:", element->mbe_grade); 556 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) { 557 if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments)) 558 pos += snprintf(string + pos, size - pos, 559 "%d+", bit); 560 } 561 if (string[pos - 1] == '+' || string[pos - 1] == ':') 562 string[--pos] = '\0'; 563 return (pos); 564 565 default: 566 panic("mac_biba_element_to_string: invalid type (%d)", 567 element->mbe_type); 568 } 569} 570 571static int 572mac_biba_to_string(char *string, size_t size, size_t *caller_len, 573 struct mac_biba *mac_biba) 574{ 575 size_t left, len; 576 char *curptr; 577 578 bzero(string, size); 579 curptr = string; 580 left = size; 581 582 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 583 len = mac_biba_element_to_string(curptr, left, 584 &mac_biba->mb_single); 585 if (len >= left) 586 return (EINVAL); 587 left -= len; 588 curptr += len; 589 } 590 591 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 592 len = snprintf(curptr, left, "("); 593 if (len >= left) 594 return (EINVAL); 595 left -= len; 596 curptr += len; 597 598 len = mac_biba_element_to_string(curptr, left, 599 &mac_biba->mb_rangelow); 600 if (len >= left) 601 return (EINVAL); 602 left -= len; 603 curptr += len; 604 605 len = snprintf(curptr, left, "-"); 606 if (len >= left) 607 return (EINVAL); 608 left -= len; 609 curptr += len; 610 611 len = mac_biba_element_to_string(curptr, left, 612 &mac_biba->mb_rangehigh); 613 if (len >= left) 614 return (EINVAL); 615 left -= len; 616 curptr += len; 617 618 len = snprintf(curptr, left, ")"); 619 if (len >= left) 620 return (EINVAL); 621 left -= len; 622 curptr += len; 623 } 624 625 *caller_len = strlen(string); 626 return (0); 627} 628 629static int 630mac_biba_externalize_label(struct label *label, char *element_name, 631 char *element_data, size_t size, size_t *len, int *claimed) 632{ 633 struct mac_biba *mac_biba; 634 int error; 635 636 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 637 return (0); 638 639 (*claimed)++; 640 641 mac_biba = SLOT(label); 642 error = mac_biba_to_string(element_data, size, len, mac_biba); 643 if (error) 644 return (error); 645 646 *len = strlen(element_data); 647 return (0); 648} 649 650static int 651mac_biba_parse_element(struct mac_biba_element *element, char *string) 652{ 653 654 if (strcmp(string, "high") == 0 || 655 strcmp(string, "hi") == 0) { 656 element->mbe_type = MAC_BIBA_TYPE_HIGH; 657 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 658 } else if (strcmp(string, "low") == 0 || 659 strcmp(string, "lo") == 0) { 660 element->mbe_type = MAC_BIBA_TYPE_LOW; 661 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 662 } else if (strcmp(string, "equal") == 0 || 663 strcmp(string, "eq") == 0) { 664 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 665 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 666 } else { 667 char *p0, *p1; 668 int d; 669 670 p0 = string; 671 d = strtol(p0, &p1, 10); 672 673 if (d < 0 || d > 65535) 674 return (EINVAL); 675 element->mbe_type = MAC_BIBA_TYPE_GRADE; 676 element->mbe_grade = d; 677 678 if (*p1 != ':') { 679 if (p1 == p0 || *p1 != '\0') 680 return (EINVAL); 681 else 682 return (0); 683 } 684 else 685 if (*(p1 + 1) == '\0') 686 return (0); 687 688 while ((p0 = ++p1)) { 689 d = strtol(p0, &p1, 10); 690 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS) 691 return (EINVAL); 692 693 MAC_BIBA_BIT_SET(d, element->mbe_compartments); 694 695 if (*p1 == '\0') 696 break; 697 if (p1 == p0 || *p1 != '+') 698 return (EINVAL); 699 } 700 } 701 702 return (0); 703} 704 705/* 706 * Note: destructively consumes the string, make a local copy before 707 * calling if that's a problem. 708 */ 709static int 710mac_biba_parse(struct mac_biba *mac_biba, char *string) 711{ 712 char *range, *rangeend, *rangehigh, *rangelow, *single; 713 int error; 714 715 /* Do we have a range? */ 716 single = string; 717 range = index(string, '('); 718 if (range == single) 719 single = NULL; 720 rangelow = rangehigh = NULL; 721 if (range != NULL) { 722 /* Nul terminate the end of the single string. */ 723 *range = '\0'; 724 range++; 725 rangelow = range; 726 rangehigh = index(rangelow, '-'); 727 if (rangehigh == NULL) 728 return (EINVAL); 729 rangehigh++; 730 if (*rangelow == '\0' || *rangehigh == '\0') 731 return (EINVAL); 732 rangeend = index(rangehigh, ')'); 733 if (rangeend == NULL) 734 return (EINVAL); 735 if (*(rangeend + 1) != '\0') 736 return (EINVAL); 737 /* Nul terminate the ends of the ranges. */ 738 *(rangehigh - 1) = '\0'; 739 *rangeend = '\0'; 740 } 741 KASSERT((rangelow != NULL && rangehigh != NULL) || 742 (rangelow == NULL && rangehigh == NULL), 743 ("mac_biba_internalize_label: range mismatch")); 744 745 bzero(mac_biba, sizeof(*mac_biba)); 746 if (single != NULL) { 747 error = mac_biba_parse_element(&mac_biba->mb_single, single); 748 if (error) 749 return (error); 750 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 751 } 752 753 if (rangelow != NULL) { 754 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 755 rangelow); 756 if (error) 757 return (error); 758 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 759 rangehigh); 760 if (error) 761 return (error); 762 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 763 } 764 765 error = mac_biba_valid(mac_biba); 766 if (error) 767 return (error); 768 769 return (0); 770} 771 772static int 773mac_biba_internalize_label(struct label *label, char *element_name, 774 char *element_data, int *claimed) 775{ 776 struct mac_biba *mac_biba, mac_biba_temp; 777 int error; 778 779 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 780 return (0); 781 782 (*claimed)++; 783 784 error = mac_biba_parse(&mac_biba_temp, element_data); 785 if (error) 786 return (error); 787 788 mac_biba = SLOT(label); 789 *mac_biba = mac_biba_temp; 790 791 return (0); 792} 793 794static void 795mac_biba_copy_label(struct label *src, struct label *dest) 796{ 797 798 *SLOT(dest) = *SLOT(src); 799} 800 801/* 802 * Labeling event operations: file system objects, and things that look 803 * a lot like file system objects. 804 */ 805static void 806mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 807 struct label *label) 808{ 809 struct mac_biba *mac_biba; 810 int biba_type; 811 812 mac_biba = SLOT(label); 813 if (strcmp(dev->si_name, "null") == 0 || 814 strcmp(dev->si_name, "zero") == 0 || 815 strcmp(dev->si_name, "random") == 0 || 816 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 817 biba_type = MAC_BIBA_TYPE_EQUAL; 818 else if (ptys_equal && 819 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 820 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 821 biba_type = MAC_BIBA_TYPE_EQUAL; 822 else 823 biba_type = MAC_BIBA_TYPE_HIGH; 824 mac_biba_set_single(mac_biba, biba_type, 0, NULL); 825} 826 827static void 828mac_biba_create_devfs_directory(char *dirname, int dirnamelen, 829 struct devfs_dirent *devfs_dirent, struct label *label) 830{ 831 struct mac_biba *mac_biba; 832 833 mac_biba = SLOT(label); 834 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 835} 836 837static void 838mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 839 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) 840{ 841 struct mac_biba *source, *dest; 842 843 source = SLOT(&cred->cr_label); 844 dest = SLOT(delabel); 845 846 mac_biba_copy_single(source, dest); 847} 848 849static void 850mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 851 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 852{ 853 struct mac_biba *source, *dest; 854 855 source = SLOT(direntlabel); 856 dest = SLOT(vnodelabel); 857 mac_biba_copy_single(source, dest); 858} 859 860static void 861mac_biba_create_mount(struct ucred *cred, struct mount *mp, 862 struct label *mntlabel, struct label *fslabel) 863{ 864 struct mac_biba *source, *dest; 865 866 source = SLOT(&cred->cr_label); 867 dest = SLOT(mntlabel); 868 mac_biba_copy_single(source, dest); 869 dest = SLOT(fslabel); 870 mac_biba_copy_single(source, dest); 871} 872 873static void 874mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 875 struct label *mntlabel, struct label *fslabel) 876{ 877 struct mac_biba *mac_biba; 878 879 /* Always mount root as high integrity. */ 880 mac_biba = SLOT(fslabel); 881 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 882 mac_biba = SLOT(mntlabel); 883 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 884} 885 886static void 887mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 888 struct label *vnodelabel, struct label *label) 889{ 890 struct mac_biba *source, *dest; 891 892 source = SLOT(label); 893 dest = SLOT(vnodelabel); 894 895 mac_biba_copy(source, dest); 896} 897 898static void 899mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent, 900 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 901{ 902 struct mac_biba *source, *dest; 903 904 source = SLOT(vnodelabel); 905 dest = SLOT(direntlabel); 906 907 mac_biba_copy(source, dest); 908} 909 910static void 911mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 912 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 913 struct label *vlabel) 914{ 915 struct mac_biba *source, *dest; 916 917 source = SLOT(delabel); 918 dest = SLOT(vlabel); 919 920 mac_biba_copy_single(source, dest); 921} 922 923static int 924mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 925 struct vnode *vp, struct label *vlabel) 926{ 927 struct mac_biba temp, *source, *dest;
| 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_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_privileged(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_privileged: 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 340static int 341mac_biba_high_single(struct mac_biba *mac_biba) 342{ 343 344 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 345 ("mac_biba_equal_single: mac_biba not single")); 346 347 return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH); 348} 349 350static int 351mac_biba_valid(struct mac_biba *mac_biba) 352{ 353 354 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 355 switch (mac_biba->mb_single.mbe_type) { 356 case MAC_BIBA_TYPE_GRADE: 357 break; 358 359 case MAC_BIBA_TYPE_EQUAL: 360 case MAC_BIBA_TYPE_HIGH: 361 case MAC_BIBA_TYPE_LOW: 362 if (mac_biba->mb_single.mbe_grade != 0 || 363 !MAC_BIBA_BIT_SET_EMPTY( 364 mac_biba->mb_single.mbe_compartments)) 365 return (EINVAL); 366 break; 367 368 default: 369 return (EINVAL); 370 } 371 } else { 372 if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 373 return (EINVAL); 374 } 375 376 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 377 switch (mac_biba->mb_rangelow.mbe_type) { 378 case MAC_BIBA_TYPE_GRADE: 379 break; 380 381 case MAC_BIBA_TYPE_EQUAL: 382 case MAC_BIBA_TYPE_HIGH: 383 case MAC_BIBA_TYPE_LOW: 384 if (mac_biba->mb_rangelow.mbe_grade != 0 || 385 !MAC_BIBA_BIT_SET_EMPTY( 386 mac_biba->mb_rangelow.mbe_compartments)) 387 return (EINVAL); 388 break; 389 390 default: 391 return (EINVAL); 392 } 393 394 switch (mac_biba->mb_rangehigh.mbe_type) { 395 case MAC_BIBA_TYPE_GRADE: 396 break; 397 398 case MAC_BIBA_TYPE_EQUAL: 399 case MAC_BIBA_TYPE_HIGH: 400 case MAC_BIBA_TYPE_LOW: 401 if (mac_biba->mb_rangehigh.mbe_grade != 0 || 402 !MAC_BIBA_BIT_SET_EMPTY( 403 mac_biba->mb_rangehigh.mbe_compartments)) 404 return (EINVAL); 405 break; 406 407 default: 408 return (EINVAL); 409 } 410 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 411 &mac_biba->mb_rangelow)) 412 return (EINVAL); 413 } else { 414 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 415 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 416 return (EINVAL); 417 } 418 419 return (0); 420} 421 422static void 423mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 424 u_short gradelow, u_char *compartmentslow, u_short typehigh, 425 u_short gradehigh, u_char *compartmentshigh) 426{ 427 428 mac_biba->mb_rangelow.mbe_type = typelow; 429 mac_biba->mb_rangelow.mbe_grade = gradelow; 430 if (compartmentslow != NULL) 431 memcpy(mac_biba->mb_rangelow.mbe_compartments, 432 compartmentslow, 433 sizeof(mac_biba->mb_rangelow.mbe_compartments)); 434 mac_biba->mb_rangehigh.mbe_type = typehigh; 435 mac_biba->mb_rangehigh.mbe_grade = gradehigh; 436 if (compartmentshigh != NULL) 437 memcpy(mac_biba->mb_rangehigh.mbe_compartments, 438 compartmentshigh, 439 sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 440 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 441} 442 443static void 444mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 445 u_char *compartments) 446{ 447 448 mac_biba->mb_single.mbe_type = type; 449 mac_biba->mb_single.mbe_grade = grade; 450 if (compartments != NULL) 451 memcpy(mac_biba->mb_single.mbe_compartments, compartments, 452 sizeof(mac_biba->mb_single.mbe_compartments)); 453 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 454} 455 456static void 457mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 458{ 459 460 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 461 ("mac_biba_copy_range: labelfrom not range")); 462 463 labelto->mb_rangelow = labelfrom->mb_rangelow; 464 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 465 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 466} 467 468static void 469mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 470{ 471 472 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 473 ("mac_biba_copy_single: labelfrom not single")); 474 475 labelto->mb_single = labelfrom->mb_single; 476 labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 477} 478 479static void 480mac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 481{ 482 483 if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 484 mac_biba_copy_single(source, dest); 485 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 486 mac_biba_copy_range(source, dest); 487} 488 489/* 490 * Policy module operations. 491 */ 492static void 493mac_biba_destroy(struct mac_policy_conf *conf) 494{ 495 496} 497 498static void 499mac_biba_init(struct mac_policy_conf *conf) 500{ 501 502} 503 504/* 505 * Label operations. 506 */ 507static void 508mac_biba_init_label(struct label *label) 509{ 510 511 SLOT(label) = biba_alloc(M_WAITOK); 512} 513 514static int 515mac_biba_init_label_waitcheck(struct label *label, int flag) 516{ 517 518 SLOT(label) = biba_alloc(flag); 519 if (SLOT(label) == NULL) 520 return (ENOMEM); 521 522 return (0); 523} 524 525static void 526mac_biba_destroy_label(struct label *label) 527{ 528 529 biba_free(SLOT(label)); 530 SLOT(label) = NULL; 531} 532 533/* 534 * mac_biba_element_to_string() is basically an snprintf wrapper with 535 * the same properties as snprintf(). It returns the length it would 536 * have added to the string in the event the string is too short. 537 */ 538static size_t 539mac_biba_element_to_string(char *string, size_t size, 540 struct mac_biba_element *element) 541{ 542 int pos, bit = 1; 543 544 switch (element->mbe_type) { 545 case MAC_BIBA_TYPE_HIGH: 546 return (snprintf(string, size, "high")); 547 548 case MAC_BIBA_TYPE_LOW: 549 return (snprintf(string, size, "low")); 550 551 case MAC_BIBA_TYPE_EQUAL: 552 return (snprintf(string, size, "equal")); 553 554 case MAC_BIBA_TYPE_GRADE: 555 pos = snprintf(string, size, "%d:", element->mbe_grade); 556 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) { 557 if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments)) 558 pos += snprintf(string + pos, size - pos, 559 "%d+", bit); 560 } 561 if (string[pos - 1] == '+' || string[pos - 1] == ':') 562 string[--pos] = '\0'; 563 return (pos); 564 565 default: 566 panic("mac_biba_element_to_string: invalid type (%d)", 567 element->mbe_type); 568 } 569} 570 571static int 572mac_biba_to_string(char *string, size_t size, size_t *caller_len, 573 struct mac_biba *mac_biba) 574{ 575 size_t left, len; 576 char *curptr; 577 578 bzero(string, size); 579 curptr = string; 580 left = size; 581 582 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 583 len = mac_biba_element_to_string(curptr, left, 584 &mac_biba->mb_single); 585 if (len >= left) 586 return (EINVAL); 587 left -= len; 588 curptr += len; 589 } 590 591 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 592 len = snprintf(curptr, left, "("); 593 if (len >= left) 594 return (EINVAL); 595 left -= len; 596 curptr += len; 597 598 len = mac_biba_element_to_string(curptr, left, 599 &mac_biba->mb_rangelow); 600 if (len >= left) 601 return (EINVAL); 602 left -= len; 603 curptr += len; 604 605 len = snprintf(curptr, left, "-"); 606 if (len >= left) 607 return (EINVAL); 608 left -= len; 609 curptr += len; 610 611 len = mac_biba_element_to_string(curptr, left, 612 &mac_biba->mb_rangehigh); 613 if (len >= left) 614 return (EINVAL); 615 left -= len; 616 curptr += len; 617 618 len = snprintf(curptr, left, ")"); 619 if (len >= left) 620 return (EINVAL); 621 left -= len; 622 curptr += len; 623 } 624 625 *caller_len = strlen(string); 626 return (0); 627} 628 629static int 630mac_biba_externalize_label(struct label *label, char *element_name, 631 char *element_data, size_t size, size_t *len, int *claimed) 632{ 633 struct mac_biba *mac_biba; 634 int error; 635 636 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 637 return (0); 638 639 (*claimed)++; 640 641 mac_biba = SLOT(label); 642 error = mac_biba_to_string(element_data, size, len, mac_biba); 643 if (error) 644 return (error); 645 646 *len = strlen(element_data); 647 return (0); 648} 649 650static int 651mac_biba_parse_element(struct mac_biba_element *element, char *string) 652{ 653 654 if (strcmp(string, "high") == 0 || 655 strcmp(string, "hi") == 0) { 656 element->mbe_type = MAC_BIBA_TYPE_HIGH; 657 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 658 } else if (strcmp(string, "low") == 0 || 659 strcmp(string, "lo") == 0) { 660 element->mbe_type = MAC_BIBA_TYPE_LOW; 661 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 662 } else if (strcmp(string, "equal") == 0 || 663 strcmp(string, "eq") == 0) { 664 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 665 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 666 } else { 667 char *p0, *p1; 668 int d; 669 670 p0 = string; 671 d = strtol(p0, &p1, 10); 672 673 if (d < 0 || d > 65535) 674 return (EINVAL); 675 element->mbe_type = MAC_BIBA_TYPE_GRADE; 676 element->mbe_grade = d; 677 678 if (*p1 != ':') { 679 if (p1 == p0 || *p1 != '\0') 680 return (EINVAL); 681 else 682 return (0); 683 } 684 else 685 if (*(p1 + 1) == '\0') 686 return (0); 687 688 while ((p0 = ++p1)) { 689 d = strtol(p0, &p1, 10); 690 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS) 691 return (EINVAL); 692 693 MAC_BIBA_BIT_SET(d, element->mbe_compartments); 694 695 if (*p1 == '\0') 696 break; 697 if (p1 == p0 || *p1 != '+') 698 return (EINVAL); 699 } 700 } 701 702 return (0); 703} 704 705/* 706 * Note: destructively consumes the string, make a local copy before 707 * calling if that's a problem. 708 */ 709static int 710mac_biba_parse(struct mac_biba *mac_biba, char *string) 711{ 712 char *range, *rangeend, *rangehigh, *rangelow, *single; 713 int error; 714 715 /* Do we have a range? */ 716 single = string; 717 range = index(string, '('); 718 if (range == single) 719 single = NULL; 720 rangelow = rangehigh = NULL; 721 if (range != NULL) { 722 /* Nul terminate the end of the single string. */ 723 *range = '\0'; 724 range++; 725 rangelow = range; 726 rangehigh = index(rangelow, '-'); 727 if (rangehigh == NULL) 728 return (EINVAL); 729 rangehigh++; 730 if (*rangelow == '\0' || *rangehigh == '\0') 731 return (EINVAL); 732 rangeend = index(rangehigh, ')'); 733 if (rangeend == NULL) 734 return (EINVAL); 735 if (*(rangeend + 1) != '\0') 736 return (EINVAL); 737 /* Nul terminate the ends of the ranges. */ 738 *(rangehigh - 1) = '\0'; 739 *rangeend = '\0'; 740 } 741 KASSERT((rangelow != NULL && rangehigh != NULL) || 742 (rangelow == NULL && rangehigh == NULL), 743 ("mac_biba_internalize_label: range mismatch")); 744 745 bzero(mac_biba, sizeof(*mac_biba)); 746 if (single != NULL) { 747 error = mac_biba_parse_element(&mac_biba->mb_single, single); 748 if (error) 749 return (error); 750 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 751 } 752 753 if (rangelow != NULL) { 754 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 755 rangelow); 756 if (error) 757 return (error); 758 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 759 rangehigh); 760 if (error) 761 return (error); 762 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 763 } 764 765 error = mac_biba_valid(mac_biba); 766 if (error) 767 return (error); 768 769 return (0); 770} 771 772static int 773mac_biba_internalize_label(struct label *label, char *element_name, 774 char *element_data, int *claimed) 775{ 776 struct mac_biba *mac_biba, mac_biba_temp; 777 int error; 778 779 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 780 return (0); 781 782 (*claimed)++; 783 784 error = mac_biba_parse(&mac_biba_temp, element_data); 785 if (error) 786 return (error); 787 788 mac_biba = SLOT(label); 789 *mac_biba = mac_biba_temp; 790 791 return (0); 792} 793 794static void 795mac_biba_copy_label(struct label *src, struct label *dest) 796{ 797 798 *SLOT(dest) = *SLOT(src); 799} 800 801/* 802 * Labeling event operations: file system objects, and things that look 803 * a lot like file system objects. 804 */ 805static void 806mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 807 struct label *label) 808{ 809 struct mac_biba *mac_biba; 810 int biba_type; 811 812 mac_biba = SLOT(label); 813 if (strcmp(dev->si_name, "null") == 0 || 814 strcmp(dev->si_name, "zero") == 0 || 815 strcmp(dev->si_name, "random") == 0 || 816 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 817 biba_type = MAC_BIBA_TYPE_EQUAL; 818 else if (ptys_equal && 819 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 820 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 821 biba_type = MAC_BIBA_TYPE_EQUAL; 822 else 823 biba_type = MAC_BIBA_TYPE_HIGH; 824 mac_biba_set_single(mac_biba, biba_type, 0, NULL); 825} 826 827static void 828mac_biba_create_devfs_directory(char *dirname, int dirnamelen, 829 struct devfs_dirent *devfs_dirent, struct label *label) 830{ 831 struct mac_biba *mac_biba; 832 833 mac_biba = SLOT(label); 834 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 835} 836 837static void 838mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 839 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) 840{ 841 struct mac_biba *source, *dest; 842 843 source = SLOT(&cred->cr_label); 844 dest = SLOT(delabel); 845 846 mac_biba_copy_single(source, dest); 847} 848 849static void 850mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 851 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 852{ 853 struct mac_biba *source, *dest; 854 855 source = SLOT(direntlabel); 856 dest = SLOT(vnodelabel); 857 mac_biba_copy_single(source, dest); 858} 859 860static void 861mac_biba_create_mount(struct ucred *cred, struct mount *mp, 862 struct label *mntlabel, struct label *fslabel) 863{ 864 struct mac_biba *source, *dest; 865 866 source = SLOT(&cred->cr_label); 867 dest = SLOT(mntlabel); 868 mac_biba_copy_single(source, dest); 869 dest = SLOT(fslabel); 870 mac_biba_copy_single(source, dest); 871} 872 873static void 874mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 875 struct label *mntlabel, struct label *fslabel) 876{ 877 struct mac_biba *mac_biba; 878 879 /* Always mount root as high integrity. */ 880 mac_biba = SLOT(fslabel); 881 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 882 mac_biba = SLOT(mntlabel); 883 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 884} 885 886static void 887mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 888 struct label *vnodelabel, struct label *label) 889{ 890 struct mac_biba *source, *dest; 891 892 source = SLOT(label); 893 dest = SLOT(vnodelabel); 894 895 mac_biba_copy(source, dest); 896} 897 898static void 899mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent, 900 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 901{ 902 struct mac_biba *source, *dest; 903 904 source = SLOT(vnodelabel); 905 dest = SLOT(direntlabel); 906 907 mac_biba_copy(source, dest); 908} 909 910static void 911mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 912 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 913 struct label *vlabel) 914{ 915 struct mac_biba *source, *dest; 916 917 source = SLOT(delabel); 918 dest = SLOT(vlabel); 919 920 mac_biba_copy_single(source, dest); 921} 922 923static int 924mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 925 struct vnode *vp, struct label *vlabel) 926{ 927 struct mac_biba temp, *source, *dest;
|
930 931 source = SLOT(fslabel); 932 dest = SLOT(vlabel); 933 934 buflen = sizeof(temp); 935 bzero(&temp, buflen); 936 937 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 938 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 939 if (error == ENOATTR || error == EOPNOTSUPP) { 940 /* Fall back to the fslabel. */ 941 mac_biba_copy_single(source, dest); 942 return (0); 943 } else if (error) 944 return (error); 945 946 if (buflen != sizeof(temp)) { 947 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 948 buflen); 949 return (EPERM); 950 } 951 if (mac_biba_valid(&temp) != 0) { 952 printf("mac_biba_associate_vnode_extattr: invalid\n"); 953 return (EPERM); 954 } 955 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 956 printf("mac_biba_associate_vnode_extattr: not single\n"); 957 return (EPERM); 958 } 959 960 mac_biba_copy_single(&temp, dest); 961 return (0); 962} 963 964static void 965mac_biba_associate_vnode_singlelabel(struct mount *mp, 966 struct label *fslabel, struct vnode *vp, struct label *vlabel) 967{ 968 struct mac_biba *source, *dest; 969 970 source = SLOT(fslabel); 971 dest = SLOT(vlabel); 972 973 mac_biba_copy_single(source, dest); 974} 975 976static int 977mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 978 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 979 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 980{ 981 struct mac_biba *source, *dest, temp; 982 size_t buflen; 983 int error; 984 985 buflen = sizeof(temp); 986 bzero(&temp, buflen); 987 988 source = SLOT(&cred->cr_label); 989 dest = SLOT(vlabel); 990 mac_biba_copy_single(source, &temp); 991 992 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 993 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 994 if (error == 0) 995 mac_biba_copy_single(source, dest); 996 return (error); 997} 998 999static int 1000mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1001 struct label *vlabel, struct label *intlabel) 1002{ 1003 struct mac_biba *source, temp; 1004 size_t buflen; 1005 int error; 1006 1007 buflen = sizeof(temp); 1008 bzero(&temp, buflen); 1009 1010 source = SLOT(intlabel); 1011 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 1012 return (0); 1013 1014 mac_biba_copy_single(source, &temp); 1015 1016 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 1017 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 1018 return (error); 1019} 1020 1021/* 1022 * Labeling event operations: IPC object. 1023 */ 1024static void 1025mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1026 struct mbuf *m, struct label *mbuflabel) 1027{ 1028 struct mac_biba *source, *dest; 1029 1030 source = SLOT(socketlabel); 1031 dest = SLOT(mbuflabel); 1032 1033 mac_biba_copy_single(source, dest); 1034} 1035 1036static void 1037mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1038 struct label *socketlabel) 1039{ 1040 struct mac_biba *source, *dest; 1041 1042 source = SLOT(&cred->cr_label); 1043 dest = SLOT(socketlabel); 1044 1045 mac_biba_copy_single(source, dest); 1046} 1047 1048static void 1049mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1050 struct label *pipelabel) 1051{ 1052 struct mac_biba *source, *dest; 1053 1054 source = SLOT(&cred->cr_label); 1055 dest = SLOT(pipelabel); 1056 1057 mac_biba_copy_single(source, dest); 1058} 1059 1060static void 1061mac_biba_create_socket_from_socket(struct socket *oldsocket, 1062 struct label *oldsocketlabel, struct socket *newsocket, 1063 struct label *newsocketlabel) 1064{ 1065 struct mac_biba *source, *dest; 1066 1067 source = SLOT(oldsocketlabel); 1068 dest = SLOT(newsocketlabel); 1069 1070 mac_biba_copy_single(source, dest); 1071} 1072 1073static void 1074mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1075 struct label *socketlabel, struct label *newlabel) 1076{ 1077 struct mac_biba *source, *dest; 1078 1079 source = SLOT(newlabel); 1080 dest = SLOT(socketlabel); 1081 1082 mac_biba_copy(source, dest); 1083} 1084 1085static void 1086mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1087 struct label *pipelabel, struct label *newlabel) 1088{ 1089 struct mac_biba *source, *dest; 1090 1091 source = SLOT(newlabel); 1092 dest = SLOT(pipelabel); 1093 1094 mac_biba_copy(source, dest); 1095} 1096 1097static void 1098mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1099 struct socket *socket, struct label *socketpeerlabel) 1100{ 1101 struct mac_biba *source, *dest; 1102 1103 source = SLOT(mbuflabel); 1104 dest = SLOT(socketpeerlabel); 1105 1106 mac_biba_copy_single(source, dest); 1107} 1108 1109/* 1110 * Labeling event operations: network objects. 1111 */ 1112static void 1113mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1114 struct label *oldsocketlabel, struct socket *newsocket, 1115 struct label *newsocketpeerlabel) 1116{ 1117 struct mac_biba *source, *dest; 1118 1119 source = SLOT(oldsocketlabel); 1120 dest = SLOT(newsocketpeerlabel); 1121 1122 mac_biba_copy_single(source, dest); 1123} 1124 1125static void 1126mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1127 struct label *bpflabel) 1128{ 1129 struct mac_biba *source, *dest; 1130 1131 source = SLOT(&cred->cr_label); 1132 dest = SLOT(bpflabel); 1133 1134 mac_biba_copy_single(source, dest); 1135} 1136 1137static void 1138mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1139{ 1140 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1141 char tiflist[sizeof(trusted_interfaces)]; 1142 struct mac_biba *dest; 1143 int len, grade; 1144 1145 dest = SLOT(ifnetlabel); 1146 1147 if (ifnet->if_type == IFT_LOOP) { 1148 grade = MAC_BIBA_TYPE_EQUAL; 1149 goto set; 1150 } 1151 1152 if (trust_all_interfaces) { 1153 grade = MAC_BIBA_TYPE_HIGH; 1154 goto set; 1155 } 1156 1157 grade = MAC_BIBA_TYPE_LOW; 1158 1159 if (trusted_interfaces[0] == '\0' || 1160 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1161 goto set; 1162 1163 bzero(tiflist, sizeof(tiflist)); 1164 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1165 if(*p != ' ' && *p != '\t') 1166 *q = *p; 1167 1168 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1169 1170 for (p = q = tiflist;; p++) { 1171 if (*p == ',' || *p == '\0') { 1172 len = p - q; 1173 if (len < IFNAMSIZ) { 1174 bzero(tifname, sizeof(tifname)); 1175 bcopy(q, tifname, len); 1176 if (strcmp(tifname, ifname) == 0) { 1177 grade = MAC_BIBA_TYPE_HIGH; 1178 break; 1179 } 1180 } else { 1181 *p = '\0'; 1182 printf("mac_biba warning: interface name " 1183 "\"%s\" is too long (must be < %d)\n", 1184 q, IFNAMSIZ); 1185 } 1186 if (*p == '\0') 1187 break; 1188 q = p + 1; 1189 } 1190 } 1191set: 1192 mac_biba_set_single(dest, grade, 0, NULL); 1193 mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL); 1194} 1195 1196static void 1197mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1198 struct ipq *ipq, struct label *ipqlabel) 1199{ 1200 struct mac_biba *source, *dest; 1201 1202 source = SLOT(fragmentlabel); 1203 dest = SLOT(ipqlabel); 1204 1205 mac_biba_copy_single(source, dest); 1206} 1207 1208static void 1209mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1210 struct mbuf *datagram, struct label *datagramlabel) 1211{ 1212 struct mac_biba *source, *dest; 1213 1214 source = SLOT(ipqlabel); 1215 dest = SLOT(datagramlabel); 1216 1217 /* Just use the head, since we require them all to match. */ 1218 mac_biba_copy_single(source, dest); 1219} 1220 1221static void 1222mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1223 struct mbuf *fragment, struct label *fragmentlabel) 1224{ 1225 struct mac_biba *source, *dest; 1226 1227 source = SLOT(datagramlabel); 1228 dest = SLOT(fragmentlabel); 1229 1230 mac_biba_copy_single(source, dest); 1231} 1232 1233static void 1234mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1235 struct label *oldmbuflabel, struct mbuf *newmbuf, 1236 struct label *newmbuflabel) 1237{ 1238 struct mac_biba *source, *dest; 1239 1240 source = SLOT(oldmbuflabel); 1241 dest = SLOT(newmbuflabel); 1242 1243 /* 1244 * Because the source mbuf may not yet have been "created", 1245 * just initialized, we do a conditional copy. Since we don't 1246 * allow mbufs to have ranges, do a KASSERT to make sure that 1247 * doesn't happen. 1248 */ 1249 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1250 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1251 mac_biba_copy(source, dest); 1252} 1253 1254static void 1255mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1256 struct mbuf *mbuf, struct label *mbuflabel) 1257{ 1258 struct mac_biba *dest; 1259 1260 dest = SLOT(mbuflabel); 1261 1262 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1263} 1264 1265static void 1266mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1267 struct mbuf *mbuf, struct label *mbuflabel) 1268{ 1269 struct mac_biba *source, *dest; 1270 1271 source = SLOT(bpflabel); 1272 dest = SLOT(mbuflabel); 1273 1274 mac_biba_copy_single(source, dest); 1275} 1276 1277static void 1278mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1279 struct mbuf *m, struct label *mbuflabel) 1280{ 1281 struct mac_biba *source, *dest; 1282 1283 source = SLOT(ifnetlabel); 1284 dest = SLOT(mbuflabel); 1285 1286 mac_biba_copy_single(source, dest); 1287} 1288 1289static void 1290mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1291 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1292 struct mbuf *newmbuf, struct label *newmbuflabel) 1293{ 1294 struct mac_biba *source, *dest; 1295 1296 source = SLOT(oldmbuflabel); 1297 dest = SLOT(newmbuflabel); 1298 1299 mac_biba_copy_single(source, dest); 1300} 1301 1302static void 1303mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1304 struct mbuf *newmbuf, struct label *newmbuflabel) 1305{ 1306 struct mac_biba *source, *dest; 1307 1308 source = SLOT(oldmbuflabel); 1309 dest = SLOT(newmbuflabel); 1310 1311 mac_biba_copy_single(source, dest); 1312} 1313 1314static int 1315mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1316 struct ipq *ipq, struct label *ipqlabel) 1317{ 1318 struct mac_biba *a, *b; 1319 1320 a = SLOT(ipqlabel); 1321 b = SLOT(fragmentlabel); 1322 1323 return (mac_biba_equal_single(a, b)); 1324} 1325 1326static void 1327mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1328 struct label *ifnetlabel, struct label *newlabel) 1329{ 1330 struct mac_biba *source, *dest; 1331 1332 source = SLOT(newlabel); 1333 dest = SLOT(ifnetlabel); 1334 1335 mac_biba_copy(source, dest); 1336} 1337 1338static void 1339mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1340 struct ipq *ipq, struct label *ipqlabel) 1341{ 1342 1343 /* NOOP: we only accept matching labels, so no need to update */ 1344} 1345 1346/* 1347 * Labeling event operations: processes. 1348 */ 1349static void 1350mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1351{ 1352 struct mac_biba *source, *dest; 1353 1354 source = SLOT(&cred_parent->cr_label); 1355 dest = SLOT(&cred_child->cr_label); 1356 1357 mac_biba_copy_single(source, dest); 1358 mac_biba_copy_range(source, dest); 1359} 1360 1361static void 1362mac_biba_execve_transition(struct ucred *old, struct ucred *new, 1363 struct vnode *vp, struct label *vnodelabel) 1364{ 1365 struct mac_biba *source, *dest; 1366 1367 source = SLOT(&old->cr_label); 1368 dest = SLOT(&new->cr_label); 1369 1370 mac_biba_copy_single(source, dest); 1371 mac_biba_copy_range(source, dest); 1372} 1373 1374static int 1375mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp, 1376 struct label *vnodelabel) 1377{ 1378 1379 return (0); 1380} 1381 1382static void 1383mac_biba_create_proc0(struct ucred *cred) 1384{ 1385 struct mac_biba *dest; 1386 1387 dest = SLOT(&cred->cr_label); 1388 1389 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1390 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1391 MAC_BIBA_TYPE_HIGH, 0, NULL); 1392} 1393 1394static void 1395mac_biba_create_proc1(struct ucred *cred) 1396{ 1397 struct mac_biba *dest; 1398 1399 dest = SLOT(&cred->cr_label); 1400 1401 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1402 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1403 MAC_BIBA_TYPE_HIGH, 0, NULL); 1404} 1405 1406static void 1407mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1408{ 1409 struct mac_biba *source, *dest; 1410 1411 source = SLOT(newlabel); 1412 dest = SLOT(&cred->cr_label); 1413 1414 mac_biba_copy(source, dest); 1415} 1416 1417/* 1418 * Access control checks. 1419 */ 1420static int 1421mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1422 struct ifnet *ifnet, struct label *ifnetlabel) 1423{ 1424 struct mac_biba *a, *b; 1425 1426 if (!mac_biba_enabled) 1427 return (0); 1428 1429 a = SLOT(bpflabel); 1430 b = SLOT(ifnetlabel); 1431 1432 if (mac_biba_equal_single(a, b)) 1433 return (0); 1434 return (EACCES); 1435} 1436 1437static int 1438mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1439{ 1440 struct mac_biba *subj, *new; 1441 int error; 1442 1443 subj = SLOT(&cred->cr_label); 1444 new = SLOT(newlabel); 1445 1446 /* 1447 * If there is a Biba label update for the credential, it may 1448 * be an update of the single, range, or both. 1449 */ 1450 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1451 if (error) 1452 return (error); 1453 1454 /* 1455 * If the Biba label is to be changed, authorize as appropriate. 1456 */ 1457 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1458 /* 1459 * To change the Biba single label on a credential, the 1460 * new single label must be in the current range. 1461 */ 1462 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1463 !mac_biba_single_in_range(new, subj)) 1464 return (EPERM); 1465 1466 /* 1467 * To change the Biba range on a credential, the new 1468 * range label must be in the current range. 1469 */ 1470 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1471 !mac_biba_range_in_range(new, subj)) 1472 return (EPERM); 1473 1474 /* 1475 * To have EQUAL in any component of the new credential 1476 * Biba label, the subject must already have EQUAL in 1477 * their label. 1478 */ 1479 if (mac_biba_contains_equal(new)) { 1480 error = mac_biba_subject_privileged(subj); 1481 if (error) 1482 return (error); 1483 } 1484 1485 /* 1486 * XXXMAC: Additional consistency tests regarding the 1487 * single and range of the new label might be performed 1488 * here. 1489 */ 1490 } 1491 1492 return (0); 1493} 1494 1495static int 1496mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1497{ 1498 struct mac_biba *subj, *obj; 1499 1500 if (!mac_biba_enabled) 1501 return (0); 1502 1503 subj = SLOT(&u1->cr_label); 1504 obj = SLOT(&u2->cr_label); 1505 1506 /* XXX: range */ 1507 if (!mac_biba_dominate_single(obj, subj)) 1508 return (ESRCH); 1509 1510 return (0); 1511} 1512 1513static int 1514mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1515 struct label *ifnetlabel, struct label *newlabel) 1516{ 1517 struct mac_biba *subj, *new; 1518 int error; 1519 1520 subj = SLOT(&cred->cr_label); 1521 new = SLOT(newlabel); 1522 1523 /* 1524 * If there is a Biba label update for the interface, it may 1525 * be an update of the single, range, or both. 1526 */ 1527 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1528 if (error) 1529 return (error); 1530 1531 /* 1532 * Relabling network interfaces requires Biba privilege. 1533 */ 1534 error = mac_biba_subject_privileged(subj); 1535 if (error) 1536 return (error); 1537 1538 /* 1539 * If the Biba label is to be changed, authorize as appropriate. 1540 */ 1541 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1542 /* 1543 * Rely on the traditional superuser status for the Biba 1544 * interface relabel requirements. XXXMAC: This will go 1545 * away. 1546 */ 1547 error = suser_cred(cred, 0); 1548 if (error) 1549 return (EPERM); 1550 1551 /* 1552 * XXXMAC: Additional consistency tests regarding the single 1553 * and the range of the new label might be performed here. 1554 */ 1555 } 1556 1557 return (0); 1558} 1559 1560static int 1561mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1562 struct mbuf *m, struct label *mbuflabel) 1563{ 1564 struct mac_biba *p, *i; 1565 1566 if (!mac_biba_enabled) 1567 return (0); 1568 1569 p = SLOT(mbuflabel); 1570 i = SLOT(ifnetlabel); 1571 1572 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1573} 1574 1575static int 1576mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1577 struct label *mntlabel) 1578{ 1579 struct mac_biba *subj, *obj; 1580 1581 if (!mac_biba_enabled) 1582 return (0); 1583 1584 subj = SLOT(&cred->cr_label); 1585 obj = SLOT(mntlabel); 1586 1587 if (!mac_biba_dominate_single(obj, subj)) 1588 return (EACCES); 1589 1590 return (0); 1591} 1592 1593static int 1594mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1595 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1596{ 1597 1598 if(!mac_biba_enabled) 1599 return (0); 1600 1601 /* XXX: This will be implemented soon... */ 1602 1603 return (0); 1604} 1605 1606static int 1607mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1608 struct label *pipelabel) 1609{ 1610 struct mac_biba *subj, *obj; 1611 1612 if (!mac_biba_enabled) 1613 return (0); 1614 1615 subj = SLOT(&cred->cr_label); 1616 obj = SLOT((pipelabel)); 1617 1618 if (!mac_biba_dominate_single(obj, subj)) 1619 return (EACCES); 1620 1621 return (0); 1622} 1623 1624static int 1625mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1626 struct label *pipelabel) 1627{ 1628 struct mac_biba *subj, *obj; 1629 1630 if (!mac_biba_enabled) 1631 return (0); 1632 1633 subj = SLOT(&cred->cr_label); 1634 obj = SLOT((pipelabel)); 1635 1636 if (!mac_biba_dominate_single(obj, subj)) 1637 return (EACCES); 1638 1639 return (0); 1640} 1641 1642static int 1643mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1644 struct label *pipelabel, struct label *newlabel) 1645{ 1646 struct mac_biba *subj, *obj, *new; 1647 int error; 1648 1649 new = SLOT(newlabel); 1650 subj = SLOT(&cred->cr_label); 1651 obj = SLOT(pipelabel); 1652 1653 /* 1654 * If there is a Biba label update for a pipe, it must be a 1655 * single update. 1656 */ 1657 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1658 if (error) 1659 return (error); 1660 1661 /* 1662 * To perform a relabel of a pipe (Biba label or not), Biba must 1663 * authorize the relabel. 1664 */ 1665 if (!mac_biba_single_in_range(obj, subj)) 1666 return (EPERM); 1667 1668 /* 1669 * If the Biba label is to be changed, authorize as appropriate. 1670 */ 1671 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1672 /* 1673 * To change the Biba label on a pipe, the new pipe label 1674 * must be in the subject range. 1675 */ 1676 if (!mac_biba_single_in_range(new, subj)) 1677 return (EPERM); 1678 1679 /* 1680 * To change the Biba label on a pipe to be EQUAL, the 1681 * subject must have appropriate privilege. 1682 */ 1683 if (mac_biba_contains_equal(new)) { 1684 error = mac_biba_subject_privileged(subj); 1685 if (error) 1686 return (error); 1687 } 1688 } 1689 1690 return (0); 1691} 1692 1693static int 1694mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1695 struct label *pipelabel) 1696{ 1697 struct mac_biba *subj, *obj; 1698 1699 if (!mac_biba_enabled) 1700 return (0); 1701 1702 subj = SLOT(&cred->cr_label); 1703 obj = SLOT((pipelabel)); 1704 1705 if (!mac_biba_dominate_single(obj, subj)) 1706 return (EACCES); 1707 1708 return (0); 1709} 1710 1711static int 1712mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1713 struct label *pipelabel) 1714{ 1715 struct mac_biba *subj, *obj; 1716 1717 if (!mac_biba_enabled) 1718 return (0); 1719 1720 subj = SLOT(&cred->cr_label); 1721 obj = SLOT((pipelabel)); 1722 1723 if (!mac_biba_dominate_single(subj, obj)) 1724 return (EACCES); 1725 1726 return (0); 1727} 1728 1729static int 1730mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1731{ 1732 struct mac_biba *subj, *obj; 1733 1734 if (!mac_biba_enabled) 1735 return (0); 1736 1737 subj = SLOT(&cred->cr_label); 1738 obj = SLOT(&proc->p_ucred->cr_label); 1739 1740 /* XXX: range checks */ 1741 if (!mac_biba_dominate_single(obj, subj)) 1742 return (ESRCH); 1743 if (!mac_biba_dominate_single(subj, obj)) 1744 return (EACCES); 1745 1746 return (0); 1747} 1748 1749static int 1750mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1751{ 1752 struct mac_biba *subj, *obj; 1753 1754 if (!mac_biba_enabled) 1755 return (0); 1756 1757 subj = SLOT(&cred->cr_label); 1758 obj = SLOT(&proc->p_ucred->cr_label); 1759 1760 /* XXX: range checks */ 1761 if (!mac_biba_dominate_single(obj, subj)) 1762 return (ESRCH); 1763 if (!mac_biba_dominate_single(subj, obj)) 1764 return (EACCES); 1765 1766 return (0); 1767} 1768 1769static int 1770mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1771{ 1772 struct mac_biba *subj, *obj; 1773 1774 if (!mac_biba_enabled) 1775 return (0); 1776 1777 subj = SLOT(&cred->cr_label); 1778 obj = SLOT(&proc->p_ucred->cr_label); 1779 1780 /* XXX: range checks */ 1781 if (!mac_biba_dominate_single(obj, subj)) 1782 return (ESRCH); 1783 if (!mac_biba_dominate_single(subj, obj)) 1784 return (EACCES); 1785 1786 return (0); 1787} 1788 1789static int 1790mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1791 struct mbuf *m, struct label *mbuflabel) 1792{ 1793 struct mac_biba *p, *s; 1794 1795 if (!mac_biba_enabled) 1796 return (0); 1797 1798 p = SLOT(mbuflabel); 1799 s = SLOT(socketlabel); 1800 1801 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1802} 1803 1804static int 1805mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1806 struct label *socketlabel, struct label *newlabel) 1807{ 1808 struct mac_biba *subj, *obj, *new; 1809 int error; 1810 1811 new = SLOT(newlabel); 1812 subj = SLOT(&cred->cr_label); 1813 obj = SLOT(socketlabel); 1814 1815 /* 1816 * If there is a Biba label update for the socket, it may be 1817 * an update of single. 1818 */ 1819 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1820 if (error) 1821 return (error); 1822 1823 /* 1824 * To relabel a socket, the old socket single must be in the subject 1825 * range. 1826 */ 1827 if (!mac_biba_single_in_range(obj, subj)) 1828 return (EPERM); 1829 1830 /* 1831 * If the Biba label is to be changed, authorize as appropriate. 1832 */ 1833 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1834 /* 1835 * To relabel a socket, the new socket single must be in 1836 * the subject range. 1837 */ 1838 if (!mac_biba_single_in_range(new, subj)) 1839 return (EPERM); 1840 1841 /* 1842 * To change the Biba label on the socket to contain EQUAL, 1843 * the subject must have appropriate privilege. 1844 */ 1845 if (mac_biba_contains_equal(new)) { 1846 error = mac_biba_subject_privileged(subj); 1847 if (error) 1848 return (error); 1849 } 1850 } 1851 1852 return (0); 1853} 1854 1855static int 1856mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1857 struct label *socketlabel) 1858{ 1859 struct mac_biba *subj, *obj; 1860 1861 if (!mac_biba_enabled) 1862 return (0); 1863 1864 subj = SLOT(&cred->cr_label); 1865 obj = SLOT(socketlabel); 1866 1867 if (!mac_biba_dominate_single(obj, subj)) 1868 return (ENOENT); 1869 1870 return (0); 1871} 1872 1873static int 1874mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1875 struct label *label) 1876{ 1877 struct mac_biba *subj, *obj; 1878 1879 if (!mac_biba_enabled) 1880 return (0); 1881 1882 subj = SLOT(&cred->cr_label); 1883 obj = SLOT(label); 1884 1885 if (!mac_biba_subject_privileged(subj)) 1886 return (EPERM); 1887 1888 if (!mac_biba_high_single(obj)) 1889 return (EACCES); 1890 1891 return (0); 1892} 1893 1894static int 1895mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1896 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1897{ 1898 struct mac_biba *subj; 1899 int error; 1900 1901 if (!mac_biba_enabled) 1902 return (0); 1903 1904 subj = SLOT(&cred->cr_label); 1905 1906 /* 1907 * In general, treat sysctl variables as biba/high, but also 1908 * require privilege to change them, since they are a 1909 * communications channel between grades. Exempt MIB 1910 * queries from this due to undocmented sysctl magic. 1911 * XXXMAC: This probably requires some more review. 1912 */ 1913 if (new != NULL) { 1914 if (namelen > 0 && name[0] == 0) 1915 return (0); 1916 1917 if (!mac_biba_subject_dominate_high(subj)) 1918 return (EACCES); 1919 1920 error = mac_biba_subject_privileged(subj); 1921 if (error) 1922 return (error); 1923 } 1924 1925 return (0); 1926} 1927 1928static int 1929mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1930 struct label *dlabel) 1931{ 1932 struct mac_biba *subj, *obj; 1933 1934 if (!mac_biba_enabled) 1935 return (0); 1936 1937 subj = SLOT(&cred->cr_label); 1938 obj = SLOT(dlabel); 1939 1940 if (!mac_biba_dominate_single(obj, subj)) 1941 return (EACCES); 1942 1943 return (0); 1944} 1945 1946static int 1947mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1948 struct label *dlabel) 1949{ 1950 struct mac_biba *subj, *obj; 1951 1952 if (!mac_biba_enabled) 1953 return (0); 1954 1955 subj = SLOT(&cred->cr_label); 1956 obj = SLOT(dlabel); 1957 1958 if (!mac_biba_dominate_single(obj, subj)) 1959 return (EACCES); 1960 1961 return (0); 1962} 1963 1964static int 1965mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1966 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1967{ 1968 struct mac_biba *subj, *obj; 1969 1970 if (!mac_biba_enabled) 1971 return (0); 1972 1973 subj = SLOT(&cred->cr_label); 1974 obj = SLOT(dlabel); 1975 1976 if (!mac_biba_dominate_single(subj, obj)) 1977 return (EACCES); 1978 1979 return (0); 1980} 1981 1982static int 1983mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1984 struct label *dlabel, struct vnode *vp, struct label *label, 1985 struct componentname *cnp) 1986{ 1987 struct mac_biba *subj, *obj; 1988 1989 if (!mac_biba_enabled) 1990 return (0); 1991 1992 subj = SLOT(&cred->cr_label); 1993 obj = SLOT(dlabel); 1994 1995 if (!mac_biba_dominate_single(subj, obj)) 1996 return (EACCES); 1997 1998 obj = SLOT(label); 1999 2000 if (!mac_biba_dominate_single(subj, obj)) 2001 return (EACCES); 2002 2003 return (0); 2004} 2005 2006static int 2007mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2008 struct label *label, acl_type_t type) 2009{ 2010 struct mac_biba *subj, *obj; 2011 2012 if (!mac_biba_enabled) 2013 return (0); 2014 2015 subj = SLOT(&cred->cr_label); 2016 obj = SLOT(label); 2017 2018 if (!mac_biba_dominate_single(subj, obj)) 2019 return (EACCES); 2020 2021 return (0); 2022} 2023 2024static int 2025mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2026 struct label *label) 2027{ 2028 struct mac_biba *subj, *obj; 2029 2030 if (!mac_biba_enabled) 2031 return (0); 2032 2033 subj = SLOT(&cred->cr_label); 2034 obj = SLOT(label); 2035 2036 if (!mac_biba_dominate_single(obj, subj)) 2037 return (EACCES); 2038 2039 return (0); 2040} 2041 2042static int 2043mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2044 struct label *label, acl_type_t type) 2045{ 2046 struct mac_biba *subj, *obj; 2047 2048 if (!mac_biba_enabled) 2049 return (0); 2050 2051 subj = SLOT(&cred->cr_label); 2052 obj = SLOT(label); 2053 2054 if (!mac_biba_dominate_single(obj, subj)) 2055 return (EACCES); 2056 2057 return (0); 2058} 2059 2060static int 2061mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2062 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2063{ 2064 struct mac_biba *subj, *obj; 2065 2066 if (!mac_biba_enabled) 2067 return (0); 2068 2069 subj = SLOT(&cred->cr_label); 2070 obj = SLOT(label); 2071 2072 if (!mac_biba_dominate_single(obj, subj)) 2073 return (EACCES); 2074 2075 return (0); 2076} 2077 2078static int 2079mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2080 struct label *dlabel, struct vnode *vp, struct label *label, 2081 struct componentname *cnp) 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(dlabel); 2090 2091 if (!mac_biba_dominate_single(subj, obj)) 2092 return (EACCES); 2093 2094 obj = SLOT(label); 2095 2096 if (!mac_biba_dominate_single(subj, obj)) 2097 return (EACCES); 2098 2099 return (0); 2100} 2101 2102static int 2103mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2104 struct label *dlabel, struct componentname *cnp) 2105{ 2106 struct mac_biba *subj, *obj; 2107 2108 if (!mac_biba_enabled) 2109 return (0); 2110 2111 subj = SLOT(&cred->cr_label); 2112 obj = SLOT(dlabel); 2113 2114 if (!mac_biba_dominate_single(obj, subj)) 2115 return (EACCES); 2116 2117 return (0); 2118} 2119 2120static int 2121mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2122 struct label *label, int prot) 2123{ 2124 struct mac_biba *subj, *obj; 2125 2126 /* 2127 * Rely on the use of open()-time protections to handle 2128 * non-revocation cases. 2129 */ 2130 if (!mac_biba_enabled || !revocation_enabled) 2131 return (0); 2132 2133 subj = SLOT(&cred->cr_label); 2134 obj = SLOT(label); 2135 2136 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2137 if (!mac_biba_dominate_single(obj, subj)) 2138 return (EACCES); 2139 } 2140 if (prot & VM_PROT_WRITE) { 2141 if (!mac_biba_dominate_single(subj, obj)) 2142 return (EACCES); 2143 } 2144 2145 return (0); 2146} 2147 2148static int 2149mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2150 struct label *vnodelabel, int acc_mode) 2151{ 2152 struct mac_biba *subj, *obj; 2153 2154 if (!mac_biba_enabled) 2155 return (0); 2156 2157 subj = SLOT(&cred->cr_label); 2158 obj = SLOT(vnodelabel); 2159 2160 /* XXX privilege override for admin? */ 2161 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2162 if (!mac_biba_dominate_single(obj, subj)) 2163 return (EACCES); 2164 } 2165 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2166 if (!mac_biba_dominate_single(subj, obj)) 2167 return (EACCES); 2168 } 2169 2170 return (0); 2171} 2172 2173static int 2174mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2175 struct vnode *vp, struct label *label) 2176{ 2177 struct mac_biba *subj, *obj; 2178 2179 if (!mac_biba_enabled || !revocation_enabled) 2180 return (0); 2181 2182 subj = SLOT(&active_cred->cr_label); 2183 obj = SLOT(label); 2184 2185 if (!mac_biba_dominate_single(obj, subj)) 2186 return (EACCES); 2187 2188 return (0); 2189} 2190 2191static int 2192mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2193 struct vnode *vp, struct label *label) 2194{ 2195 struct mac_biba *subj, *obj; 2196 2197 if (!mac_biba_enabled || !revocation_enabled) 2198 return (0); 2199 2200 subj = SLOT(&active_cred->cr_label); 2201 obj = SLOT(label); 2202 2203 if (!mac_biba_dominate_single(obj, subj)) 2204 return (EACCES); 2205 2206 return (0); 2207} 2208 2209static int 2210mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2211 struct label *dlabel) 2212{ 2213 struct mac_biba *subj, *obj; 2214 2215 if (!mac_biba_enabled) 2216 return (0); 2217 2218 subj = SLOT(&cred->cr_label); 2219 obj = SLOT(dlabel); 2220 2221 if (!mac_biba_dominate_single(obj, subj)) 2222 return (EACCES); 2223 2224 return (0); 2225} 2226 2227static int 2228mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2229 struct label *label) 2230{ 2231 struct mac_biba *subj, *obj; 2232 2233 if (!mac_biba_enabled) 2234 return (0); 2235 2236 subj = SLOT(&cred->cr_label); 2237 obj = SLOT(label); 2238 2239 if (!mac_biba_dominate_single(obj, subj)) 2240 return (EACCES); 2241 2242 return (0); 2243} 2244 2245static int 2246mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2247 struct label *vnodelabel, struct label *newlabel) 2248{ 2249 struct mac_biba *old, *new, *subj; 2250 int error; 2251 2252 old = SLOT(vnodelabel); 2253 new = SLOT(newlabel); 2254 subj = SLOT(&cred->cr_label); 2255 2256 /* 2257 * If there is a Biba label update for the vnode, it must be a 2258 * single label. 2259 */ 2260 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2261 if (error) 2262 return (error); 2263 2264 /* 2265 * To perform a relabel of the vnode (Biba label or not), Biba must 2266 * authorize the relabel. 2267 */ 2268 if (!mac_biba_single_in_range(old, subj)) 2269 return (EPERM); 2270 2271 /* 2272 * If the Biba label is to be changed, authorize as appropriate. 2273 */ 2274 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2275 /* 2276 * To change the Biba label on a vnode, the new vnode label 2277 * must be in the subject range. 2278 */ 2279 if (!mac_biba_single_in_range(new, subj)) 2280 return (EPERM); 2281 2282 /* 2283 * To change the Biba label on the vnode to be EQUAL, 2284 * the subject must have appropriate privilege. 2285 */ 2286 if (mac_biba_contains_equal(new)) { 2287 error = mac_biba_subject_privileged(subj); 2288 if (error) 2289 return (error); 2290 } 2291 } 2292 2293 return (0); 2294} 2295 2296static int 2297mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2298 struct label *dlabel, struct vnode *vp, struct label *label, 2299 struct componentname *cnp) 2300{ 2301 struct mac_biba *subj, *obj; 2302 2303 if (!mac_biba_enabled) 2304 return (0); 2305 2306 subj = SLOT(&cred->cr_label); 2307 obj = SLOT(dlabel); 2308 2309 if (!mac_biba_dominate_single(subj, obj)) 2310 return (EACCES); 2311 2312 obj = SLOT(label); 2313 2314 if (!mac_biba_dominate_single(subj, obj)) 2315 return (EACCES); 2316 2317 return (0); 2318} 2319 2320static int 2321mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2322 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2323 struct componentname *cnp) 2324{ 2325 struct mac_biba *subj, *obj; 2326 2327 if (!mac_biba_enabled) 2328 return (0); 2329 2330 subj = SLOT(&cred->cr_label); 2331 obj = SLOT(dlabel); 2332 2333 if (!mac_biba_dominate_single(subj, obj)) 2334 return (EACCES); 2335 2336 if (vp != NULL) { 2337 obj = SLOT(label); 2338 2339 if (!mac_biba_dominate_single(subj, obj)) 2340 return (EACCES); 2341 } 2342 2343 return (0); 2344} 2345 2346static int 2347mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2348 struct label *label) 2349{ 2350 struct mac_biba *subj, *obj; 2351 2352 if (!mac_biba_enabled) 2353 return (0); 2354 2355 subj = SLOT(&cred->cr_label); 2356 obj = SLOT(label); 2357 2358 if (!mac_biba_dominate_single(subj, obj)) 2359 return (EACCES); 2360 2361 return (0); 2362} 2363 2364static int 2365mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2366 struct label *label, acl_type_t type, struct acl *acl) 2367{ 2368 struct mac_biba *subj, *obj; 2369 2370 if (!mac_biba_enabled) 2371 return (0); 2372 2373 subj = SLOT(&cred->cr_label); 2374 obj = SLOT(label); 2375 2376 if (!mac_biba_dominate_single(subj, obj)) 2377 return (EACCES); 2378 2379 return (0); 2380} 2381 2382static int 2383mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2384 struct label *vnodelabel, int attrnamespace, const char *name, 2385 struct uio *uio) 2386{ 2387 struct mac_biba *subj, *obj; 2388 2389 if (!mac_biba_enabled) 2390 return (0); 2391 2392 subj = SLOT(&cred->cr_label); 2393 obj = SLOT(vnodelabel); 2394 2395 if (!mac_biba_dominate_single(subj, obj)) 2396 return (EACCES); 2397 2398 /* XXX: protect the MAC EA in a special way? */ 2399 2400 return (0); 2401} 2402 2403static int 2404mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2405 struct label *vnodelabel, u_long flags) 2406{ 2407 struct mac_biba *subj, *obj; 2408 2409 if (!mac_biba_enabled) 2410 return (0); 2411 2412 subj = SLOT(&cred->cr_label); 2413 obj = SLOT(vnodelabel); 2414 2415 if (!mac_biba_dominate_single(subj, obj)) 2416 return (EACCES); 2417 2418 return (0); 2419} 2420 2421static int 2422mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2423 struct label *vnodelabel, mode_t mode) 2424{ 2425 struct mac_biba *subj, *obj; 2426 2427 if (!mac_biba_enabled) 2428 return (0); 2429 2430 subj = SLOT(&cred->cr_label); 2431 obj = SLOT(vnodelabel); 2432 2433 if (!mac_biba_dominate_single(subj, obj)) 2434 return (EACCES); 2435 2436 return (0); 2437} 2438 2439static int 2440mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2441 struct label *vnodelabel, uid_t uid, gid_t gid) 2442{ 2443 struct mac_biba *subj, *obj; 2444 2445 if (!mac_biba_enabled) 2446 return (0); 2447 2448 subj = SLOT(&cred->cr_label); 2449 obj = SLOT(vnodelabel); 2450 2451 if (!mac_biba_dominate_single(subj, obj)) 2452 return (EACCES); 2453 2454 return (0); 2455} 2456 2457static int 2458mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2459 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2460{ 2461 struct mac_biba *subj, *obj; 2462 2463 if (!mac_biba_enabled) 2464 return (0); 2465 2466 subj = SLOT(&cred->cr_label); 2467 obj = SLOT(vnodelabel); 2468 2469 if (!mac_biba_dominate_single(subj, obj)) 2470 return (EACCES); 2471 2472 return (0); 2473} 2474 2475static int 2476mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2477 struct vnode *vp, struct label *vnodelabel) 2478{ 2479 struct mac_biba *subj, *obj; 2480 2481 if (!mac_biba_enabled) 2482 return (0); 2483 2484 subj = SLOT(&active_cred->cr_label); 2485 obj = SLOT(vnodelabel); 2486 2487 if (!mac_biba_dominate_single(obj, subj)) 2488 return (EACCES); 2489 2490 return (0); 2491} 2492 2493static int 2494mac_biba_check_vnode_write(struct ucred *active_cred, 2495 struct ucred *file_cred, struct vnode *vp, struct label *label) 2496{ 2497 struct mac_biba *subj, *obj; 2498 2499 if (!mac_biba_enabled || !revocation_enabled) 2500 return (0); 2501 2502 subj = SLOT(&active_cred->cr_label); 2503 obj = SLOT(label); 2504 2505 if (!mac_biba_dominate_single(subj, obj)) 2506 return (EACCES); 2507 2508 return (0); 2509} 2510 2511static struct mac_policy_ops mac_biba_ops = 2512{ 2513 .mpo_destroy = mac_biba_destroy, 2514 .mpo_init = mac_biba_init, 2515 .mpo_init_bpfdesc_label = mac_biba_init_label, 2516 .mpo_init_cred_label = mac_biba_init_label, 2517 .mpo_init_devfsdirent_label = mac_biba_init_label, 2518 .mpo_init_ifnet_label = mac_biba_init_label, 2519 .mpo_init_ipq_label = mac_biba_init_label, 2520 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2521 .mpo_init_mount_label = mac_biba_init_label, 2522 .mpo_init_mount_fs_label = mac_biba_init_label, 2523 .mpo_init_pipe_label = mac_biba_init_label, 2524 .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2525 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2526 .mpo_init_vnode_label = mac_biba_init_label, 2527 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2528 .mpo_destroy_cred_label = mac_biba_destroy_label, 2529 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2530 .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2531 .mpo_destroy_ipq_label = mac_biba_destroy_label, 2532 .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2533 .mpo_destroy_mount_label = mac_biba_destroy_label, 2534 .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2535 .mpo_destroy_pipe_label = mac_biba_destroy_label, 2536 .mpo_destroy_socket_label = mac_biba_destroy_label, 2537 .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2538 .mpo_destroy_vnode_label = mac_biba_destroy_label, 2539 .mpo_copy_pipe_label = mac_biba_copy_label, 2540 .mpo_copy_vnode_label = mac_biba_copy_label, 2541 .mpo_externalize_cred_label = mac_biba_externalize_label, 2542 .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2543 .mpo_externalize_pipe_label = mac_biba_externalize_label, 2544 .mpo_externalize_socket_label = mac_biba_externalize_label, 2545 .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2546 .mpo_externalize_vnode_label = mac_biba_externalize_label, 2547 .mpo_internalize_cred_label = mac_biba_internalize_label, 2548 .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2549 .mpo_internalize_pipe_label = mac_biba_internalize_label, 2550 .mpo_internalize_socket_label = mac_biba_internalize_label, 2551 .mpo_internalize_vnode_label = mac_biba_internalize_label, 2552 .mpo_create_devfs_device = mac_biba_create_devfs_device, 2553 .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2554 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2555 .mpo_create_devfs_vnode = mac_biba_create_devfs_vnode, 2556 .mpo_create_mount = mac_biba_create_mount, 2557 .mpo_create_root_mount = mac_biba_create_root_mount, 2558 .mpo_relabel_vnode = mac_biba_relabel_vnode, 2559 .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2560 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2561 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2562 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2563 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2564 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2565 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2566 .mpo_create_pipe = mac_biba_create_pipe, 2567 .mpo_create_socket = mac_biba_create_socket, 2568 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2569 .mpo_relabel_pipe = mac_biba_relabel_pipe, 2570 .mpo_relabel_socket = mac_biba_relabel_socket, 2571 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2572 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2573 .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2574 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2575 .mpo_create_fragment = mac_biba_create_fragment, 2576 .mpo_create_ifnet = mac_biba_create_ifnet, 2577 .mpo_create_ipq = mac_biba_create_ipq, 2578 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2579 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2580 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2581 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2582 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2583 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2584 .mpo_fragment_match = mac_biba_fragment_match, 2585 .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2586 .mpo_update_ipq = mac_biba_update_ipq, 2587 .mpo_create_cred = mac_biba_create_cred, 2588 .mpo_execve_transition = mac_biba_execve_transition, 2589 .mpo_execve_will_transition = mac_biba_execve_will_transition, 2590 .mpo_create_proc0 = mac_biba_create_proc0, 2591 .mpo_create_proc1 = mac_biba_create_proc1, 2592 .mpo_relabel_cred = mac_biba_relabel_cred, 2593 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2594 .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2595 .mpo_check_cred_visible = mac_biba_check_cred_visible, 2596 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2597 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2598 .mpo_check_mount_stat = mac_biba_check_mount_stat, 2599 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2600 .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2601 .mpo_check_pipe_read = mac_biba_check_pipe_read, 2602 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2603 .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2604 .mpo_check_pipe_write = mac_biba_check_pipe_write, 2605 .mpo_check_proc_debug = mac_biba_check_proc_debug, 2606 .mpo_check_proc_sched = mac_biba_check_proc_sched, 2607 .mpo_check_proc_signal = mac_biba_check_proc_signal, 2608 .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2609 .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2610 .mpo_check_socket_visible = mac_biba_check_socket_visible, 2611 .mpo_check_system_swapon = mac_biba_check_system_swapon, 2612 .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2613 .mpo_check_vnode_access = mac_biba_check_vnode_open, 2614 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2615 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2616 .mpo_check_vnode_create = mac_biba_check_vnode_create, 2617 .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2618 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2619 .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2620 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2621 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2622 .mpo_check_vnode_link = mac_biba_check_vnode_link, 2623 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2624 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2625 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2626 .mpo_check_vnode_open = mac_biba_check_vnode_open, 2627 .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2628 .mpo_check_vnode_read = mac_biba_check_vnode_read, 2629 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2630 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2631 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2632 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2633 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2634 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2635 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2636 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2637 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2638 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2639 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2640 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2641 .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2642 .mpo_check_vnode_write = mac_biba_check_vnode_write, 2643}; 2644 2645MAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2646 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
| 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 1162 bzero(tiflist, sizeof(tiflist)); 1163 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1164 if(*p != ' ' && *p != '\t') 1165 *q = *p; 1166 1167 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1168 1169 for (p = q = tiflist;; p++) { 1170 if (*p == ',' || *p == '\0') { 1171 len = p - q; 1172 if (len < IFNAMSIZ) { 1173 bzero(tifname, sizeof(tifname)); 1174 bcopy(q, tifname, len); 1175 if (strcmp(tifname, ifname) == 0) { 1176 grade = MAC_BIBA_TYPE_HIGH; 1177 break; 1178 } 1179 } else { 1180 *p = '\0'; 1181 printf("mac_biba warning: interface name " 1182 "\"%s\" is too long (must be < %d)\n", 1183 q, IFNAMSIZ); 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 label *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 label *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_privileged(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 * Relabling network interfaces requires Biba privilege. 1532 */ 1533 error = mac_biba_subject_privileged(subj); 1534 if (error) 1535 return (error); 1536 1537 /* 1538 * If the Biba label is to be changed, authorize as appropriate. 1539 */ 1540 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1541 /* 1542 * Rely on the traditional superuser status for the Biba 1543 * interface relabel requirements. XXXMAC: This will go 1544 * away. 1545 */ 1546 error = suser_cred(cred, 0); 1547 if (error) 1548 return (EPERM); 1549 1550 /* 1551 * XXXMAC: Additional consistency tests regarding the single 1552 * and the range of the new label might be performed here. 1553 */ 1554 } 1555 1556 return (0); 1557} 1558 1559static int 1560mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1561 struct mbuf *m, struct label *mbuflabel) 1562{ 1563 struct mac_biba *p, *i; 1564 1565 if (!mac_biba_enabled) 1566 return (0); 1567 1568 p = SLOT(mbuflabel); 1569 i = SLOT(ifnetlabel); 1570 1571 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1572} 1573 1574static int 1575mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1576 struct label *mntlabel) 1577{ 1578 struct mac_biba *subj, *obj; 1579 1580 if (!mac_biba_enabled) 1581 return (0); 1582 1583 subj = SLOT(&cred->cr_label); 1584 obj = SLOT(mntlabel); 1585 1586 if (!mac_biba_dominate_single(obj, subj)) 1587 return (EACCES); 1588 1589 return (0); 1590} 1591 1592static int 1593mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1594 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1595{ 1596 1597 if(!mac_biba_enabled) 1598 return (0); 1599 1600 /* XXX: This will be implemented soon... */ 1601 1602 return (0); 1603} 1604 1605static int 1606mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1607 struct label *pipelabel) 1608{ 1609 struct mac_biba *subj, *obj; 1610 1611 if (!mac_biba_enabled) 1612 return (0); 1613 1614 subj = SLOT(&cred->cr_label); 1615 obj = SLOT((pipelabel)); 1616 1617 if (!mac_biba_dominate_single(obj, subj)) 1618 return (EACCES); 1619 1620 return (0); 1621} 1622 1623static int 1624mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1625 struct label *pipelabel) 1626{ 1627 struct mac_biba *subj, *obj; 1628 1629 if (!mac_biba_enabled) 1630 return (0); 1631 1632 subj = SLOT(&cred->cr_label); 1633 obj = SLOT((pipelabel)); 1634 1635 if (!mac_biba_dominate_single(obj, subj)) 1636 return (EACCES); 1637 1638 return (0); 1639} 1640 1641static int 1642mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1643 struct label *pipelabel, struct label *newlabel) 1644{ 1645 struct mac_biba *subj, *obj, *new; 1646 int error; 1647 1648 new = SLOT(newlabel); 1649 subj = SLOT(&cred->cr_label); 1650 obj = SLOT(pipelabel); 1651 1652 /* 1653 * If there is a Biba label update for a pipe, it must be a 1654 * single update. 1655 */ 1656 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1657 if (error) 1658 return (error); 1659 1660 /* 1661 * To perform a relabel of a pipe (Biba label or not), Biba must 1662 * authorize the relabel. 1663 */ 1664 if (!mac_biba_single_in_range(obj, subj)) 1665 return (EPERM); 1666 1667 /* 1668 * If the Biba label is to be changed, authorize as appropriate. 1669 */ 1670 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1671 /* 1672 * To change the Biba label on a pipe, the new pipe label 1673 * must be in the subject range. 1674 */ 1675 if (!mac_biba_single_in_range(new, subj)) 1676 return (EPERM); 1677 1678 /* 1679 * To change the Biba label on a pipe to be EQUAL, the 1680 * subject must have appropriate privilege. 1681 */ 1682 if (mac_biba_contains_equal(new)) { 1683 error = mac_biba_subject_privileged(subj); 1684 if (error) 1685 return (error); 1686 } 1687 } 1688 1689 return (0); 1690} 1691 1692static int 1693mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1694 struct label *pipelabel) 1695{ 1696 struct mac_biba *subj, *obj; 1697 1698 if (!mac_biba_enabled) 1699 return (0); 1700 1701 subj = SLOT(&cred->cr_label); 1702 obj = SLOT((pipelabel)); 1703 1704 if (!mac_biba_dominate_single(obj, subj)) 1705 return (EACCES); 1706 1707 return (0); 1708} 1709 1710static int 1711mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1712 struct label *pipelabel) 1713{ 1714 struct mac_biba *subj, *obj; 1715 1716 if (!mac_biba_enabled) 1717 return (0); 1718 1719 subj = SLOT(&cred->cr_label); 1720 obj = SLOT((pipelabel)); 1721 1722 if (!mac_biba_dominate_single(subj, obj)) 1723 return (EACCES); 1724 1725 return (0); 1726} 1727 1728static int 1729mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1730{ 1731 struct mac_biba *subj, *obj; 1732 1733 if (!mac_biba_enabled) 1734 return (0); 1735 1736 subj = SLOT(&cred->cr_label); 1737 obj = SLOT(&proc->p_ucred->cr_label); 1738 1739 /* XXX: range checks */ 1740 if (!mac_biba_dominate_single(obj, subj)) 1741 return (ESRCH); 1742 if (!mac_biba_dominate_single(subj, obj)) 1743 return (EACCES); 1744 1745 return (0); 1746} 1747 1748static int 1749mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1750{ 1751 struct mac_biba *subj, *obj; 1752 1753 if (!mac_biba_enabled) 1754 return (0); 1755 1756 subj = SLOT(&cred->cr_label); 1757 obj = SLOT(&proc->p_ucred->cr_label); 1758 1759 /* XXX: range checks */ 1760 if (!mac_biba_dominate_single(obj, subj)) 1761 return (ESRCH); 1762 if (!mac_biba_dominate_single(subj, obj)) 1763 return (EACCES); 1764 1765 return (0); 1766} 1767 1768static int 1769mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1770{ 1771 struct mac_biba *subj, *obj; 1772 1773 if (!mac_biba_enabled) 1774 return (0); 1775 1776 subj = SLOT(&cred->cr_label); 1777 obj = SLOT(&proc->p_ucred->cr_label); 1778 1779 /* XXX: range checks */ 1780 if (!mac_biba_dominate_single(obj, subj)) 1781 return (ESRCH); 1782 if (!mac_biba_dominate_single(subj, obj)) 1783 return (EACCES); 1784 1785 return (0); 1786} 1787 1788static int 1789mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1790 struct mbuf *m, struct label *mbuflabel) 1791{ 1792 struct mac_biba *p, *s; 1793 1794 if (!mac_biba_enabled) 1795 return (0); 1796 1797 p = SLOT(mbuflabel); 1798 s = SLOT(socketlabel); 1799 1800 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1801} 1802 1803static int 1804mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1805 struct label *socketlabel, struct label *newlabel) 1806{ 1807 struct mac_biba *subj, *obj, *new; 1808 int error; 1809 1810 new = SLOT(newlabel); 1811 subj = SLOT(&cred->cr_label); 1812 obj = SLOT(socketlabel); 1813 1814 /* 1815 * If there is a Biba label update for the socket, it may be 1816 * an update of single. 1817 */ 1818 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1819 if (error) 1820 return (error); 1821 1822 /* 1823 * To relabel a socket, the old socket single must be in the subject 1824 * range. 1825 */ 1826 if (!mac_biba_single_in_range(obj, subj)) 1827 return (EPERM); 1828 1829 /* 1830 * If the Biba label is to be changed, authorize as appropriate. 1831 */ 1832 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1833 /* 1834 * To relabel a socket, the new socket single must be in 1835 * the subject range. 1836 */ 1837 if (!mac_biba_single_in_range(new, subj)) 1838 return (EPERM); 1839 1840 /* 1841 * To change the Biba label on the socket to contain EQUAL, 1842 * the subject must have appropriate privilege. 1843 */ 1844 if (mac_biba_contains_equal(new)) { 1845 error = mac_biba_subject_privileged(subj); 1846 if (error) 1847 return (error); 1848 } 1849 } 1850 1851 return (0); 1852} 1853 1854static int 1855mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1856 struct label *socketlabel) 1857{ 1858 struct mac_biba *subj, *obj; 1859 1860 if (!mac_biba_enabled) 1861 return (0); 1862 1863 subj = SLOT(&cred->cr_label); 1864 obj = SLOT(socketlabel); 1865 1866 if (!mac_biba_dominate_single(obj, subj)) 1867 return (ENOENT); 1868 1869 return (0); 1870} 1871 1872static int 1873mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1874 struct label *label) 1875{ 1876 struct mac_biba *subj, *obj; 1877 1878 if (!mac_biba_enabled) 1879 return (0); 1880 1881 subj = SLOT(&cred->cr_label); 1882 obj = SLOT(label); 1883 1884 if (!mac_biba_subject_privileged(subj)) 1885 return (EPERM); 1886 1887 if (!mac_biba_high_single(obj)) 1888 return (EACCES); 1889 1890 return (0); 1891} 1892 1893static int 1894mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1895 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1896{ 1897 struct mac_biba *subj; 1898 int error; 1899 1900 if (!mac_biba_enabled) 1901 return (0); 1902 1903 subj = SLOT(&cred->cr_label); 1904 1905 /* 1906 * In general, treat sysctl variables as biba/high, but also 1907 * require privilege to change them, since they are a 1908 * communications channel between grades. Exempt MIB 1909 * queries from this due to undocmented sysctl magic. 1910 * XXXMAC: This probably requires some more review. 1911 */ 1912 if (new != NULL) { 1913 if (namelen > 0 && name[0] == 0) 1914 return (0); 1915 1916 if (!mac_biba_subject_dominate_high(subj)) 1917 return (EACCES); 1918 1919 error = mac_biba_subject_privileged(subj); 1920 if (error) 1921 return (error); 1922 } 1923 1924 return (0); 1925} 1926 1927static int 1928mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1929 struct label *dlabel) 1930{ 1931 struct mac_biba *subj, *obj; 1932 1933 if (!mac_biba_enabled) 1934 return (0); 1935 1936 subj = SLOT(&cred->cr_label); 1937 obj = SLOT(dlabel); 1938 1939 if (!mac_biba_dominate_single(obj, subj)) 1940 return (EACCES); 1941 1942 return (0); 1943} 1944 1945static int 1946mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1947 struct label *dlabel) 1948{ 1949 struct mac_biba *subj, *obj; 1950 1951 if (!mac_biba_enabled) 1952 return (0); 1953 1954 subj = SLOT(&cred->cr_label); 1955 obj = SLOT(dlabel); 1956 1957 if (!mac_biba_dominate_single(obj, subj)) 1958 return (EACCES); 1959 1960 return (0); 1961} 1962 1963static int 1964mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1965 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1966{ 1967 struct mac_biba *subj, *obj; 1968 1969 if (!mac_biba_enabled) 1970 return (0); 1971 1972 subj = SLOT(&cred->cr_label); 1973 obj = SLOT(dlabel); 1974 1975 if (!mac_biba_dominate_single(subj, obj)) 1976 return (EACCES); 1977 1978 return (0); 1979} 1980 1981static int 1982mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1983 struct label *dlabel, struct vnode *vp, struct label *label, 1984 struct componentname *cnp) 1985{ 1986 struct mac_biba *subj, *obj; 1987 1988 if (!mac_biba_enabled) 1989 return (0); 1990 1991 subj = SLOT(&cred->cr_label); 1992 obj = SLOT(dlabel); 1993 1994 if (!mac_biba_dominate_single(subj, obj)) 1995 return (EACCES); 1996 1997 obj = SLOT(label); 1998 1999 if (!mac_biba_dominate_single(subj, obj)) 2000 return (EACCES); 2001 2002 return (0); 2003} 2004 2005static int 2006mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2007 struct label *label, acl_type_t type) 2008{ 2009 struct mac_biba *subj, *obj; 2010 2011 if (!mac_biba_enabled) 2012 return (0); 2013 2014 subj = SLOT(&cred->cr_label); 2015 obj = SLOT(label); 2016 2017 if (!mac_biba_dominate_single(subj, obj)) 2018 return (EACCES); 2019 2020 return (0); 2021} 2022 2023static int 2024mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2025 struct label *label) 2026{ 2027 struct mac_biba *subj, *obj; 2028 2029 if (!mac_biba_enabled) 2030 return (0); 2031 2032 subj = SLOT(&cred->cr_label); 2033 obj = SLOT(label); 2034 2035 if (!mac_biba_dominate_single(obj, subj)) 2036 return (EACCES); 2037 2038 return (0); 2039} 2040 2041static int 2042mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2043 struct label *label, acl_type_t type) 2044{ 2045 struct mac_biba *subj, *obj; 2046 2047 if (!mac_biba_enabled) 2048 return (0); 2049 2050 subj = SLOT(&cred->cr_label); 2051 obj = SLOT(label); 2052 2053 if (!mac_biba_dominate_single(obj, subj)) 2054 return (EACCES); 2055 2056 return (0); 2057} 2058 2059static int 2060mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2061 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2062{ 2063 struct mac_biba *subj, *obj; 2064 2065 if (!mac_biba_enabled) 2066 return (0); 2067 2068 subj = SLOT(&cred->cr_label); 2069 obj = SLOT(label); 2070 2071 if (!mac_biba_dominate_single(obj, subj)) 2072 return (EACCES); 2073 2074 return (0); 2075} 2076 2077static int 2078mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2079 struct label *dlabel, struct vnode *vp, struct label *label, 2080 struct componentname *cnp) 2081{ 2082 struct mac_biba *subj, *obj; 2083 2084 if (!mac_biba_enabled) 2085 return (0); 2086 2087 subj = SLOT(&cred->cr_label); 2088 obj = SLOT(dlabel); 2089 2090 if (!mac_biba_dominate_single(subj, obj)) 2091 return (EACCES); 2092 2093 obj = SLOT(label); 2094 2095 if (!mac_biba_dominate_single(subj, obj)) 2096 return (EACCES); 2097 2098 return (0); 2099} 2100 2101static int 2102mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2103 struct label *dlabel, struct componentname *cnp) 2104{ 2105 struct mac_biba *subj, *obj; 2106 2107 if (!mac_biba_enabled) 2108 return (0); 2109 2110 subj = SLOT(&cred->cr_label); 2111 obj = SLOT(dlabel); 2112 2113 if (!mac_biba_dominate_single(obj, subj)) 2114 return (EACCES); 2115 2116 return (0); 2117} 2118 2119static int 2120mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2121 struct label *label, int prot) 2122{ 2123 struct mac_biba *subj, *obj; 2124 2125 /* 2126 * Rely on the use of open()-time protections to handle 2127 * non-revocation cases. 2128 */ 2129 if (!mac_biba_enabled || !revocation_enabled) 2130 return (0); 2131 2132 subj = SLOT(&cred->cr_label); 2133 obj = SLOT(label); 2134 2135 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2136 if (!mac_biba_dominate_single(obj, subj)) 2137 return (EACCES); 2138 } 2139 if (prot & VM_PROT_WRITE) { 2140 if (!mac_biba_dominate_single(subj, obj)) 2141 return (EACCES); 2142 } 2143 2144 return (0); 2145} 2146 2147static int 2148mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2149 struct label *vnodelabel, int acc_mode) 2150{ 2151 struct mac_biba *subj, *obj; 2152 2153 if (!mac_biba_enabled) 2154 return (0); 2155 2156 subj = SLOT(&cred->cr_label); 2157 obj = SLOT(vnodelabel); 2158 2159 /* XXX privilege override for admin? */ 2160 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2161 if (!mac_biba_dominate_single(obj, subj)) 2162 return (EACCES); 2163 } 2164 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2165 if (!mac_biba_dominate_single(subj, obj)) 2166 return (EACCES); 2167 } 2168 2169 return (0); 2170} 2171 2172static int 2173mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2174 struct vnode *vp, struct label *label) 2175{ 2176 struct mac_biba *subj, *obj; 2177 2178 if (!mac_biba_enabled || !revocation_enabled) 2179 return (0); 2180 2181 subj = SLOT(&active_cred->cr_label); 2182 obj = SLOT(label); 2183 2184 if (!mac_biba_dominate_single(obj, subj)) 2185 return (EACCES); 2186 2187 return (0); 2188} 2189 2190static int 2191mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2192 struct vnode *vp, struct label *label) 2193{ 2194 struct mac_biba *subj, *obj; 2195 2196 if (!mac_biba_enabled || !revocation_enabled) 2197 return (0); 2198 2199 subj = SLOT(&active_cred->cr_label); 2200 obj = SLOT(label); 2201 2202 if (!mac_biba_dominate_single(obj, subj)) 2203 return (EACCES); 2204 2205 return (0); 2206} 2207 2208static int 2209mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2210 struct label *dlabel) 2211{ 2212 struct mac_biba *subj, *obj; 2213 2214 if (!mac_biba_enabled) 2215 return (0); 2216 2217 subj = SLOT(&cred->cr_label); 2218 obj = SLOT(dlabel); 2219 2220 if (!mac_biba_dominate_single(obj, subj)) 2221 return (EACCES); 2222 2223 return (0); 2224} 2225 2226static int 2227mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2228 struct label *label) 2229{ 2230 struct mac_biba *subj, *obj; 2231 2232 if (!mac_biba_enabled) 2233 return (0); 2234 2235 subj = SLOT(&cred->cr_label); 2236 obj = SLOT(label); 2237 2238 if (!mac_biba_dominate_single(obj, subj)) 2239 return (EACCES); 2240 2241 return (0); 2242} 2243 2244static int 2245mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2246 struct label *vnodelabel, struct label *newlabel) 2247{ 2248 struct mac_biba *old, *new, *subj; 2249 int error; 2250 2251 old = SLOT(vnodelabel); 2252 new = SLOT(newlabel); 2253 subj = SLOT(&cred->cr_label); 2254 2255 /* 2256 * If there is a Biba label update for the vnode, it must be a 2257 * single label. 2258 */ 2259 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2260 if (error) 2261 return (error); 2262 2263 /* 2264 * To perform a relabel of the vnode (Biba label or not), Biba must 2265 * authorize the relabel. 2266 */ 2267 if (!mac_biba_single_in_range(old, subj)) 2268 return (EPERM); 2269 2270 /* 2271 * If the Biba label is to be changed, authorize as appropriate. 2272 */ 2273 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2274 /* 2275 * To change the Biba label on a vnode, the new vnode label 2276 * must be in the subject range. 2277 */ 2278 if (!mac_biba_single_in_range(new, subj)) 2279 return (EPERM); 2280 2281 /* 2282 * To change the Biba label on the vnode to be EQUAL, 2283 * the subject must have appropriate privilege. 2284 */ 2285 if (mac_biba_contains_equal(new)) { 2286 error = mac_biba_subject_privileged(subj); 2287 if (error) 2288 return (error); 2289 } 2290 } 2291 2292 return (0); 2293} 2294 2295static int 2296mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2297 struct label *dlabel, struct vnode *vp, struct label *label, 2298 struct componentname *cnp) 2299{ 2300 struct mac_biba *subj, *obj; 2301 2302 if (!mac_biba_enabled) 2303 return (0); 2304 2305 subj = SLOT(&cred->cr_label); 2306 obj = SLOT(dlabel); 2307 2308 if (!mac_biba_dominate_single(subj, obj)) 2309 return (EACCES); 2310 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_rename_to(struct ucred *cred, struct vnode *dvp, 2321 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2322 struct componentname *cnp) 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(dlabel); 2331 2332 if (!mac_biba_dominate_single(subj, obj)) 2333 return (EACCES); 2334 2335 if (vp != NULL) { 2336 obj = SLOT(label); 2337 2338 if (!mac_biba_dominate_single(subj, obj)) 2339 return (EACCES); 2340 } 2341 2342 return (0); 2343} 2344 2345static int 2346mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2347 struct label *label) 2348{ 2349 struct mac_biba *subj, *obj; 2350 2351 if (!mac_biba_enabled) 2352 return (0); 2353 2354 subj = SLOT(&cred->cr_label); 2355 obj = SLOT(label); 2356 2357 if (!mac_biba_dominate_single(subj, obj)) 2358 return (EACCES); 2359 2360 return (0); 2361} 2362 2363static int 2364mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2365 struct label *label, acl_type_t type, struct acl *acl) 2366{ 2367 struct mac_biba *subj, *obj; 2368 2369 if (!mac_biba_enabled) 2370 return (0); 2371 2372 subj = SLOT(&cred->cr_label); 2373 obj = SLOT(label); 2374 2375 if (!mac_biba_dominate_single(subj, obj)) 2376 return (EACCES); 2377 2378 return (0); 2379} 2380 2381static int 2382mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2383 struct label *vnodelabel, int attrnamespace, const char *name, 2384 struct uio *uio) 2385{ 2386 struct mac_biba *subj, *obj; 2387 2388 if (!mac_biba_enabled) 2389 return (0); 2390 2391 subj = SLOT(&cred->cr_label); 2392 obj = SLOT(vnodelabel); 2393 2394 if (!mac_biba_dominate_single(subj, obj)) 2395 return (EACCES); 2396 2397 /* XXX: protect the MAC EA in a special way? */ 2398 2399 return (0); 2400} 2401 2402static int 2403mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2404 struct label *vnodelabel, u_long flags) 2405{ 2406 struct mac_biba *subj, *obj; 2407 2408 if (!mac_biba_enabled) 2409 return (0); 2410 2411 subj = SLOT(&cred->cr_label); 2412 obj = SLOT(vnodelabel); 2413 2414 if (!mac_biba_dominate_single(subj, obj)) 2415 return (EACCES); 2416 2417 return (0); 2418} 2419 2420static int 2421mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2422 struct label *vnodelabel, mode_t mode) 2423{ 2424 struct mac_biba *subj, *obj; 2425 2426 if (!mac_biba_enabled) 2427 return (0); 2428 2429 subj = SLOT(&cred->cr_label); 2430 obj = SLOT(vnodelabel); 2431 2432 if (!mac_biba_dominate_single(subj, obj)) 2433 return (EACCES); 2434 2435 return (0); 2436} 2437 2438static int 2439mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2440 struct label *vnodelabel, uid_t uid, gid_t gid) 2441{ 2442 struct mac_biba *subj, *obj; 2443 2444 if (!mac_biba_enabled) 2445 return (0); 2446 2447 subj = SLOT(&cred->cr_label); 2448 obj = SLOT(vnodelabel); 2449 2450 if (!mac_biba_dominate_single(subj, obj)) 2451 return (EACCES); 2452 2453 return (0); 2454} 2455 2456static int 2457mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2458 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2459{ 2460 struct mac_biba *subj, *obj; 2461 2462 if (!mac_biba_enabled) 2463 return (0); 2464 2465 subj = SLOT(&cred->cr_label); 2466 obj = SLOT(vnodelabel); 2467 2468 if (!mac_biba_dominate_single(subj, obj)) 2469 return (EACCES); 2470 2471 return (0); 2472} 2473 2474static int 2475mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2476 struct vnode *vp, struct label *vnodelabel) 2477{ 2478 struct mac_biba *subj, *obj; 2479 2480 if (!mac_biba_enabled) 2481 return (0); 2482 2483 subj = SLOT(&active_cred->cr_label); 2484 obj = SLOT(vnodelabel); 2485 2486 if (!mac_biba_dominate_single(obj, subj)) 2487 return (EACCES); 2488 2489 return (0); 2490} 2491 2492static int 2493mac_biba_check_vnode_write(struct ucred *active_cred, 2494 struct ucred *file_cred, struct vnode *vp, struct label *label) 2495{ 2496 struct mac_biba *subj, *obj; 2497 2498 if (!mac_biba_enabled || !revocation_enabled) 2499 return (0); 2500 2501 subj = SLOT(&active_cred->cr_label); 2502 obj = SLOT(label); 2503 2504 if (!mac_biba_dominate_single(subj, obj)) 2505 return (EACCES); 2506 2507 return (0); 2508} 2509 2510static struct mac_policy_ops mac_biba_ops = 2511{ 2512 .mpo_destroy = mac_biba_destroy, 2513 .mpo_init = mac_biba_init, 2514 .mpo_init_bpfdesc_label = mac_biba_init_label, 2515 .mpo_init_cred_label = mac_biba_init_label, 2516 .mpo_init_devfsdirent_label = mac_biba_init_label, 2517 .mpo_init_ifnet_label = mac_biba_init_label, 2518 .mpo_init_ipq_label = mac_biba_init_label, 2519 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2520 .mpo_init_mount_label = mac_biba_init_label, 2521 .mpo_init_mount_fs_label = mac_biba_init_label, 2522 .mpo_init_pipe_label = mac_biba_init_label, 2523 .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2524 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2525 .mpo_init_vnode_label = mac_biba_init_label, 2526 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2527 .mpo_destroy_cred_label = mac_biba_destroy_label, 2528 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2529 .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2530 .mpo_destroy_ipq_label = mac_biba_destroy_label, 2531 .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2532 .mpo_destroy_mount_label = mac_biba_destroy_label, 2533 .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2534 .mpo_destroy_pipe_label = mac_biba_destroy_label, 2535 .mpo_destroy_socket_label = mac_biba_destroy_label, 2536 .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2537 .mpo_destroy_vnode_label = mac_biba_destroy_label, 2538 .mpo_copy_pipe_label = mac_biba_copy_label, 2539 .mpo_copy_vnode_label = mac_biba_copy_label, 2540 .mpo_externalize_cred_label = mac_biba_externalize_label, 2541 .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2542 .mpo_externalize_pipe_label = mac_biba_externalize_label, 2543 .mpo_externalize_socket_label = mac_biba_externalize_label, 2544 .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2545 .mpo_externalize_vnode_label = mac_biba_externalize_label, 2546 .mpo_internalize_cred_label = mac_biba_internalize_label, 2547 .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2548 .mpo_internalize_pipe_label = mac_biba_internalize_label, 2549 .mpo_internalize_socket_label = mac_biba_internalize_label, 2550 .mpo_internalize_vnode_label = mac_biba_internalize_label, 2551 .mpo_create_devfs_device = mac_biba_create_devfs_device, 2552 .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2553 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2554 .mpo_create_devfs_vnode = mac_biba_create_devfs_vnode, 2555 .mpo_create_mount = mac_biba_create_mount, 2556 .mpo_create_root_mount = mac_biba_create_root_mount, 2557 .mpo_relabel_vnode = mac_biba_relabel_vnode, 2558 .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2559 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2560 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2561 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2562 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2563 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2564 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2565 .mpo_create_pipe = mac_biba_create_pipe, 2566 .mpo_create_socket = mac_biba_create_socket, 2567 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2568 .mpo_relabel_pipe = mac_biba_relabel_pipe, 2569 .mpo_relabel_socket = mac_biba_relabel_socket, 2570 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2571 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2572 .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2573 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2574 .mpo_create_fragment = mac_biba_create_fragment, 2575 .mpo_create_ifnet = mac_biba_create_ifnet, 2576 .mpo_create_ipq = mac_biba_create_ipq, 2577 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2578 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2579 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2580 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2581 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2582 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2583 .mpo_fragment_match = mac_biba_fragment_match, 2584 .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2585 .mpo_update_ipq = mac_biba_update_ipq, 2586 .mpo_create_cred = mac_biba_create_cred, 2587 .mpo_execve_transition = mac_biba_execve_transition, 2588 .mpo_execve_will_transition = mac_biba_execve_will_transition, 2589 .mpo_create_proc0 = mac_biba_create_proc0, 2590 .mpo_create_proc1 = mac_biba_create_proc1, 2591 .mpo_relabel_cred = mac_biba_relabel_cred, 2592 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2593 .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2594 .mpo_check_cred_visible = mac_biba_check_cred_visible, 2595 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2596 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2597 .mpo_check_mount_stat = mac_biba_check_mount_stat, 2598 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2599 .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2600 .mpo_check_pipe_read = mac_biba_check_pipe_read, 2601 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2602 .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2603 .mpo_check_pipe_write = mac_biba_check_pipe_write, 2604 .mpo_check_proc_debug = mac_biba_check_proc_debug, 2605 .mpo_check_proc_sched = mac_biba_check_proc_sched, 2606 .mpo_check_proc_signal = mac_biba_check_proc_signal, 2607 .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2608 .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2609 .mpo_check_socket_visible = mac_biba_check_socket_visible, 2610 .mpo_check_system_swapon = mac_biba_check_system_swapon, 2611 .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2612 .mpo_check_vnode_access = mac_biba_check_vnode_open, 2613 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2614 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2615 .mpo_check_vnode_create = mac_biba_check_vnode_create, 2616 .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2617 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2618 .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2619 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2620 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2621 .mpo_check_vnode_link = mac_biba_check_vnode_link, 2622 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2623 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2624 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2625 .mpo_check_vnode_open = mac_biba_check_vnode_open, 2626 .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2627 .mpo_check_vnode_read = mac_biba_check_vnode_read, 2628 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2629 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2630 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2631 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2632 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2633 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2634 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2635 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2636 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2637 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2638 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2639 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2640 .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2641 .mpo_check_vnode_write = mac_biba_check_vnode_write, 2642}; 2643 2644MAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2645 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot);
|