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