1 /*- 2 * Copyright (c) 1999-2002, 2007-2011 Robert N. M. Watson 3 * Copyright (c) 2001-2005 McAfee, Inc. 4 * Copyright (c) 2006 SPARTA, Inc. 5 * All rights reserved. 6 * 7 * This software was developed by Robert Watson for the TrustedBSD Project. 8 * 9 * This software was developed for the FreeBSD Project in part by McAfee 10 * Research, the Security Research Division of McAfee, Inc. under 11 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 12 * CHATS research program. 13 * 14 * This software was enhanced by SPARTA ISSO under SPAWAR contract 15 * N66001-04-C-6019 ("SEFOS"). 16 * 17 * This software was developed at the University of Cambridge Computer 18 * Laboratory with support from a grant from Google, Inc. 19 * 20 * Redistribution and use in source and binary forms, with or without 21 * modification, are permitted provided that the following conditions 22 * are met: 23 * 1. Redistributions of source code must retain the above copyright 24 * notice, this list of conditions and the following disclaimer. 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 */ 41 42 /* 43 * Developed by the TrustedBSD Project. 44 * 45 * Biba fixed label mandatory integrity policy. 46 */ 47 48 #include <sys/param.h> 49 #include <sys/conf.h> 50 #include <sys/extattr.h> 51 #include <sys/kernel.h> 52 #include <sys/ksem.h> 53 #include <sys/malloc.h> 54 #include <sys/mman.h> 55 #include <sys/mount.h> 56 #include <sys/priv.h> 57 #include <sys/proc.h> 58 #include <sys/sbuf.h> 59 #include <sys/systm.h> 60 #include <sys/sysproto.h> 61 #include <sys/sysent.h> 62 #include <sys/systm.h> 63 #include <sys/vnode.h> 64 #include <sys/file.h> 65 #include <sys/socket.h> 66 #include <sys/socketvar.h> 67 #include <sys/pipe.h> 68 #include <sys/sx.h> 69 #include <sys/sysctl.h> 70 #include <sys/msg.h> 71 #include <sys/sem.h> 72 #include <sys/shm.h> 73 74 #include <fs/devfs/devfs.h> 75 76 #include <net/bpfdesc.h> 77 #include <net/if.h> 78 #include <net/if_types.h> 79 #include <net/if_var.h> 80 81 #include <netinet/in.h> 82 #include <netinet/in_pcb.h> 83 #include <netinet/ip_var.h> 84 85 #include <vm/uma.h> 86 #include <vm/vm.h> 87 88 #include <security/mac/mac_policy.h> 89 #include <security/mac_biba/mac_biba.h> 90 91 SYSCTL_DECL(_security_mac); 92 93 static SYSCTL_NODE(_security_mac, OID_AUTO, biba, 94 CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 95 "TrustedBSD mac_biba policy controls"); 96 97 static int biba_label_size = sizeof(struct mac_biba); 98 SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 99 &biba_label_size, 0, "Size of struct mac_biba"); 100 101 static int biba_enabled = 1; 102 SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RWTUN, &biba_enabled, 103 0, "Enforce MAC/Biba policy"); 104 105 static int destroyed_not_inited; 106 SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 107 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 108 109 static int trust_all_interfaces = 0; 110 SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RDTUN, 111 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 112 113 static char trusted_interfaces[128]; 114 SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RDTUN, 115 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 116 117 static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 118 SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 119 &max_compartments, 0, "Maximum supported compartments"); 120 121 static int ptys_equal = 0; 122 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RWTUN, &ptys_equal, 123 0, "Label pty devices as biba/equal on create"); 124 125 static int interfaces_equal = 1; 126 SYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RWTUN, 127 &interfaces_equal, 0, "Label network interfaces as biba/equal on create"); 128 129 static int revocation_enabled = 0; 130 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RWTUN, 131 &revocation_enabled, 0, "Revoke access to objects on relabel"); 132 133 static int biba_slot; 134 #define SLOT(l) ((struct mac_biba *)mac_label_get((l), biba_slot)) 135 #define SLOT_SET(l, val) mac_label_set((l), biba_slot, (uintptr_t)(val)) 136 137 static uma_zone_t zone_biba; 138 139 static __inline int 140 biba_bit_set_empty(u_char *set) { 141 int i; 142 143 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 144 if (set[i] != 0) 145 return (0); 146 return (1); 147 } 148 149 static struct mac_biba * 150 biba_alloc(int flag) 151 { 152 153 return (uma_zalloc(zone_biba, flag | M_ZERO)); 154 } 155 156 static void 157 biba_free(struct mac_biba *mb) 158 { 159 160 if (mb != NULL) 161 uma_zfree(zone_biba, mb); 162 else 163 atomic_add_int(&destroyed_not_inited, 1); 164 } 165 166 static int 167 biba_atmostflags(struct mac_biba *mb, int flags) 168 { 169 170 if ((mb->mb_flags & flags) != mb->mb_flags) 171 return (EINVAL); 172 return (0); 173 } 174 175 static int 176 biba_dominate_element(struct mac_biba_element *a, struct mac_biba_element *b) 177 { 178 int bit; 179 180 switch (a->mbe_type) { 181 case MAC_BIBA_TYPE_EQUAL: 182 case MAC_BIBA_TYPE_HIGH: 183 return (1); 184 185 case MAC_BIBA_TYPE_LOW: 186 switch (b->mbe_type) { 187 case MAC_BIBA_TYPE_GRADE: 188 case MAC_BIBA_TYPE_HIGH: 189 return (0); 190 191 case MAC_BIBA_TYPE_EQUAL: 192 case MAC_BIBA_TYPE_LOW: 193 return (1); 194 195 default: 196 panic("biba_dominate_element: b->mbe_type invalid"); 197 } 198 199 case MAC_BIBA_TYPE_GRADE: 200 switch (b->mbe_type) { 201 case MAC_BIBA_TYPE_EQUAL: 202 case MAC_BIBA_TYPE_LOW: 203 return (1); 204 205 case MAC_BIBA_TYPE_HIGH: 206 return (0); 207 208 case MAC_BIBA_TYPE_GRADE: 209 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 210 if (!MAC_BIBA_BIT_TEST(bit, 211 a->mbe_compartments) && 212 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 213 return (0); 214 return (a->mbe_grade >= b->mbe_grade); 215 216 default: 217 panic("biba_dominate_element: b->mbe_type invalid"); 218 } 219 220 default: 221 panic("biba_dominate_element: a->mbe_type invalid"); 222 } 223 224 return (0); 225 } 226 227 static int 228 biba_subject_dominate_high(struct mac_biba *mb) 229 { 230 struct mac_biba_element *element; 231 232 KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 233 ("biba_effective_in_range: mb not effective")); 234 element = &mb->mb_effective; 235 236 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 237 element->mbe_type == MAC_BIBA_TYPE_HIGH); 238 } 239 240 static int 241 biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 242 { 243 244 return (biba_dominate_element(&rangeb->mb_rangehigh, 245 &rangea->mb_rangehigh) && 246 biba_dominate_element(&rangea->mb_rangelow, 247 &rangeb->mb_rangelow)); 248 } 249 250 static int 251 biba_effective_in_range(struct mac_biba *effective, struct mac_biba *range) 252 { 253 254 KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 255 ("biba_effective_in_range: a not effective")); 256 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 257 ("biba_effective_in_range: b not range")); 258 259 return (biba_dominate_element(&range->mb_rangehigh, 260 &effective->mb_effective) && 261 biba_dominate_element(&effective->mb_effective, 262 &range->mb_rangelow)); 263 264 return (1); 265 } 266 267 static int 268 biba_dominate_effective(struct mac_biba *a, struct mac_biba *b) 269 { 270 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 271 ("biba_dominate_effective: a not effective")); 272 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 273 ("biba_dominate_effective: b not effective")); 274 275 return (biba_dominate_element(&a->mb_effective, &b->mb_effective)); 276 } 277 278 static int 279 biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 280 { 281 282 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 283 b->mbe_type == MAC_BIBA_TYPE_EQUAL) 284 return (1); 285 286 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 287 } 288 289 static int 290 biba_equal_effective(struct mac_biba *a, struct mac_biba *b) 291 { 292 293 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 294 ("biba_equal_effective: a not effective")); 295 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 296 ("biba_equal_effective: b not effective")); 297 298 return (biba_equal_element(&a->mb_effective, &b->mb_effective)); 299 } 300 301 static int 302 biba_contains_equal(struct mac_biba *mb) 303 { 304 305 if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 306 if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 307 return (1); 308 } 309 310 if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 311 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 312 return (1); 313 if (mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 314 return (1); 315 } 316 317 return (0); 318 } 319 320 static int 321 biba_subject_privileged(struct mac_biba *mb) 322 { 323 324 KASSERT((mb->mb_flags & MAC_BIBA_FLAGS_BOTH) == MAC_BIBA_FLAGS_BOTH, 325 ("biba_subject_privileged: subject doesn't have both labels")); 326 327 /* If the effective is EQUAL, it's ok. */ 328 if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 329 return (0); 330 331 /* If either range endpoint is EQUAL, it's ok. */ 332 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 333 mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 334 return (0); 335 336 /* If the range is low-high, it's ok. */ 337 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 338 mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 339 return (0); 340 341 /* It's not ok. */ 342 return (EPERM); 343 } 344 345 static int 346 biba_high_effective(struct mac_biba *mb) 347 { 348 349 KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 350 ("biba_equal_effective: mb not effective")); 351 352 return (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH); 353 } 354 355 static int 356 biba_valid(struct mac_biba *mb) 357 { 358 359 if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 360 switch (mb->mb_effective.mbe_type) { 361 case MAC_BIBA_TYPE_GRADE: 362 break; 363 364 case MAC_BIBA_TYPE_EQUAL: 365 case MAC_BIBA_TYPE_HIGH: 366 case MAC_BIBA_TYPE_LOW: 367 if (mb->mb_effective.mbe_grade != 0 || 368 !MAC_BIBA_BIT_SET_EMPTY( 369 mb->mb_effective.mbe_compartments)) 370 return (EINVAL); 371 break; 372 373 default: 374 return (EINVAL); 375 } 376 } else { 377 if (mb->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF) 378 return (EINVAL); 379 } 380 381 if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 382 switch (mb->mb_rangelow.mbe_type) { 383 case MAC_BIBA_TYPE_GRADE: 384 break; 385 386 case MAC_BIBA_TYPE_EQUAL: 387 case MAC_BIBA_TYPE_HIGH: 388 case MAC_BIBA_TYPE_LOW: 389 if (mb->mb_rangelow.mbe_grade != 0 || 390 !MAC_BIBA_BIT_SET_EMPTY( 391 mb->mb_rangelow.mbe_compartments)) 392 return (EINVAL); 393 break; 394 395 default: 396 return (EINVAL); 397 } 398 399 switch (mb->mb_rangehigh.mbe_type) { 400 case MAC_BIBA_TYPE_GRADE: 401 break; 402 403 case MAC_BIBA_TYPE_EQUAL: 404 case MAC_BIBA_TYPE_HIGH: 405 case MAC_BIBA_TYPE_LOW: 406 if (mb->mb_rangehigh.mbe_grade != 0 || 407 !MAC_BIBA_BIT_SET_EMPTY( 408 mb->mb_rangehigh.mbe_compartments)) 409 return (EINVAL); 410 break; 411 412 default: 413 return (EINVAL); 414 } 415 if (!biba_dominate_element(&mb->mb_rangehigh, 416 &mb->mb_rangelow)) 417 return (EINVAL); 418 } else { 419 if (mb->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 420 mb->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 421 return (EINVAL); 422 } 423 424 return (0); 425 } 426 427 static void 428 biba_set_range(struct mac_biba *mb, u_short typelow, u_short gradelow, 429 u_char *compartmentslow, u_short typehigh, u_short gradehigh, 430 u_char *compartmentshigh) 431 { 432 433 mb->mb_rangelow.mbe_type = typelow; 434 mb->mb_rangelow.mbe_grade = gradelow; 435 if (compartmentslow != NULL) 436 memcpy(mb->mb_rangelow.mbe_compartments, compartmentslow, 437 sizeof(mb->mb_rangelow.mbe_compartments)); 438 mb->mb_rangehigh.mbe_type = typehigh; 439 mb->mb_rangehigh.mbe_grade = gradehigh; 440 if (compartmentshigh != NULL) 441 memcpy(mb->mb_rangehigh.mbe_compartments, compartmentshigh, 442 sizeof(mb->mb_rangehigh.mbe_compartments)); 443 mb->mb_flags |= MAC_BIBA_FLAG_RANGE; 444 } 445 446 static void 447 biba_set_effective(struct mac_biba *mb, u_short type, u_short grade, 448 u_char *compartments) 449 { 450 451 mb->mb_effective.mbe_type = type; 452 mb->mb_effective.mbe_grade = grade; 453 if (compartments != NULL) 454 memcpy(mb->mb_effective.mbe_compartments, compartments, 455 sizeof(mb->mb_effective.mbe_compartments)); 456 mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 457 } 458 459 static void 460 biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 461 { 462 463 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 464 ("biba_copy_range: labelfrom not range")); 465 466 labelto->mb_rangelow = labelfrom->mb_rangelow; 467 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 468 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 469 } 470 471 static void 472 biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto) 473 { 474 475 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 476 ("biba_copy_effective: labelfrom not effective")); 477 478 labelto->mb_effective = labelfrom->mb_effective; 479 labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 480 } 481 482 static void 483 biba_copy(struct mac_biba *source, struct mac_biba *dest) 484 { 485 486 if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) 487 biba_copy_effective(source, dest); 488 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 489 biba_copy_range(source, dest); 490 } 491 492 /* 493 * Policy module operations. 494 */ 495 static void 496 biba_init(struct mac_policy_conf *conf) 497 { 498 499 zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL, 500 NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 501 } 502 503 /* 504 * Label operations. 505 */ 506 static void 507 biba_init_label(struct label *label) 508 { 509 510 SLOT_SET(label, biba_alloc(M_WAITOK)); 511 } 512 513 static int 514 biba_init_label_waitcheck(struct label *label, int flag) 515 { 516 517 SLOT_SET(label, biba_alloc(flag)); 518 if (SLOT(label) == NULL) 519 return (ENOMEM); 520 521 return (0); 522 } 523 524 static void 525 biba_destroy_label(struct label *label) 526 { 527 528 biba_free(SLOT(label)); 529 SLOT_SET(label, NULL); 530 } 531 532 /* 533 * biba_element_to_string() accepts an sbuf and Biba element. It converts 534 * the Biba element to a string and stores the result in the sbuf; if there 535 * isn't space in the sbuf, -1 is returned. 536 */ 537 static int 538 biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element) 539 { 540 int i, first; 541 542 switch (element->mbe_type) { 543 case MAC_BIBA_TYPE_HIGH: 544 return (sbuf_printf(sb, "high")); 545 546 case MAC_BIBA_TYPE_LOW: 547 return (sbuf_printf(sb, "low")); 548 549 case MAC_BIBA_TYPE_EQUAL: 550 return (sbuf_printf(sb, "equal")); 551 552 case MAC_BIBA_TYPE_GRADE: 553 if (sbuf_printf(sb, "%d", element->mbe_grade) == -1) 554 return (-1); 555 556 first = 1; 557 for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) { 558 if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) { 559 if (first) { 560 if (sbuf_putc(sb, ':') == -1) 561 return (-1); 562 if (sbuf_printf(sb, "%d", i) == -1) 563 return (-1); 564 first = 0; 565 } else { 566 if (sbuf_printf(sb, "+%d", i) == -1) 567 return (-1); 568 } 569 } 570 } 571 return (0); 572 573 default: 574 panic("biba_element_to_string: invalid type (%d)", 575 element->mbe_type); 576 } 577 } 578 579 /* 580 * biba_to_string() converts a Biba label to a string, and places the results 581 * in the passed sbuf. It returns 0 on success, or EINVAL if there isn't 582 * room in the sbuf. Note: the sbuf will be modified even in a failure case, 583 * so the caller may need to revert the sbuf by restoring the offset if 584 * that's undesired. 585 */ 586 static int 587 biba_to_string(struct sbuf *sb, struct mac_biba *mb) 588 { 589 590 if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 591 if (biba_element_to_string(sb, &mb->mb_effective) == -1) 592 return (EINVAL); 593 } 594 595 if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 596 if (sbuf_putc(sb, '(') == -1) 597 return (EINVAL); 598 599 if (biba_element_to_string(sb, &mb->mb_rangelow) == -1) 600 return (EINVAL); 601 602 if (sbuf_putc(sb, '-') == -1) 603 return (EINVAL); 604 605 if (biba_element_to_string(sb, &mb->mb_rangehigh) == -1) 606 return (EINVAL); 607 608 if (sbuf_putc(sb, ')') == -1) 609 return (EINVAL); 610 } 611 612 return (0); 613 } 614 615 static int 616 biba_externalize_label(struct label *label, char *element_name, 617 struct sbuf *sb, int *claimed) 618 { 619 struct mac_biba *mb; 620 621 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 622 return (0); 623 624 (*claimed)++; 625 626 mb = SLOT(label); 627 return (biba_to_string(sb, mb)); 628 } 629 630 static int 631 biba_parse_element(struct mac_biba_element *element, char *string) 632 { 633 char *compartment, *end, *grade; 634 int value; 635 636 if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { 637 element->mbe_type = MAC_BIBA_TYPE_HIGH; 638 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 639 } else if (strcmp(string, "low") == 0 || 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 are 662 * included, we assume that the label has no compartments. 663 */ 664 if (string == NULL) 665 return (0); 666 if (*string == '\0') 667 return (0); 668 669 while ((compartment = strsep(&string, "+")) != NULL) { 670 value = strtol(compartment, &end, 10); 671 if (compartment == end || *end != '\0') 672 return (EINVAL); 673 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 674 return (EINVAL); 675 MAC_BIBA_BIT_SET(value, element->mbe_compartments); 676 } 677 } 678 679 return (0); 680 } 681 682 /* 683 * Note: destructively consumes the string, make a local copy before calling 684 * if that's a problem. 685 */ 686 static int 687 biba_parse(struct mac_biba *mb, char *string) 688 { 689 char *rangehigh, *rangelow, *effective; 690 int error; 691 692 effective = strsep(&string, "("); 693 if (*effective == '\0') 694 effective = NULL; 695 696 if (string != NULL) { 697 rangelow = strsep(&string, "-"); 698 if (string == NULL) 699 return (EINVAL); 700 rangehigh = strsep(&string, ")"); 701 if (string == NULL) 702 return (EINVAL); 703 if (*string != '\0') 704 return (EINVAL); 705 } else { 706 rangelow = NULL; 707 rangehigh = NULL; 708 } 709 710 KASSERT((rangelow != NULL && rangehigh != NULL) || 711 (rangelow == NULL && rangehigh == NULL), 712 ("biba_parse: range mismatch")); 713 714 bzero(mb, sizeof(*mb)); 715 if (effective != NULL) { 716 error = biba_parse_element(&mb->mb_effective, effective); 717 if (error) 718 return (error); 719 mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 720 } 721 722 if (rangelow != NULL) { 723 error = biba_parse_element(&mb->mb_rangelow, rangelow); 724 if (error) 725 return (error); 726 error = biba_parse_element(&mb->mb_rangehigh, rangehigh); 727 if (error) 728 return (error); 729 mb->mb_flags |= MAC_BIBA_FLAG_RANGE; 730 } 731 732 error = biba_valid(mb); 733 if (error) 734 return (error); 735 736 return (0); 737 } 738 739 static int 740 biba_internalize_label(struct label *label, char *element_name, 741 char *element_data, int *claimed) 742 { 743 struct mac_biba *mb, mb_temp; 744 int error; 745 746 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 747 return (0); 748 749 (*claimed)++; 750 751 error = biba_parse(&mb_temp, element_data); 752 if (error) 753 return (error); 754 755 mb = SLOT(label); 756 *mb = mb_temp; 757 758 return (0); 759 } 760 761 static void 762 biba_copy_label(struct label *src, struct label *dest) 763 { 764 765 *SLOT(dest) = *SLOT(src); 766 } 767 768 /* 769 * Object-specific entry point implementations are sorted alphabetically by 770 * object type name and then by operation. 771 */ 772 static int 773 biba_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 774 struct ifnet *ifp, struct label *ifplabel) 775 { 776 struct mac_biba *a, *b; 777 778 if (!biba_enabled) 779 return (0); 780 781 a = SLOT(dlabel); 782 b = SLOT(ifplabel); 783 784 if (biba_equal_effective(a, b)) 785 return (0); 786 return (EACCES); 787 } 788 789 static void 790 biba_bpfdesc_create(struct ucred *cred, struct bpf_d *d, 791 struct label *dlabel) 792 { 793 struct mac_biba *source, *dest; 794 795 source = SLOT(cred->cr_label); 796 dest = SLOT(dlabel); 797 798 biba_copy_effective(source, dest); 799 } 800 801 static void 802 biba_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 803 struct mbuf *m, struct label *mlabel) 804 { 805 struct mac_biba *source, *dest; 806 807 source = SLOT(dlabel); 808 dest = SLOT(mlabel); 809 810 biba_copy_effective(source, dest); 811 } 812 813 static void 814 biba_cred_associate_nfsd(struct ucred *cred) 815 { 816 struct mac_biba *label; 817 818 label = SLOT(cred->cr_label); 819 biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL); 820 biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 821 0, NULL); 822 } 823 824 static int 825 biba_cred_check_relabel(struct ucred *cred, struct label *newlabel) 826 { 827 struct mac_biba *subj, *new; 828 int error; 829 830 subj = SLOT(cred->cr_label); 831 new = SLOT(newlabel); 832 833 /* 834 * If there is a Biba label update for the credential, it may 835 * be an update of the effective, range, or both. 836 */ 837 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 838 if (error) 839 return (error); 840 841 /* 842 * If the Biba label is to be changed, authorize as appropriate. 843 */ 844 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 845 /* 846 * If the change request modifies both the Biba label 847 * effective and range, check that the new effective will be 848 * in the new range. 849 */ 850 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 851 MAC_BIBA_FLAGS_BOTH && 852 !biba_effective_in_range(new, new)) 853 return (EINVAL); 854 855 /* 856 * To change the Biba effective label on a credential, the 857 * new effective label must be in the current range. 858 */ 859 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE && 860 !biba_effective_in_range(new, subj)) 861 return (EPERM); 862 863 /* 864 * To change the Biba range on a credential, the new range 865 * label must be in the current range. 866 */ 867 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 868 !biba_range_in_range(new, subj)) 869 return (EPERM); 870 871 /* 872 * To have EQUAL in any component of the new credential Biba 873 * label, the subject must already have EQUAL in their label. 874 */ 875 if (biba_contains_equal(new)) { 876 error = biba_subject_privileged(subj); 877 if (error) 878 return (error); 879 } 880 } 881 882 return (0); 883 } 884 885 static int 886 biba_cred_check_visible(struct ucred *u1, struct ucred *u2) 887 { 888 struct mac_biba *subj, *obj; 889 890 if (!biba_enabled) 891 return (0); 892 893 subj = SLOT(u1->cr_label); 894 obj = SLOT(u2->cr_label); 895 896 /* XXX: range */ 897 if (!biba_dominate_effective(obj, subj)) 898 return (ESRCH); 899 900 return (0); 901 } 902 903 static void 904 biba_cred_create_init(struct ucred *cred) 905 { 906 struct mac_biba *dest; 907 908 dest = SLOT(cred->cr_label); 909 910 biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 911 biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 912 0, NULL); 913 } 914 915 static void 916 biba_cred_create_swapper(struct ucred *cred) 917 { 918 struct mac_biba *dest; 919 920 dest = SLOT(cred->cr_label); 921 922 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 923 biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 924 0, NULL); 925 } 926 927 static void 928 biba_cred_relabel(struct ucred *cred, struct label *newlabel) 929 { 930 struct mac_biba *source, *dest; 931 932 source = SLOT(newlabel); 933 dest = SLOT(cred->cr_label); 934 935 biba_copy(source, dest); 936 } 937 938 static void 939 biba_devfs_create_device(struct ucred *cred, struct mount *mp, 940 struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 941 { 942 struct mac_biba *mb; 943 const char *dn; 944 int biba_type; 945 946 mb = SLOT(delabel); 947 dn = devtoname(dev); 948 if (strcmp(dn, "null") == 0 || 949 strcmp(dn, "zero") == 0 || 950 strcmp(dn, "random") == 0 || 951 strncmp(dn, "fd/", strlen("fd/")) == 0) 952 biba_type = MAC_BIBA_TYPE_EQUAL; 953 else if (ptys_equal && 954 (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 955 strncmp(dn, "pts/", strlen("pts/")) == 0 || 956 strncmp(dn, "ptyp", strlen("ptyp")) == 0)) 957 biba_type = MAC_BIBA_TYPE_EQUAL; 958 else 959 biba_type = MAC_BIBA_TYPE_HIGH; 960 biba_set_effective(mb, biba_type, 0, NULL); 961 } 962 963 static void 964 biba_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 965 struct devfs_dirent *de, struct label *delabel) 966 { 967 struct mac_biba *mb; 968 969 mb = SLOT(delabel); 970 971 biba_set_effective(mb, MAC_BIBA_TYPE_HIGH, 0, NULL); 972 } 973 974 static void 975 biba_devfs_create_symlink(struct ucred *cred, struct mount *mp, 976 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 977 struct label *delabel) 978 { 979 struct mac_biba *source, *dest; 980 981 source = SLOT(cred->cr_label); 982 dest = SLOT(delabel); 983 984 biba_copy_effective(source, dest); 985 } 986 987 static void 988 biba_devfs_update(struct mount *mp, struct devfs_dirent *de, 989 struct label *delabel, struct vnode *vp, struct label *vplabel) 990 { 991 struct mac_biba *source, *dest; 992 993 source = SLOT(vplabel); 994 dest = SLOT(delabel); 995 996 biba_copy(source, dest); 997 } 998 999 static void 1000 biba_devfs_vnode_associate(struct mount *mp, struct label *mntlabel, 1001 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 1002 struct label *vplabel) 1003 { 1004 struct mac_biba *source, *dest; 1005 1006 source = SLOT(delabel); 1007 dest = SLOT(vplabel); 1008 1009 biba_copy_effective(source, dest); 1010 } 1011 1012 static int 1013 biba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1014 struct label *ifplabel, struct label *newlabel) 1015 { 1016 struct mac_biba *subj, *new; 1017 int error; 1018 1019 subj = SLOT(cred->cr_label); 1020 new = SLOT(newlabel); 1021 1022 /* 1023 * If there is a Biba label update for the interface, it may be an 1024 * update of the effective, range, or both. 1025 */ 1026 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1027 if (error) 1028 return (error); 1029 1030 /* 1031 * Relabling network interfaces requires Biba privilege. 1032 */ 1033 error = biba_subject_privileged(subj); 1034 if (error) 1035 return (error); 1036 1037 return (0); 1038 } 1039 1040 static int 1041 biba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1042 struct mbuf *m, struct label *mlabel) 1043 { 1044 struct mac_biba *p, *i; 1045 1046 if (!biba_enabled) 1047 return (0); 1048 1049 p = SLOT(mlabel); 1050 i = SLOT(ifplabel); 1051 1052 return (biba_effective_in_range(p, i) ? 0 : EACCES); 1053 } 1054 1055 static void 1056 biba_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1057 { 1058 char tifname[IFNAMSIZ], *p, *q; 1059 char tiflist[sizeof(trusted_interfaces)]; 1060 struct mac_biba *dest; 1061 int len, type; 1062 1063 dest = SLOT(ifplabel); 1064 1065 if (if_gettype(ifp) == IFT_LOOP || interfaces_equal != 0) { 1066 type = MAC_BIBA_TYPE_EQUAL; 1067 goto set; 1068 } 1069 1070 if (trust_all_interfaces) { 1071 type = MAC_BIBA_TYPE_HIGH; 1072 goto set; 1073 } 1074 1075 type = MAC_BIBA_TYPE_LOW; 1076 1077 if (trusted_interfaces[0] == '\0' || 1078 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1079 goto set; 1080 1081 bzero(tiflist, sizeof(tiflist)); 1082 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1083 if(*p != ' ' && *p != '\t') 1084 *q = *p; 1085 1086 for (p = q = tiflist;; p++) { 1087 if (*p == ',' || *p == '\0') { 1088 len = p - q; 1089 if (len < IFNAMSIZ) { 1090 bzero(tifname, sizeof(tifname)); 1091 bcopy(q, tifname, len); 1092 if (strcmp(tifname, if_name(ifp)) == 0) { 1093 type = MAC_BIBA_TYPE_HIGH; 1094 break; 1095 } 1096 } else { 1097 *p = '\0'; 1098 printf("mac_biba warning: interface name " 1099 "\"%s\" is too long (must be < %d)\n", 1100 q, IFNAMSIZ); 1101 } 1102 if (*p == '\0') 1103 break; 1104 q = p + 1; 1105 } 1106 } 1107 set: 1108 biba_set_effective(dest, type, 0, NULL); 1109 biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1110 } 1111 1112 static void 1113 biba_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1114 struct mbuf *m, struct label *mlabel) 1115 { 1116 struct mac_biba *source, *dest; 1117 1118 source = SLOT(ifplabel); 1119 dest = SLOT(mlabel); 1120 1121 biba_copy_effective(source, dest); 1122 } 1123 1124 static void 1125 biba_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1126 struct label *ifplabel, struct label *newlabel) 1127 { 1128 struct mac_biba *source, *dest; 1129 1130 source = SLOT(newlabel); 1131 dest = SLOT(ifplabel); 1132 1133 biba_copy(source, dest); 1134 } 1135 1136 static int 1137 biba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1138 struct mbuf *m, struct label *mlabel) 1139 { 1140 struct mac_biba *p, *i; 1141 1142 if (!biba_enabled) 1143 return (0); 1144 1145 p = SLOT(mlabel); 1146 i = SLOT(inplabel); 1147 1148 return (biba_equal_effective(p, i) ? 0 : EACCES); 1149 } 1150 1151 static int 1152 biba_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 1153 struct label *inplabel) 1154 { 1155 struct mac_biba *subj, *obj; 1156 1157 if (!biba_enabled) 1158 return (0); 1159 1160 subj = SLOT(cred->cr_label); 1161 obj = SLOT(inplabel); 1162 1163 if (!biba_dominate_effective(obj, subj)) 1164 return (ENOENT); 1165 1166 return (0); 1167 } 1168 1169 static void 1170 biba_inpcb_create(struct socket *so, struct label *solabel, 1171 struct inpcb *inp, struct label *inplabel) 1172 { 1173 struct mac_biba *source, *dest; 1174 1175 source = SLOT(solabel); 1176 dest = SLOT(inplabel); 1177 1178 SOCK_LOCK(so); 1179 biba_copy_effective(source, dest); 1180 SOCK_UNLOCK(so); 1181 } 1182 1183 static void 1184 biba_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1185 struct mbuf *m, struct label *mlabel) 1186 { 1187 struct mac_biba *source, *dest; 1188 1189 source = SLOT(inplabel); 1190 dest = SLOT(mlabel); 1191 1192 biba_copy_effective(source, dest); 1193 } 1194 1195 static void 1196 biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1197 struct inpcb *inp, struct label *inplabel) 1198 { 1199 struct mac_biba *source, *dest; 1200 1201 SOCK_LOCK_ASSERT(so); 1202 1203 source = SLOT(solabel); 1204 dest = SLOT(inplabel); 1205 1206 biba_copy(source, dest); 1207 } 1208 1209 static void 1210 biba_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1211 struct label *q6label) 1212 { 1213 struct mac_biba *source, *dest; 1214 1215 source = SLOT(mlabel); 1216 dest = SLOT(q6label); 1217 1218 biba_copy_effective(source, dest); 1219 } 1220 1221 static int 1222 biba_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1223 struct label *q6label) 1224 { 1225 struct mac_biba *a, *b; 1226 1227 a = SLOT(q6label); 1228 b = SLOT(mlabel); 1229 1230 return (biba_equal_effective(a, b)); 1231 } 1232 1233 static void 1234 biba_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1235 struct label *mlabel) 1236 { 1237 struct mac_biba *source, *dest; 1238 1239 source = SLOT(q6label); 1240 dest = SLOT(mlabel); 1241 1242 /* Just use the head, since we require them all to match. */ 1243 biba_copy_effective(source, dest); 1244 } 1245 1246 static void 1247 biba_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1248 struct label *q6label) 1249 { 1250 1251 /* NOOP: we only accept matching labels, so no need to update */ 1252 } 1253 1254 static void 1255 biba_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1256 struct label *qlabel) 1257 { 1258 struct mac_biba *source, *dest; 1259 1260 source = SLOT(mlabel); 1261 dest = SLOT(qlabel); 1262 1263 biba_copy_effective(source, dest); 1264 } 1265 1266 static int 1267 biba_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1268 struct label *qlabel) 1269 { 1270 struct mac_biba *a, *b; 1271 1272 a = SLOT(qlabel); 1273 b = SLOT(mlabel); 1274 1275 return (biba_equal_effective(a, b)); 1276 } 1277 1278 static void 1279 biba_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1280 struct label *mlabel) 1281 { 1282 struct mac_biba *source, *dest; 1283 1284 source = SLOT(qlabel); 1285 dest = SLOT(mlabel); 1286 1287 /* Just use the head, since we require them all to match. */ 1288 biba_copy_effective(source, dest); 1289 } 1290 1291 static void 1292 biba_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1293 struct label *qlabel) 1294 { 1295 1296 /* NOOP: we only accept matching labels, so no need to update */ 1297 } 1298 1299 static int 1300 biba_kld_check_load(struct ucred *cred, struct vnode *vp, 1301 struct label *vplabel) 1302 { 1303 struct mac_biba *subj, *obj; 1304 int error; 1305 1306 if (!biba_enabled) 1307 return (0); 1308 1309 subj = SLOT(cred->cr_label); 1310 1311 error = biba_subject_privileged(subj); 1312 if (error) 1313 return (error); 1314 1315 obj = SLOT(vplabel); 1316 if (!biba_high_effective(obj)) 1317 return (EACCES); 1318 1319 return (0); 1320 } 1321 1322 static int 1323 biba_mount_check_stat(struct ucred *cred, struct mount *mp, 1324 struct label *mplabel) 1325 { 1326 struct mac_biba *subj, *obj; 1327 1328 if (!biba_enabled) 1329 return (0); 1330 1331 subj = SLOT(cred->cr_label); 1332 obj = SLOT(mplabel); 1333 1334 if (!biba_dominate_effective(obj, subj)) 1335 return (EACCES); 1336 1337 return (0); 1338 } 1339 1340 static void 1341 biba_mount_create(struct ucred *cred, struct mount *mp, 1342 struct label *mplabel) 1343 { 1344 struct mac_biba *source, *dest; 1345 1346 source = SLOT(cred->cr_label); 1347 dest = SLOT(mplabel); 1348 1349 biba_copy_effective(source, dest); 1350 } 1351 1352 static void 1353 biba_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1354 struct mbuf *m, struct label *mlabel) 1355 { 1356 struct mac_biba *dest; 1357 1358 dest = SLOT(mlabel); 1359 1360 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1361 } 1362 1363 static void 1364 biba_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1365 struct mbuf *msend, struct label *msendlabel) 1366 { 1367 struct mac_biba *source, *dest; 1368 1369 source = SLOT(mrecvlabel); 1370 dest = SLOT(msendlabel); 1371 1372 biba_copy_effective(source, dest); 1373 } 1374 1375 static void 1376 biba_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1377 { 1378 struct mac_biba *dest; 1379 1380 dest = SLOT(mlabel); 1381 1382 /* XXX: where is the label for the firewall really coming from? */ 1383 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1384 } 1385 1386 static void 1387 biba_netinet_fragment(struct mbuf *m, struct label *mlabel, 1388 struct mbuf *frag, struct label *fraglabel) 1389 { 1390 struct mac_biba *source, *dest; 1391 1392 source = SLOT(mlabel); 1393 dest = SLOT(fraglabel); 1394 1395 biba_copy_effective(source, dest); 1396 } 1397 1398 static void 1399 biba_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1400 struct mbuf *msend, struct label *msendlabel) 1401 { 1402 struct mac_biba *source, *dest; 1403 1404 source = SLOT(mrecvlabel); 1405 dest = SLOT(msendlabel); 1406 1407 biba_copy_effective(source, dest); 1408 } 1409 1410 static void 1411 biba_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1412 struct mbuf *m, struct label *mlabel) 1413 { 1414 struct mac_biba *dest; 1415 1416 dest = SLOT(mlabel); 1417 1418 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1419 } 1420 1421 static void 1422 biba_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1423 struct mbuf *m, struct label *mlabel) 1424 { 1425 struct mac_biba *dest; 1426 1427 dest = SLOT(mlabel); 1428 1429 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1430 } 1431 1432 static int 1433 biba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1434 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1435 { 1436 1437 if(!biba_enabled) 1438 return (0); 1439 1440 /* XXX: This will be implemented soon... */ 1441 1442 return (0); 1443 } 1444 1445 static int 1446 biba_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1447 struct label *pplabel) 1448 { 1449 struct mac_biba *subj, *obj; 1450 1451 if (!biba_enabled) 1452 return (0); 1453 1454 subj = SLOT(cred->cr_label); 1455 obj = SLOT(pplabel); 1456 1457 if (!biba_dominate_effective(obj, subj)) 1458 return (EACCES); 1459 1460 return (0); 1461 } 1462 1463 static int 1464 biba_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1465 struct label *pplabel) 1466 { 1467 struct mac_biba *subj, *obj; 1468 1469 if (!biba_enabled) 1470 return (0); 1471 1472 subj = SLOT(cred->cr_label); 1473 obj = SLOT(pplabel); 1474 1475 if (!biba_dominate_effective(obj, subj)) 1476 return (EACCES); 1477 1478 return (0); 1479 } 1480 1481 static int 1482 biba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1483 struct label *pplabel, struct label *newlabel) 1484 { 1485 struct mac_biba *subj, *obj, *new; 1486 int error; 1487 1488 new = SLOT(newlabel); 1489 subj = SLOT(cred->cr_label); 1490 obj = SLOT(pplabel); 1491 1492 /* 1493 * If there is a Biba label update for a pipe, it must be a effective 1494 * update. 1495 */ 1496 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 1497 if (error) 1498 return (error); 1499 1500 /* 1501 * To perform a relabel of a pipe (Biba label or not), Biba must 1502 * authorize the relabel. 1503 */ 1504 if (!biba_effective_in_range(obj, subj)) 1505 return (EPERM); 1506 1507 /* 1508 * If the Biba label is to be changed, authorize as appropriate. 1509 */ 1510 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 1511 /* 1512 * To change the Biba label on a pipe, the new pipe label 1513 * must be in the subject range. 1514 */ 1515 if (!biba_effective_in_range(new, subj)) 1516 return (EPERM); 1517 1518 /* 1519 * To change the Biba label on a pipe to be EQUAL, the 1520 * subject must have appropriate privilege. 1521 */ 1522 if (biba_contains_equal(new)) { 1523 error = biba_subject_privileged(subj); 1524 if (error) 1525 return (error); 1526 } 1527 } 1528 1529 return (0); 1530 } 1531 1532 static int 1533 biba_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 1534 struct label *pplabel) 1535 { 1536 struct mac_biba *subj, *obj; 1537 1538 if (!biba_enabled) 1539 return (0); 1540 1541 subj = SLOT(cred->cr_label); 1542 obj = SLOT(pplabel); 1543 1544 if (!biba_dominate_effective(obj, subj)) 1545 return (EACCES); 1546 1547 return (0); 1548 } 1549 1550 static int 1551 biba_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1552 struct label *pplabel) 1553 { 1554 struct mac_biba *subj, *obj; 1555 1556 if (!biba_enabled) 1557 return (0); 1558 1559 subj = SLOT(cred->cr_label); 1560 obj = SLOT(pplabel); 1561 1562 if (!biba_dominate_effective(subj, obj)) 1563 return (EACCES); 1564 1565 return (0); 1566 } 1567 1568 static void 1569 biba_pipe_create(struct ucred *cred, struct pipepair *pp, 1570 struct label *pplabel) 1571 { 1572 struct mac_biba *source, *dest; 1573 1574 source = SLOT(cred->cr_label); 1575 dest = SLOT(pplabel); 1576 1577 biba_copy_effective(source, dest); 1578 } 1579 1580 static void 1581 biba_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1582 struct label *pplabel, struct label *newlabel) 1583 { 1584 struct mac_biba *source, *dest; 1585 1586 source = SLOT(newlabel); 1587 dest = SLOT(pplabel); 1588 1589 biba_copy(source, dest); 1590 } 1591 1592 static int 1593 biba_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks, 1594 struct label *kslabel) 1595 { 1596 struct mac_biba *subj, *obj; 1597 1598 if (!biba_enabled) 1599 return (0); 1600 1601 subj = SLOT(cred->cr_label); 1602 obj = SLOT(kslabel); 1603 1604 if (!biba_dominate_effective(subj, obj)) 1605 return (EACCES); 1606 1607 return (0); 1608 } 1609 1610 static int 1611 biba_posixsem_check_setmode(struct ucred *cred, struct ksem *ks, 1612 struct label *kslabel, mode_t mode) 1613 { 1614 struct mac_biba *subj, *obj; 1615 1616 if (!biba_enabled) 1617 return (0); 1618 1619 subj = SLOT(cred->cr_label); 1620 obj = SLOT(kslabel); 1621 1622 if (!biba_dominate_effective(subj, obj)) 1623 return (EACCES); 1624 1625 return (0); 1626 } 1627 1628 static int 1629 biba_posixsem_check_setowner(struct ucred *cred, struct ksem *ks, 1630 struct label *kslabel, uid_t uid, gid_t gid) 1631 { 1632 struct mac_biba *subj, *obj; 1633 1634 if (!biba_enabled) 1635 return (0); 1636 1637 subj = SLOT(cred->cr_label); 1638 obj = SLOT(kslabel); 1639 1640 if (!biba_dominate_effective(subj, obj)) 1641 return (EACCES); 1642 1643 return (0); 1644 } 1645 1646 static int 1647 biba_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred, 1648 struct ksem *ks, struct label *kslabel) 1649 { 1650 struct mac_biba *subj, *obj; 1651 1652 if (!biba_enabled) 1653 return (0); 1654 1655 subj = SLOT(active_cred->cr_label); 1656 obj = SLOT(kslabel); 1657 1658 if (!biba_dominate_effective(subj, obj)) 1659 return (EACCES); 1660 1661 return (0); 1662 } 1663 1664 static int 1665 biba_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred, 1666 struct ksem *ks, struct label *kslabel) 1667 { 1668 struct mac_biba *subj, *obj; 1669 1670 if (!biba_enabled) 1671 return (0); 1672 1673 subj = SLOT(active_cred->cr_label); 1674 obj = SLOT(kslabel); 1675 1676 if (!biba_dominate_effective(obj, subj)) 1677 return (EACCES); 1678 1679 return (0); 1680 } 1681 1682 static void 1683 biba_posixsem_create(struct ucred *cred, struct ksem *ks, 1684 struct label *kslabel) 1685 { 1686 struct mac_biba *source, *dest; 1687 1688 source = SLOT(cred->cr_label); 1689 dest = SLOT(kslabel); 1690 1691 biba_copy_effective(source, dest); 1692 } 1693 1694 static int 1695 biba_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd, 1696 struct label *shmlabel, int prot, int flags) 1697 { 1698 struct mac_biba *subj, *obj; 1699 1700 if (!biba_enabled || !revocation_enabled) 1701 return (0); 1702 1703 subj = SLOT(cred->cr_label); 1704 obj = SLOT(shmlabel); 1705 1706 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 1707 if (!biba_dominate_effective(obj, subj)) 1708 return (EACCES); 1709 } 1710 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 1711 if (!biba_dominate_effective(subj, obj)) 1712 return (EACCES); 1713 } 1714 1715 return (0); 1716 } 1717 1718 static int 1719 biba_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd, 1720 struct label *shmlabel, accmode_t accmode) 1721 { 1722 struct mac_biba *subj, *obj; 1723 1724 if (!biba_enabled) 1725 return (0); 1726 1727 subj = SLOT(cred->cr_label); 1728 obj = SLOT(shmlabel); 1729 1730 if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 1731 if (!biba_dominate_effective(obj, subj)) 1732 return (EACCES); 1733 } 1734 if (accmode & VMODIFY_PERMS) { 1735 if (!biba_dominate_effective(subj, obj)) 1736 return (EACCES); 1737 } 1738 1739 return (0); 1740 } 1741 1742 static int 1743 biba_posixshm_check_read(struct ucred *active_cred, struct ucred *file_cred, 1744 struct shmfd *vp, struct label *shmlabel) 1745 { 1746 struct mac_biba *subj, *obj; 1747 1748 if (!biba_enabled || !revocation_enabled) 1749 return (0); 1750 1751 subj = SLOT(active_cred->cr_label); 1752 obj = SLOT(shmlabel); 1753 1754 if (!biba_dominate_effective(obj, subj)) 1755 return (EACCES); 1756 1757 return (0); 1758 } 1759 1760 static int 1761 biba_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd, 1762 struct label *shmlabel, mode_t mode) 1763 { 1764 struct mac_biba *subj, *obj; 1765 1766 if (!biba_enabled) 1767 return (0); 1768 1769 subj = SLOT(cred->cr_label); 1770 obj = SLOT(shmlabel); 1771 1772 if (!biba_dominate_effective(subj, obj)) 1773 return (EACCES); 1774 1775 return (0); 1776 } 1777 1778 static int 1779 biba_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd, 1780 struct label *shmlabel, uid_t uid, gid_t gid) 1781 { 1782 struct mac_biba *subj, *obj; 1783 1784 if (!biba_enabled) 1785 return (0); 1786 1787 subj = SLOT(cred->cr_label); 1788 obj = SLOT(shmlabel); 1789 1790 if (!biba_dominate_effective(subj, obj)) 1791 return (EACCES); 1792 1793 return (0); 1794 } 1795 1796 static int 1797 biba_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred, 1798 struct shmfd *shmfd, struct label *shmlabel) 1799 { 1800 struct mac_biba *subj, *obj; 1801 1802 if (!biba_enabled) 1803 return (0); 1804 1805 subj = SLOT(active_cred->cr_label); 1806 obj = SLOT(shmlabel); 1807 1808 if (!biba_dominate_effective(obj, subj)) 1809 return (EACCES); 1810 1811 return (0); 1812 } 1813 1814 static int 1815 biba_posixshm_check_truncate(struct ucred *active_cred, 1816 struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel) 1817 { 1818 struct mac_biba *subj, *obj; 1819 1820 if (!biba_enabled) 1821 return (0); 1822 1823 subj = SLOT(active_cred->cr_label); 1824 obj = SLOT(shmlabel); 1825 1826 if (!biba_dominate_effective(subj, obj)) 1827 return (EACCES); 1828 1829 return (0); 1830 } 1831 1832 static int 1833 biba_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd, 1834 struct label *shmlabel) 1835 { 1836 struct mac_biba *subj, *obj; 1837 1838 if (!biba_enabled) 1839 return (0); 1840 1841 subj = SLOT(cred->cr_label); 1842 obj = SLOT(shmlabel); 1843 1844 if (!biba_dominate_effective(subj, obj)) 1845 return (EACCES); 1846 1847 return (0); 1848 } 1849 1850 static int 1851 biba_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred, 1852 struct shmfd *vp, struct label *shmlabel) 1853 { 1854 struct mac_biba *subj, *obj; 1855 1856 if (!biba_enabled || !revocation_enabled) 1857 return (0); 1858 1859 subj = SLOT(active_cred->cr_label); 1860 obj = SLOT(shmlabel); 1861 1862 if (!biba_dominate_effective(obj, subj)) 1863 return (EACCES); 1864 1865 return (0); 1866 } 1867 1868 static void 1869 biba_posixshm_create(struct ucred *cred, struct shmfd *shmfd, 1870 struct label *shmlabel) 1871 { 1872 struct mac_biba *source, *dest; 1873 1874 source = SLOT(cred->cr_label); 1875 dest = SLOT(shmlabel); 1876 1877 biba_copy_effective(source, dest); 1878 } 1879 1880 /* 1881 * Some system privileges are allowed regardless of integrity grade; others 1882 * are allowed only when running with privilege with respect to the Biba 1883 * policy as they might otherwise allow bypassing of the integrity policy. 1884 */ 1885 static int 1886 biba_priv_check(struct ucred *cred, int priv) 1887 { 1888 struct mac_biba *subj; 1889 int error; 1890 1891 if (!biba_enabled) 1892 return (0); 1893 1894 /* 1895 * Exempt only specific privileges from the Biba integrity policy. 1896 */ 1897 switch (priv) { 1898 case PRIV_KTRACE: 1899 case PRIV_MSGBUF: 1900 1901 /* 1902 * Allow processes to manipulate basic process audit properties, and 1903 * to submit audit records. 1904 */ 1905 case PRIV_AUDIT_GETAUDIT: 1906 case PRIV_AUDIT_SETAUDIT: 1907 case PRIV_AUDIT_SUBMIT: 1908 1909 /* 1910 * Allow processes to manipulate their regular UNIX credentials. 1911 */ 1912 case PRIV_CRED_SETUID: 1913 case PRIV_CRED_SETEUID: 1914 case PRIV_CRED_SETGID: 1915 case PRIV_CRED_SETEGID: 1916 case PRIV_CRED_SETGROUPS: 1917 case PRIV_CRED_SETREUID: 1918 case PRIV_CRED_SETREGID: 1919 case PRIV_CRED_SETRESUID: 1920 case PRIV_CRED_SETRESGID: 1921 1922 /* 1923 * Allow processes to perform system monitoring. 1924 */ 1925 case PRIV_SEEOTHERGIDS: 1926 case PRIV_SEEOTHERUIDS: 1927 case PRIV_SEEJAILPROC: 1928 break; 1929 1930 /* 1931 * Allow access to general process debugging facilities. We 1932 * separately control debugging based on MAC label. 1933 */ 1934 case PRIV_DEBUG_DIFFCRED: 1935 case PRIV_DEBUG_SUGID: 1936 case PRIV_DEBUG_UNPRIV: 1937 1938 /* 1939 * Allow manipulating jails. 1940 */ 1941 case PRIV_JAIL_ATTACH: 1942 1943 /* 1944 * Allow privilege with respect to the Partition policy, but not the 1945 * Privs policy. 1946 */ 1947 case PRIV_MAC_PARTITION: 1948 1949 /* 1950 * Allow privilege with respect to process resource limits and login 1951 * context. 1952 */ 1953 case PRIV_PROC_LIMIT: 1954 case PRIV_PROC_SETLOGIN: 1955 case PRIV_PROC_SETRLIMIT: 1956 1957 /* 1958 * Allow System V and POSIX IPC privileges. 1959 */ 1960 case PRIV_IPC_READ: 1961 case PRIV_IPC_WRITE: 1962 case PRIV_IPC_ADMIN: 1963 case PRIV_IPC_MSGSIZE: 1964 case PRIV_MQ_ADMIN: 1965 1966 /* 1967 * Allow certain scheduler manipulations -- possibly this should be 1968 * controlled by more fine-grained policy, as potentially low 1969 * integrity processes can deny CPU to higher integrity ones. 1970 */ 1971 case PRIV_SCHED_DIFFCRED: 1972 case PRIV_SCHED_SETPRIORITY: 1973 case PRIV_SCHED_RTPRIO: 1974 case PRIV_SCHED_SETPOLICY: 1975 case PRIV_SCHED_SET: 1976 case PRIV_SCHED_SETPARAM: 1977 case PRIV_SCHED_IDPRIO: 1978 1979 /* 1980 * More IPC privileges. 1981 */ 1982 case PRIV_SEM_WRITE: 1983 1984 /* 1985 * Allow signaling privileges subject to integrity policy. 1986 */ 1987 case PRIV_SIGNAL_DIFFCRED: 1988 case PRIV_SIGNAL_SUGID: 1989 1990 /* 1991 * Allow access to only limited sysctls from lower integrity levels; 1992 * piggy-back on the Jail definition. 1993 */ 1994 case PRIV_SYSCTL_WRITEJAIL: 1995 1996 /* 1997 * Allow TTY-based privileges, subject to general device access using 1998 * labels on TTY device nodes, but not console privilege. 1999 */ 2000 case PRIV_TTY_DRAINWAIT: 2001 case PRIV_TTY_DTRWAIT: 2002 case PRIV_TTY_EXCLUSIVE: 2003 case PRIV_TTY_STI: 2004 case PRIV_TTY_SETA: 2005 2006 /* 2007 * Grant most VFS privileges, as almost all are in practice bounded 2008 * by more specific checks using labels. 2009 */ 2010 case PRIV_VFS_READ: 2011 case PRIV_VFS_WRITE: 2012 case PRIV_VFS_ADMIN: 2013 case PRIV_VFS_EXEC: 2014 case PRIV_VFS_LOOKUP: 2015 case PRIV_VFS_CHFLAGS_DEV: 2016 case PRIV_VFS_CHOWN: 2017 case PRIV_VFS_CHROOT: 2018 case PRIV_VFS_RETAINSUGID: 2019 case PRIV_VFS_EXCEEDQUOTA: 2020 case PRIV_VFS_FCHROOT: 2021 case PRIV_VFS_FHOPEN: 2022 case PRIV_VFS_FHSTATFS: 2023 case PRIV_VFS_GENERATION: 2024 case PRIV_VFS_GETFH: 2025 case PRIV_VFS_GETQUOTA: 2026 case PRIV_VFS_LINK: 2027 case PRIV_VFS_MOUNT: 2028 case PRIV_VFS_MOUNT_OWNER: 2029 case PRIV_VFS_MOUNT_PERM: 2030 case PRIV_VFS_MOUNT_SUIDDIR: 2031 case PRIV_VFS_MOUNT_NONUSER: 2032 case PRIV_VFS_SETGID: 2033 case PRIV_VFS_STICKYFILE: 2034 case PRIV_VFS_SYSFLAGS: 2035 case PRIV_VFS_UNMOUNT: 2036 2037 /* 2038 * Allow VM privileges; it would be nice if these were subject to 2039 * resource limits. 2040 */ 2041 case PRIV_VM_MADV_PROTECT: 2042 case PRIV_VM_MLOCK: 2043 case PRIV_VM_MUNLOCK: 2044 case PRIV_VM_SWAP_NOQUOTA: 2045 case PRIV_VM_SWAP_NORLIMIT: 2046 2047 /* 2048 * Allow some but not all network privileges. In general, dont allow 2049 * reconfiguring the network stack, just normal use. 2050 */ 2051 case PRIV_NETINET_RESERVEDPORT: 2052 case PRIV_NETINET_RAW: 2053 case PRIV_NETINET_REUSEPORT: 2054 break; 2055 2056 /* 2057 * All remaining system privileges are allow only if the process 2058 * holds privilege with respect to the Biba policy. 2059 */ 2060 default: 2061 subj = SLOT(cred->cr_label); 2062 error = biba_subject_privileged(subj); 2063 if (error) 2064 return (error); 2065 } 2066 return (0); 2067 } 2068 2069 static int 2070 biba_proc_check_debug(struct ucred *cred, struct proc *p) 2071 { 2072 struct mac_biba *subj, *obj; 2073 2074 if (!biba_enabled) 2075 return (0); 2076 2077 subj = SLOT(cred->cr_label); 2078 obj = SLOT(p->p_ucred->cr_label); 2079 2080 /* XXX: range checks */ 2081 if (!biba_dominate_effective(obj, subj)) 2082 return (ESRCH); 2083 if (!biba_dominate_effective(subj, obj)) 2084 return (EACCES); 2085 2086 return (0); 2087 } 2088 2089 static int 2090 biba_proc_check_sched(struct ucred *cred, struct proc *p) 2091 { 2092 struct mac_biba *subj, *obj; 2093 2094 if (!biba_enabled) 2095 return (0); 2096 2097 subj = SLOT(cred->cr_label); 2098 obj = SLOT(p->p_ucred->cr_label); 2099 2100 /* XXX: range checks */ 2101 if (!biba_dominate_effective(obj, subj)) 2102 return (ESRCH); 2103 if (!biba_dominate_effective(subj, obj)) 2104 return (EACCES); 2105 2106 return (0); 2107 } 2108 2109 static int 2110 biba_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 2111 { 2112 struct mac_biba *subj, *obj; 2113 2114 if (!biba_enabled) 2115 return (0); 2116 2117 subj = SLOT(cred->cr_label); 2118 obj = SLOT(p->p_ucred->cr_label); 2119 2120 /* XXX: range checks */ 2121 if (!biba_dominate_effective(obj, subj)) 2122 return (ESRCH); 2123 if (!biba_dominate_effective(subj, obj)) 2124 return (EACCES); 2125 2126 return (0); 2127 } 2128 2129 static int 2130 biba_socket_check_deliver(struct socket *so, struct label *solabel, 2131 struct mbuf *m, struct label *mlabel) 2132 { 2133 struct mac_biba *p, *s; 2134 int error; 2135 2136 if (!biba_enabled) 2137 return (0); 2138 2139 p = SLOT(mlabel); 2140 s = SLOT(solabel); 2141 2142 SOCK_LOCK(so); 2143 error = biba_equal_effective(p, s) ? 0 : EACCES; 2144 SOCK_UNLOCK(so); 2145 return (error); 2146 } 2147 2148 static int 2149 biba_socket_check_relabel(struct ucred *cred, struct socket *so, 2150 struct label *solabel, struct label *newlabel) 2151 { 2152 struct mac_biba *subj, *obj, *new; 2153 int error; 2154 2155 SOCK_LOCK_ASSERT(so); 2156 2157 new = SLOT(newlabel); 2158 subj = SLOT(cred->cr_label); 2159 obj = SLOT(solabel); 2160 2161 /* 2162 * If there is a Biba label update for the socket, it may be an 2163 * update of effective. 2164 */ 2165 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2166 if (error) 2167 return (error); 2168 2169 /* 2170 * To relabel a socket, the old socket effective must be in the 2171 * subject range. 2172 */ 2173 if (!biba_effective_in_range(obj, subj)) 2174 return (EPERM); 2175 2176 /* 2177 * If the Biba label is to be changed, authorize as appropriate. 2178 */ 2179 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2180 /* 2181 * To relabel a socket, the new socket effective must be in 2182 * the subject range. 2183 */ 2184 if (!biba_effective_in_range(new, subj)) 2185 return (EPERM); 2186 2187 /* 2188 * To change the Biba label on the socket to contain EQUAL, 2189 * the subject must have appropriate privilege. 2190 */ 2191 if (biba_contains_equal(new)) { 2192 error = biba_subject_privileged(subj); 2193 if (error) 2194 return (error); 2195 } 2196 } 2197 2198 return (0); 2199 } 2200 2201 static int 2202 biba_socket_check_visible(struct ucred *cred, struct socket *so, 2203 struct label *solabel) 2204 { 2205 struct mac_biba *subj, *obj; 2206 2207 if (!biba_enabled) 2208 return (0); 2209 2210 subj = SLOT(cred->cr_label); 2211 obj = SLOT(solabel); 2212 2213 SOCK_LOCK(so); 2214 if (!biba_dominate_effective(obj, subj)) { 2215 SOCK_UNLOCK(so); 2216 return (ENOENT); 2217 } 2218 SOCK_UNLOCK(so); 2219 2220 return (0); 2221 } 2222 2223 static void 2224 biba_socket_create(struct ucred *cred, struct socket *so, 2225 struct label *solabel) 2226 { 2227 struct mac_biba *source, *dest; 2228 2229 source = SLOT(cred->cr_label); 2230 dest = SLOT(solabel); 2231 2232 biba_copy_effective(source, dest); 2233 } 2234 2235 static void 2236 biba_socket_create_mbuf(struct socket *so, struct label *solabel, 2237 struct mbuf *m, struct label *mlabel) 2238 { 2239 struct mac_biba *source, *dest; 2240 2241 source = SLOT(solabel); 2242 dest = SLOT(mlabel); 2243 2244 SOCK_LOCK(so); 2245 biba_copy_effective(source, dest); 2246 SOCK_UNLOCK(so); 2247 } 2248 2249 static void 2250 biba_socket_newconn(struct socket *oldso, struct label *oldsolabel, 2251 struct socket *newso, struct label *newsolabel) 2252 { 2253 struct mac_biba source, *dest; 2254 2255 SOCK_LOCK(oldso); 2256 source = *SLOT(oldsolabel); 2257 SOCK_UNLOCK(oldso); 2258 2259 dest = SLOT(newsolabel); 2260 2261 SOCK_LOCK(newso); 2262 biba_copy_effective(&source, dest); 2263 SOCK_UNLOCK(newso); 2264 } 2265 2266 static void 2267 biba_socket_relabel(struct ucred *cred, struct socket *so, 2268 struct label *solabel, struct label *newlabel) 2269 { 2270 struct mac_biba *source, *dest; 2271 2272 SOCK_LOCK_ASSERT(so); 2273 2274 source = SLOT(newlabel); 2275 dest = SLOT(solabel); 2276 2277 biba_copy(source, dest); 2278 } 2279 2280 static void 2281 biba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 2282 struct socket *so, struct label *sopeerlabel) 2283 { 2284 struct mac_biba *source, *dest; 2285 2286 source = SLOT(mlabel); 2287 dest = SLOT(sopeerlabel); 2288 2289 SOCK_LOCK(so); 2290 biba_copy_effective(source, dest); 2291 SOCK_UNLOCK(so); 2292 } 2293 2294 static void 2295 biba_socketpeer_set_from_socket(struct socket *oldso, 2296 struct label *oldsolabel, struct socket *newso, 2297 struct label *newsopeerlabel) 2298 { 2299 struct mac_biba source, *dest; 2300 2301 SOCK_LOCK(oldso); 2302 source = *SLOT(oldsolabel); 2303 SOCK_UNLOCK(oldso); 2304 dest = SLOT(newsopeerlabel); 2305 2306 SOCK_LOCK(newso); 2307 biba_copy_effective(&source, dest); 2308 SOCK_UNLOCK(newso); 2309 } 2310 2311 static void 2312 biba_syncache_create(struct label *label, struct inpcb *inp) 2313 { 2314 struct mac_biba *source, *dest; 2315 2316 source = SLOT(inp->inp_label); 2317 dest = SLOT(label); 2318 biba_copy_effective(source, dest); 2319 } 2320 2321 static void 2322 biba_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2323 struct label *mlabel) 2324 { 2325 struct mac_biba *source, *dest; 2326 2327 source = SLOT(sc_label); 2328 dest = SLOT(mlabel); 2329 biba_copy_effective(source, dest); 2330 } 2331 2332 static int 2333 biba_system_check_acct(struct ucred *cred, struct vnode *vp, 2334 struct label *vplabel) 2335 { 2336 struct mac_biba *subj, *obj; 2337 int error; 2338 2339 if (!biba_enabled) 2340 return (0); 2341 2342 subj = SLOT(cred->cr_label); 2343 2344 error = biba_subject_privileged(subj); 2345 if (error) 2346 return (error); 2347 2348 if (vplabel == NULL) 2349 return (0); 2350 2351 obj = SLOT(vplabel); 2352 if (!biba_high_effective(obj)) 2353 return (EACCES); 2354 2355 return (0); 2356 } 2357 2358 static int 2359 biba_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2360 struct label *vplabel) 2361 { 2362 struct mac_biba *subj, *obj; 2363 int error; 2364 2365 if (!biba_enabled) 2366 return (0); 2367 2368 subj = SLOT(cred->cr_label); 2369 2370 error = biba_subject_privileged(subj); 2371 if (error) 2372 return (error); 2373 2374 if (vplabel == NULL) 2375 return (0); 2376 2377 obj = SLOT(vplabel); 2378 if (!biba_high_effective(obj)) 2379 return (EACCES); 2380 2381 return (0); 2382 } 2383 2384 static int 2385 biba_system_check_auditon(struct ucred *cred, int cmd) 2386 { 2387 struct mac_biba *subj; 2388 int error; 2389 2390 if (!biba_enabled) 2391 return (0); 2392 2393 subj = SLOT(cred->cr_label); 2394 2395 error = biba_subject_privileged(subj); 2396 if (error) 2397 return (error); 2398 2399 return (0); 2400 } 2401 2402 static int 2403 biba_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2404 struct label *label) 2405 { 2406 struct mac_biba *subj; 2407 int error; 2408 2409 if (!biba_enabled) 2410 return (0); 2411 2412 subj = SLOT(cred->cr_label); 2413 2414 error = biba_subject_privileged(subj); 2415 if (error) 2416 return (error); 2417 2418 return (0); 2419 } 2420 2421 static int 2422 biba_system_check_swapon(struct ucred *cred, struct vnode *vp, 2423 struct label *vplabel) 2424 { 2425 struct mac_biba *subj, *obj; 2426 int error; 2427 2428 if (!biba_enabled) 2429 return (0); 2430 2431 subj = SLOT(cred->cr_label); 2432 obj = SLOT(vplabel); 2433 2434 error = biba_subject_privileged(subj); 2435 if (error) 2436 return (error); 2437 2438 if (!biba_high_effective(obj)) 2439 return (EACCES); 2440 2441 return (0); 2442 } 2443 2444 static int 2445 biba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2446 void *arg1, int arg2, struct sysctl_req *req) 2447 { 2448 struct mac_biba *subj; 2449 int error; 2450 2451 if (!biba_enabled) 2452 return (0); 2453 2454 subj = SLOT(cred->cr_label); 2455 2456 /* 2457 * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high, 2458 * but also require privilege to change them. 2459 */ 2460 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2461 if (!biba_subject_dominate_high(subj)) 2462 return (EACCES); 2463 2464 error = biba_subject_privileged(subj); 2465 if (error) 2466 return (error); 2467 } 2468 2469 return (0); 2470 } 2471 2472 static void 2473 biba_sysvmsg_cleanup(struct label *msglabel) 2474 { 2475 2476 bzero(SLOT(msglabel), sizeof(struct mac_biba)); 2477 } 2478 2479 static void 2480 biba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2481 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 2482 { 2483 struct mac_biba *source, *dest; 2484 2485 /* Ignore the msgq label */ 2486 source = SLOT(cred->cr_label); 2487 dest = SLOT(msglabel); 2488 2489 biba_copy_effective(source, dest); 2490 } 2491 2492 static int 2493 biba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 2494 struct label *msglabel) 2495 { 2496 struct mac_biba *subj, *obj; 2497 2498 if (!biba_enabled) 2499 return (0); 2500 2501 subj = SLOT(cred->cr_label); 2502 obj = SLOT(msglabel); 2503 2504 if (!biba_dominate_effective(obj, subj)) 2505 return (EACCES); 2506 2507 return (0); 2508 } 2509 2510 static int 2511 biba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 2512 struct label *msglabel) 2513 { 2514 struct mac_biba *subj, *obj; 2515 2516 if (!biba_enabled) 2517 return (0); 2518 2519 subj = SLOT(cred->cr_label); 2520 obj = SLOT(msglabel); 2521 2522 if (!biba_dominate_effective(subj, obj)) 2523 return (EACCES); 2524 2525 return (0); 2526 } 2527 2528 static int 2529 biba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 2530 struct label *msqklabel) 2531 { 2532 struct mac_biba *subj, *obj; 2533 2534 if (!biba_enabled) 2535 return (0); 2536 2537 subj = SLOT(cred->cr_label); 2538 obj = SLOT(msqklabel); 2539 2540 if (!biba_dominate_effective(obj, subj)) 2541 return (EACCES); 2542 2543 return (0); 2544 } 2545 2546 static int 2547 biba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 2548 struct label *msqklabel) 2549 { 2550 struct mac_biba *subj, *obj; 2551 2552 if (!biba_enabled) 2553 return (0); 2554 2555 subj = SLOT(cred->cr_label); 2556 obj = SLOT(msqklabel); 2557 2558 if (!biba_dominate_effective(subj, obj)) 2559 return (EACCES); 2560 2561 return (0); 2562 } 2563 2564 static int 2565 biba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 2566 struct label *msqklabel) 2567 { 2568 struct mac_biba *subj, *obj; 2569 2570 if (!biba_enabled) 2571 return (0); 2572 2573 subj = SLOT(cred->cr_label); 2574 obj = SLOT(msqklabel); 2575 2576 if (!biba_dominate_effective(obj, subj)) 2577 return (EACCES); 2578 2579 return (0); 2580 } 2581 2582 static int 2583 biba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 2584 struct label *msqklabel, int cmd) 2585 { 2586 struct mac_biba *subj, *obj; 2587 2588 if (!biba_enabled) 2589 return (0); 2590 2591 subj = SLOT(cred->cr_label); 2592 obj = SLOT(msqklabel); 2593 2594 switch(cmd) { 2595 case IPC_RMID: 2596 case IPC_SET: 2597 if (!biba_dominate_effective(subj, obj)) 2598 return (EACCES); 2599 break; 2600 2601 case IPC_STAT: 2602 if (!biba_dominate_effective(obj, subj)) 2603 return (EACCES); 2604 break; 2605 2606 default: 2607 return (EACCES); 2608 } 2609 2610 return (0); 2611 } 2612 2613 static void 2614 biba_sysvmsq_cleanup(struct label *msqlabel) 2615 { 2616 2617 bzero(SLOT(msqlabel), sizeof(struct mac_biba)); 2618 } 2619 2620 static void 2621 biba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2622 struct label *msqlabel) 2623 { 2624 struct mac_biba *source, *dest; 2625 2626 source = SLOT(cred->cr_label); 2627 dest = SLOT(msqlabel); 2628 2629 biba_copy_effective(source, dest); 2630 } 2631 2632 static int 2633 biba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 2634 struct label *semaklabel, int cmd) 2635 { 2636 struct mac_biba *subj, *obj; 2637 2638 if (!biba_enabled) 2639 return (0); 2640 2641 subj = SLOT(cred->cr_label); 2642 obj = SLOT(semaklabel); 2643 2644 switch(cmd) { 2645 case IPC_RMID: 2646 case IPC_SET: 2647 case SETVAL: 2648 case SETALL: 2649 if (!biba_dominate_effective(subj, obj)) 2650 return (EACCES); 2651 break; 2652 2653 case IPC_STAT: 2654 case GETVAL: 2655 case GETPID: 2656 case GETNCNT: 2657 case GETZCNT: 2658 case GETALL: 2659 if (!biba_dominate_effective(obj, subj)) 2660 return (EACCES); 2661 break; 2662 2663 default: 2664 return (EACCES); 2665 } 2666 2667 return (0); 2668 } 2669 2670 static int 2671 biba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 2672 struct label *semaklabel) 2673 { 2674 struct mac_biba *subj, *obj; 2675 2676 if (!biba_enabled) 2677 return (0); 2678 2679 subj = SLOT(cred->cr_label); 2680 obj = SLOT(semaklabel); 2681 2682 if (!biba_dominate_effective(obj, subj)) 2683 return (EACCES); 2684 2685 return (0); 2686 } 2687 2688 static int 2689 biba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2690 struct label *semaklabel, size_t accesstype) 2691 { 2692 struct mac_biba *subj, *obj; 2693 2694 if (!biba_enabled) 2695 return (0); 2696 2697 subj = SLOT(cred->cr_label); 2698 obj = SLOT(semaklabel); 2699 2700 if (accesstype & SEM_R) 2701 if (!biba_dominate_effective(obj, subj)) 2702 return (EACCES); 2703 2704 if (accesstype & SEM_A) 2705 if (!biba_dominate_effective(subj, obj)) 2706 return (EACCES); 2707 2708 return (0); 2709 } 2710 2711 static void 2712 biba_sysvsem_cleanup(struct label *semalabel) 2713 { 2714 2715 bzero(SLOT(semalabel), sizeof(struct mac_biba)); 2716 } 2717 2718 static void 2719 biba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2720 struct label *semalabel) 2721 { 2722 struct mac_biba *source, *dest; 2723 2724 source = SLOT(cred->cr_label); 2725 dest = SLOT(semalabel); 2726 2727 biba_copy_effective(source, dest); 2728 } 2729 2730 static int 2731 biba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2732 struct label *shmseglabel, int shmflg) 2733 { 2734 struct mac_biba *subj, *obj; 2735 2736 if (!biba_enabled) 2737 return (0); 2738 2739 subj = SLOT(cred->cr_label); 2740 obj = SLOT(shmseglabel); 2741 2742 if (!biba_dominate_effective(obj, subj)) 2743 return (EACCES); 2744 if ((shmflg & SHM_RDONLY) == 0) { 2745 if (!biba_dominate_effective(subj, obj)) 2746 return (EACCES); 2747 } 2748 2749 return (0); 2750 } 2751 2752 static int 2753 biba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2754 struct label *shmseglabel, int cmd) 2755 { 2756 struct mac_biba *subj, *obj; 2757 2758 if (!biba_enabled) 2759 return (0); 2760 2761 subj = SLOT(cred->cr_label); 2762 obj = SLOT(shmseglabel); 2763 2764 switch(cmd) { 2765 case IPC_RMID: 2766 case IPC_SET: 2767 if (!biba_dominate_effective(subj, obj)) 2768 return (EACCES); 2769 break; 2770 2771 case IPC_STAT: 2772 case SHM_STAT: 2773 if (!biba_dominate_effective(obj, subj)) 2774 return (EACCES); 2775 break; 2776 2777 default: 2778 return (EACCES); 2779 } 2780 2781 return (0); 2782 } 2783 2784 static int 2785 biba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2786 struct label *shmseglabel, int shmflg) 2787 { 2788 struct mac_biba *subj, *obj; 2789 2790 if (!biba_enabled) 2791 return (0); 2792 2793 subj = SLOT(cred->cr_label); 2794 obj = SLOT(shmseglabel); 2795 2796 if (!biba_dominate_effective(obj, subj)) 2797 return (EACCES); 2798 2799 return (0); 2800 } 2801 2802 static void 2803 biba_sysvshm_cleanup(struct label *shmlabel) 2804 { 2805 2806 bzero(SLOT(shmlabel), sizeof(struct mac_biba)); 2807 } 2808 2809 static void 2810 biba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2811 struct label *shmlabel) 2812 { 2813 struct mac_biba *source, *dest; 2814 2815 source = SLOT(cred->cr_label); 2816 dest = SLOT(shmlabel); 2817 2818 biba_copy_effective(source, dest); 2819 } 2820 2821 static int 2822 biba_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2823 struct vnode *vp, struct label *vplabel) 2824 { 2825 struct mac_biba mb_temp, *source, *dest; 2826 int buflen, error; 2827 2828 source = SLOT(mplabel); 2829 dest = SLOT(vplabel); 2830 2831 buflen = sizeof(mb_temp); 2832 bzero(&mb_temp, buflen); 2833 2834 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 2835 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread); 2836 if (error == ENOATTR || error == EOPNOTSUPP) { 2837 /* Fall back to the mntlabel. */ 2838 biba_copy_effective(source, dest); 2839 return (0); 2840 } else if (error) 2841 return (error); 2842 2843 if (buflen != sizeof(mb_temp)) { 2844 printf("biba_vnode_associate_extattr: bad size %d\n", 2845 buflen); 2846 return (EPERM); 2847 } 2848 if (biba_valid(&mb_temp) != 0) { 2849 printf("biba_vnode_associate_extattr: invalid\n"); 2850 return (EPERM); 2851 } 2852 if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != 2853 MAC_BIBA_FLAG_EFFECTIVE) { 2854 printf("biba_vnode_associate_extattr: not effective\n"); 2855 return (EPERM); 2856 } 2857 2858 biba_copy_effective(&mb_temp, dest); 2859 return (0); 2860 } 2861 2862 static void 2863 biba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2864 struct vnode *vp, struct label *vplabel) 2865 { 2866 struct mac_biba *source, *dest; 2867 2868 source = SLOT(mplabel); 2869 dest = SLOT(vplabel); 2870 2871 biba_copy_effective(source, dest); 2872 } 2873 2874 static int 2875 biba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2876 struct label *dvplabel) 2877 { 2878 struct mac_biba *subj, *obj; 2879 2880 if (!biba_enabled) 2881 return (0); 2882 2883 subj = SLOT(cred->cr_label); 2884 obj = SLOT(dvplabel); 2885 2886 if (!biba_dominate_effective(obj, subj)) 2887 return (EACCES); 2888 2889 return (0); 2890 } 2891 2892 static int 2893 biba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2894 struct label *dvplabel) 2895 { 2896 struct mac_biba *subj, *obj; 2897 2898 if (!biba_enabled) 2899 return (0); 2900 2901 subj = SLOT(cred->cr_label); 2902 obj = SLOT(dvplabel); 2903 2904 if (!biba_dominate_effective(obj, subj)) 2905 return (EACCES); 2906 2907 return (0); 2908 } 2909 2910 static int 2911 biba_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2912 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2913 { 2914 struct mac_biba *subj, *obj; 2915 2916 if (!biba_enabled) 2917 return (0); 2918 2919 subj = SLOT(cred->cr_label); 2920 obj = SLOT(dvplabel); 2921 2922 if (!biba_dominate_effective(subj, obj)) 2923 return (EACCES); 2924 2925 return (0); 2926 } 2927 2928 static int 2929 biba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2930 struct label *vplabel, acl_type_t type) 2931 { 2932 struct mac_biba *subj, *obj; 2933 2934 if (!biba_enabled) 2935 return (0); 2936 2937 subj = SLOT(cred->cr_label); 2938 obj = SLOT(vplabel); 2939 2940 if (!biba_dominate_effective(subj, obj)) 2941 return (EACCES); 2942 2943 return (0); 2944 } 2945 2946 static int 2947 biba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2948 struct label *vplabel, int attrnamespace, const char *name) 2949 { 2950 struct mac_biba *subj, *obj; 2951 2952 if (!biba_enabled) 2953 return (0); 2954 2955 subj = SLOT(cred->cr_label); 2956 obj = SLOT(vplabel); 2957 2958 if (!biba_dominate_effective(subj, obj)) 2959 return (EACCES); 2960 2961 return (0); 2962 } 2963 2964 static int 2965 biba_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2966 struct label *vplabel, struct image_params *imgp, 2967 struct label *execlabel) 2968 { 2969 struct mac_biba *subj, *obj, *exec; 2970 int error; 2971 2972 if (execlabel != NULL) { 2973 /* 2974 * We currently don't permit labels to be changed at 2975 * exec-time as part of Biba, so disallow non-NULL Biba label 2976 * elements in the execlabel. 2977 */ 2978 exec = SLOT(execlabel); 2979 error = biba_atmostflags(exec, 0); 2980 if (error) 2981 return (error); 2982 } 2983 2984 if (!biba_enabled) 2985 return (0); 2986 2987 subj = SLOT(cred->cr_label); 2988 obj = SLOT(vplabel); 2989 2990 if (!biba_dominate_effective(obj, subj)) 2991 return (EACCES); 2992 2993 return (0); 2994 } 2995 2996 static int 2997 biba_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2998 struct label *vplabel, acl_type_t type) 2999 { 3000 struct mac_biba *subj, *obj; 3001 3002 if (!biba_enabled) 3003 return (0); 3004 3005 subj = SLOT(cred->cr_label); 3006 obj = SLOT(vplabel); 3007 3008 if (!biba_dominate_effective(obj, subj)) 3009 return (EACCES); 3010 3011 return (0); 3012 } 3013 3014 static int 3015 biba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 3016 struct label *vplabel, int attrnamespace, const char *name) 3017 { 3018 struct mac_biba *subj, *obj; 3019 3020 if (!biba_enabled) 3021 return (0); 3022 3023 subj = SLOT(cred->cr_label); 3024 obj = SLOT(vplabel); 3025 3026 if (!biba_dominate_effective(obj, subj)) 3027 return (EACCES); 3028 3029 return (0); 3030 } 3031 3032 static int 3033 biba_vnode_check_link(struct ucred *cred, struct vnode *dvp, 3034 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3035 struct componentname *cnp) 3036 { 3037 struct mac_biba *subj, *obj; 3038 3039 if (!biba_enabled) 3040 return (0); 3041 3042 subj = SLOT(cred->cr_label); 3043 obj = SLOT(dvplabel); 3044 3045 if (!biba_dominate_effective(subj, obj)) 3046 return (EACCES); 3047 3048 obj = SLOT(vplabel); 3049 3050 if (!biba_dominate_effective(subj, obj)) 3051 return (EACCES); 3052 3053 return (0); 3054 } 3055 3056 static int 3057 biba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 3058 struct label *vplabel, int attrnamespace) 3059 { 3060 struct mac_biba *subj, *obj; 3061 3062 if (!biba_enabled) 3063 return (0); 3064 3065 subj = SLOT(cred->cr_label); 3066 obj = SLOT(vplabel); 3067 3068 if (!biba_dominate_effective(obj, subj)) 3069 return (EACCES); 3070 3071 return (0); 3072 } 3073 3074 static int 3075 biba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 3076 struct label *dvplabel, struct componentname *cnp) 3077 { 3078 struct mac_biba *subj, *obj; 3079 3080 if (!biba_enabled) 3081 return (0); 3082 3083 subj = SLOT(cred->cr_label); 3084 obj = SLOT(dvplabel); 3085 3086 if (!biba_dominate_effective(obj, subj)) 3087 return (EACCES); 3088 3089 return (0); 3090 } 3091 3092 static int 3093 biba_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 3094 struct label *vplabel, int prot, int flags) 3095 { 3096 struct mac_biba *subj, *obj; 3097 3098 /* 3099 * Rely on the use of open()-time protections to handle 3100 * non-revocation cases. 3101 */ 3102 if (!biba_enabled || !revocation_enabled) 3103 return (0); 3104 3105 subj = SLOT(cred->cr_label); 3106 obj = SLOT(vplabel); 3107 3108 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 3109 if (!biba_dominate_effective(obj, subj)) 3110 return (EACCES); 3111 } 3112 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 3113 if (!biba_dominate_effective(subj, obj)) 3114 return (EACCES); 3115 } 3116 3117 return (0); 3118 } 3119 3120 static int 3121 biba_vnode_check_open(struct ucred *cred, struct vnode *vp, 3122 struct label *vplabel, accmode_t accmode) 3123 { 3124 struct mac_biba *subj, *obj; 3125 3126 if (!biba_enabled) 3127 return (0); 3128 3129 subj = SLOT(cred->cr_label); 3130 obj = SLOT(vplabel); 3131 3132 /* XXX privilege override for admin? */ 3133 if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 3134 if (!biba_dominate_effective(obj, subj)) 3135 return (EACCES); 3136 } 3137 if (accmode & VMODIFY_PERMS) { 3138 if (!biba_dominate_effective(subj, obj)) 3139 return (EACCES); 3140 } 3141 3142 return (0); 3143 } 3144 3145 static int 3146 biba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 3147 struct vnode *vp, struct label *vplabel) 3148 { 3149 struct mac_biba *subj, *obj; 3150 3151 if (!biba_enabled || !revocation_enabled) 3152 return (0); 3153 3154 subj = SLOT(active_cred->cr_label); 3155 obj = SLOT(vplabel); 3156 3157 if (!biba_dominate_effective(obj, subj)) 3158 return (EACCES); 3159 3160 return (0); 3161 } 3162 3163 static int 3164 biba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 3165 struct vnode *vp, struct label *vplabel) 3166 { 3167 struct mac_biba *subj, *obj; 3168 3169 if (!biba_enabled || !revocation_enabled) 3170 return (0); 3171 3172 subj = SLOT(active_cred->cr_label); 3173 obj = SLOT(vplabel); 3174 3175 if (!biba_dominate_effective(obj, subj)) 3176 return (EACCES); 3177 3178 return (0); 3179 } 3180 3181 static int 3182 biba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 3183 struct label *dvplabel) 3184 { 3185 struct mac_biba *subj, *obj; 3186 3187 if (!biba_enabled) 3188 return (0); 3189 3190 subj = SLOT(cred->cr_label); 3191 obj = SLOT(dvplabel); 3192 3193 if (!biba_dominate_effective(obj, subj)) 3194 return (EACCES); 3195 3196 return (0); 3197 } 3198 3199 static int 3200 biba_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 3201 struct label *vplabel) 3202 { 3203 struct mac_biba *subj, *obj; 3204 3205 if (!biba_enabled) 3206 return (0); 3207 3208 subj = SLOT(cred->cr_label); 3209 obj = SLOT(vplabel); 3210 3211 if (!biba_dominate_effective(obj, subj)) 3212 return (EACCES); 3213 3214 return (0); 3215 } 3216 3217 static int 3218 biba_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 3219 struct label *vplabel, struct label *newlabel) 3220 { 3221 struct mac_biba *old, *new, *subj; 3222 int error; 3223 3224 old = SLOT(vplabel); 3225 new = SLOT(newlabel); 3226 subj = SLOT(cred->cr_label); 3227 3228 /* 3229 * If there is a Biba label update for the vnode, it must be a 3230 * effective label. 3231 */ 3232 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 3233 if (error) 3234 return (error); 3235 3236 /* 3237 * To perform a relabel of the vnode (Biba label or not), Biba must 3238 * authorize the relabel. 3239 */ 3240 if (!biba_effective_in_range(old, subj)) 3241 return (EPERM); 3242 3243 /* 3244 * If the Biba label is to be changed, authorize as appropriate. 3245 */ 3246 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 3247 /* 3248 * To change the Biba label on a vnode, the new vnode label 3249 * must be in the subject range. 3250 */ 3251 if (!biba_effective_in_range(new, subj)) 3252 return (EPERM); 3253 3254 /* 3255 * To change the Biba label on the vnode to be EQUAL, the 3256 * subject must have appropriate privilege. 3257 */ 3258 if (biba_contains_equal(new)) { 3259 error = biba_subject_privileged(subj); 3260 if (error) 3261 return (error); 3262 } 3263 } 3264 3265 return (0); 3266 } 3267 3268 static int 3269 biba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 3270 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3271 struct componentname *cnp) 3272 { 3273 struct mac_biba *subj, *obj; 3274 3275 if (!biba_enabled) 3276 return (0); 3277 3278 subj = SLOT(cred->cr_label); 3279 obj = SLOT(dvplabel); 3280 3281 if (!biba_dominate_effective(subj, obj)) 3282 return (EACCES); 3283 3284 obj = SLOT(vplabel); 3285 3286 if (!biba_dominate_effective(subj, obj)) 3287 return (EACCES); 3288 3289 return (0); 3290 } 3291 3292 static int 3293 biba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 3294 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3295 int samedir, struct componentname *cnp) 3296 { 3297 struct mac_biba *subj, *obj; 3298 3299 if (!biba_enabled) 3300 return (0); 3301 3302 subj = SLOT(cred->cr_label); 3303 obj = SLOT(dvplabel); 3304 3305 if (!biba_dominate_effective(subj, obj)) 3306 return (EACCES); 3307 3308 if (vp != NULL) { 3309 obj = SLOT(vplabel); 3310 3311 if (!biba_dominate_effective(subj, obj)) 3312 return (EACCES); 3313 } 3314 3315 return (0); 3316 } 3317 3318 static int 3319 biba_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 3320 struct label *vplabel) 3321 { 3322 struct mac_biba *subj, *obj; 3323 3324 if (!biba_enabled) 3325 return (0); 3326 3327 subj = SLOT(cred->cr_label); 3328 obj = SLOT(vplabel); 3329 3330 if (!biba_dominate_effective(subj, obj)) 3331 return (EACCES); 3332 3333 return (0); 3334 } 3335 3336 static int 3337 biba_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 3338 struct label *vplabel, acl_type_t type, struct acl *acl) 3339 { 3340 struct mac_biba *subj, *obj; 3341 3342 if (!biba_enabled) 3343 return (0); 3344 3345 subj = SLOT(cred->cr_label); 3346 obj = SLOT(vplabel); 3347 3348 if (!biba_dominate_effective(subj, obj)) 3349 return (EACCES); 3350 3351 return (0); 3352 } 3353 3354 static int 3355 biba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 3356 struct label *vplabel, int attrnamespace, const char *name) 3357 { 3358 struct mac_biba *subj, *obj; 3359 3360 if (!biba_enabled) 3361 return (0); 3362 3363 subj = SLOT(cred->cr_label); 3364 obj = SLOT(vplabel); 3365 3366 if (!biba_dominate_effective(subj, obj)) 3367 return (EACCES); 3368 3369 /* XXX: protect the MAC EA in a special way? */ 3370 3371 return (0); 3372 } 3373 3374 static int 3375 biba_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 3376 struct label *vplabel, u_long flags) 3377 { 3378 struct mac_biba *subj, *obj; 3379 3380 if (!biba_enabled) 3381 return (0); 3382 3383 subj = SLOT(cred->cr_label); 3384 obj = SLOT(vplabel); 3385 3386 if (!biba_dominate_effective(subj, obj)) 3387 return (EACCES); 3388 3389 return (0); 3390 } 3391 3392 static int 3393 biba_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 3394 struct label *vplabel, mode_t mode) 3395 { 3396 struct mac_biba *subj, *obj; 3397 3398 if (!biba_enabled) 3399 return (0); 3400 3401 subj = SLOT(cred->cr_label); 3402 obj = SLOT(vplabel); 3403 3404 if (!biba_dominate_effective(subj, obj)) 3405 return (EACCES); 3406 3407 return (0); 3408 } 3409 3410 static int 3411 biba_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 3412 struct label *vplabel, uid_t uid, gid_t gid) 3413 { 3414 struct mac_biba *subj, *obj; 3415 3416 if (!biba_enabled) 3417 return (0); 3418 3419 subj = SLOT(cred->cr_label); 3420 obj = SLOT(vplabel); 3421 3422 if (!biba_dominate_effective(subj, obj)) 3423 return (EACCES); 3424 3425 return (0); 3426 } 3427 3428 static int 3429 biba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 3430 struct label *vplabel, struct timespec atime, struct timespec mtime) 3431 { 3432 struct mac_biba *subj, *obj; 3433 3434 if (!biba_enabled) 3435 return (0); 3436 3437 subj = SLOT(cred->cr_label); 3438 obj = SLOT(vplabel); 3439 3440 if (!biba_dominate_effective(subj, obj)) 3441 return (EACCES); 3442 3443 return (0); 3444 } 3445 3446 static int 3447 biba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 3448 struct vnode *vp, struct label *vplabel) 3449 { 3450 struct mac_biba *subj, *obj; 3451 3452 if (!biba_enabled) 3453 return (0); 3454 3455 subj = SLOT(active_cred->cr_label); 3456 obj = SLOT(vplabel); 3457 3458 if (!biba_dominate_effective(obj, subj)) 3459 return (EACCES); 3460 3461 return (0); 3462 } 3463 3464 static int 3465 biba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 3466 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3467 struct componentname *cnp) 3468 { 3469 struct mac_biba *subj, *obj; 3470 3471 if (!biba_enabled) 3472 return (0); 3473 3474 subj = SLOT(cred->cr_label); 3475 obj = SLOT(dvplabel); 3476 3477 if (!biba_dominate_effective(subj, obj)) 3478 return (EACCES); 3479 3480 obj = SLOT(vplabel); 3481 3482 if (!biba_dominate_effective(subj, obj)) 3483 return (EACCES); 3484 3485 return (0); 3486 } 3487 3488 static int 3489 biba_vnode_check_write(struct ucred *active_cred, 3490 struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 3491 { 3492 struct mac_biba *subj, *obj; 3493 3494 if (!biba_enabled || !revocation_enabled) 3495 return (0); 3496 3497 subj = SLOT(active_cred->cr_label); 3498 obj = SLOT(vplabel); 3499 3500 if (!biba_dominate_effective(subj, obj)) 3501 return (EACCES); 3502 3503 return (0); 3504 } 3505 3506 static int 3507 biba_vnode_create_extattr(struct ucred *cred, struct mount *mp, 3508 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 3509 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 3510 { 3511 struct mac_biba *source, *dest, mb_temp; 3512 size_t buflen; 3513 int error; 3514 3515 buflen = sizeof(mb_temp); 3516 bzero(&mb_temp, buflen); 3517 3518 source = SLOT(cred->cr_label); 3519 dest = SLOT(vplabel); 3520 biba_copy_effective(source, &mb_temp); 3521 3522 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 3523 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread); 3524 if (error == 0) 3525 biba_copy_effective(source, dest); 3526 return (error); 3527 } 3528 3529 static void 3530 biba_vnode_relabel(struct ucred *cred, struct vnode *vp, 3531 struct label *vplabel, struct label *newlabel) 3532 { 3533 struct mac_biba *source, *dest; 3534 3535 source = SLOT(newlabel); 3536 dest = SLOT(vplabel); 3537 3538 biba_copy(source, dest); 3539 } 3540 3541 static int 3542 biba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 3543 struct label *vplabel, struct label *intlabel) 3544 { 3545 struct mac_biba *source, mb_temp; 3546 size_t buflen; 3547 int error; 3548 3549 buflen = sizeof(mb_temp); 3550 bzero(&mb_temp, buflen); 3551 3552 source = SLOT(intlabel); 3553 if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0) 3554 return (0); 3555 3556 biba_copy_effective(source, &mb_temp); 3557 3558 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 3559 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread); 3560 return (error); 3561 } 3562 3563 static struct mac_policy_ops mac_biba_ops = 3564 { 3565 .mpo_init = biba_init, 3566 3567 .mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive, 3568 .mpo_bpfdesc_create = biba_bpfdesc_create, 3569 .mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf, 3570 .mpo_bpfdesc_destroy_label = biba_destroy_label, 3571 .mpo_bpfdesc_init_label = biba_init_label, 3572 3573 .mpo_cred_associate_nfsd = biba_cred_associate_nfsd, 3574 .mpo_cred_check_relabel = biba_cred_check_relabel, 3575 .mpo_cred_check_visible = biba_cred_check_visible, 3576 .mpo_cred_copy_label = biba_copy_label, 3577 .mpo_cred_create_init = biba_cred_create_init, 3578 .mpo_cred_create_swapper = biba_cred_create_swapper, 3579 .mpo_cred_destroy_label = biba_destroy_label, 3580 .mpo_cred_externalize_label = biba_externalize_label, 3581 .mpo_cred_init_label = biba_init_label, 3582 .mpo_cred_internalize_label = biba_internalize_label, 3583 .mpo_cred_relabel = biba_cred_relabel, 3584 3585 .mpo_devfs_create_device = biba_devfs_create_device, 3586 .mpo_devfs_create_directory = biba_devfs_create_directory, 3587 .mpo_devfs_create_symlink = biba_devfs_create_symlink, 3588 .mpo_devfs_destroy_label = biba_destroy_label, 3589 .mpo_devfs_init_label = biba_init_label, 3590 .mpo_devfs_update = biba_devfs_update, 3591 .mpo_devfs_vnode_associate = biba_devfs_vnode_associate, 3592 3593 .mpo_ifnet_check_relabel = biba_ifnet_check_relabel, 3594 .mpo_ifnet_check_transmit = biba_ifnet_check_transmit, 3595 .mpo_ifnet_copy_label = biba_copy_label, 3596 .mpo_ifnet_create = biba_ifnet_create, 3597 .mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf, 3598 .mpo_ifnet_destroy_label = biba_destroy_label, 3599 .mpo_ifnet_externalize_label = biba_externalize_label, 3600 .mpo_ifnet_init_label = biba_init_label, 3601 .mpo_ifnet_internalize_label = biba_internalize_label, 3602 .mpo_ifnet_relabel = biba_ifnet_relabel, 3603 3604 .mpo_inpcb_check_deliver = biba_inpcb_check_deliver, 3605 .mpo_inpcb_check_visible = biba_inpcb_check_visible, 3606 .mpo_inpcb_create = biba_inpcb_create, 3607 .mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf, 3608 .mpo_inpcb_destroy_label = biba_destroy_label, 3609 .mpo_inpcb_init_label = biba_init_label_waitcheck, 3610 .mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel, 3611 3612 .mpo_ip6q_create = biba_ip6q_create, 3613 .mpo_ip6q_destroy_label = biba_destroy_label, 3614 .mpo_ip6q_init_label = biba_init_label_waitcheck, 3615 .mpo_ip6q_match = biba_ip6q_match, 3616 .mpo_ip6q_reassemble = biba_ip6q_reassemble, 3617 .mpo_ip6q_update = biba_ip6q_update, 3618 3619 .mpo_ipq_create = biba_ipq_create, 3620 .mpo_ipq_destroy_label = biba_destroy_label, 3621 .mpo_ipq_init_label = biba_init_label_waitcheck, 3622 .mpo_ipq_match = biba_ipq_match, 3623 .mpo_ipq_reassemble = biba_ipq_reassemble, 3624 .mpo_ipq_update = biba_ipq_update, 3625 3626 .mpo_kld_check_load = biba_kld_check_load, 3627 3628 .mpo_mbuf_copy_label = biba_copy_label, 3629 .mpo_mbuf_destroy_label = biba_destroy_label, 3630 .mpo_mbuf_init_label = biba_init_label_waitcheck, 3631 3632 .mpo_mount_check_stat = biba_mount_check_stat, 3633 .mpo_mount_create = biba_mount_create, 3634 .mpo_mount_destroy_label = biba_destroy_label, 3635 .mpo_mount_init_label = biba_init_label, 3636 3637 .mpo_netinet_arp_send = biba_netinet_arp_send, 3638 .mpo_netinet_firewall_reply = biba_netinet_firewall_reply, 3639 .mpo_netinet_firewall_send = biba_netinet_firewall_send, 3640 .mpo_netinet_fragment = biba_netinet_fragment, 3641 .mpo_netinet_icmp_reply = biba_netinet_icmp_reply, 3642 .mpo_netinet_igmp_send = biba_netinet_igmp_send, 3643 3644 .mpo_netinet6_nd6_send = biba_netinet6_nd6_send, 3645 3646 .mpo_pipe_check_ioctl = biba_pipe_check_ioctl, 3647 .mpo_pipe_check_poll = biba_pipe_check_poll, 3648 .mpo_pipe_check_read = biba_pipe_check_read, 3649 .mpo_pipe_check_relabel = biba_pipe_check_relabel, 3650 .mpo_pipe_check_stat = biba_pipe_check_stat, 3651 .mpo_pipe_check_write = biba_pipe_check_write, 3652 .mpo_pipe_copy_label = biba_copy_label, 3653 .mpo_pipe_create = biba_pipe_create, 3654 .mpo_pipe_destroy_label = biba_destroy_label, 3655 .mpo_pipe_externalize_label = biba_externalize_label, 3656 .mpo_pipe_init_label = biba_init_label, 3657 .mpo_pipe_internalize_label = biba_internalize_label, 3658 .mpo_pipe_relabel = biba_pipe_relabel, 3659 3660 .mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly, 3661 .mpo_posixsem_check_open = biba_posixsem_check_openunlink, 3662 .mpo_posixsem_check_post = biba_posixsem_check_write, 3663 .mpo_posixsem_check_setmode = biba_posixsem_check_setmode, 3664 .mpo_posixsem_check_setowner = biba_posixsem_check_setowner, 3665 .mpo_posixsem_check_stat = biba_posixsem_check_rdonly, 3666 .mpo_posixsem_check_unlink = biba_posixsem_check_openunlink, 3667 .mpo_posixsem_check_wait = biba_posixsem_check_write, 3668 .mpo_posixsem_create = biba_posixsem_create, 3669 .mpo_posixsem_destroy_label = biba_destroy_label, 3670 .mpo_posixsem_init_label = biba_init_label, 3671 3672 .mpo_posixshm_check_mmap = biba_posixshm_check_mmap, 3673 .mpo_posixshm_check_open = biba_posixshm_check_open, 3674 .mpo_posixshm_check_read = biba_posixshm_check_read, 3675 .mpo_posixshm_check_setmode = biba_posixshm_check_setmode, 3676 .mpo_posixshm_check_setowner = biba_posixshm_check_setowner, 3677 .mpo_posixshm_check_stat = biba_posixshm_check_stat, 3678 .mpo_posixshm_check_truncate = biba_posixshm_check_truncate, 3679 .mpo_posixshm_check_unlink = biba_posixshm_check_unlink, 3680 .mpo_posixshm_check_write = biba_posixshm_check_write, 3681 .mpo_posixshm_create = biba_posixshm_create, 3682 .mpo_posixshm_destroy_label = biba_destroy_label, 3683 .mpo_posixshm_init_label = biba_init_label, 3684 3685 .mpo_priv_check = biba_priv_check, 3686 3687 .mpo_proc_check_debug = biba_proc_check_debug, 3688 .mpo_proc_check_sched = biba_proc_check_sched, 3689 .mpo_proc_check_signal = biba_proc_check_signal, 3690 3691 .mpo_socket_check_deliver = biba_socket_check_deliver, 3692 .mpo_socket_check_relabel = biba_socket_check_relabel, 3693 .mpo_socket_check_visible = biba_socket_check_visible, 3694 .mpo_socket_copy_label = biba_copy_label, 3695 .mpo_socket_create = biba_socket_create, 3696 .mpo_socket_create_mbuf = biba_socket_create_mbuf, 3697 .mpo_socket_destroy_label = biba_destroy_label, 3698 .mpo_socket_externalize_label = biba_externalize_label, 3699 .mpo_socket_init_label = biba_init_label_waitcheck, 3700 .mpo_socket_internalize_label = biba_internalize_label, 3701 .mpo_socket_newconn = biba_socket_newconn, 3702 .mpo_socket_relabel = biba_socket_relabel, 3703 3704 .mpo_socketpeer_destroy_label = biba_destroy_label, 3705 .mpo_socketpeer_externalize_label = biba_externalize_label, 3706 .mpo_socketpeer_init_label = biba_init_label_waitcheck, 3707 .mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf, 3708 .mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket, 3709 3710 .mpo_syncache_create = biba_syncache_create, 3711 .mpo_syncache_create_mbuf = biba_syncache_create_mbuf, 3712 .mpo_syncache_destroy_label = biba_destroy_label, 3713 .mpo_syncache_init_label = biba_init_label_waitcheck, 3714 3715 .mpo_system_check_acct = biba_system_check_acct, 3716 .mpo_system_check_auditctl = biba_system_check_auditctl, 3717 .mpo_system_check_auditon = biba_system_check_auditon, 3718 .mpo_system_check_swapoff = biba_system_check_swapoff, 3719 .mpo_system_check_swapon = biba_system_check_swapon, 3720 .mpo_system_check_sysctl = biba_system_check_sysctl, 3721 3722 .mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup, 3723 .mpo_sysvmsg_create = biba_sysvmsg_create, 3724 .mpo_sysvmsg_destroy_label = biba_destroy_label, 3725 .mpo_sysvmsg_init_label = biba_init_label, 3726 3727 .mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv, 3728 .mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid, 3729 .mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget, 3730 .mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd, 3731 .mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv, 3732 .mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl, 3733 .mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup, 3734 .mpo_sysvmsq_create = biba_sysvmsq_create, 3735 .mpo_sysvmsq_destroy_label = biba_destroy_label, 3736 .mpo_sysvmsq_init_label = biba_init_label, 3737 3738 .mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl, 3739 .mpo_sysvsem_check_semget = biba_sysvsem_check_semget, 3740 .mpo_sysvsem_check_semop = biba_sysvsem_check_semop, 3741 .mpo_sysvsem_cleanup = biba_sysvsem_cleanup, 3742 .mpo_sysvsem_create = biba_sysvsem_create, 3743 .mpo_sysvsem_destroy_label = biba_destroy_label, 3744 .mpo_sysvsem_init_label = biba_init_label, 3745 3746 .mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat, 3747 .mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl, 3748 .mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget, 3749 .mpo_sysvshm_cleanup = biba_sysvshm_cleanup, 3750 .mpo_sysvshm_create = biba_sysvshm_create, 3751 .mpo_sysvshm_destroy_label = biba_destroy_label, 3752 .mpo_sysvshm_init_label = biba_init_label, 3753 3754 .mpo_vnode_associate_extattr = biba_vnode_associate_extattr, 3755 .mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel, 3756 .mpo_vnode_check_access = biba_vnode_check_open, 3757 .mpo_vnode_check_chdir = biba_vnode_check_chdir, 3758 .mpo_vnode_check_chroot = biba_vnode_check_chroot, 3759 .mpo_vnode_check_create = biba_vnode_check_create, 3760 .mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl, 3761 .mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr, 3762 .mpo_vnode_check_exec = biba_vnode_check_exec, 3763 .mpo_vnode_check_getacl = biba_vnode_check_getacl, 3764 .mpo_vnode_check_getextattr = biba_vnode_check_getextattr, 3765 .mpo_vnode_check_link = biba_vnode_check_link, 3766 .mpo_vnode_check_listextattr = biba_vnode_check_listextattr, 3767 .mpo_vnode_check_lookup = biba_vnode_check_lookup, 3768 .mpo_vnode_check_mmap = biba_vnode_check_mmap, 3769 .mpo_vnode_check_open = biba_vnode_check_open, 3770 .mpo_vnode_check_poll = biba_vnode_check_poll, 3771 .mpo_vnode_check_read = biba_vnode_check_read, 3772 .mpo_vnode_check_readdir = biba_vnode_check_readdir, 3773 .mpo_vnode_check_readlink = biba_vnode_check_readlink, 3774 .mpo_vnode_check_relabel = biba_vnode_check_relabel, 3775 .mpo_vnode_check_rename_from = biba_vnode_check_rename_from, 3776 .mpo_vnode_check_rename_to = biba_vnode_check_rename_to, 3777 .mpo_vnode_check_revoke = biba_vnode_check_revoke, 3778 .mpo_vnode_check_setacl = biba_vnode_check_setacl, 3779 .mpo_vnode_check_setextattr = biba_vnode_check_setextattr, 3780 .mpo_vnode_check_setflags = biba_vnode_check_setflags, 3781 .mpo_vnode_check_setmode = biba_vnode_check_setmode, 3782 .mpo_vnode_check_setowner = biba_vnode_check_setowner, 3783 .mpo_vnode_check_setutimes = biba_vnode_check_setutimes, 3784 .mpo_vnode_check_stat = biba_vnode_check_stat, 3785 .mpo_vnode_check_unlink = biba_vnode_check_unlink, 3786 .mpo_vnode_check_write = biba_vnode_check_write, 3787 .mpo_vnode_create_extattr = biba_vnode_create_extattr, 3788 .mpo_vnode_copy_label = biba_copy_label, 3789 .mpo_vnode_destroy_label = biba_destroy_label, 3790 .mpo_vnode_externalize_label = biba_externalize_label, 3791 .mpo_vnode_init_label = biba_init_label, 3792 .mpo_vnode_internalize_label = biba_internalize_label, 3793 .mpo_vnode_relabel = biba_vnode_relabel, 3794 .mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr, 3795 }; 3796 3797 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 3798 MPC_LOADTIME_FLAG_NOTLATE, &biba_slot); 3799