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