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 (ifp->if_type == 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, ifp->if_xname) == 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 1979 /* 1980 * More IPC privileges. 1981 */ 1982 case PRIV_SEM_WRITE: 1983 1984 /* 1985 * Allow signaling privileges subject to integrity policy. 1986 */ 1987 case PRIV_SIGNAL_DIFFCRED: 1988 case PRIV_SIGNAL_SUGID: 1989 1990 /* 1991 * Allow access to only limited sysctls from lower integrity levels; 1992 * piggy-back on the Jail definition. 1993 */ 1994 case PRIV_SYSCTL_WRITEJAIL: 1995 1996 /* 1997 * Allow TTY-based privileges, subject to general device access using 1998 * labels on TTY device nodes, but not console privilege. 1999 */ 2000 case PRIV_TTY_DRAINWAIT: 2001 case PRIV_TTY_DTRWAIT: 2002 case PRIV_TTY_EXCLUSIVE: 2003 case PRIV_TTY_STI: 2004 case PRIV_TTY_SETA: 2005 2006 /* 2007 * Grant most VFS privileges, as almost all are in practice bounded 2008 * by more specific checks using labels. 2009 */ 2010 case PRIV_VFS_READ: 2011 case PRIV_VFS_WRITE: 2012 case PRIV_VFS_ADMIN: 2013 case PRIV_VFS_EXEC: 2014 case PRIV_VFS_LOOKUP: 2015 case PRIV_VFS_CHFLAGS_DEV: 2016 case PRIV_VFS_CHOWN: 2017 case PRIV_VFS_CHROOT: 2018 case PRIV_VFS_RETAINSUGID: 2019 case PRIV_VFS_EXCEEDQUOTA: 2020 case PRIV_VFS_FCHROOT: 2021 case PRIV_VFS_FHOPEN: 2022 case PRIV_VFS_FHSTATFS: 2023 case PRIV_VFS_GENERATION: 2024 case PRIV_VFS_GETFH: 2025 case PRIV_VFS_GETQUOTA: 2026 case PRIV_VFS_LINK: 2027 case PRIV_VFS_MOUNT: 2028 case PRIV_VFS_MOUNT_OWNER: 2029 case PRIV_VFS_MOUNT_PERM: 2030 case PRIV_VFS_MOUNT_SUIDDIR: 2031 case PRIV_VFS_MOUNT_NONUSER: 2032 case PRIV_VFS_SETGID: 2033 case PRIV_VFS_STICKYFILE: 2034 case PRIV_VFS_SYSFLAGS: 2035 case PRIV_VFS_UNMOUNT: 2036 2037 /* 2038 * Allow VM privileges; it would be nice if these were subject to 2039 * resource limits. 2040 */ 2041 case PRIV_VM_MADV_PROTECT: 2042 case PRIV_VM_MLOCK: 2043 case PRIV_VM_MUNLOCK: 2044 case PRIV_VM_SWAP_NOQUOTA: 2045 case PRIV_VM_SWAP_NORLIMIT: 2046 2047 /* 2048 * Allow some but not all network privileges. In general, dont allow 2049 * reconfiguring the network stack, just normal use. 2050 */ 2051 case PRIV_NETINET_RESERVEDPORT: 2052 case PRIV_NETINET_RAW: 2053 case PRIV_NETINET_REUSEPORT: 2054 break; 2055 2056 /* 2057 * All remaining system privileges are allow only if the process 2058 * holds privilege with respect to the Biba policy. 2059 */ 2060 default: 2061 subj = SLOT(cred->cr_label); 2062 error = biba_subject_privileged(subj); 2063 if (error) 2064 return (error); 2065 } 2066 return (0); 2067 } 2068 2069 static int 2070 biba_proc_check_debug(struct ucred *cred, struct proc *p) 2071 { 2072 struct mac_biba *subj, *obj; 2073 2074 if (!biba_enabled) 2075 return (0); 2076 2077 subj = SLOT(cred->cr_label); 2078 obj = SLOT(p->p_ucred->cr_label); 2079 2080 /* XXX: range checks */ 2081 if (!biba_dominate_effective(obj, subj)) 2082 return (ESRCH); 2083 if (!biba_dominate_effective(subj, obj)) 2084 return (EACCES); 2085 2086 return (0); 2087 } 2088 2089 static int 2090 biba_proc_check_sched(struct ucred *cred, struct proc *p) 2091 { 2092 struct mac_biba *subj, *obj; 2093 2094 if (!biba_enabled) 2095 return (0); 2096 2097 subj = SLOT(cred->cr_label); 2098 obj = SLOT(p->p_ucred->cr_label); 2099 2100 /* XXX: range checks */ 2101 if (!biba_dominate_effective(obj, subj)) 2102 return (ESRCH); 2103 if (!biba_dominate_effective(subj, obj)) 2104 return (EACCES); 2105 2106 return (0); 2107 } 2108 2109 static int 2110 biba_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 2111 { 2112 struct mac_biba *subj, *obj; 2113 2114 if (!biba_enabled) 2115 return (0); 2116 2117 subj = SLOT(cred->cr_label); 2118 obj = SLOT(p->p_ucred->cr_label); 2119 2120 /* XXX: range checks */ 2121 if (!biba_dominate_effective(obj, subj)) 2122 return (ESRCH); 2123 if (!biba_dominate_effective(subj, obj)) 2124 return (EACCES); 2125 2126 return (0); 2127 } 2128 2129 static int 2130 biba_socket_check_deliver(struct socket *so, struct label *solabel, 2131 struct mbuf *m, struct label *mlabel) 2132 { 2133 struct mac_biba *p, *s; 2134 int error; 2135 2136 if (!biba_enabled) 2137 return (0); 2138 2139 p = SLOT(mlabel); 2140 s = SLOT(solabel); 2141 2142 SOCK_LOCK(so); 2143 error = biba_equal_effective(p, s) ? 0 : EACCES; 2144 SOCK_UNLOCK(so); 2145 return (error); 2146 } 2147 2148 static int 2149 biba_socket_check_relabel(struct ucred *cred, struct socket *so, 2150 struct label *solabel, struct label *newlabel) 2151 { 2152 struct mac_biba *subj, *obj, *new; 2153 int error; 2154 2155 SOCK_LOCK_ASSERT(so); 2156 2157 new = SLOT(newlabel); 2158 subj = SLOT(cred->cr_label); 2159 obj = SLOT(solabel); 2160 2161 /* 2162 * If there is a Biba label update for the socket, it may be an 2163 * update of effective. 2164 */ 2165 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2166 if (error) 2167 return (error); 2168 2169 /* 2170 * To relabel a socket, the old socket effective must be in the 2171 * subject range. 2172 */ 2173 if (!biba_effective_in_range(obj, subj)) 2174 return (EPERM); 2175 2176 /* 2177 * If the Biba label is to be changed, authorize as appropriate. 2178 */ 2179 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2180 /* 2181 * To relabel a socket, the new socket effective must be in 2182 * the subject range. 2183 */ 2184 if (!biba_effective_in_range(new, subj)) 2185 return (EPERM); 2186 2187 /* 2188 * To change the Biba label on the socket to contain EQUAL, 2189 * the subject must have appropriate privilege. 2190 */ 2191 if (biba_contains_equal(new)) { 2192 error = biba_subject_privileged(subj); 2193 if (error) 2194 return (error); 2195 } 2196 } 2197 2198 return (0); 2199 } 2200 2201 static int 2202 biba_socket_check_visible(struct ucred *cred, struct socket *so, 2203 struct label *solabel) 2204 { 2205 struct mac_biba *subj, *obj; 2206 2207 if (!biba_enabled) 2208 return (0); 2209 2210 subj = SLOT(cred->cr_label); 2211 obj = SLOT(solabel); 2212 2213 SOCK_LOCK(so); 2214 if (!biba_dominate_effective(obj, subj)) { 2215 SOCK_UNLOCK(so); 2216 return (ENOENT); 2217 } 2218 SOCK_UNLOCK(so); 2219 2220 return (0); 2221 } 2222 2223 static void 2224 biba_socket_create(struct ucred *cred, struct socket *so, 2225 struct label *solabel) 2226 { 2227 struct mac_biba *source, *dest; 2228 2229 source = SLOT(cred->cr_label); 2230 dest = SLOT(solabel); 2231 2232 biba_copy_effective(source, dest); 2233 } 2234 2235 static void 2236 biba_socket_create_mbuf(struct socket *so, struct label *solabel, 2237 struct mbuf *m, struct label *mlabel) 2238 { 2239 struct mac_biba *source, *dest; 2240 2241 source = SLOT(solabel); 2242 dest = SLOT(mlabel); 2243 2244 SOCK_LOCK(so); 2245 biba_copy_effective(source, dest); 2246 SOCK_UNLOCK(so); 2247 } 2248 2249 static void 2250 biba_socket_newconn(struct socket *oldso, struct label *oldsolabel, 2251 struct socket *newso, struct label *newsolabel) 2252 { 2253 struct mac_biba source, *dest; 2254 2255 SOCK_LOCK(oldso); 2256 source = *SLOT(oldsolabel); 2257 SOCK_UNLOCK(oldso); 2258 2259 dest = SLOT(newsolabel); 2260 2261 SOCK_LOCK(newso); 2262 biba_copy_effective(&source, dest); 2263 SOCK_UNLOCK(newso); 2264 } 2265 2266 static void 2267 biba_socket_relabel(struct ucred *cred, struct socket *so, 2268 struct label *solabel, struct label *newlabel) 2269 { 2270 struct mac_biba *source, *dest; 2271 2272 SOCK_LOCK_ASSERT(so); 2273 2274 source = SLOT(newlabel); 2275 dest = SLOT(solabel); 2276 2277 biba_copy(source, dest); 2278 } 2279 2280 static void 2281 biba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 2282 struct socket *so, struct label *sopeerlabel) 2283 { 2284 struct mac_biba *source, *dest; 2285 2286 source = SLOT(mlabel); 2287 dest = SLOT(sopeerlabel); 2288 2289 SOCK_LOCK(so); 2290 biba_copy_effective(source, dest); 2291 SOCK_UNLOCK(so); 2292 } 2293 2294 static void 2295 biba_socketpeer_set_from_socket(struct socket *oldso, 2296 struct label *oldsolabel, struct socket *newso, 2297 struct label *newsopeerlabel) 2298 { 2299 struct mac_biba source, *dest; 2300 2301 SOCK_LOCK(oldso); 2302 source = *SLOT(oldsolabel); 2303 SOCK_UNLOCK(oldso); 2304 dest = SLOT(newsopeerlabel); 2305 2306 SOCK_LOCK(newso); 2307 biba_copy_effective(&source, dest); 2308 SOCK_UNLOCK(newso); 2309 } 2310 2311 static void 2312 biba_syncache_create(struct label *label, struct inpcb *inp) 2313 { 2314 struct mac_biba *source, *dest; 2315 2316 source = SLOT(inp->inp_label); 2317 dest = SLOT(label); 2318 biba_copy_effective(source, dest); 2319 } 2320 2321 static void 2322 biba_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2323 struct label *mlabel) 2324 { 2325 struct mac_biba *source, *dest; 2326 2327 source = SLOT(sc_label); 2328 dest = SLOT(mlabel); 2329 biba_copy_effective(source, dest); 2330 } 2331 2332 static int 2333 biba_system_check_acct(struct ucred *cred, struct vnode *vp, 2334 struct label *vplabel) 2335 { 2336 struct mac_biba *subj, *obj; 2337 int error; 2338 2339 if (!biba_enabled) 2340 return (0); 2341 2342 subj = SLOT(cred->cr_label); 2343 2344 error = biba_subject_privileged(subj); 2345 if (error) 2346 return (error); 2347 2348 if (vplabel == NULL) 2349 return (0); 2350 2351 obj = SLOT(vplabel); 2352 if (!biba_high_effective(obj)) 2353 return (EACCES); 2354 2355 return (0); 2356 } 2357 2358 static int 2359 biba_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2360 struct label *vplabel) 2361 { 2362 struct mac_biba *subj, *obj; 2363 int error; 2364 2365 if (!biba_enabled) 2366 return (0); 2367 2368 subj = SLOT(cred->cr_label); 2369 2370 error = biba_subject_privileged(subj); 2371 if (error) 2372 return (error); 2373 2374 if (vplabel == NULL) 2375 return (0); 2376 2377 obj = SLOT(vplabel); 2378 if (!biba_high_effective(obj)) 2379 return (EACCES); 2380 2381 return (0); 2382 } 2383 2384 static int 2385 biba_system_check_auditon(struct ucred *cred, int cmd) 2386 { 2387 struct mac_biba *subj; 2388 int error; 2389 2390 if (!biba_enabled) 2391 return (0); 2392 2393 subj = SLOT(cred->cr_label); 2394 2395 error = biba_subject_privileged(subj); 2396 if (error) 2397 return (error); 2398 2399 return (0); 2400 } 2401 2402 static int 2403 biba_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2404 struct label *label) 2405 { 2406 struct mac_biba *subj; 2407 int error; 2408 2409 if (!biba_enabled) 2410 return (0); 2411 2412 subj = SLOT(cred->cr_label); 2413 2414 error = biba_subject_privileged(subj); 2415 if (error) 2416 return (error); 2417 2418 return (0); 2419 } 2420 2421 static int 2422 biba_system_check_swapon(struct ucred *cred, struct vnode *vp, 2423 struct label *vplabel) 2424 { 2425 struct mac_biba *subj, *obj; 2426 int error; 2427 2428 if (!biba_enabled) 2429 return (0); 2430 2431 subj = SLOT(cred->cr_label); 2432 obj = SLOT(vplabel); 2433 2434 error = biba_subject_privileged(subj); 2435 if (error) 2436 return (error); 2437 2438 if (!biba_high_effective(obj)) 2439 return (EACCES); 2440 2441 return (0); 2442 } 2443 2444 static int 2445 biba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2446 void *arg1, int arg2, struct sysctl_req *req) 2447 { 2448 struct mac_biba *subj; 2449 int error; 2450 2451 if (!biba_enabled) 2452 return (0); 2453 2454 subj = SLOT(cred->cr_label); 2455 2456 /* 2457 * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high, 2458 * but also require privilege to change them. 2459 */ 2460 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2461 if (!biba_subject_dominate_high(subj)) 2462 return (EACCES); 2463 2464 error = biba_subject_privileged(subj); 2465 if (error) 2466 return (error); 2467 } 2468 2469 return (0); 2470 } 2471 2472 static void 2473 biba_sysvmsg_cleanup(struct label *msglabel) 2474 { 2475 2476 bzero(SLOT(msglabel), sizeof(struct mac_biba)); 2477 } 2478 2479 static void 2480 biba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2481 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 2482 { 2483 struct mac_biba *source, *dest; 2484 2485 /* Ignore the msgq label */ 2486 source = SLOT(cred->cr_label); 2487 dest = SLOT(msglabel); 2488 2489 biba_copy_effective(source, dest); 2490 } 2491 2492 static int 2493 biba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 2494 struct label *msglabel) 2495 { 2496 struct mac_biba *subj, *obj; 2497 2498 if (!biba_enabled) 2499 return (0); 2500 2501 subj = SLOT(cred->cr_label); 2502 obj = SLOT(msglabel); 2503 2504 if (!biba_dominate_effective(obj, subj)) 2505 return (EACCES); 2506 2507 return (0); 2508 } 2509 2510 static int 2511 biba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 2512 struct label *msglabel) 2513 { 2514 struct mac_biba *subj, *obj; 2515 2516 if (!biba_enabled) 2517 return (0); 2518 2519 subj = SLOT(cred->cr_label); 2520 obj = SLOT(msglabel); 2521 2522 if (!biba_dominate_effective(subj, obj)) 2523 return (EACCES); 2524 2525 return (0); 2526 } 2527 2528 static int 2529 biba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 2530 struct label *msqklabel) 2531 { 2532 struct mac_biba *subj, *obj; 2533 2534 if (!biba_enabled) 2535 return (0); 2536 2537 subj = SLOT(cred->cr_label); 2538 obj = SLOT(msqklabel); 2539 2540 if (!biba_dominate_effective(obj, subj)) 2541 return (EACCES); 2542 2543 return (0); 2544 } 2545 2546 static int 2547 biba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 2548 struct label *msqklabel) 2549 { 2550 struct mac_biba *subj, *obj; 2551 2552 if (!biba_enabled) 2553 return (0); 2554 2555 subj = SLOT(cred->cr_label); 2556 obj = SLOT(msqklabel); 2557 2558 if (!biba_dominate_effective(subj, obj)) 2559 return (EACCES); 2560 2561 return (0); 2562 } 2563 2564 static int 2565 biba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 2566 struct label *msqklabel) 2567 { 2568 struct mac_biba *subj, *obj; 2569 2570 if (!biba_enabled) 2571 return (0); 2572 2573 subj = SLOT(cred->cr_label); 2574 obj = SLOT(msqklabel); 2575 2576 if (!biba_dominate_effective(obj, subj)) 2577 return (EACCES); 2578 2579 return (0); 2580 } 2581 2582 static int 2583 biba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 2584 struct label *msqklabel, int cmd) 2585 { 2586 struct mac_biba *subj, *obj; 2587 2588 if (!biba_enabled) 2589 return (0); 2590 2591 subj = SLOT(cred->cr_label); 2592 obj = SLOT(msqklabel); 2593 2594 switch(cmd) { 2595 case IPC_RMID: 2596 case IPC_SET: 2597 if (!biba_dominate_effective(subj, obj)) 2598 return (EACCES); 2599 break; 2600 2601 case IPC_STAT: 2602 if (!biba_dominate_effective(obj, subj)) 2603 return (EACCES); 2604 break; 2605 2606 default: 2607 return (EACCES); 2608 } 2609 2610 return (0); 2611 } 2612 2613 static void 2614 biba_sysvmsq_cleanup(struct label *msqlabel) 2615 { 2616 2617 bzero(SLOT(msqlabel), sizeof(struct mac_biba)); 2618 } 2619 2620 static void 2621 biba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2622 struct label *msqlabel) 2623 { 2624 struct mac_biba *source, *dest; 2625 2626 source = SLOT(cred->cr_label); 2627 dest = SLOT(msqlabel); 2628 2629 biba_copy_effective(source, dest); 2630 } 2631 2632 static int 2633 biba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 2634 struct label *semaklabel, int cmd) 2635 { 2636 struct mac_biba *subj, *obj; 2637 2638 if (!biba_enabled) 2639 return (0); 2640 2641 subj = SLOT(cred->cr_label); 2642 obj = SLOT(semaklabel); 2643 2644 switch(cmd) { 2645 case IPC_RMID: 2646 case IPC_SET: 2647 case SETVAL: 2648 case SETALL: 2649 if (!biba_dominate_effective(subj, obj)) 2650 return (EACCES); 2651 break; 2652 2653 case IPC_STAT: 2654 case GETVAL: 2655 case GETPID: 2656 case GETNCNT: 2657 case GETZCNT: 2658 case GETALL: 2659 if (!biba_dominate_effective(obj, subj)) 2660 return (EACCES); 2661 break; 2662 2663 default: 2664 return (EACCES); 2665 } 2666 2667 return (0); 2668 } 2669 2670 static int 2671 biba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 2672 struct label *semaklabel) 2673 { 2674 struct mac_biba *subj, *obj; 2675 2676 if (!biba_enabled) 2677 return (0); 2678 2679 subj = SLOT(cred->cr_label); 2680 obj = SLOT(semaklabel); 2681 2682 if (!biba_dominate_effective(obj, subj)) 2683 return (EACCES); 2684 2685 return (0); 2686 } 2687 2688 static int 2689 biba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2690 struct label *semaklabel, size_t accesstype) 2691 { 2692 struct mac_biba *subj, *obj; 2693 2694 if (!biba_enabled) 2695 return (0); 2696 2697 subj = SLOT(cred->cr_label); 2698 obj = SLOT(semaklabel); 2699 2700 if (accesstype & SEM_R) 2701 if (!biba_dominate_effective(obj, subj)) 2702 return (EACCES); 2703 2704 if (accesstype & SEM_A) 2705 if (!biba_dominate_effective(subj, obj)) 2706 return (EACCES); 2707 2708 return (0); 2709 } 2710 2711 static void 2712 biba_sysvsem_cleanup(struct label *semalabel) 2713 { 2714 2715 bzero(SLOT(semalabel), sizeof(struct mac_biba)); 2716 } 2717 2718 static void 2719 biba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2720 struct label *semalabel) 2721 { 2722 struct mac_biba *source, *dest; 2723 2724 source = SLOT(cred->cr_label); 2725 dest = SLOT(semalabel); 2726 2727 biba_copy_effective(source, dest); 2728 } 2729 2730 static int 2731 biba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2732 struct label *shmseglabel, int shmflg) 2733 { 2734 struct mac_biba *subj, *obj; 2735 2736 if (!biba_enabled) 2737 return (0); 2738 2739 subj = SLOT(cred->cr_label); 2740 obj = SLOT(shmseglabel); 2741 2742 if (!biba_dominate_effective(obj, subj)) 2743 return (EACCES); 2744 if ((shmflg & SHM_RDONLY) == 0) { 2745 if (!biba_dominate_effective(subj, obj)) 2746 return (EACCES); 2747 } 2748 2749 return (0); 2750 } 2751 2752 static int 2753 biba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2754 struct label *shmseglabel, int cmd) 2755 { 2756 struct mac_biba *subj, *obj; 2757 2758 if (!biba_enabled) 2759 return (0); 2760 2761 subj = SLOT(cred->cr_label); 2762 obj = SLOT(shmseglabel); 2763 2764 switch(cmd) { 2765 case IPC_RMID: 2766 case IPC_SET: 2767 if (!biba_dominate_effective(subj, obj)) 2768 return (EACCES); 2769 break; 2770 2771 case IPC_STAT: 2772 case SHM_STAT: 2773 if (!biba_dominate_effective(obj, subj)) 2774 return (EACCES); 2775 break; 2776 2777 default: 2778 return (EACCES); 2779 } 2780 2781 return (0); 2782 } 2783 2784 static int 2785 biba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2786 struct label *shmseglabel, int shmflg) 2787 { 2788 struct mac_biba *subj, *obj; 2789 2790 if (!biba_enabled) 2791 return (0); 2792 2793 subj = SLOT(cred->cr_label); 2794 obj = SLOT(shmseglabel); 2795 2796 if (!biba_dominate_effective(obj, subj)) 2797 return (EACCES); 2798 2799 return (0); 2800 } 2801 2802 static void 2803 biba_sysvshm_cleanup(struct label *shmlabel) 2804 { 2805 2806 bzero(SLOT(shmlabel), sizeof(struct mac_biba)); 2807 } 2808 2809 static void 2810 biba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2811 struct label *shmlabel) 2812 { 2813 struct mac_biba *source, *dest; 2814 2815 source = SLOT(cred->cr_label); 2816 dest = SLOT(shmlabel); 2817 2818 biba_copy_effective(source, dest); 2819 } 2820 2821 static int 2822 biba_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2823 struct vnode *vp, struct label *vplabel) 2824 { 2825 struct mac_biba mb_temp, *source, *dest; 2826 int buflen, error; 2827 2828 source = SLOT(mplabel); 2829 dest = SLOT(vplabel); 2830 2831 buflen = sizeof(mb_temp); 2832 bzero(&mb_temp, buflen); 2833 2834 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 2835 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread); 2836 if (error == ENOATTR || error == EOPNOTSUPP) { 2837 /* Fall back to the mntlabel. */ 2838 biba_copy_effective(source, dest); 2839 return (0); 2840 } else if (error) 2841 return (error); 2842 2843 if (buflen != sizeof(mb_temp)) { 2844 printf("biba_vnode_associate_extattr: bad size %d\n", 2845 buflen); 2846 return (EPERM); 2847 } 2848 if (biba_valid(&mb_temp) != 0) { 2849 printf("biba_vnode_associate_extattr: invalid\n"); 2850 return (EPERM); 2851 } 2852 if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != 2853 MAC_BIBA_FLAG_EFFECTIVE) { 2854 printf("biba_vnode_associate_extattr: not effective\n"); 2855 return (EPERM); 2856 } 2857 2858 biba_copy_effective(&mb_temp, dest); 2859 return (0); 2860 } 2861 2862 static void 2863 biba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2864 struct vnode *vp, struct label *vplabel) 2865 { 2866 struct mac_biba *source, *dest; 2867 2868 source = SLOT(mplabel); 2869 dest = SLOT(vplabel); 2870 2871 biba_copy_effective(source, dest); 2872 } 2873 2874 static int 2875 biba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2876 struct label *dvplabel) 2877 { 2878 struct mac_biba *subj, *obj; 2879 2880 if (!biba_enabled) 2881 return (0); 2882 2883 subj = SLOT(cred->cr_label); 2884 obj = SLOT(dvplabel); 2885 2886 if (!biba_dominate_effective(obj, subj)) 2887 return (EACCES); 2888 2889 return (0); 2890 } 2891 2892 static int 2893 biba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2894 struct label *dvplabel) 2895 { 2896 struct mac_biba *subj, *obj; 2897 2898 if (!biba_enabled) 2899 return (0); 2900 2901 subj = SLOT(cred->cr_label); 2902 obj = SLOT(dvplabel); 2903 2904 if (!biba_dominate_effective(obj, subj)) 2905 return (EACCES); 2906 2907 return (0); 2908 } 2909 2910 static int 2911 biba_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2912 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2913 { 2914 struct mac_biba *subj, *obj; 2915 2916 if (!biba_enabled) 2917 return (0); 2918 2919 subj = SLOT(cred->cr_label); 2920 obj = SLOT(dvplabel); 2921 2922 if (!biba_dominate_effective(subj, obj)) 2923 return (EACCES); 2924 2925 return (0); 2926 } 2927 2928 static int 2929 biba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2930 struct label *vplabel, acl_type_t type) 2931 { 2932 struct mac_biba *subj, *obj; 2933 2934 if (!biba_enabled) 2935 return (0); 2936 2937 subj = SLOT(cred->cr_label); 2938 obj = SLOT(vplabel); 2939 2940 if (!biba_dominate_effective(subj, obj)) 2941 return (EACCES); 2942 2943 return (0); 2944 } 2945 2946 static int 2947 biba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2948 struct label *vplabel, int attrnamespace, const char *name) 2949 { 2950 struct mac_biba *subj, *obj; 2951 2952 if (!biba_enabled) 2953 return (0); 2954 2955 subj = SLOT(cred->cr_label); 2956 obj = SLOT(vplabel); 2957 2958 if (!biba_dominate_effective(subj, obj)) 2959 return (EACCES); 2960 2961 return (0); 2962 } 2963 2964 static int 2965 biba_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2966 struct label *vplabel, struct image_params *imgp, 2967 struct label *execlabel) 2968 { 2969 struct mac_biba *subj, *obj, *exec; 2970 int error; 2971 2972 if (execlabel != NULL) { 2973 /* 2974 * We currently don't permit labels to be changed at 2975 * exec-time as part of Biba, so disallow non-NULL Biba label 2976 * elements in the execlabel. 2977 */ 2978 exec = SLOT(execlabel); 2979 error = biba_atmostflags(exec, 0); 2980 if (error) 2981 return (error); 2982 } 2983 2984 if (!biba_enabled) 2985 return (0); 2986 2987 subj = SLOT(cred->cr_label); 2988 obj = SLOT(vplabel); 2989 2990 if (!biba_dominate_effective(obj, subj)) 2991 return (EACCES); 2992 2993 return (0); 2994 } 2995 2996 static int 2997 biba_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2998 struct label *vplabel, acl_type_t type) 2999 { 3000 struct mac_biba *subj, *obj; 3001 3002 if (!biba_enabled) 3003 return (0); 3004 3005 subj = SLOT(cred->cr_label); 3006 obj = SLOT(vplabel); 3007 3008 if (!biba_dominate_effective(obj, subj)) 3009 return (EACCES); 3010 3011 return (0); 3012 } 3013 3014 static int 3015 biba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 3016 struct label *vplabel, int attrnamespace, const char *name) 3017 { 3018 struct mac_biba *subj, *obj; 3019 3020 if (!biba_enabled) 3021 return (0); 3022 3023 subj = SLOT(cred->cr_label); 3024 obj = SLOT(vplabel); 3025 3026 if (!biba_dominate_effective(obj, subj)) 3027 return (EACCES); 3028 3029 return (0); 3030 } 3031 3032 static int 3033 biba_vnode_check_link(struct ucred *cred, struct vnode *dvp, 3034 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3035 struct componentname *cnp) 3036 { 3037 struct mac_biba *subj, *obj; 3038 3039 if (!biba_enabled) 3040 return (0); 3041 3042 subj = SLOT(cred->cr_label); 3043 obj = SLOT(dvplabel); 3044 3045 if (!biba_dominate_effective(subj, obj)) 3046 return (EACCES); 3047 3048 obj = SLOT(vplabel); 3049 3050 if (!biba_dominate_effective(subj, obj)) 3051 return (EACCES); 3052 3053 return (0); 3054 } 3055 3056 static int 3057 biba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 3058 struct label *vplabel, int attrnamespace) 3059 { 3060 struct mac_biba *subj, *obj; 3061 3062 if (!biba_enabled) 3063 return (0); 3064 3065 subj = SLOT(cred->cr_label); 3066 obj = SLOT(vplabel); 3067 3068 if (!biba_dominate_effective(obj, subj)) 3069 return (EACCES); 3070 3071 return (0); 3072 } 3073 3074 static int 3075 biba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 3076 struct label *dvplabel, struct componentname *cnp) 3077 { 3078 struct mac_biba *subj, *obj; 3079 3080 if (!biba_enabled) 3081 return (0); 3082 3083 subj = SLOT(cred->cr_label); 3084 obj = SLOT(dvplabel); 3085 3086 if (!biba_dominate_effective(obj, subj)) 3087 return (EACCES); 3088 3089 return (0); 3090 } 3091 3092 static int 3093 biba_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 3094 struct label *vplabel, int prot, int flags) 3095 { 3096 struct mac_biba *subj, *obj; 3097 3098 /* 3099 * Rely on the use of open()-time protections to handle 3100 * non-revocation cases. 3101 */ 3102 if (!biba_enabled || !revocation_enabled) 3103 return (0); 3104 3105 subj = SLOT(cred->cr_label); 3106 obj = SLOT(vplabel); 3107 3108 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 3109 if (!biba_dominate_effective(obj, subj)) 3110 return (EACCES); 3111 } 3112 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 3113 if (!biba_dominate_effective(subj, obj)) 3114 return (EACCES); 3115 } 3116 3117 return (0); 3118 } 3119 3120 static int 3121 biba_vnode_check_open(struct ucred *cred, struct vnode *vp, 3122 struct label *vplabel, accmode_t accmode) 3123 { 3124 struct mac_biba *subj, *obj; 3125 3126 if (!biba_enabled) 3127 return (0); 3128 3129 subj = SLOT(cred->cr_label); 3130 obj = SLOT(vplabel); 3131 3132 /* XXX privilege override for admin? */ 3133 if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 3134 if (!biba_dominate_effective(obj, subj)) 3135 return (EACCES); 3136 } 3137 if (accmode & VMODIFY_PERMS) { 3138 if (!biba_dominate_effective(subj, obj)) 3139 return (EACCES); 3140 } 3141 3142 return (0); 3143 } 3144 3145 static int 3146 biba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 3147 struct vnode *vp, struct label *vplabel) 3148 { 3149 struct mac_biba *subj, *obj; 3150 3151 if (!biba_enabled || !revocation_enabled) 3152 return (0); 3153 3154 subj = SLOT(active_cred->cr_label); 3155 obj = SLOT(vplabel); 3156 3157 if (!biba_dominate_effective(obj, subj)) 3158 return (EACCES); 3159 3160 return (0); 3161 } 3162 3163 static int 3164 biba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 3165 struct vnode *vp, struct label *vplabel) 3166 { 3167 struct mac_biba *subj, *obj; 3168 3169 if (!biba_enabled || !revocation_enabled) 3170 return (0); 3171 3172 subj = SLOT(active_cred->cr_label); 3173 obj = SLOT(vplabel); 3174 3175 if (!biba_dominate_effective(obj, subj)) 3176 return (EACCES); 3177 3178 return (0); 3179 } 3180 3181 static int 3182 biba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 3183 struct label *dvplabel) 3184 { 3185 struct mac_biba *subj, *obj; 3186 3187 if (!biba_enabled) 3188 return (0); 3189 3190 subj = SLOT(cred->cr_label); 3191 obj = SLOT(dvplabel); 3192 3193 if (!biba_dominate_effective(obj, subj)) 3194 return (EACCES); 3195 3196 return (0); 3197 } 3198 3199 static int 3200 biba_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 3201 struct label *vplabel) 3202 { 3203 struct mac_biba *subj, *obj; 3204 3205 if (!biba_enabled) 3206 return (0); 3207 3208 subj = SLOT(cred->cr_label); 3209 obj = SLOT(vplabel); 3210 3211 if (!biba_dominate_effective(obj, subj)) 3212 return (EACCES); 3213 3214 return (0); 3215 } 3216 3217 static int 3218 biba_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 3219 struct label *vplabel, struct label *newlabel) 3220 { 3221 struct mac_biba *old, *new, *subj; 3222 int error; 3223 3224 old = SLOT(vplabel); 3225 new = SLOT(newlabel); 3226 subj = SLOT(cred->cr_label); 3227 3228 /* 3229 * If there is a Biba label update for the vnode, it must be a 3230 * effective label. 3231 */ 3232 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 3233 if (error) 3234 return (error); 3235 3236 /* 3237 * To perform a relabel of the vnode (Biba label or not), Biba must 3238 * authorize the relabel. 3239 */ 3240 if (!biba_effective_in_range(old, subj)) 3241 return (EPERM); 3242 3243 /* 3244 * If the Biba label is to be changed, authorize as appropriate. 3245 */ 3246 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 3247 /* 3248 * To change the Biba label on a vnode, the new vnode label 3249 * must be in the subject range. 3250 */ 3251 if (!biba_effective_in_range(new, subj)) 3252 return (EPERM); 3253 3254 /* 3255 * To change the Biba label on the vnode to be EQUAL, the 3256 * subject must have appropriate privilege. 3257 */ 3258 if (biba_contains_equal(new)) { 3259 error = biba_subject_privileged(subj); 3260 if (error) 3261 return (error); 3262 } 3263 } 3264 3265 return (0); 3266 } 3267 3268 static int 3269 biba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 3270 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3271 struct componentname *cnp) 3272 { 3273 struct mac_biba *subj, *obj; 3274 3275 if (!biba_enabled) 3276 return (0); 3277 3278 subj = SLOT(cred->cr_label); 3279 obj = SLOT(dvplabel); 3280 3281 if (!biba_dominate_effective(subj, obj)) 3282 return (EACCES); 3283 3284 obj = SLOT(vplabel); 3285 3286 if (!biba_dominate_effective(subj, obj)) 3287 return (EACCES); 3288 3289 return (0); 3290 } 3291 3292 static int 3293 biba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 3294 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3295 int samedir, struct componentname *cnp) 3296 { 3297 struct mac_biba *subj, *obj; 3298 3299 if (!biba_enabled) 3300 return (0); 3301 3302 subj = SLOT(cred->cr_label); 3303 obj = SLOT(dvplabel); 3304 3305 if (!biba_dominate_effective(subj, obj)) 3306 return (EACCES); 3307 3308 if (vp != NULL) { 3309 obj = SLOT(vplabel); 3310 3311 if (!biba_dominate_effective(subj, obj)) 3312 return (EACCES); 3313 } 3314 3315 return (0); 3316 } 3317 3318 static int 3319 biba_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 3320 struct label *vplabel) 3321 { 3322 struct mac_biba *subj, *obj; 3323 3324 if (!biba_enabled) 3325 return (0); 3326 3327 subj = SLOT(cred->cr_label); 3328 obj = SLOT(vplabel); 3329 3330 if (!biba_dominate_effective(subj, obj)) 3331 return (EACCES); 3332 3333 return (0); 3334 } 3335 3336 static int 3337 biba_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 3338 struct label *vplabel, acl_type_t type, struct acl *acl) 3339 { 3340 struct mac_biba *subj, *obj; 3341 3342 if (!biba_enabled) 3343 return (0); 3344 3345 subj = SLOT(cred->cr_label); 3346 obj = SLOT(vplabel); 3347 3348 if (!biba_dominate_effective(subj, obj)) 3349 return (EACCES); 3350 3351 return (0); 3352 } 3353 3354 static int 3355 biba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 3356 struct label *vplabel, int attrnamespace, const char *name) 3357 { 3358 struct mac_biba *subj, *obj; 3359 3360 if (!biba_enabled) 3361 return (0); 3362 3363 subj = SLOT(cred->cr_label); 3364 obj = SLOT(vplabel); 3365 3366 if (!biba_dominate_effective(subj, obj)) 3367 return (EACCES); 3368 3369 /* XXX: protect the MAC EA in a special way? */ 3370 3371 return (0); 3372 } 3373 3374 static int 3375 biba_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 3376 struct label *vplabel, u_long flags) 3377 { 3378 struct mac_biba *subj, *obj; 3379 3380 if (!biba_enabled) 3381 return (0); 3382 3383 subj = SLOT(cred->cr_label); 3384 obj = SLOT(vplabel); 3385 3386 if (!biba_dominate_effective(subj, obj)) 3387 return (EACCES); 3388 3389 return (0); 3390 } 3391 3392 static int 3393 biba_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 3394 struct label *vplabel, mode_t mode) 3395 { 3396 struct mac_biba *subj, *obj; 3397 3398 if (!biba_enabled) 3399 return (0); 3400 3401 subj = SLOT(cred->cr_label); 3402 obj = SLOT(vplabel); 3403 3404 if (!biba_dominate_effective(subj, obj)) 3405 return (EACCES); 3406 3407 return (0); 3408 } 3409 3410 static int 3411 biba_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 3412 struct label *vplabel, uid_t uid, gid_t gid) 3413 { 3414 struct mac_biba *subj, *obj; 3415 3416 if (!biba_enabled) 3417 return (0); 3418 3419 subj = SLOT(cred->cr_label); 3420 obj = SLOT(vplabel); 3421 3422 if (!biba_dominate_effective(subj, obj)) 3423 return (EACCES); 3424 3425 return (0); 3426 } 3427 3428 static int 3429 biba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 3430 struct label *vplabel, struct timespec atime, struct timespec mtime) 3431 { 3432 struct mac_biba *subj, *obj; 3433 3434 if (!biba_enabled) 3435 return (0); 3436 3437 subj = SLOT(cred->cr_label); 3438 obj = SLOT(vplabel); 3439 3440 if (!biba_dominate_effective(subj, obj)) 3441 return (EACCES); 3442 3443 return (0); 3444 } 3445 3446 static int 3447 biba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 3448 struct vnode *vp, struct label *vplabel) 3449 { 3450 struct mac_biba *subj, *obj; 3451 3452 if (!biba_enabled) 3453 return (0); 3454 3455 subj = SLOT(active_cred->cr_label); 3456 obj = SLOT(vplabel); 3457 3458 if (!biba_dominate_effective(obj, subj)) 3459 return (EACCES); 3460 3461 return (0); 3462 } 3463 3464 static int 3465 biba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 3466 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3467 struct componentname *cnp) 3468 { 3469 struct mac_biba *subj, *obj; 3470 3471 if (!biba_enabled) 3472 return (0); 3473 3474 subj = SLOT(cred->cr_label); 3475 obj = SLOT(dvplabel); 3476 3477 if (!biba_dominate_effective(subj, obj)) 3478 return (EACCES); 3479 3480 obj = SLOT(vplabel); 3481 3482 if (!biba_dominate_effective(subj, obj)) 3483 return (EACCES); 3484 3485 return (0); 3486 } 3487 3488 static int 3489 biba_vnode_check_write(struct ucred *active_cred, 3490 struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 3491 { 3492 struct mac_biba *subj, *obj; 3493 3494 if (!biba_enabled || !revocation_enabled) 3495 return (0); 3496 3497 subj = SLOT(active_cred->cr_label); 3498 obj = SLOT(vplabel); 3499 3500 if (!biba_dominate_effective(subj, obj)) 3501 return (EACCES); 3502 3503 return (0); 3504 } 3505 3506 static int 3507 biba_vnode_create_extattr(struct ucred *cred, struct mount *mp, 3508 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 3509 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 3510 { 3511 struct mac_biba *source, *dest, mb_temp; 3512 size_t buflen; 3513 int error; 3514 3515 buflen = sizeof(mb_temp); 3516 bzero(&mb_temp, buflen); 3517 3518 source = SLOT(cred->cr_label); 3519 dest = SLOT(vplabel); 3520 biba_copy_effective(source, &mb_temp); 3521 3522 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 3523 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread); 3524 if (error == 0) 3525 biba_copy_effective(source, dest); 3526 return (error); 3527 } 3528 3529 static void 3530 biba_vnode_relabel(struct ucred *cred, struct vnode *vp, 3531 struct label *vplabel, struct label *newlabel) 3532 { 3533 struct mac_biba *source, *dest; 3534 3535 source = SLOT(newlabel); 3536 dest = SLOT(vplabel); 3537 3538 biba_copy(source, dest); 3539 } 3540 3541 static int 3542 biba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 3543 struct label *vplabel, struct label *intlabel) 3544 { 3545 struct mac_biba *source, mb_temp; 3546 size_t buflen; 3547 int error; 3548 3549 buflen = sizeof(mb_temp); 3550 bzero(&mb_temp, buflen); 3551 3552 source = SLOT(intlabel); 3553 if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0) 3554 return (0); 3555 3556 biba_copy_effective(source, &mb_temp); 3557 3558 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 3559 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread); 3560 return (error); 3561 } 3562 3563 static struct mac_policy_ops mac_biba_ops = 3564 { 3565 .mpo_init = biba_init, 3566 3567 .mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive, 3568 .mpo_bpfdesc_create = biba_bpfdesc_create, 3569 .mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf, 3570 .mpo_bpfdesc_destroy_label = biba_destroy_label, 3571 .mpo_bpfdesc_init_label = biba_init_label, 3572 3573 .mpo_cred_associate_nfsd = biba_cred_associate_nfsd, 3574 .mpo_cred_check_relabel = biba_cred_check_relabel, 3575 .mpo_cred_check_visible = biba_cred_check_visible, 3576 .mpo_cred_copy_label = biba_copy_label, 3577 .mpo_cred_create_init = biba_cred_create_init, 3578 .mpo_cred_create_swapper = biba_cred_create_swapper, 3579 .mpo_cred_destroy_label = biba_destroy_label, 3580 .mpo_cred_externalize_label = biba_externalize_label, 3581 .mpo_cred_init_label = biba_init_label, 3582 .mpo_cred_internalize_label = biba_internalize_label, 3583 .mpo_cred_relabel = biba_cred_relabel, 3584 3585 .mpo_devfs_create_device = biba_devfs_create_device, 3586 .mpo_devfs_create_directory = biba_devfs_create_directory, 3587 .mpo_devfs_create_symlink = biba_devfs_create_symlink, 3588 .mpo_devfs_destroy_label = biba_destroy_label, 3589 .mpo_devfs_init_label = biba_init_label, 3590 .mpo_devfs_update = biba_devfs_update, 3591 .mpo_devfs_vnode_associate = biba_devfs_vnode_associate, 3592 3593 .mpo_ifnet_check_relabel = biba_ifnet_check_relabel, 3594 .mpo_ifnet_check_transmit = biba_ifnet_check_transmit, 3595 .mpo_ifnet_copy_label = biba_copy_label, 3596 .mpo_ifnet_create = biba_ifnet_create, 3597 .mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf, 3598 .mpo_ifnet_destroy_label = biba_destroy_label, 3599 .mpo_ifnet_externalize_label = biba_externalize_label, 3600 .mpo_ifnet_init_label = biba_init_label, 3601 .mpo_ifnet_internalize_label = biba_internalize_label, 3602 .mpo_ifnet_relabel = biba_ifnet_relabel, 3603 3604 .mpo_inpcb_check_deliver = biba_inpcb_check_deliver, 3605 .mpo_inpcb_check_visible = biba_inpcb_check_visible, 3606 .mpo_inpcb_create = biba_inpcb_create, 3607 .mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf, 3608 .mpo_inpcb_destroy_label = biba_destroy_label, 3609 .mpo_inpcb_init_label = biba_init_label_waitcheck, 3610 .mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel, 3611 3612 .mpo_ip6q_create = biba_ip6q_create, 3613 .mpo_ip6q_destroy_label = biba_destroy_label, 3614 .mpo_ip6q_init_label = biba_init_label_waitcheck, 3615 .mpo_ip6q_match = biba_ip6q_match, 3616 .mpo_ip6q_reassemble = biba_ip6q_reassemble, 3617 .mpo_ip6q_update = biba_ip6q_update, 3618 3619 .mpo_ipq_create = biba_ipq_create, 3620 .mpo_ipq_destroy_label = biba_destroy_label, 3621 .mpo_ipq_init_label = biba_init_label_waitcheck, 3622 .mpo_ipq_match = biba_ipq_match, 3623 .mpo_ipq_reassemble = biba_ipq_reassemble, 3624 .mpo_ipq_update = biba_ipq_update, 3625 3626 .mpo_kld_check_load = biba_kld_check_load, 3627 3628 .mpo_mbuf_copy_label = biba_copy_label, 3629 .mpo_mbuf_destroy_label = biba_destroy_label, 3630 .mpo_mbuf_init_label = biba_init_label_waitcheck, 3631 3632 .mpo_mount_check_stat = biba_mount_check_stat, 3633 .mpo_mount_create = biba_mount_create, 3634 .mpo_mount_destroy_label = biba_destroy_label, 3635 .mpo_mount_init_label = biba_init_label, 3636 3637 .mpo_netinet_arp_send = biba_netinet_arp_send, 3638 .mpo_netinet_firewall_reply = biba_netinet_firewall_reply, 3639 .mpo_netinet_firewall_send = biba_netinet_firewall_send, 3640 .mpo_netinet_fragment = biba_netinet_fragment, 3641 .mpo_netinet_icmp_reply = biba_netinet_icmp_reply, 3642 .mpo_netinet_igmp_send = biba_netinet_igmp_send, 3643 3644 .mpo_netinet6_nd6_send = biba_netinet6_nd6_send, 3645 3646 .mpo_pipe_check_ioctl = biba_pipe_check_ioctl, 3647 .mpo_pipe_check_poll = biba_pipe_check_poll, 3648 .mpo_pipe_check_read = biba_pipe_check_read, 3649 .mpo_pipe_check_relabel = biba_pipe_check_relabel, 3650 .mpo_pipe_check_stat = biba_pipe_check_stat, 3651 .mpo_pipe_check_write = biba_pipe_check_write, 3652 .mpo_pipe_copy_label = biba_copy_label, 3653 .mpo_pipe_create = biba_pipe_create, 3654 .mpo_pipe_destroy_label = biba_destroy_label, 3655 .mpo_pipe_externalize_label = biba_externalize_label, 3656 .mpo_pipe_init_label = biba_init_label, 3657 .mpo_pipe_internalize_label = biba_internalize_label, 3658 .mpo_pipe_relabel = biba_pipe_relabel, 3659 3660 .mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly, 3661 .mpo_posixsem_check_open = biba_posixsem_check_openunlink, 3662 .mpo_posixsem_check_post = biba_posixsem_check_write, 3663 .mpo_posixsem_check_setmode = biba_posixsem_check_setmode, 3664 .mpo_posixsem_check_setowner = biba_posixsem_check_setowner, 3665 .mpo_posixsem_check_stat = biba_posixsem_check_rdonly, 3666 .mpo_posixsem_check_unlink = biba_posixsem_check_openunlink, 3667 .mpo_posixsem_check_wait = biba_posixsem_check_write, 3668 .mpo_posixsem_create = biba_posixsem_create, 3669 .mpo_posixsem_destroy_label = biba_destroy_label, 3670 .mpo_posixsem_init_label = biba_init_label, 3671 3672 .mpo_posixshm_check_mmap = biba_posixshm_check_mmap, 3673 .mpo_posixshm_check_open = biba_posixshm_check_open, 3674 .mpo_posixshm_check_read = biba_posixshm_check_read, 3675 .mpo_posixshm_check_setmode = biba_posixshm_check_setmode, 3676 .mpo_posixshm_check_setowner = biba_posixshm_check_setowner, 3677 .mpo_posixshm_check_stat = biba_posixshm_check_stat, 3678 .mpo_posixshm_check_truncate = biba_posixshm_check_truncate, 3679 .mpo_posixshm_check_unlink = biba_posixshm_check_unlink, 3680 .mpo_posixshm_check_write = biba_posixshm_check_write, 3681 .mpo_posixshm_create = biba_posixshm_create, 3682 .mpo_posixshm_destroy_label = biba_destroy_label, 3683 .mpo_posixshm_init_label = biba_init_label, 3684 3685 .mpo_priv_check = biba_priv_check, 3686 3687 .mpo_proc_check_debug = biba_proc_check_debug, 3688 .mpo_proc_check_sched = biba_proc_check_sched, 3689 .mpo_proc_check_signal = biba_proc_check_signal, 3690 3691 .mpo_socket_check_deliver = biba_socket_check_deliver, 3692 .mpo_socket_check_relabel = biba_socket_check_relabel, 3693 .mpo_socket_check_visible = biba_socket_check_visible, 3694 .mpo_socket_copy_label = biba_copy_label, 3695 .mpo_socket_create = biba_socket_create, 3696 .mpo_socket_create_mbuf = biba_socket_create_mbuf, 3697 .mpo_socket_destroy_label = biba_destroy_label, 3698 .mpo_socket_externalize_label = biba_externalize_label, 3699 .mpo_socket_init_label = biba_init_label_waitcheck, 3700 .mpo_socket_internalize_label = biba_internalize_label, 3701 .mpo_socket_newconn = biba_socket_newconn, 3702 .mpo_socket_relabel = biba_socket_relabel, 3703 3704 .mpo_socketpeer_destroy_label = biba_destroy_label, 3705 .mpo_socketpeer_externalize_label = biba_externalize_label, 3706 .mpo_socketpeer_init_label = biba_init_label_waitcheck, 3707 .mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf, 3708 .mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket, 3709 3710 .mpo_syncache_create = biba_syncache_create, 3711 .mpo_syncache_create_mbuf = biba_syncache_create_mbuf, 3712 .mpo_syncache_destroy_label = biba_destroy_label, 3713 .mpo_syncache_init_label = biba_init_label_waitcheck, 3714 3715 .mpo_system_check_acct = biba_system_check_acct, 3716 .mpo_system_check_auditctl = biba_system_check_auditctl, 3717 .mpo_system_check_auditon = biba_system_check_auditon, 3718 .mpo_system_check_swapoff = biba_system_check_swapoff, 3719 .mpo_system_check_swapon = biba_system_check_swapon, 3720 .mpo_system_check_sysctl = biba_system_check_sysctl, 3721 3722 .mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup, 3723 .mpo_sysvmsg_create = biba_sysvmsg_create, 3724 .mpo_sysvmsg_destroy_label = biba_destroy_label, 3725 .mpo_sysvmsg_init_label = biba_init_label, 3726 3727 .mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv, 3728 .mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid, 3729 .mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget, 3730 .mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd, 3731 .mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv, 3732 .mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl, 3733 .mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup, 3734 .mpo_sysvmsq_create = biba_sysvmsq_create, 3735 .mpo_sysvmsq_destroy_label = biba_destroy_label, 3736 .mpo_sysvmsq_init_label = biba_init_label, 3737 3738 .mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl, 3739 .mpo_sysvsem_check_semget = biba_sysvsem_check_semget, 3740 .mpo_sysvsem_check_semop = biba_sysvsem_check_semop, 3741 .mpo_sysvsem_cleanup = biba_sysvsem_cleanup, 3742 .mpo_sysvsem_create = biba_sysvsem_create, 3743 .mpo_sysvsem_destroy_label = biba_destroy_label, 3744 .mpo_sysvsem_init_label = biba_init_label, 3745 3746 .mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat, 3747 .mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl, 3748 .mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget, 3749 .mpo_sysvshm_cleanup = biba_sysvshm_cleanup, 3750 .mpo_sysvshm_create = biba_sysvshm_create, 3751 .mpo_sysvshm_destroy_label = biba_destroy_label, 3752 .mpo_sysvshm_init_label = biba_init_label, 3753 3754 .mpo_vnode_associate_extattr = biba_vnode_associate_extattr, 3755 .mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel, 3756 .mpo_vnode_check_access = biba_vnode_check_open, 3757 .mpo_vnode_check_chdir = biba_vnode_check_chdir, 3758 .mpo_vnode_check_chroot = biba_vnode_check_chroot, 3759 .mpo_vnode_check_create = biba_vnode_check_create, 3760 .mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl, 3761 .mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr, 3762 .mpo_vnode_check_exec = biba_vnode_check_exec, 3763 .mpo_vnode_check_getacl = biba_vnode_check_getacl, 3764 .mpo_vnode_check_getextattr = biba_vnode_check_getextattr, 3765 .mpo_vnode_check_link = biba_vnode_check_link, 3766 .mpo_vnode_check_listextattr = biba_vnode_check_listextattr, 3767 .mpo_vnode_check_lookup = biba_vnode_check_lookup, 3768 .mpo_vnode_check_mmap = biba_vnode_check_mmap, 3769 .mpo_vnode_check_open = biba_vnode_check_open, 3770 .mpo_vnode_check_poll = biba_vnode_check_poll, 3771 .mpo_vnode_check_read = biba_vnode_check_read, 3772 .mpo_vnode_check_readdir = biba_vnode_check_readdir, 3773 .mpo_vnode_check_readlink = biba_vnode_check_readlink, 3774 .mpo_vnode_check_relabel = biba_vnode_check_relabel, 3775 .mpo_vnode_check_rename_from = biba_vnode_check_rename_from, 3776 .mpo_vnode_check_rename_to = biba_vnode_check_rename_to, 3777 .mpo_vnode_check_revoke = biba_vnode_check_revoke, 3778 .mpo_vnode_check_setacl = biba_vnode_check_setacl, 3779 .mpo_vnode_check_setextattr = biba_vnode_check_setextattr, 3780 .mpo_vnode_check_setflags = biba_vnode_check_setflags, 3781 .mpo_vnode_check_setmode = biba_vnode_check_setmode, 3782 .mpo_vnode_check_setowner = biba_vnode_check_setowner, 3783 .mpo_vnode_check_setutimes = biba_vnode_check_setutimes, 3784 .mpo_vnode_check_stat = biba_vnode_check_stat, 3785 .mpo_vnode_check_unlink = biba_vnode_check_unlink, 3786 .mpo_vnode_check_write = biba_vnode_check_write, 3787 .mpo_vnode_create_extattr = biba_vnode_create_extattr, 3788 .mpo_vnode_copy_label = biba_copy_label, 3789 .mpo_vnode_destroy_label = biba_destroy_label, 3790 .mpo_vnode_externalize_label = biba_externalize_label, 3791 .mpo_vnode_init_label = biba_init_label, 3792 .mpo_vnode_internalize_label = biba_internalize_label, 3793 .mpo_vnode_relabel = biba_vnode_relabel, 3794 .mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr, 3795 }; 3796 3797 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 3798 MPC_LOADTIME_FLAG_NOTLATE, &biba_slot); 3799