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