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