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