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