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