1 /*- 2 * Copyright (c) 1999-2002, 2007-2011 Robert N. M. Watson 3 * Copyright (c) 2001-2005 McAfee, Inc. 4 * Copyright (c) 2006 SPARTA, Inc. 5 * All rights reserved. 6 * 7 * This software was developed by Robert Watson for the TrustedBSD Project. 8 * 9 * This software was developed for the FreeBSD Project in part by McAfee 10 * Research, the Security Research Division of McAfee, Inc. under 11 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 12 * CHATS research program. 13 * 14 * This software was enhanced by SPARTA ISSO under SPAWAR contract 15 * N66001-04-C-6019 ("SEFOS"). 16 * 17 * This software was developed at the University of Cambridge Computer 18 * Laboratory with support from a grant from Google, Inc. 19 * 20 * Redistribution and use in source and binary forms, with or without 21 * modification, are permitted provided that the following conditions 22 * are met: 23 * 1. Redistributions of source code must retain the above copyright 24 * notice, this list of conditions and the following disclaimer. 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * $FreeBSD$ 42 */ 43 44 /* 45 * Developed by the TrustedBSD Project. 46 * 47 * Biba fixed label mandatory integrity policy. 48 */ 49 50 #include <sys/param.h> 51 #include <sys/conf.h> 52 #include <sys/extattr.h> 53 #include <sys/kernel.h> 54 #include <sys/ksem.h> 55 #include <sys/malloc.h> 56 #include <sys/mman.h> 57 #include <sys/mount.h> 58 #include <sys/priv.h> 59 #include <sys/proc.h> 60 #include <sys/sbuf.h> 61 #include <sys/systm.h> 62 #include <sys/sysproto.h> 63 #include <sys/sysent.h> 64 #include <sys/systm.h> 65 #include <sys/vnode.h> 66 #include <sys/file.h> 67 #include <sys/socket.h> 68 #include <sys/socketvar.h> 69 #include <sys/pipe.h> 70 #include <sys/sx.h> 71 #include <sys/sysctl.h> 72 #include <sys/msg.h> 73 #include <sys/sem.h> 74 #include <sys/shm.h> 75 76 #include <fs/devfs/devfs.h> 77 78 #include <net/bpfdesc.h> 79 #include <net/if.h> 80 #include <net/if_types.h> 81 #include <net/if_var.h> 82 83 #include <netinet/in.h> 84 #include <netinet/in_pcb.h> 85 #include <netinet/ip_var.h> 86 87 #include <vm/uma.h> 88 #include <vm/vm.h> 89 90 #include <security/mac/mac_policy.h> 91 #include <security/mac_biba/mac_biba.h> 92 93 SYSCTL_DECL(_security_mac); 94 95 static SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 96 "TrustedBSD mac_biba policy controls"); 97 98 static int biba_label_size = sizeof(struct mac_biba); 99 SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 100 &biba_label_size, 0, "Size of struct mac_biba"); 101 102 static int biba_enabled = 1; 103 SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RWTUN, &biba_enabled, 104 0, "Enforce MAC/Biba policy"); 105 106 static int destroyed_not_inited; 107 SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 108 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 109 110 static int trust_all_interfaces = 0; 111 SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RDTUN, 112 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 113 114 static char trusted_interfaces[128]; 115 SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RDTUN, 116 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 117 118 static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 119 SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 120 &max_compartments, 0, "Maximum supported compartments"); 121 122 static int ptys_equal = 0; 123 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RWTUN, &ptys_equal, 124 0, "Label pty devices as biba/equal on create"); 125 126 static int interfaces_equal = 1; 127 SYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RWTUN, 128 &interfaces_equal, 0, "Label network interfaces as biba/equal on create"); 129 130 static int revocation_enabled = 0; 131 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RWTUN, 132 &revocation_enabled, 0, "Revoke access to objects on relabel"); 133 134 static int biba_slot; 135 #define SLOT(l) ((struct mac_biba *)mac_label_get((l), biba_slot)) 136 #define SLOT_SET(l, val) mac_label_set((l), biba_slot, (uintptr_t)(val)) 137 138 static uma_zone_t zone_biba; 139 140 static __inline int 141 biba_bit_set_empty(u_char *set) { 142 int i; 143 144 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 145 if (set[i] != 0) 146 return (0); 147 return (1); 148 } 149 150 static struct mac_biba * 151 biba_alloc(int flag) 152 { 153 154 return (uma_zalloc(zone_biba, flag | M_ZERO)); 155 } 156 157 static void 158 biba_free(struct mac_biba *mb) 159 { 160 161 if (mb != NULL) 162 uma_zfree(zone_biba, mb); 163 else 164 atomic_add_int(&destroyed_not_inited, 1); 165 } 166 167 static int 168 biba_atmostflags(struct mac_biba *mb, int flags) 169 { 170 171 if ((mb->mb_flags & flags) != mb->mb_flags) 172 return (EINVAL); 173 return (0); 174 } 175 176 static int 177 biba_dominate_element(struct mac_biba_element *a, struct mac_biba_element *b) 178 { 179 int bit; 180 181 switch (a->mbe_type) { 182 case MAC_BIBA_TYPE_EQUAL: 183 case MAC_BIBA_TYPE_HIGH: 184 return (1); 185 186 case MAC_BIBA_TYPE_LOW: 187 switch (b->mbe_type) { 188 case MAC_BIBA_TYPE_GRADE: 189 case MAC_BIBA_TYPE_HIGH: 190 return (0); 191 192 case MAC_BIBA_TYPE_EQUAL: 193 case MAC_BIBA_TYPE_LOW: 194 return (1); 195 196 default: 197 panic("biba_dominate_element: b->mbe_type invalid"); 198 } 199 200 case MAC_BIBA_TYPE_GRADE: 201 switch (b->mbe_type) { 202 case MAC_BIBA_TYPE_EQUAL: 203 case MAC_BIBA_TYPE_LOW: 204 return (1); 205 206 case MAC_BIBA_TYPE_HIGH: 207 return (0); 208 209 case MAC_BIBA_TYPE_GRADE: 210 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 211 if (!MAC_BIBA_BIT_TEST(bit, 212 a->mbe_compartments) && 213 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 214 return (0); 215 return (a->mbe_grade >= b->mbe_grade); 216 217 default: 218 panic("biba_dominate_element: b->mbe_type invalid"); 219 } 220 221 default: 222 panic("biba_dominate_element: a->mbe_type invalid"); 223 } 224 225 return (0); 226 } 227 228 static int 229 biba_subject_dominate_high(struct mac_biba *mb) 230 { 231 struct mac_biba_element *element; 232 233 KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 234 ("biba_effective_in_range: mb not effective")); 235 element = &mb->mb_effective; 236 237 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 238 element->mbe_type == MAC_BIBA_TYPE_HIGH); 239 } 240 241 static int 242 biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 243 { 244 245 return (biba_dominate_element(&rangeb->mb_rangehigh, 246 &rangea->mb_rangehigh) && 247 biba_dominate_element(&rangea->mb_rangelow, 248 &rangeb->mb_rangelow)); 249 } 250 251 static int 252 biba_effective_in_range(struct mac_biba *effective, struct mac_biba *range) 253 { 254 255 KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 256 ("biba_effective_in_range: a not effective")); 257 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 258 ("biba_effective_in_range: b not range")); 259 260 return (biba_dominate_element(&range->mb_rangehigh, 261 &effective->mb_effective) && 262 biba_dominate_element(&effective->mb_effective, 263 &range->mb_rangelow)); 264 265 return (1); 266 } 267 268 static int 269 biba_dominate_effective(struct mac_biba *a, struct mac_biba *b) 270 { 271 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 272 ("biba_dominate_effective: a not effective")); 273 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 274 ("biba_dominate_effective: b not effective")); 275 276 return (biba_dominate_element(&a->mb_effective, &b->mb_effective)); 277 } 278 279 static int 280 biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 281 { 282 283 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 284 b->mbe_type == MAC_BIBA_TYPE_EQUAL) 285 return (1); 286 287 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 288 } 289 290 static int 291 biba_equal_effective(struct mac_biba *a, struct mac_biba *b) 292 { 293 294 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 295 ("biba_equal_effective: a not effective")); 296 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 297 ("biba_equal_effective: b not effective")); 298 299 return (biba_equal_element(&a->mb_effective, &b->mb_effective)); 300 } 301 302 static int 303 biba_contains_equal(struct mac_biba *mb) 304 { 305 306 if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 307 if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 308 return (1); 309 } 310 311 if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 312 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 313 return (1); 314 if (mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 315 return (1); 316 } 317 318 return (0); 319 } 320 321 static int 322 biba_subject_privileged(struct mac_biba *mb) 323 { 324 325 KASSERT((mb->mb_flags & MAC_BIBA_FLAGS_BOTH) == MAC_BIBA_FLAGS_BOTH, 326 ("biba_subject_privileged: subject doesn't have both labels")); 327 328 /* If the effective is EQUAL, it's ok. */ 329 if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 330 return (0); 331 332 /* If either range endpoint is EQUAL, it's ok. */ 333 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 334 mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 335 return (0); 336 337 /* If the range is low-high, it's ok. */ 338 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 339 mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 340 return (0); 341 342 /* It's not ok. */ 343 return (EPERM); 344 } 345 346 static int 347 biba_high_effective(struct mac_biba *mb) 348 { 349 350 KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 351 ("biba_equal_effective: mb not effective")); 352 353 return (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH); 354 } 355 356 static int 357 biba_valid(struct mac_biba *mb) 358 { 359 360 if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 361 switch (mb->mb_effective.mbe_type) { 362 case MAC_BIBA_TYPE_GRADE: 363 break; 364 365 case MAC_BIBA_TYPE_EQUAL: 366 case MAC_BIBA_TYPE_HIGH: 367 case MAC_BIBA_TYPE_LOW: 368 if (mb->mb_effective.mbe_grade != 0 || 369 !MAC_BIBA_BIT_SET_EMPTY( 370 mb->mb_effective.mbe_compartments)) 371 return (EINVAL); 372 break; 373 374 default: 375 return (EINVAL); 376 } 377 } else { 378 if (mb->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF) 379 return (EINVAL); 380 } 381 382 if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 383 switch (mb->mb_rangelow.mbe_type) { 384 case MAC_BIBA_TYPE_GRADE: 385 break; 386 387 case MAC_BIBA_TYPE_EQUAL: 388 case MAC_BIBA_TYPE_HIGH: 389 case MAC_BIBA_TYPE_LOW: 390 if (mb->mb_rangelow.mbe_grade != 0 || 391 !MAC_BIBA_BIT_SET_EMPTY( 392 mb->mb_rangelow.mbe_compartments)) 393 return (EINVAL); 394 break; 395 396 default: 397 return (EINVAL); 398 } 399 400 switch (mb->mb_rangehigh.mbe_type) { 401 case MAC_BIBA_TYPE_GRADE: 402 break; 403 404 case MAC_BIBA_TYPE_EQUAL: 405 case MAC_BIBA_TYPE_HIGH: 406 case MAC_BIBA_TYPE_LOW: 407 if (mb->mb_rangehigh.mbe_grade != 0 || 408 !MAC_BIBA_BIT_SET_EMPTY( 409 mb->mb_rangehigh.mbe_compartments)) 410 return (EINVAL); 411 break; 412 413 default: 414 return (EINVAL); 415 } 416 if (!biba_dominate_element(&mb->mb_rangehigh, 417 &mb->mb_rangelow)) 418 return (EINVAL); 419 } else { 420 if (mb->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 421 mb->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 422 return (EINVAL); 423 } 424 425 return (0); 426 } 427 428 static void 429 biba_set_range(struct mac_biba *mb, u_short typelow, u_short gradelow, 430 u_char *compartmentslow, u_short typehigh, u_short gradehigh, 431 u_char *compartmentshigh) 432 { 433 434 mb->mb_rangelow.mbe_type = typelow; 435 mb->mb_rangelow.mbe_grade = gradelow; 436 if (compartmentslow != NULL) 437 memcpy(mb->mb_rangelow.mbe_compartments, compartmentslow, 438 sizeof(mb->mb_rangelow.mbe_compartments)); 439 mb->mb_rangehigh.mbe_type = typehigh; 440 mb->mb_rangehigh.mbe_grade = gradehigh; 441 if (compartmentshigh != NULL) 442 memcpy(mb->mb_rangehigh.mbe_compartments, compartmentshigh, 443 sizeof(mb->mb_rangehigh.mbe_compartments)); 444 mb->mb_flags |= MAC_BIBA_FLAG_RANGE; 445 } 446 447 static void 448 biba_set_effective(struct mac_biba *mb, u_short type, u_short grade, 449 u_char *compartments) 450 { 451 452 mb->mb_effective.mbe_type = type; 453 mb->mb_effective.mbe_grade = grade; 454 if (compartments != NULL) 455 memcpy(mb->mb_effective.mbe_compartments, compartments, 456 sizeof(mb->mb_effective.mbe_compartments)); 457 mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 458 } 459 460 static void 461 biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 462 { 463 464 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 465 ("biba_copy_range: labelfrom not range")); 466 467 labelto->mb_rangelow = labelfrom->mb_rangelow; 468 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 469 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 470 } 471 472 static void 473 biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto) 474 { 475 476 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 477 ("biba_copy_effective: labelfrom not effective")); 478 479 labelto->mb_effective = labelfrom->mb_effective; 480 labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 481 } 482 483 static void 484 biba_copy(struct mac_biba *source, struct mac_biba *dest) 485 { 486 487 if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) 488 biba_copy_effective(source, dest); 489 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 490 biba_copy_range(source, dest); 491 } 492 493 /* 494 * Policy module operations. 495 */ 496 static void 497 biba_init(struct mac_policy_conf *conf) 498 { 499 500 zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL, 501 NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 502 } 503 504 /* 505 * Label operations. 506 */ 507 static void 508 biba_init_label(struct label *label) 509 { 510 511 SLOT_SET(label, biba_alloc(M_WAITOK)); 512 } 513 514 static int 515 biba_init_label_waitcheck(struct label *label, int flag) 516 { 517 518 SLOT_SET(label, biba_alloc(flag)); 519 if (SLOT(label) == NULL) 520 return (ENOMEM); 521 522 return (0); 523 } 524 525 static void 526 biba_destroy_label(struct label *label) 527 { 528 529 biba_free(SLOT(label)); 530 SLOT_SET(label, NULL); 531 } 532 533 /* 534 * biba_element_to_string() accepts an sbuf and Biba element. It converts 535 * the Biba element to a string and stores the result in the sbuf; if there 536 * isn't space in the sbuf, -1 is returned. 537 */ 538 static int 539 biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element) 540 { 541 int i, first; 542 543 switch (element->mbe_type) { 544 case MAC_BIBA_TYPE_HIGH: 545 return (sbuf_printf(sb, "high")); 546 547 case MAC_BIBA_TYPE_LOW: 548 return (sbuf_printf(sb, "low")); 549 550 case MAC_BIBA_TYPE_EQUAL: 551 return (sbuf_printf(sb, "equal")); 552 553 case MAC_BIBA_TYPE_GRADE: 554 if (sbuf_printf(sb, "%d", element->mbe_grade) == -1) 555 return (-1); 556 557 first = 1; 558 for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) { 559 if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) { 560 if (first) { 561 if (sbuf_putc(sb, ':') == -1) 562 return (-1); 563 if (sbuf_printf(sb, "%d", i) == -1) 564 return (-1); 565 first = 0; 566 } else { 567 if (sbuf_printf(sb, "+%d", i) == -1) 568 return (-1); 569 } 570 } 571 } 572 return (0); 573 574 default: 575 panic("biba_element_to_string: invalid type (%d)", 576 element->mbe_type); 577 } 578 } 579 580 /* 581 * biba_to_string() converts a Biba label to a string, and places the results 582 * in the passed sbuf. It returns 0 on success, or EINVAL if there isn't 583 * room in the sbuf. Note: the sbuf will be modified even in a failure case, 584 * so the caller may need to revert the sbuf by restoring the offset if 585 * that's undesired. 586 */ 587 static int 588 biba_to_string(struct sbuf *sb, struct mac_biba *mb) 589 { 590 591 if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 592 if (biba_element_to_string(sb, &mb->mb_effective) == -1) 593 return (EINVAL); 594 } 595 596 if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 597 if (sbuf_putc(sb, '(') == -1) 598 return (EINVAL); 599 600 if (biba_element_to_string(sb, &mb->mb_rangelow) == -1) 601 return (EINVAL); 602 603 if (sbuf_putc(sb, '-') == -1) 604 return (EINVAL); 605 606 if (biba_element_to_string(sb, &mb->mb_rangehigh) == -1) 607 return (EINVAL); 608 609 if (sbuf_putc(sb, ')') == -1) 610 return (EINVAL); 611 } 612 613 return (0); 614 } 615 616 static int 617 biba_externalize_label(struct label *label, char *element_name, 618 struct sbuf *sb, int *claimed) 619 { 620 struct mac_biba *mb; 621 622 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 623 return (0); 624 625 (*claimed)++; 626 627 mb = SLOT(label); 628 return (biba_to_string(sb, mb)); 629 } 630 631 static int 632 biba_parse_element(struct mac_biba_element *element, char *string) 633 { 634 char *compartment, *end, *grade; 635 int value; 636 637 if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { 638 element->mbe_type = MAC_BIBA_TYPE_HIGH; 639 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 640 } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { 641 element->mbe_type = MAC_BIBA_TYPE_LOW; 642 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 643 } else if (strcmp(string, "equal") == 0 || 644 strcmp(string, "eq") == 0) { 645 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 646 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 647 } else { 648 element->mbe_type = MAC_BIBA_TYPE_GRADE; 649 650 /* 651 * Numeric grade piece of the element. 652 */ 653 grade = strsep(&string, ":"); 654 value = strtol(grade, &end, 10); 655 if (end == grade || *end != '\0') 656 return (EINVAL); 657 if (value < 0 || value > 65535) 658 return (EINVAL); 659 element->mbe_grade = value; 660 661 /* 662 * Optional compartment piece of the element. If none are 663 * included, we assume that the label has no compartments. 664 */ 665 if (string == NULL) 666 return (0); 667 if (*string == '\0') 668 return (0); 669 670 while ((compartment = strsep(&string, "+")) != NULL) { 671 value = strtol(compartment, &end, 10); 672 if (compartment == end || *end != '\0') 673 return (EINVAL); 674 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 675 return (EINVAL); 676 MAC_BIBA_BIT_SET(value, element->mbe_compartments); 677 } 678 } 679 680 return (0); 681 } 682 683 /* 684 * Note: destructively consumes the string, make a local copy before calling 685 * if that's a problem. 686 */ 687 static int 688 biba_parse(struct mac_biba *mb, char *string) 689 { 690 char *rangehigh, *rangelow, *effective; 691 int error; 692 693 effective = strsep(&string, "("); 694 if (*effective == '\0') 695 effective = NULL; 696 697 if (string != NULL) { 698 rangelow = strsep(&string, "-"); 699 if (string == NULL) 700 return (EINVAL); 701 rangehigh = strsep(&string, ")"); 702 if (string == NULL) 703 return (EINVAL); 704 if (*string != '\0') 705 return (EINVAL); 706 } else { 707 rangelow = NULL; 708 rangehigh = NULL; 709 } 710 711 KASSERT((rangelow != NULL && rangehigh != NULL) || 712 (rangelow == NULL && rangehigh == NULL), 713 ("biba_parse: range mismatch")); 714 715 bzero(mb, sizeof(*mb)); 716 if (effective != NULL) { 717 error = biba_parse_element(&mb->mb_effective, effective); 718 if (error) 719 return (error); 720 mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 721 } 722 723 if (rangelow != NULL) { 724 error = biba_parse_element(&mb->mb_rangelow, rangelow); 725 if (error) 726 return (error); 727 error = biba_parse_element(&mb->mb_rangehigh, rangehigh); 728 if (error) 729 return (error); 730 mb->mb_flags |= MAC_BIBA_FLAG_RANGE; 731 } 732 733 error = biba_valid(mb); 734 if (error) 735 return (error); 736 737 return (0); 738 } 739 740 static int 741 biba_internalize_label(struct label *label, char *element_name, 742 char *element_data, int *claimed) 743 { 744 struct mac_biba *mb, mb_temp; 745 int error; 746 747 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 748 return (0); 749 750 (*claimed)++; 751 752 error = biba_parse(&mb_temp, element_data); 753 if (error) 754 return (error); 755 756 mb = SLOT(label); 757 *mb = mb_temp; 758 759 return (0); 760 } 761 762 static void 763 biba_copy_label(struct label *src, struct label *dest) 764 { 765 766 *SLOT(dest) = *SLOT(src); 767 } 768 769 /* 770 * Object-specific entry point implementations are sorted alphabetically by 771 * object type name and then by operation. 772 */ 773 static int 774 biba_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 775 struct ifnet *ifp, struct label *ifplabel) 776 { 777 struct mac_biba *a, *b; 778 779 if (!biba_enabled) 780 return (0); 781 782 a = SLOT(dlabel); 783 b = SLOT(ifplabel); 784 785 if (biba_equal_effective(a, b)) 786 return (0); 787 return (EACCES); 788 } 789 790 static void 791 biba_bpfdesc_create(struct ucred *cred, struct bpf_d *d, 792 struct label *dlabel) 793 { 794 struct mac_biba *source, *dest; 795 796 source = SLOT(cred->cr_label); 797 dest = SLOT(dlabel); 798 799 biba_copy_effective(source, dest); 800 } 801 802 static void 803 biba_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 804 struct mbuf *m, struct label *mlabel) 805 { 806 struct mac_biba *source, *dest; 807 808 source = SLOT(dlabel); 809 dest = SLOT(mlabel); 810 811 biba_copy_effective(source, dest); 812 } 813 814 static void 815 biba_cred_associate_nfsd(struct ucred *cred) 816 { 817 struct mac_biba *label; 818 819 label = SLOT(cred->cr_label); 820 biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL); 821 biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 822 0, NULL); 823 } 824 825 static int 826 biba_cred_check_relabel(struct ucred *cred, struct label *newlabel) 827 { 828 struct mac_biba *subj, *new; 829 int error; 830 831 subj = SLOT(cred->cr_label); 832 new = SLOT(newlabel); 833 834 /* 835 * If there is a Biba label update for the credential, it may 836 * be an update of the effective, range, or both. 837 */ 838 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 839 if (error) 840 return (error); 841 842 /* 843 * If the Biba label is to be changed, authorize as appropriate. 844 */ 845 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 846 /* 847 * If the change request modifies both the Biba label 848 * effective and range, check that the new effective will be 849 * in the new range. 850 */ 851 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 852 MAC_BIBA_FLAGS_BOTH && 853 !biba_effective_in_range(new, new)) 854 return (EINVAL); 855 856 /* 857 * To change the Biba effective label on a credential, the 858 * new effective label must be in the current range. 859 */ 860 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE && 861 !biba_effective_in_range(new, subj)) 862 return (EPERM); 863 864 /* 865 * To change the Biba range on a credential, the new range 866 * label must be in the current range. 867 */ 868 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 869 !biba_range_in_range(new, subj)) 870 return (EPERM); 871 872 /* 873 * To have EQUAL in any component of the new credential Biba 874 * label, the subject must already have EQUAL in their label. 875 */ 876 if (biba_contains_equal(new)) { 877 error = biba_subject_privileged(subj); 878 if (error) 879 return (error); 880 } 881 } 882 883 return (0); 884 } 885 886 static int 887 biba_cred_check_visible(struct ucred *u1, struct ucred *u2) 888 { 889 struct mac_biba *subj, *obj; 890 891 if (!biba_enabled) 892 return (0); 893 894 subj = SLOT(u1->cr_label); 895 obj = SLOT(u2->cr_label); 896 897 /* XXX: range */ 898 if (!biba_dominate_effective(obj, subj)) 899 return (ESRCH); 900 901 return (0); 902 } 903 904 static void 905 biba_cred_create_init(struct ucred *cred) 906 { 907 struct mac_biba *dest; 908 909 dest = SLOT(cred->cr_label); 910 911 biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 912 biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 913 0, NULL); 914 } 915 916 static void 917 biba_cred_create_swapper(struct ucred *cred) 918 { 919 struct mac_biba *dest; 920 921 dest = SLOT(cred->cr_label); 922 923 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 924 biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 925 0, NULL); 926 } 927 928 static void 929 biba_cred_relabel(struct ucred *cred, struct label *newlabel) 930 { 931 struct mac_biba *source, *dest; 932 933 source = SLOT(newlabel); 934 dest = SLOT(cred->cr_label); 935 936 biba_copy(source, dest); 937 } 938 939 static void 940 biba_devfs_create_device(struct ucred *cred, struct mount *mp, 941 struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 942 { 943 struct mac_biba *mb; 944 const char *dn; 945 int biba_type; 946 947 mb = SLOT(delabel); 948 dn = devtoname(dev); 949 if (strcmp(dn, "null") == 0 || 950 strcmp(dn, "zero") == 0 || 951 strcmp(dn, "random") == 0 || 952 strncmp(dn, "fd/", strlen("fd/")) == 0) 953 biba_type = MAC_BIBA_TYPE_EQUAL; 954 else if (ptys_equal && 955 (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 956 strncmp(dn, "pts/", strlen("pts/")) == 0 || 957 strncmp(dn, "ptyp", strlen("ptyp")) == 0)) 958 biba_type = MAC_BIBA_TYPE_EQUAL; 959 else 960 biba_type = MAC_BIBA_TYPE_HIGH; 961 biba_set_effective(mb, biba_type, 0, NULL); 962 } 963 964 static void 965 biba_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 966 struct devfs_dirent *de, struct label *delabel) 967 { 968 struct mac_biba *mb; 969 970 mb = SLOT(delabel); 971 972 biba_set_effective(mb, MAC_BIBA_TYPE_HIGH, 0, NULL); 973 } 974 975 static void 976 biba_devfs_create_symlink(struct ucred *cred, struct mount *mp, 977 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 978 struct label *delabel) 979 { 980 struct mac_biba *source, *dest; 981 982 source = SLOT(cred->cr_label); 983 dest = SLOT(delabel); 984 985 biba_copy_effective(source, dest); 986 } 987 988 static void 989 biba_devfs_update(struct mount *mp, struct devfs_dirent *de, 990 struct label *delabel, struct vnode *vp, struct label *vplabel) 991 { 992 struct mac_biba *source, *dest; 993 994 source = SLOT(vplabel); 995 dest = SLOT(delabel); 996 997 biba_copy(source, dest); 998 } 999 1000 static void 1001 biba_devfs_vnode_associate(struct mount *mp, struct label *mntlabel, 1002 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 1003 struct label *vplabel) 1004 { 1005 struct mac_biba *source, *dest; 1006 1007 source = SLOT(delabel); 1008 dest = SLOT(vplabel); 1009 1010 biba_copy_effective(source, dest); 1011 } 1012 1013 static int 1014 biba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1015 struct label *ifplabel, struct label *newlabel) 1016 { 1017 struct mac_biba *subj, *new; 1018 int error; 1019 1020 subj = SLOT(cred->cr_label); 1021 new = SLOT(newlabel); 1022 1023 /* 1024 * If there is a Biba label update for the interface, it may be an 1025 * update of the effective, range, or both. 1026 */ 1027 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1028 if (error) 1029 return (error); 1030 1031 /* 1032 * Relabling network interfaces requires Biba privilege. 1033 */ 1034 error = biba_subject_privileged(subj); 1035 if (error) 1036 return (error); 1037 1038 return (0); 1039 } 1040 1041 static int 1042 biba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1043 struct mbuf *m, struct label *mlabel) 1044 { 1045 struct mac_biba *p, *i; 1046 1047 if (!biba_enabled) 1048 return (0); 1049 1050 p = SLOT(mlabel); 1051 i = SLOT(ifplabel); 1052 1053 return (biba_effective_in_range(p, i) ? 0 : EACCES); 1054 } 1055 1056 static void 1057 biba_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1058 { 1059 char tifname[IFNAMSIZ], *p, *q; 1060 char tiflist[sizeof(trusted_interfaces)]; 1061 struct mac_biba *dest; 1062 int len, type; 1063 1064 dest = SLOT(ifplabel); 1065 1066 if (ifp->if_type == IFT_LOOP || interfaces_equal != 0) { 1067 type = MAC_BIBA_TYPE_EQUAL; 1068 goto set; 1069 } 1070 1071 if (trust_all_interfaces) { 1072 type = MAC_BIBA_TYPE_HIGH; 1073 goto set; 1074 } 1075 1076 type = MAC_BIBA_TYPE_LOW; 1077 1078 if (trusted_interfaces[0] == '\0' || 1079 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1080 goto set; 1081 1082 bzero(tiflist, sizeof(tiflist)); 1083 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1084 if(*p != ' ' && *p != '\t') 1085 *q = *p; 1086 1087 for (p = q = tiflist;; p++) { 1088 if (*p == ',' || *p == '\0') { 1089 len = p - q; 1090 if (len < IFNAMSIZ) { 1091 bzero(tifname, sizeof(tifname)); 1092 bcopy(q, tifname, len); 1093 if (strcmp(tifname, ifp->if_xname) == 0) { 1094 type = MAC_BIBA_TYPE_HIGH; 1095 break; 1096 } 1097 } else { 1098 *p = '\0'; 1099 printf("mac_biba warning: interface name " 1100 "\"%s\" is too long (must be < %d)\n", 1101 q, IFNAMSIZ); 1102 } 1103 if (*p == '\0') 1104 break; 1105 q = p + 1; 1106 } 1107 } 1108 set: 1109 biba_set_effective(dest, type, 0, NULL); 1110 biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1111 } 1112 1113 static void 1114 biba_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1115 struct mbuf *m, struct label *mlabel) 1116 { 1117 struct mac_biba *source, *dest; 1118 1119 source = SLOT(ifplabel); 1120 dest = SLOT(mlabel); 1121 1122 biba_copy_effective(source, dest); 1123 } 1124 1125 static void 1126 biba_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1127 struct label *ifplabel, struct label *newlabel) 1128 { 1129 struct mac_biba *source, *dest; 1130 1131 source = SLOT(newlabel); 1132 dest = SLOT(ifplabel); 1133 1134 biba_copy(source, dest); 1135 } 1136 1137 static int 1138 biba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1139 struct mbuf *m, struct label *mlabel) 1140 { 1141 struct mac_biba *p, *i; 1142 1143 if (!biba_enabled) 1144 return (0); 1145 1146 p = SLOT(mlabel); 1147 i = SLOT(inplabel); 1148 1149 return (biba_equal_effective(p, i) ? 0 : EACCES); 1150 } 1151 1152 static int 1153 biba_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 1154 struct label *inplabel) 1155 { 1156 struct mac_biba *subj, *obj; 1157 1158 if (!biba_enabled) 1159 return (0); 1160 1161 subj = SLOT(cred->cr_label); 1162 obj = SLOT(inplabel); 1163 1164 if (!biba_dominate_effective(obj, subj)) 1165 return (ENOENT); 1166 1167 return (0); 1168 } 1169 1170 static void 1171 biba_inpcb_create(struct socket *so, struct label *solabel, 1172 struct inpcb *inp, struct label *inplabel) 1173 { 1174 struct mac_biba *source, *dest; 1175 1176 source = SLOT(solabel); 1177 dest = SLOT(inplabel); 1178 1179 SOCK_LOCK(so); 1180 biba_copy_effective(source, dest); 1181 SOCK_UNLOCK(so); 1182 } 1183 1184 static void 1185 biba_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1186 struct mbuf *m, struct label *mlabel) 1187 { 1188 struct mac_biba *source, *dest; 1189 1190 source = SLOT(inplabel); 1191 dest = SLOT(mlabel); 1192 1193 biba_copy_effective(source, dest); 1194 } 1195 1196 static void 1197 biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1198 struct inpcb *inp, struct label *inplabel) 1199 { 1200 struct mac_biba *source, *dest; 1201 1202 SOCK_LOCK_ASSERT(so); 1203 1204 source = SLOT(solabel); 1205 dest = SLOT(inplabel); 1206 1207 biba_copy(source, dest); 1208 } 1209 1210 static void 1211 biba_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1212 struct label *q6label) 1213 { 1214 struct mac_biba *source, *dest; 1215 1216 source = SLOT(mlabel); 1217 dest = SLOT(q6label); 1218 1219 biba_copy_effective(source, dest); 1220 } 1221 1222 static int 1223 biba_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1224 struct label *q6label) 1225 { 1226 struct mac_biba *a, *b; 1227 1228 a = SLOT(q6label); 1229 b = SLOT(mlabel); 1230 1231 return (biba_equal_effective(a, b)); 1232 } 1233 1234 static void 1235 biba_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1236 struct label *mlabel) 1237 { 1238 struct mac_biba *source, *dest; 1239 1240 source = SLOT(q6label); 1241 dest = SLOT(mlabel); 1242 1243 /* Just use the head, since we require them all to match. */ 1244 biba_copy_effective(source, dest); 1245 } 1246 1247 static void 1248 biba_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1249 struct label *q6label) 1250 { 1251 1252 /* NOOP: we only accept matching labels, so no need to update */ 1253 } 1254 1255 static void 1256 biba_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1257 struct label *qlabel) 1258 { 1259 struct mac_biba *source, *dest; 1260 1261 source = SLOT(mlabel); 1262 dest = SLOT(qlabel); 1263 1264 biba_copy_effective(source, dest); 1265 } 1266 1267 static int 1268 biba_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1269 struct label *qlabel) 1270 { 1271 struct mac_biba *a, *b; 1272 1273 a = SLOT(qlabel); 1274 b = SLOT(mlabel); 1275 1276 return (biba_equal_effective(a, b)); 1277 } 1278 1279 static void 1280 biba_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1281 struct label *mlabel) 1282 { 1283 struct mac_biba *source, *dest; 1284 1285 source = SLOT(qlabel); 1286 dest = SLOT(mlabel); 1287 1288 /* Just use the head, since we require them all to match. */ 1289 biba_copy_effective(source, dest); 1290 } 1291 1292 static void 1293 biba_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1294 struct label *qlabel) 1295 { 1296 1297 /* NOOP: we only accept matching labels, so no need to update */ 1298 } 1299 1300 static int 1301 biba_kld_check_load(struct ucred *cred, struct vnode *vp, 1302 struct label *vplabel) 1303 { 1304 struct mac_biba *subj, *obj; 1305 int error; 1306 1307 if (!biba_enabled) 1308 return (0); 1309 1310 subj = SLOT(cred->cr_label); 1311 1312 error = biba_subject_privileged(subj); 1313 if (error) 1314 return (error); 1315 1316 obj = SLOT(vplabel); 1317 if (!biba_high_effective(obj)) 1318 return (EACCES); 1319 1320 return (0); 1321 } 1322 1323 static int 1324 biba_mount_check_stat(struct ucred *cred, struct mount *mp, 1325 struct label *mplabel) 1326 { 1327 struct mac_biba *subj, *obj; 1328 1329 if (!biba_enabled) 1330 return (0); 1331 1332 subj = SLOT(cred->cr_label); 1333 obj = SLOT(mplabel); 1334 1335 if (!biba_dominate_effective(obj, subj)) 1336 return (EACCES); 1337 1338 return (0); 1339 } 1340 1341 static void 1342 biba_mount_create(struct ucred *cred, struct mount *mp, 1343 struct label *mplabel) 1344 { 1345 struct mac_biba *source, *dest; 1346 1347 source = SLOT(cred->cr_label); 1348 dest = SLOT(mplabel); 1349 1350 biba_copy_effective(source, dest); 1351 } 1352 1353 static void 1354 biba_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1355 struct mbuf *m, struct label *mlabel) 1356 { 1357 struct mac_biba *dest; 1358 1359 dest = SLOT(mlabel); 1360 1361 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1362 } 1363 1364 static void 1365 biba_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1366 struct mbuf *msend, struct label *msendlabel) 1367 { 1368 struct mac_biba *source, *dest; 1369 1370 source = SLOT(mrecvlabel); 1371 dest = SLOT(msendlabel); 1372 1373 biba_copy_effective(source, dest); 1374 } 1375 1376 static void 1377 biba_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1378 { 1379 struct mac_biba *dest; 1380 1381 dest = SLOT(mlabel); 1382 1383 /* XXX: where is the label for the firewall really coming from? */ 1384 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1385 } 1386 1387 static void 1388 biba_netinet_fragment(struct mbuf *m, struct label *mlabel, 1389 struct mbuf *frag, struct label *fraglabel) 1390 { 1391 struct mac_biba *source, *dest; 1392 1393 source = SLOT(mlabel); 1394 dest = SLOT(fraglabel); 1395 1396 biba_copy_effective(source, dest); 1397 } 1398 1399 static void 1400 biba_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1401 struct mbuf *msend, struct label *msendlabel) 1402 { 1403 struct mac_biba *source, *dest; 1404 1405 source = SLOT(mrecvlabel); 1406 dest = SLOT(msendlabel); 1407 1408 biba_copy_effective(source, dest); 1409 } 1410 1411 static void 1412 biba_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1413 struct mbuf *m, struct label *mlabel) 1414 { 1415 struct mac_biba *dest; 1416 1417 dest = SLOT(mlabel); 1418 1419 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1420 } 1421 1422 static void 1423 biba_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1424 struct mbuf *m, struct label *mlabel) 1425 { 1426 struct mac_biba *dest; 1427 1428 dest = SLOT(mlabel); 1429 1430 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1431 } 1432 1433 static int 1434 biba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1435 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1436 { 1437 1438 if(!biba_enabled) 1439 return (0); 1440 1441 /* XXX: This will be implemented soon... */ 1442 1443 return (0); 1444 } 1445 1446 static int 1447 biba_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1448 struct label *pplabel) 1449 { 1450 struct mac_biba *subj, *obj; 1451 1452 if (!biba_enabled) 1453 return (0); 1454 1455 subj = SLOT(cred->cr_label); 1456 obj = SLOT(pplabel); 1457 1458 if (!biba_dominate_effective(obj, subj)) 1459 return (EACCES); 1460 1461 return (0); 1462 } 1463 1464 static int 1465 biba_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1466 struct label *pplabel) 1467 { 1468 struct mac_biba *subj, *obj; 1469 1470 if (!biba_enabled) 1471 return (0); 1472 1473 subj = SLOT(cred->cr_label); 1474 obj = SLOT(pplabel); 1475 1476 if (!biba_dominate_effective(obj, subj)) 1477 return (EACCES); 1478 1479 return (0); 1480 } 1481 1482 static int 1483 biba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1484 struct label *pplabel, struct label *newlabel) 1485 { 1486 struct mac_biba *subj, *obj, *new; 1487 int error; 1488 1489 new = SLOT(newlabel); 1490 subj = SLOT(cred->cr_label); 1491 obj = SLOT(pplabel); 1492 1493 /* 1494 * If there is a Biba label update for a pipe, it must be a effective 1495 * update. 1496 */ 1497 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 1498 if (error) 1499 return (error); 1500 1501 /* 1502 * To perform a relabel of a pipe (Biba label or not), Biba must 1503 * authorize the relabel. 1504 */ 1505 if (!biba_effective_in_range(obj, subj)) 1506 return (EPERM); 1507 1508 /* 1509 * If the Biba label is to be changed, authorize as appropriate. 1510 */ 1511 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 1512 /* 1513 * To change the Biba label on a pipe, the new pipe label 1514 * must be in the subject range. 1515 */ 1516 if (!biba_effective_in_range(new, subj)) 1517 return (EPERM); 1518 1519 /* 1520 * To change the Biba label on a pipe to be EQUAL, the 1521 * subject must have appropriate privilege. 1522 */ 1523 if (biba_contains_equal(new)) { 1524 error = biba_subject_privileged(subj); 1525 if (error) 1526 return (error); 1527 } 1528 } 1529 1530 return (0); 1531 } 1532 1533 static int 1534 biba_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 1535 struct label *pplabel) 1536 { 1537 struct mac_biba *subj, *obj; 1538 1539 if (!biba_enabled) 1540 return (0); 1541 1542 subj = SLOT(cred->cr_label); 1543 obj = SLOT(pplabel); 1544 1545 if (!biba_dominate_effective(obj, subj)) 1546 return (EACCES); 1547 1548 return (0); 1549 } 1550 1551 static int 1552 biba_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1553 struct label *pplabel) 1554 { 1555 struct mac_biba *subj, *obj; 1556 1557 if (!biba_enabled) 1558 return (0); 1559 1560 subj = SLOT(cred->cr_label); 1561 obj = SLOT(pplabel); 1562 1563 if (!biba_dominate_effective(subj, obj)) 1564 return (EACCES); 1565 1566 return (0); 1567 } 1568 1569 static void 1570 biba_pipe_create(struct ucred *cred, struct pipepair *pp, 1571 struct label *pplabel) 1572 { 1573 struct mac_biba *source, *dest; 1574 1575 source = SLOT(cred->cr_label); 1576 dest = SLOT(pplabel); 1577 1578 biba_copy_effective(source, dest); 1579 } 1580 1581 static void 1582 biba_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1583 struct label *pplabel, struct label *newlabel) 1584 { 1585 struct mac_biba *source, *dest; 1586 1587 source = SLOT(newlabel); 1588 dest = SLOT(pplabel); 1589 1590 biba_copy(source, dest); 1591 } 1592 1593 static int 1594 biba_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks, 1595 struct label *kslabel) 1596 { 1597 struct mac_biba *subj, *obj; 1598 1599 if (!biba_enabled) 1600 return (0); 1601 1602 subj = SLOT(cred->cr_label); 1603 obj = SLOT(kslabel); 1604 1605 if (!biba_dominate_effective(subj, obj)) 1606 return (EACCES); 1607 1608 return (0); 1609 } 1610 1611 static int 1612 biba_posixsem_check_setmode(struct ucred *cred, struct ksem *ks, 1613 struct label *kslabel, mode_t mode) 1614 { 1615 struct mac_biba *subj, *obj; 1616 1617 if (!biba_enabled) 1618 return (0); 1619 1620 subj = SLOT(cred->cr_label); 1621 obj = SLOT(kslabel); 1622 1623 if (!biba_dominate_effective(subj, obj)) 1624 return (EACCES); 1625 1626 return (0); 1627 } 1628 1629 static int 1630 biba_posixsem_check_setowner(struct ucred *cred, struct ksem *ks, 1631 struct label *kslabel, uid_t uid, gid_t gid) 1632 { 1633 struct mac_biba *subj, *obj; 1634 1635 if (!biba_enabled) 1636 return (0); 1637 1638 subj = SLOT(cred->cr_label); 1639 obj = SLOT(kslabel); 1640 1641 if (!biba_dominate_effective(subj, obj)) 1642 return (EACCES); 1643 1644 return (0); 1645 } 1646 1647 static int 1648 biba_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred, 1649 struct ksem *ks, struct label *kslabel) 1650 { 1651 struct mac_biba *subj, *obj; 1652 1653 if (!biba_enabled) 1654 return (0); 1655 1656 subj = SLOT(active_cred->cr_label); 1657 obj = SLOT(kslabel); 1658 1659 if (!biba_dominate_effective(subj, obj)) 1660 return (EACCES); 1661 1662 return (0); 1663 } 1664 1665 static int 1666 biba_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred, 1667 struct ksem *ks, struct label *kslabel) 1668 { 1669 struct mac_biba *subj, *obj; 1670 1671 if (!biba_enabled) 1672 return (0); 1673 1674 subj = SLOT(active_cred->cr_label); 1675 obj = SLOT(kslabel); 1676 1677 if (!biba_dominate_effective(obj, subj)) 1678 return (EACCES); 1679 1680 return (0); 1681 } 1682 1683 static void 1684 biba_posixsem_create(struct ucred *cred, struct ksem *ks, 1685 struct label *kslabel) 1686 { 1687 struct mac_biba *source, *dest; 1688 1689 source = SLOT(cred->cr_label); 1690 dest = SLOT(kslabel); 1691 1692 biba_copy_effective(source, dest); 1693 } 1694 1695 static int 1696 biba_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd, 1697 struct label *shmlabel, int prot, int flags) 1698 { 1699 struct mac_biba *subj, *obj; 1700 1701 if (!biba_enabled || !revocation_enabled) 1702 return (0); 1703 1704 subj = SLOT(cred->cr_label); 1705 obj = SLOT(shmlabel); 1706 1707 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 1708 if (!biba_dominate_effective(obj, subj)) 1709 return (EACCES); 1710 } 1711 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 1712 if (!biba_dominate_effective(subj, obj)) 1713 return (EACCES); 1714 } 1715 1716 return (0); 1717 } 1718 1719 static int 1720 biba_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd, 1721 struct label *shmlabel, accmode_t accmode) 1722 { 1723 struct mac_biba *subj, *obj; 1724 1725 if (!biba_enabled) 1726 return (0); 1727 1728 subj = SLOT(cred->cr_label); 1729 obj = SLOT(shmlabel); 1730 1731 if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 1732 if (!biba_dominate_effective(obj, subj)) 1733 return (EACCES); 1734 } 1735 if (accmode & VMODIFY_PERMS) { 1736 if (!biba_dominate_effective(subj, obj)) 1737 return (EACCES); 1738 } 1739 1740 return (0); 1741 } 1742 1743 static int 1744 biba_posixshm_check_read(struct ucred *active_cred, struct ucred *file_cred, 1745 struct shmfd *vp, struct label *shmlabel) 1746 { 1747 struct mac_biba *subj, *obj; 1748 1749 if (!biba_enabled || !revocation_enabled) 1750 return (0); 1751 1752 subj = SLOT(active_cred->cr_label); 1753 obj = SLOT(shmlabel); 1754 1755 if (!biba_dominate_effective(obj, subj)) 1756 return (EACCES); 1757 1758 return (0); 1759 } 1760 1761 static int 1762 biba_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd, 1763 struct label *shmlabel, mode_t mode) 1764 { 1765 struct mac_biba *subj, *obj; 1766 1767 if (!biba_enabled) 1768 return (0); 1769 1770 subj = SLOT(cred->cr_label); 1771 obj = SLOT(shmlabel); 1772 1773 if (!biba_dominate_effective(subj, obj)) 1774 return (EACCES); 1775 1776 return (0); 1777 } 1778 1779 static int 1780 biba_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd, 1781 struct label *shmlabel, uid_t uid, gid_t gid) 1782 { 1783 struct mac_biba *subj, *obj; 1784 1785 if (!biba_enabled) 1786 return (0); 1787 1788 subj = SLOT(cred->cr_label); 1789 obj = SLOT(shmlabel); 1790 1791 if (!biba_dominate_effective(subj, obj)) 1792 return (EACCES); 1793 1794 return (0); 1795 } 1796 1797 static int 1798 biba_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred, 1799 struct shmfd *shmfd, struct label *shmlabel) 1800 { 1801 struct mac_biba *subj, *obj; 1802 1803 if (!biba_enabled) 1804 return (0); 1805 1806 subj = SLOT(active_cred->cr_label); 1807 obj = SLOT(shmlabel); 1808 1809 if (!biba_dominate_effective(obj, subj)) 1810 return (EACCES); 1811 1812 return (0); 1813 } 1814 1815 static int 1816 biba_posixshm_check_truncate(struct ucred *active_cred, 1817 struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel) 1818 { 1819 struct mac_biba *subj, *obj; 1820 1821 if (!biba_enabled) 1822 return (0); 1823 1824 subj = SLOT(active_cred->cr_label); 1825 obj = SLOT(shmlabel); 1826 1827 if (!biba_dominate_effective(subj, obj)) 1828 return (EACCES); 1829 1830 return (0); 1831 } 1832 1833 static int 1834 biba_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd, 1835 struct label *shmlabel) 1836 { 1837 struct mac_biba *subj, *obj; 1838 1839 if (!biba_enabled) 1840 return (0); 1841 1842 subj = SLOT(cred->cr_label); 1843 obj = SLOT(shmlabel); 1844 1845 if (!biba_dominate_effective(subj, obj)) 1846 return (EACCES); 1847 1848 return (0); 1849 } 1850 1851 static int 1852 biba_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred, 1853 struct shmfd *vp, struct label *shmlabel) 1854 { 1855 struct mac_biba *subj, *obj; 1856 1857 if (!biba_enabled || !revocation_enabled) 1858 return (0); 1859 1860 subj = SLOT(active_cred->cr_label); 1861 obj = SLOT(shmlabel); 1862 1863 if (!biba_dominate_effective(obj, subj)) 1864 return (EACCES); 1865 1866 return (0); 1867 } 1868 1869 static void 1870 biba_posixshm_create(struct ucred *cred, struct shmfd *shmfd, 1871 struct label *shmlabel) 1872 { 1873 struct mac_biba *source, *dest; 1874 1875 source = SLOT(cred->cr_label); 1876 dest = SLOT(shmlabel); 1877 1878 biba_copy_effective(source, dest); 1879 } 1880 1881 /* 1882 * Some system privileges are allowed regardless of integrity grade; others 1883 * are allowed only when running with privilege with respect to the Biba 1884 * policy as they might otherwise allow bypassing of the integrity policy. 1885 */ 1886 static int 1887 biba_priv_check(struct ucred *cred, int priv) 1888 { 1889 struct mac_biba *subj; 1890 int error; 1891 1892 if (!biba_enabled) 1893 return (0); 1894 1895 /* 1896 * Exempt only specific privileges from the Biba integrity policy. 1897 */ 1898 switch (priv) { 1899 case PRIV_KTRACE: 1900 case PRIV_MSGBUF: 1901 1902 /* 1903 * Allow processes to manipulate basic process audit properties, and 1904 * to submit audit records. 1905 */ 1906 case PRIV_AUDIT_GETAUDIT: 1907 case PRIV_AUDIT_SETAUDIT: 1908 case PRIV_AUDIT_SUBMIT: 1909 1910 /* 1911 * Allow processes to manipulate their regular UNIX credentials. 1912 */ 1913 case PRIV_CRED_SETUID: 1914 case PRIV_CRED_SETEUID: 1915 case PRIV_CRED_SETGID: 1916 case PRIV_CRED_SETEGID: 1917 case PRIV_CRED_SETGROUPS: 1918 case PRIV_CRED_SETREUID: 1919 case PRIV_CRED_SETREGID: 1920 case PRIV_CRED_SETRESUID: 1921 case PRIV_CRED_SETRESGID: 1922 1923 /* 1924 * Allow processes to perform system monitoring. 1925 */ 1926 case PRIV_SEEOTHERGIDS: 1927 case PRIV_SEEOTHERUIDS: 1928 break; 1929 1930 /* 1931 * Allow access to general process debugging facilities. We 1932 * separately control debugging based on MAC label. 1933 */ 1934 case PRIV_DEBUG_DIFFCRED: 1935 case PRIV_DEBUG_SUGID: 1936 case PRIV_DEBUG_UNPRIV: 1937 1938 /* 1939 * Allow manipulating jails. 1940 */ 1941 case PRIV_JAIL_ATTACH: 1942 1943 /* 1944 * Allow privilege with respect to the Partition policy, but not the 1945 * Privs policy. 1946 */ 1947 case PRIV_MAC_PARTITION: 1948 1949 /* 1950 * Allow privilege with respect to process resource limits and login 1951 * context. 1952 */ 1953 case PRIV_PROC_LIMIT: 1954 case PRIV_PROC_SETLOGIN: 1955 case PRIV_PROC_SETRLIMIT: 1956 1957 /* 1958 * Allow System V and POSIX IPC privileges. 1959 */ 1960 case PRIV_IPC_READ: 1961 case PRIV_IPC_WRITE: 1962 case PRIV_IPC_ADMIN: 1963 case PRIV_IPC_MSGSIZE: 1964 case PRIV_MQ_ADMIN: 1965 1966 /* 1967 * Allow certain scheduler manipulations -- possibly this should be 1968 * controlled by more fine-grained policy, as potentially low 1969 * integrity processes can deny CPU to higher integrity ones. 1970 */ 1971 case PRIV_SCHED_DIFFCRED: 1972 case PRIV_SCHED_SETPRIORITY: 1973 case PRIV_SCHED_RTPRIO: 1974 case PRIV_SCHED_SETPOLICY: 1975 case PRIV_SCHED_SET: 1976 case PRIV_SCHED_SETPARAM: 1977 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