1 /*- 2 * Copyright (c) 1999-2002 Robert N. M. Watson 3 * Copyright (c) 2001-2005 McAfee, Inc. 4 * All rights reserved. 5 * 6 * This software was developed by Robert Watson for the TrustedBSD Project. 7 * 8 * This software was developed for the FreeBSD Project in part by McAfee 9 * Research, the Security Research Division of McAfee, Inc. under 10 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 11 * CHATS research program. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $FreeBSD$ 35 */ 36 37 /* 38 * Developed by the TrustedBSD Project. 39 * Biba fixed label mandatory integrity policy. 40 */ 41 42 #include <sys/types.h> 43 #include <sys/param.h> 44 #include <sys/acl.h> 45 #include <sys/conf.h> 46 #include <sys/extattr.h> 47 #include <sys/kernel.h> 48 #include <sys/mac.h> 49 #include <sys/malloc.h> 50 #include <sys/mman.h> 51 #include <sys/mount.h> 52 #include <sys/proc.h> 53 #include <sys/sbuf.h> 54 #include <sys/systm.h> 55 #include <sys/sysproto.h> 56 #include <sys/sysent.h> 57 #include <sys/systm.h> 58 #include <sys/vnode.h> 59 #include <sys/file.h> 60 #include <sys/socket.h> 61 #include <sys/socketvar.h> 62 #include <sys/pipe.h> 63 #include <sys/sx.h> 64 #include <sys/sysctl.h> 65 #include <sys/msg.h> 66 #include <sys/sem.h> 67 #include <sys/shm.h> 68 69 #include <posix4/ksem.h> 70 71 #include <fs/devfs/devfs.h> 72 73 #include <net/bpfdesc.h> 74 #include <net/if.h> 75 #include <net/if_types.h> 76 #include <net/if_var.h> 77 78 #include <netinet/in.h> 79 #include <netinet/in_pcb.h> 80 #include <netinet/ip_var.h> 81 82 #include <vm/uma.h> 83 #include <vm/vm.h> 84 85 #include <sys/mac_policy.h> 86 87 #include <security/mac_biba/mac_biba.h> 88 89 SYSCTL_DECL(_security_mac); 90 91 SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 92 "TrustedBSD mac_biba policy controls"); 93 94 static int mac_biba_label_size = sizeof(struct mac_biba); 95 SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 96 &mac_biba_label_size, 0, "Size of struct mac_biba"); 97 98 static int mac_biba_enabled = 1; 99 SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 100 &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 101 TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 102 103 static int destroyed_not_inited; 104 SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 105 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 106 107 static int trust_all_interfaces = 0; 108 SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 109 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 110 TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 111 112 static char trusted_interfaces[128]; 113 SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 114 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 115 TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 116 sizeof(trusted_interfaces)); 117 118 static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 119 SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 120 &max_compartments, 0, "Maximum supported compartments"); 121 122 static int ptys_equal = 0; 123 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 124 &ptys_equal, 0, "Label pty devices as biba/equal on create"); 125 TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 126 127 static int interfaces_equal; 128 SYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW, 129 &interfaces_equal, 0, "Label network interfaces as biba/equal on create"); 130 TUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal); 131 132 static int revocation_enabled = 0; 133 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 134 &revocation_enabled, 0, "Revoke access to objects on relabel"); 135 TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 136 137 static int mac_biba_slot; 138 #define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 139 #define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_biba_slot).l_ptr = (val)) 140 141 static uma_zone_t zone_biba; 142 143 static __inline int 144 biba_bit_set_empty(u_char *set) { 145 int i; 146 147 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 148 if (set[i] != 0) 149 return (0); 150 return (1); 151 } 152 153 static struct mac_biba * 154 biba_alloc(int flag) 155 { 156 157 return (uma_zalloc(zone_biba, flag | M_ZERO)); 158 } 159 160 static void 161 biba_free(struct mac_biba *mac_biba) 162 { 163 164 if (mac_biba != NULL) 165 uma_zfree(zone_biba, mac_biba); 166 else 167 atomic_add_int(&destroyed_not_inited, 1); 168 } 169 170 static int 171 biba_atmostflags(struct mac_biba *mac_biba, int flags) 172 { 173 174 if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 175 return (EINVAL); 176 return (0); 177 } 178 179 static int 180 mac_biba_dominate_element(struct mac_biba_element *a, 181 struct mac_biba_element *b) 182 { 183 int bit; 184 185 switch (a->mbe_type) { 186 case MAC_BIBA_TYPE_EQUAL: 187 case MAC_BIBA_TYPE_HIGH: 188 return (1); 189 190 case MAC_BIBA_TYPE_LOW: 191 switch (b->mbe_type) { 192 case MAC_BIBA_TYPE_GRADE: 193 case MAC_BIBA_TYPE_HIGH: 194 return (0); 195 196 case MAC_BIBA_TYPE_EQUAL: 197 case MAC_BIBA_TYPE_LOW: 198 return (1); 199 200 default: 201 panic("mac_biba_dominate_element: b->mbe_type invalid"); 202 } 203 204 case MAC_BIBA_TYPE_GRADE: 205 switch (b->mbe_type) { 206 case MAC_BIBA_TYPE_EQUAL: 207 case MAC_BIBA_TYPE_LOW: 208 return (1); 209 210 case MAC_BIBA_TYPE_HIGH: 211 return (0); 212 213 case MAC_BIBA_TYPE_GRADE: 214 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 215 if (!MAC_BIBA_BIT_TEST(bit, 216 a->mbe_compartments) && 217 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 218 return (0); 219 return (a->mbe_grade >= b->mbe_grade); 220 221 default: 222 panic("mac_biba_dominate_element: b->mbe_type invalid"); 223 } 224 225 default: 226 panic("mac_biba_dominate_element: a->mbe_type invalid"); 227 } 228 229 return (0); 230 } 231 232 static int 233 mac_biba_subject_dominate_high(struct mac_biba *mac_biba) 234 { 235 struct mac_biba_element *element; 236 237 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 238 ("mac_biba_effective_in_range: mac_biba not effective")); 239 element = &mac_biba->mb_effective; 240 241 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 242 element->mbe_type == MAC_BIBA_TYPE_HIGH); 243 } 244 245 static int 246 mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 247 { 248 249 return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 250 &rangea->mb_rangehigh) && 251 mac_biba_dominate_element(&rangea->mb_rangelow, 252 &rangeb->mb_rangelow)); 253 } 254 255 static int 256 mac_biba_effective_in_range(struct mac_biba *effective, 257 struct mac_biba *range) 258 { 259 260 KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 261 ("mac_biba_effective_in_range: a not effective")); 262 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 263 ("mac_biba_effective_in_range: b not range")); 264 265 return (mac_biba_dominate_element(&range->mb_rangehigh, 266 &effective->mb_effective) && 267 mac_biba_dominate_element(&effective->mb_effective, 268 &range->mb_rangelow)); 269 270 return (1); 271 } 272 273 static int 274 mac_biba_dominate_effective(struct mac_biba *a, struct mac_biba *b) 275 { 276 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 277 ("mac_biba_dominate_effective: a not effective")); 278 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 279 ("mac_biba_dominate_effective: b not effective")); 280 281 return (mac_biba_dominate_element(&a->mb_effective, &b->mb_effective)); 282 } 283 284 static int 285 mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 286 { 287 288 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 289 b->mbe_type == MAC_BIBA_TYPE_EQUAL) 290 return (1); 291 292 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 293 } 294 295 static int 296 mac_biba_equal_effective(struct mac_biba *a, struct mac_biba *b) 297 { 298 299 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 300 ("mac_biba_equal_effective: a not effective")); 301 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 302 ("mac_biba_equal_effective: b not effective")); 303 304 return (mac_biba_equal_element(&a->mb_effective, &b->mb_effective)); 305 } 306 307 static int 308 mac_biba_contains_equal(struct mac_biba *mac_biba) 309 { 310 311 if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) 312 if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 313 return (1); 314 315 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 316 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 317 return (1); 318 if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 319 return (1); 320 } 321 322 return (0); 323 } 324 325 static int 326 mac_biba_subject_privileged(struct mac_biba *mac_biba) 327 { 328 329 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 330 MAC_BIBA_FLAGS_BOTH, 331 ("mac_biba_subject_privileged: subject doesn't have both labels")); 332 333 /* If the effective is EQUAL, it's ok. */ 334 if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 335 return (0); 336 337 /* If either range endpoint is EQUAL, it's ok. */ 338 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 339 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 340 return (0); 341 342 /* If the range is low-high, it's ok. */ 343 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 344 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 345 return (0); 346 347 /* It's not ok. */ 348 return (EPERM); 349 } 350 351 static int 352 mac_biba_high_effective(struct mac_biba *mac_biba) 353 { 354 355 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 356 ("mac_biba_equal_effective: mac_biba not effective")); 357 358 return (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH); 359 } 360 361 static int 362 mac_biba_valid(struct mac_biba *mac_biba) 363 { 364 365 if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 366 switch (mac_biba->mb_effective.mbe_type) { 367 case MAC_BIBA_TYPE_GRADE: 368 break; 369 370 case MAC_BIBA_TYPE_EQUAL: 371 case MAC_BIBA_TYPE_HIGH: 372 case MAC_BIBA_TYPE_LOW: 373 if (mac_biba->mb_effective.mbe_grade != 0 || 374 !MAC_BIBA_BIT_SET_EMPTY( 375 mac_biba->mb_effective.mbe_compartments)) 376 return (EINVAL); 377 break; 378 379 default: 380 return (EINVAL); 381 } 382 } else { 383 if (mac_biba->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF) 384 return (EINVAL); 385 } 386 387 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 388 switch (mac_biba->mb_rangelow.mbe_type) { 389 case MAC_BIBA_TYPE_GRADE: 390 break; 391 392 case MAC_BIBA_TYPE_EQUAL: 393 case MAC_BIBA_TYPE_HIGH: 394 case MAC_BIBA_TYPE_LOW: 395 if (mac_biba->mb_rangelow.mbe_grade != 0 || 396 !MAC_BIBA_BIT_SET_EMPTY( 397 mac_biba->mb_rangelow.mbe_compartments)) 398 return (EINVAL); 399 break; 400 401 default: 402 return (EINVAL); 403 } 404 405 switch (mac_biba->mb_rangehigh.mbe_type) { 406 case MAC_BIBA_TYPE_GRADE: 407 break; 408 409 case MAC_BIBA_TYPE_EQUAL: 410 case MAC_BIBA_TYPE_HIGH: 411 case MAC_BIBA_TYPE_LOW: 412 if (mac_biba->mb_rangehigh.mbe_grade != 0 || 413 !MAC_BIBA_BIT_SET_EMPTY( 414 mac_biba->mb_rangehigh.mbe_compartments)) 415 return (EINVAL); 416 break; 417 418 default: 419 return (EINVAL); 420 } 421 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 422 &mac_biba->mb_rangelow)) 423 return (EINVAL); 424 } else { 425 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 426 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 427 return (EINVAL); 428 } 429 430 return (0); 431 } 432 433 static void 434 mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 435 u_short gradelow, u_char *compartmentslow, u_short typehigh, 436 u_short gradehigh, u_char *compartmentshigh) 437 { 438 439 mac_biba->mb_rangelow.mbe_type = typelow; 440 mac_biba->mb_rangelow.mbe_grade = gradelow; 441 if (compartmentslow != NULL) 442 memcpy(mac_biba->mb_rangelow.mbe_compartments, 443 compartmentslow, 444 sizeof(mac_biba->mb_rangelow.mbe_compartments)); 445 mac_biba->mb_rangehigh.mbe_type = typehigh; 446 mac_biba->mb_rangehigh.mbe_grade = gradehigh; 447 if (compartmentshigh != NULL) 448 memcpy(mac_biba->mb_rangehigh.mbe_compartments, 449 compartmentshigh, 450 sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 451 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 452 } 453 454 static void 455 mac_biba_set_effective(struct mac_biba *mac_biba, u_short type, u_short grade, 456 u_char *compartments) 457 { 458 459 mac_biba->mb_effective.mbe_type = type; 460 mac_biba->mb_effective.mbe_grade = grade; 461 if (compartments != NULL) 462 memcpy(mac_biba->mb_effective.mbe_compartments, compartments, 463 sizeof(mac_biba->mb_effective.mbe_compartments)); 464 mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 465 } 466 467 static void 468 mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 469 { 470 471 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 472 ("mac_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 mac_biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto) 481 { 482 483 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 484 ("mac_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 mac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 492 { 493 494 if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) 495 mac_biba_copy_effective(source, dest); 496 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 497 mac_biba_copy_range(source, dest); 498 } 499 500 /* 501 * Policy module operations. 502 */ 503 static void 504 mac_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 mac_biba_init_label(struct label *label) 516 { 517 518 SLOT_SET(label, biba_alloc(M_WAITOK)); 519 } 520 521 static int 522 mac_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 mac_biba_destroy_label(struct label *label) 534 { 535 536 biba_free(SLOT(label)); 537 SLOT_SET(label, NULL); 538 } 539 540 /* 541 * mac_biba_element_to_string() accepts an sbuf and Biba element. It 542 * converts the Biba element to a string and stores the result in the 543 * sbuf; if there isn't space in the sbuf, -1 is returned. 544 */ 545 static int 546 mac_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("mac_biba_element_to_string: invalid type (%d)", 583 element->mbe_type); 584 } 585 } 586 587 /* 588 * mac_biba_to_string() converts a Biba label to a string, and places 589 * the results in the passed sbuf. It returns 0 on success, or EINVAL 590 * if there isn't room in the sbuf. Note: the sbuf will be modified 591 * even in a failure case, so the caller may need to revert the sbuf 592 * by restoring the offset if that's undesired. 593 */ 594 static int 595 mac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba) 596 { 597 598 if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 599 if (mac_biba_element_to_string(sb, &mac_biba->mb_effective) 600 == -1) 601 return (EINVAL); 602 } 603 604 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 605 if (sbuf_putc(sb, '(') == -1) 606 return (EINVAL); 607 608 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow) 609 == -1) 610 return (EINVAL); 611 612 if (sbuf_putc(sb, '-') == -1) 613 return (EINVAL); 614 615 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh) 616 == -1) 617 return (EINVAL); 618 619 if (sbuf_putc(sb, ')') == -1) 620 return (EINVAL); 621 } 622 623 return (0); 624 } 625 626 static int 627 mac_biba_externalize_label(struct label *label, char *element_name, 628 struct sbuf *sb, int *claimed) 629 { 630 struct mac_biba *mac_biba; 631 632 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 633 return (0); 634 635 (*claimed)++; 636 637 mac_biba = SLOT(label); 638 return (mac_biba_to_string(sb, mac_biba)); 639 } 640 641 static int 642 mac_biba_parse_element(struct mac_biba_element *element, char *string) 643 { 644 char *compartment, *end, *grade; 645 int value; 646 647 if (strcmp(string, "high") == 0 || 648 strcmp(string, "hi") == 0) { 649 element->mbe_type = MAC_BIBA_TYPE_HIGH; 650 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 651 } else if (strcmp(string, "low") == 0 || 652 strcmp(string, "lo") == 0) { 653 element->mbe_type = MAC_BIBA_TYPE_LOW; 654 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 655 } else if (strcmp(string, "equal") == 0 || 656 strcmp(string, "eq") == 0) { 657 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 658 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 659 } else { 660 element->mbe_type = MAC_BIBA_TYPE_GRADE; 661 662 /* 663 * Numeric grade piece of the element. 664 */ 665 grade = strsep(&string, ":"); 666 value = strtol(grade, &end, 10); 667 if (end == grade || *end != '\0') 668 return (EINVAL); 669 if (value < 0 || value > 65535) 670 return (EINVAL); 671 element->mbe_grade = value; 672 673 /* 674 * Optional compartment piece of the element. If none 675 * are included, we assume that the label has no 676 * compartments. 677 */ 678 if (string == NULL) 679 return (0); 680 if (*string == '\0') 681 return (0); 682 683 while ((compartment = strsep(&string, "+")) != NULL) { 684 value = strtol(compartment, &end, 10); 685 if (compartment == end || *end != '\0') 686 return (EINVAL); 687 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 688 return (EINVAL); 689 MAC_BIBA_BIT_SET(value, element->mbe_compartments); 690 } 691 } 692 693 return (0); 694 } 695 696 /* 697 * Note: destructively consumes the string, make a local copy before 698 * calling if that's a problem. 699 */ 700 static int 701 mac_biba_parse(struct mac_biba *mac_biba, char *string) 702 { 703 char *rangehigh, *rangelow, *effective; 704 int error; 705 706 effective = strsep(&string, "("); 707 if (*effective == '\0') 708 effective = NULL; 709 710 if (string != NULL) { 711 rangelow = strsep(&string, "-"); 712 if (string == NULL) 713 return (EINVAL); 714 rangehigh = strsep(&string, ")"); 715 if (string == NULL) 716 return (EINVAL); 717 if (*string != '\0') 718 return (EINVAL); 719 } else { 720 rangelow = NULL; 721 rangehigh = NULL; 722 } 723 724 KASSERT((rangelow != NULL && rangehigh != NULL) || 725 (rangelow == NULL && rangehigh == NULL), 726 ("mac_biba_parse: range mismatch")); 727 728 bzero(mac_biba, sizeof(*mac_biba)); 729 if (effective != NULL) { 730 error = mac_biba_parse_element(&mac_biba->mb_effective, effective); 731 if (error) 732 return (error); 733 mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 734 } 735 736 if (rangelow != NULL) { 737 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 738 rangelow); 739 if (error) 740 return (error); 741 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 742 rangehigh); 743 if (error) 744 return (error); 745 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 746 } 747 748 error = mac_biba_valid(mac_biba); 749 if (error) 750 return (error); 751 752 return (0); 753 } 754 755 static int 756 mac_biba_internalize_label(struct label *label, char *element_name, 757 char *element_data, int *claimed) 758 { 759 struct mac_biba *mac_biba, mac_biba_temp; 760 int error; 761 762 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 763 return (0); 764 765 (*claimed)++; 766 767 error = mac_biba_parse(&mac_biba_temp, element_data); 768 if (error) 769 return (error); 770 771 mac_biba = SLOT(label); 772 *mac_biba = mac_biba_temp; 773 774 return (0); 775 } 776 777 static void 778 mac_biba_copy_label(struct label *src, struct label *dest) 779 { 780 781 *SLOT(dest) = *SLOT(src); 782 } 783 784 /* 785 * Labeling event operations: file system objects, and things that look 786 * a lot like file system objects. 787 */ 788 static void 789 mac_biba_create_devfs_device(struct ucred *cred, struct mount *mp, 790 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label) 791 { 792 struct mac_biba *mac_biba; 793 int biba_type; 794 795 mac_biba = SLOT(label); 796 if (strcmp(dev->si_name, "null") == 0 || 797 strcmp(dev->si_name, "zero") == 0 || 798 strcmp(dev->si_name, "random") == 0 || 799 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 800 biba_type = MAC_BIBA_TYPE_EQUAL; 801 else if (ptys_equal && 802 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 803 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 804 biba_type = MAC_BIBA_TYPE_EQUAL; 805 else 806 biba_type = MAC_BIBA_TYPE_HIGH; 807 mac_biba_set_effective(mac_biba, biba_type, 0, NULL); 808 } 809 810 static void 811 mac_biba_create_devfs_directory(struct mount *mp, char *dirname, 812 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 813 { 814 struct mac_biba *mac_biba; 815 816 mac_biba = SLOT(label); 817 mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 818 } 819 820 static void 821 mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp, 822 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 823 struct label *delabel) 824 { 825 struct mac_biba *source, *dest; 826 827 source = SLOT(cred->cr_label); 828 dest = SLOT(delabel); 829 830 mac_biba_copy_effective(source, dest); 831 } 832 833 static void 834 mac_biba_create_mount(struct ucred *cred, struct mount *mp, 835 struct label *mntlabel, struct label *fslabel) 836 { 837 struct mac_biba *source, *dest; 838 839 source = SLOT(cred->cr_label); 840 dest = SLOT(mntlabel); 841 mac_biba_copy_effective(source, dest); 842 dest = SLOT(fslabel); 843 mac_biba_copy_effective(source, dest); 844 } 845 846 static void 847 mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 848 struct label *vnodelabel, struct label *label) 849 { 850 struct mac_biba *source, *dest; 851 852 source = SLOT(label); 853 dest = SLOT(vnodelabel); 854 855 mac_biba_copy(source, dest); 856 } 857 858 static void 859 mac_biba_update_devfsdirent(struct mount *mp, 860 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 861 struct vnode *vp, struct label *vnodelabel) 862 { 863 struct mac_biba *source, *dest; 864 865 source = SLOT(vnodelabel); 866 dest = SLOT(direntlabel); 867 868 mac_biba_copy(source, dest); 869 } 870 871 static void 872 mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 873 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 874 struct label *vlabel) 875 { 876 struct mac_biba *source, *dest; 877 878 source = SLOT(delabel); 879 dest = SLOT(vlabel); 880 881 mac_biba_copy_effective(source, dest); 882 } 883 884 static int 885 mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 886 struct vnode *vp, struct label *vlabel) 887 { 888 struct mac_biba temp, *source, *dest; 889 int buflen, error; 890 891 source = SLOT(fslabel); 892 dest = SLOT(vlabel); 893 894 buflen = sizeof(temp); 895 bzero(&temp, buflen); 896 897 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 898 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 899 if (error == ENOATTR || error == EOPNOTSUPP) { 900 /* Fall back to the fslabel. */ 901 mac_biba_copy_effective(source, dest); 902 return (0); 903 } else if (error) 904 return (error); 905 906 if (buflen != sizeof(temp)) { 907 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 908 buflen); 909 return (EPERM); 910 } 911 if (mac_biba_valid(&temp) != 0) { 912 printf("mac_biba_associate_vnode_extattr: invalid\n"); 913 return (EPERM); 914 } 915 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) { 916 printf("mac_biba_associate_vnode_extattr: not effective\n"); 917 return (EPERM); 918 } 919 920 mac_biba_copy_effective(&temp, dest); 921 return (0); 922 } 923 924 static void 925 mac_biba_associate_vnode_singlelabel(struct mount *mp, 926 struct label *fslabel, struct vnode *vp, struct label *vlabel) 927 { 928 struct mac_biba *source, *dest; 929 930 source = SLOT(fslabel); 931 dest = SLOT(vlabel); 932 933 mac_biba_copy_effective(source, dest); 934 } 935 936 static int 937 mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 938 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 939 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 940 { 941 struct mac_biba *source, *dest, temp; 942 size_t buflen; 943 int error; 944 945 buflen = sizeof(temp); 946 bzero(&temp, buflen); 947 948 source = SLOT(cred->cr_label); 949 dest = SLOT(vlabel); 950 mac_biba_copy_effective(source, &temp); 951 952 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 953 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 954 if (error == 0) 955 mac_biba_copy_effective(source, dest); 956 return (error); 957 } 958 959 static int 960 mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 961 struct label *vlabel, struct label *intlabel) 962 { 963 struct mac_biba *source, temp; 964 size_t buflen; 965 int error; 966 967 buflen = sizeof(temp); 968 bzero(&temp, buflen); 969 970 source = SLOT(intlabel); 971 if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0) 972 return (0); 973 974 mac_biba_copy_effective(source, &temp); 975 976 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 977 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 978 return (error); 979 } 980 981 /* 982 * Labeling event operations: IPC object. 983 */ 984 static void 985 mac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel, 986 struct inpcb *inp, struct label *inplabel) 987 { 988 struct mac_biba *source, *dest; 989 990 source = SLOT(solabel); 991 dest = SLOT(inplabel); 992 993 mac_biba_copy_effective(source, dest); 994 } 995 996 static void 997 mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 998 struct mbuf *m, struct label *mbuflabel) 999 { 1000 struct mac_biba *source, *dest; 1001 1002 source = SLOT(socketlabel); 1003 dest = SLOT(mbuflabel); 1004 1005 mac_biba_copy_effective(source, dest); 1006 } 1007 1008 static void 1009 mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1010 struct label *socketlabel) 1011 { 1012 struct mac_biba *source, *dest; 1013 1014 source = SLOT(cred->cr_label); 1015 dest = SLOT(socketlabel); 1016 1017 mac_biba_copy_effective(source, dest); 1018 } 1019 1020 static void 1021 mac_biba_create_pipe(struct ucred *cred, struct pipepair *pp, 1022 struct label *pipelabel) 1023 { 1024 struct mac_biba *source, *dest; 1025 1026 source = SLOT(cred->cr_label); 1027 dest = SLOT(pipelabel); 1028 1029 mac_biba_copy_effective(source, dest); 1030 } 1031 1032 static void 1033 mac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr, 1034 struct label *ks_label) 1035 { 1036 struct mac_biba *source, *dest; 1037 1038 source = SLOT(cred->cr_label); 1039 dest = SLOT(ks_label); 1040 1041 mac_biba_copy_effective(source, dest); 1042 } 1043 1044 static void 1045 mac_biba_create_socket_from_socket(struct socket *oldsocket, 1046 struct label *oldsocketlabel, struct socket *newsocket, 1047 struct label *newsocketlabel) 1048 { 1049 struct mac_biba *source, *dest; 1050 1051 source = SLOT(oldsocketlabel); 1052 dest = SLOT(newsocketlabel); 1053 1054 mac_biba_copy_effective(source, dest); 1055 } 1056 1057 static void 1058 mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1059 struct label *socketlabel, struct label *newlabel) 1060 { 1061 struct mac_biba *source, *dest; 1062 1063 source = SLOT(newlabel); 1064 dest = SLOT(socketlabel); 1065 1066 mac_biba_copy(source, dest); 1067 } 1068 1069 static void 1070 mac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1071 struct label *pipelabel, struct label *newlabel) 1072 { 1073 struct mac_biba *source, *dest; 1074 1075 source = SLOT(newlabel); 1076 dest = SLOT(pipelabel); 1077 1078 mac_biba_copy(source, dest); 1079 } 1080 1081 static void 1082 mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1083 struct socket *socket, struct label *socketpeerlabel) 1084 { 1085 struct mac_biba *source, *dest; 1086 1087 source = SLOT(mbuflabel); 1088 dest = SLOT(socketpeerlabel); 1089 1090 mac_biba_copy_effective(source, dest); 1091 } 1092 1093 /* 1094 * Labeling event operations: System V IPC objects. 1095 */ 1096 1097 static void 1098 mac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, 1099 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1100 { 1101 struct mac_biba *source, *dest; 1102 1103 /* Ignore the msgq label */ 1104 source = SLOT(cred->cr_label); 1105 dest = SLOT(msglabel); 1106 1107 mac_biba_copy_effective(source, dest); 1108 } 1109 1110 static void 1111 mac_biba_create_sysv_msgqueue(struct ucred *cred, 1112 struct msqid_kernel *msqkptr, struct label *msqlabel) 1113 { 1114 struct mac_biba *source, *dest; 1115 1116 source = SLOT(cred->cr_label); 1117 dest = SLOT(msqlabel); 1118 1119 mac_biba_copy_effective(source, dest); 1120 } 1121 1122 static void 1123 mac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr, 1124 struct label *semalabel) 1125 { 1126 struct mac_biba *source, *dest; 1127 1128 source = SLOT(cred->cr_label); 1129 dest = SLOT(semalabel); 1130 1131 mac_biba_copy_effective(source, dest); 1132 } 1133 1134 static void 1135 mac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr, 1136 struct label *shmlabel) 1137 { 1138 struct mac_biba *source, *dest; 1139 1140 source = SLOT(cred->cr_label); 1141 dest = SLOT(shmlabel); 1142 1143 mac_biba_copy_effective(source, dest); 1144 } 1145 1146 /* 1147 * Labeling event operations: network objects. 1148 */ 1149 static void 1150 mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1151 struct label *oldsocketlabel, struct socket *newsocket, 1152 struct label *newsocketpeerlabel) 1153 { 1154 struct mac_biba *source, *dest; 1155 1156 source = SLOT(oldsocketlabel); 1157 dest = SLOT(newsocketpeerlabel); 1158 1159 mac_biba_copy_effective(source, dest); 1160 } 1161 1162 static void 1163 mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1164 struct label *bpflabel) 1165 { 1166 struct mac_biba *source, *dest; 1167 1168 source = SLOT(cred->cr_label); 1169 dest = SLOT(bpflabel); 1170 1171 mac_biba_copy_effective(source, dest); 1172 } 1173 1174 static void 1175 mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1176 { 1177 char tifname[IFNAMSIZ], *p, *q; 1178 char tiflist[sizeof(trusted_interfaces)]; 1179 struct mac_biba *dest; 1180 int len, type; 1181 1182 dest = SLOT(ifnetlabel); 1183 1184 if (ifnet->if_type == IFT_LOOP || interfaces_equal != 0) { 1185 type = MAC_BIBA_TYPE_EQUAL; 1186 goto set; 1187 } 1188 1189 if (trust_all_interfaces) { 1190 type = MAC_BIBA_TYPE_HIGH; 1191 goto set; 1192 } 1193 1194 type = MAC_BIBA_TYPE_LOW; 1195 1196 if (trusted_interfaces[0] == '\0' || 1197 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1198 goto set; 1199 1200 bzero(tiflist, sizeof(tiflist)); 1201 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1202 if(*p != ' ' && *p != '\t') 1203 *q = *p; 1204 1205 for (p = q = tiflist;; p++) { 1206 if (*p == ',' || *p == '\0') { 1207 len = p - q; 1208 if (len < IFNAMSIZ) { 1209 bzero(tifname, sizeof(tifname)); 1210 bcopy(q, tifname, len); 1211 if (strcmp(tifname, ifnet->if_xname) == 0) { 1212 type = MAC_BIBA_TYPE_HIGH; 1213 break; 1214 } 1215 } else { 1216 *p = '\0'; 1217 printf("mac_biba warning: interface name " 1218 "\"%s\" is too long (must be < %d)\n", 1219 q, IFNAMSIZ); 1220 } 1221 if (*p == '\0') 1222 break; 1223 q = p + 1; 1224 } 1225 } 1226 set: 1227 mac_biba_set_effective(dest, type, 0, NULL); 1228 mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1229 } 1230 1231 static void 1232 mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1233 struct ipq *ipq, struct label *ipqlabel) 1234 { 1235 struct mac_biba *source, *dest; 1236 1237 source = SLOT(fragmentlabel); 1238 dest = SLOT(ipqlabel); 1239 1240 mac_biba_copy_effective(source, dest); 1241 } 1242 1243 static void 1244 mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1245 struct mbuf *datagram, struct label *datagramlabel) 1246 { 1247 struct mac_biba *source, *dest; 1248 1249 source = SLOT(ipqlabel); 1250 dest = SLOT(datagramlabel); 1251 1252 /* Just use the head, since we require them all to match. */ 1253 mac_biba_copy_effective(source, dest); 1254 } 1255 1256 static void 1257 mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1258 struct mbuf *fragment, struct label *fragmentlabel) 1259 { 1260 struct mac_biba *source, *dest; 1261 1262 source = SLOT(datagramlabel); 1263 dest = SLOT(fragmentlabel); 1264 1265 mac_biba_copy_effective(source, dest); 1266 } 1267 1268 static void 1269 mac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1270 struct mbuf *m, struct label *mlabel) 1271 { 1272 struct mac_biba *source, *dest; 1273 1274 source = SLOT(inplabel); 1275 dest = SLOT(mlabel); 1276 1277 mac_biba_copy_effective(source, dest); 1278 } 1279 1280 static void 1281 mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1282 struct mbuf *mbuf, struct label *mbuflabel) 1283 { 1284 struct mac_biba *dest; 1285 1286 dest = SLOT(mbuflabel); 1287 1288 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1289 } 1290 1291 static void 1292 mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1293 struct mbuf *mbuf, struct label *mbuflabel) 1294 { 1295 struct mac_biba *source, *dest; 1296 1297 source = SLOT(bpflabel); 1298 dest = SLOT(mbuflabel); 1299 1300 mac_biba_copy_effective(source, dest); 1301 } 1302 1303 static void 1304 mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1305 struct mbuf *m, struct label *mbuflabel) 1306 { 1307 struct mac_biba *source, *dest; 1308 1309 source = SLOT(ifnetlabel); 1310 dest = SLOT(mbuflabel); 1311 1312 mac_biba_copy_effective(source, dest); 1313 } 1314 1315 static void 1316 mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1317 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1318 struct mbuf *newmbuf, struct label *newmbuflabel) 1319 { 1320 struct mac_biba *source, *dest; 1321 1322 source = SLOT(oldmbuflabel); 1323 dest = SLOT(newmbuflabel); 1324 1325 mac_biba_copy_effective(source, dest); 1326 } 1327 1328 static void 1329 mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1330 struct mbuf *newmbuf, struct label *newmbuflabel) 1331 { 1332 struct mac_biba *source, *dest; 1333 1334 source = SLOT(oldmbuflabel); 1335 dest = SLOT(newmbuflabel); 1336 1337 mac_biba_copy_effective(source, dest); 1338 } 1339 1340 static int 1341 mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1342 struct ipq *ipq, struct label *ipqlabel) 1343 { 1344 struct mac_biba *a, *b; 1345 1346 a = SLOT(ipqlabel); 1347 b = SLOT(fragmentlabel); 1348 1349 return (mac_biba_equal_effective(a, b)); 1350 } 1351 1352 static void 1353 mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1354 struct label *ifnetlabel, struct label *newlabel) 1355 { 1356 struct mac_biba *source, *dest; 1357 1358 source = SLOT(newlabel); 1359 dest = SLOT(ifnetlabel); 1360 1361 mac_biba_copy(source, dest); 1362 } 1363 1364 static void 1365 mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1366 struct ipq *ipq, struct label *ipqlabel) 1367 { 1368 1369 /* NOOP: we only accept matching labels, so no need to update */ 1370 } 1371 1372 static void 1373 mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1374 struct inpcb *inp, struct label *inplabel) 1375 { 1376 struct mac_biba *source, *dest; 1377 1378 source = SLOT(solabel); 1379 dest = SLOT(inplabel); 1380 1381 mac_biba_copy(source, dest); 1382 } 1383 1384 /* 1385 * Labeling event operations: processes. 1386 */ 1387 static void 1388 mac_biba_create_proc0(struct ucred *cred) 1389 { 1390 struct mac_biba *dest; 1391 1392 dest = SLOT(cred->cr_label); 1393 1394 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1395 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1396 MAC_BIBA_TYPE_HIGH, 0, NULL); 1397 } 1398 1399 static void 1400 mac_biba_create_proc1(struct ucred *cred) 1401 { 1402 struct mac_biba *dest; 1403 1404 dest = SLOT(cred->cr_label); 1405 1406 mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1407 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1408 MAC_BIBA_TYPE_HIGH, 0, NULL); 1409 } 1410 1411 static void 1412 mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1413 { 1414 struct mac_biba *source, *dest; 1415 1416 source = SLOT(newlabel); 1417 dest = SLOT(cred->cr_label); 1418 1419 mac_biba_copy(source, dest); 1420 } 1421 1422 /* 1423 * Label cleanup/flush operations 1424 */ 1425 static void 1426 mac_biba_cleanup_sysv_msgmsg(struct label *msglabel) 1427 { 1428 1429 bzero(SLOT(msglabel), sizeof(struct mac_biba)); 1430 } 1431 1432 static void 1433 mac_biba_cleanup_sysv_msgqueue(struct label *msqlabel) 1434 { 1435 1436 bzero(SLOT(msqlabel), sizeof(struct mac_biba)); 1437 } 1438 1439 static void 1440 mac_biba_cleanup_sysv_sem(struct label *semalabel) 1441 { 1442 1443 bzero(SLOT(semalabel), sizeof(struct mac_biba)); 1444 } 1445 1446 static void 1447 mac_biba_cleanup_sysv_shm(struct label *shmlabel) 1448 { 1449 bzero(SLOT(shmlabel), sizeof(struct mac_biba)); 1450 } 1451 1452 /* 1453 * Access control checks. 1454 */ 1455 static int 1456 mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1457 struct ifnet *ifnet, struct label *ifnetlabel) 1458 { 1459 struct mac_biba *a, *b; 1460 1461 if (!mac_biba_enabled) 1462 return (0); 1463 1464 a = SLOT(bpflabel); 1465 b = SLOT(ifnetlabel); 1466 1467 if (mac_biba_equal_effective(a, b)) 1468 return (0); 1469 return (EACCES); 1470 } 1471 1472 static int 1473 mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1474 { 1475 struct mac_biba *subj, *new; 1476 int error; 1477 1478 subj = SLOT(cred->cr_label); 1479 new = SLOT(newlabel); 1480 1481 /* 1482 * If there is a Biba label update for the credential, it may 1483 * be an update of the effective, range, or both. 1484 */ 1485 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1486 if (error) 1487 return (error); 1488 1489 /* 1490 * If the Biba label is to be changed, authorize as appropriate. 1491 */ 1492 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1493 /* 1494 * If the change request modifies both the Biba label 1495 * effective and range, check that the new effective will be 1496 * in the new range. 1497 */ 1498 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1499 MAC_BIBA_FLAGS_BOTH && 1500 !mac_biba_effective_in_range(new, new)) 1501 return (EINVAL); 1502 1503 /* 1504 * To change the Biba effective label on a credential, the 1505 * new effective label must be in the current range. 1506 */ 1507 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE && 1508 !mac_biba_effective_in_range(new, subj)) 1509 return (EPERM); 1510 1511 /* 1512 * To change the Biba range on a credential, the new 1513 * range label must be in the current range. 1514 */ 1515 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1516 !mac_biba_range_in_range(new, subj)) 1517 return (EPERM); 1518 1519 /* 1520 * To have EQUAL in any component of the new credential 1521 * Biba label, the subject must already have EQUAL in 1522 * their label. 1523 */ 1524 if (mac_biba_contains_equal(new)) { 1525 error = mac_biba_subject_privileged(subj); 1526 if (error) 1527 return (error); 1528 } 1529 } 1530 1531 return (0); 1532 } 1533 1534 static int 1535 mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1536 { 1537 struct mac_biba *subj, *obj; 1538 1539 if (!mac_biba_enabled) 1540 return (0); 1541 1542 subj = SLOT(u1->cr_label); 1543 obj = SLOT(u2->cr_label); 1544 1545 /* XXX: range */ 1546 if (!mac_biba_dominate_effective(obj, subj)) 1547 return (ESRCH); 1548 1549 return (0); 1550 } 1551 1552 static int 1553 mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1554 struct label *ifnetlabel, struct label *newlabel) 1555 { 1556 struct mac_biba *subj, *new; 1557 int error; 1558 1559 subj = SLOT(cred->cr_label); 1560 new = SLOT(newlabel); 1561 1562 /* 1563 * If there is a Biba label update for the interface, it may 1564 * be an update of the effective, range, or both. 1565 */ 1566 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1567 if (error) 1568 return (error); 1569 1570 /* 1571 * Relabling network interfaces requires Biba privilege. 1572 */ 1573 error = mac_biba_subject_privileged(subj); 1574 if (error) 1575 return (error); 1576 1577 return (0); 1578 } 1579 1580 static int 1581 mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1582 struct mbuf *m, struct label *mbuflabel) 1583 { 1584 struct mac_biba *p, *i; 1585 1586 if (!mac_biba_enabled) 1587 return (0); 1588 1589 p = SLOT(mbuflabel); 1590 i = SLOT(ifnetlabel); 1591 1592 return (mac_biba_effective_in_range(p, i) ? 0 : EACCES); 1593 } 1594 1595 static int 1596 mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1597 struct mbuf *m, struct label *mlabel) 1598 { 1599 struct mac_biba *p, *i; 1600 1601 if (!mac_biba_enabled) 1602 return (0); 1603 1604 p = SLOT(mlabel); 1605 i = SLOT(inplabel); 1606 1607 return (mac_biba_equal_effective(p, i) ? 0 : EACCES); 1608 } 1609 1610 static int 1611 mac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr, 1612 struct label *msglabel) 1613 { 1614 struct mac_biba *subj, *obj; 1615 1616 if (!mac_biba_enabled) 1617 return (0); 1618 1619 subj = SLOT(cred->cr_label); 1620 obj = SLOT(msglabel); 1621 1622 if (!mac_biba_dominate_effective(obj, subj)) 1623 return (EACCES); 1624 1625 return (0); 1626 } 1627 1628 static int 1629 mac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr, 1630 struct label *msglabel) 1631 { 1632 struct mac_biba *subj, *obj; 1633 1634 if (!mac_biba_enabled) 1635 return (0); 1636 1637 subj = SLOT(cred->cr_label); 1638 obj = SLOT(msglabel); 1639 1640 if (!mac_biba_dominate_effective(subj, obj)) 1641 return (EACCES); 1642 1643 return (0); 1644 } 1645 1646 static int 1647 mac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1648 struct label *msqklabel) 1649 { 1650 struct mac_biba *subj, *obj; 1651 1652 if (!mac_biba_enabled) 1653 return (0); 1654 1655 subj = SLOT(cred->cr_label); 1656 obj = SLOT(msqklabel); 1657 1658 if (!mac_biba_dominate_effective(obj, subj)) 1659 return (EACCES); 1660 1661 return (0); 1662 } 1663 1664 static int 1665 mac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1666 struct label *msqklabel) 1667 { 1668 struct mac_biba *subj, *obj; 1669 1670 if (!mac_biba_enabled) 1671 return (0); 1672 1673 subj = SLOT(cred->cr_label); 1674 obj = SLOT(msqklabel); 1675 1676 if (!mac_biba_dominate_effective(subj, obj)) 1677 return (EACCES); 1678 1679 return (0); 1680 } 1681 1682 static int 1683 mac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1684 struct label *msqklabel) 1685 { 1686 struct mac_biba *subj, *obj; 1687 1688 if (!mac_biba_enabled) 1689 return (0); 1690 1691 subj = SLOT(cred->cr_label); 1692 obj = SLOT(msqklabel); 1693 1694 if (!mac_biba_dominate_effective(obj, subj)) 1695 return (EACCES); 1696 1697 return (0); 1698 } 1699 1700 1701 static int 1702 mac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1703 struct label *msqklabel, int cmd) 1704 { 1705 struct mac_biba *subj, *obj; 1706 1707 if (!mac_biba_enabled) 1708 return (0); 1709 1710 subj = SLOT(cred->cr_label); 1711 obj = SLOT(msqklabel); 1712 1713 switch(cmd) { 1714 case IPC_RMID: 1715 case IPC_SET: 1716 if (!mac_biba_dominate_effective(subj, obj)) 1717 return (EACCES); 1718 break; 1719 1720 case IPC_STAT: 1721 if (!mac_biba_dominate_effective(obj, subj)) 1722 return (EACCES); 1723 break; 1724 1725 default: 1726 return (EACCES); 1727 } 1728 1729 return (0); 1730 } 1731 1732 static int 1733 mac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1734 struct label *semaklabel, int cmd) 1735 { 1736 struct mac_biba *subj, *obj; 1737 1738 if (!mac_biba_enabled) 1739 return (0); 1740 1741 subj = SLOT(cred->cr_label); 1742 obj = SLOT(semaklabel); 1743 1744 switch(cmd) { 1745 case IPC_RMID: 1746 case IPC_SET: 1747 case SETVAL: 1748 case SETALL: 1749 if (!mac_biba_dominate_effective(subj, obj)) 1750 return (EACCES); 1751 break; 1752 1753 case IPC_STAT: 1754 case GETVAL: 1755 case GETPID: 1756 case GETNCNT: 1757 case GETZCNT: 1758 case GETALL: 1759 if (!mac_biba_dominate_effective(obj, subj)) 1760 return (EACCES); 1761 break; 1762 1763 default: 1764 return (EACCES); 1765 } 1766 1767 return (0); 1768 } 1769 1770 1771 static int 1772 mac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr, 1773 struct label *semaklabel) 1774 { 1775 struct mac_biba *subj, *obj; 1776 1777 if (!mac_biba_enabled) 1778 return (0); 1779 1780 subj = SLOT(cred->cr_label); 1781 obj = SLOT(semaklabel); 1782 1783 if (!mac_biba_dominate_effective(obj, subj)) 1784 return (EACCES); 1785 1786 return (0); 1787 } 1788 1789 1790 static int 1791 mac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr, 1792 struct label *semaklabel, size_t accesstype) 1793 { 1794 struct mac_biba *subj, *obj; 1795 1796 if (!mac_biba_enabled) 1797 return (0); 1798 1799 subj = SLOT(cred->cr_label); 1800 obj = SLOT(semaklabel); 1801 1802 if (accesstype & SEM_R) 1803 if (!mac_biba_dominate_effective(obj, subj)) 1804 return (EACCES); 1805 1806 if (accesstype & SEM_A) 1807 if (!mac_biba_dominate_effective(subj, obj)) 1808 return (EACCES); 1809 1810 return (0); 1811 } 1812 1813 static int 1814 mac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 1815 struct label *shmseglabel, int shmflg) 1816 { 1817 struct mac_biba *subj, *obj; 1818 1819 if (!mac_biba_enabled) 1820 return (0); 1821 1822 subj = SLOT(cred->cr_label); 1823 obj = SLOT(shmseglabel); 1824 1825 if (!mac_biba_dominate_effective(obj, subj)) 1826 return (EACCES); 1827 if ((shmflg & SHM_RDONLY) == 0) { 1828 if (!mac_biba_dominate_effective(subj, obj)) 1829 return (EACCES); 1830 } 1831 1832 return (0); 1833 } 1834 1835 static int 1836 mac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 1837 struct label *shmseglabel, int cmd) 1838 { 1839 struct mac_biba *subj, *obj; 1840 1841 if (!mac_biba_enabled) 1842 return (0); 1843 1844 subj = SLOT(cred->cr_label); 1845 obj = SLOT(shmseglabel); 1846 1847 switch(cmd) { 1848 case IPC_RMID: 1849 case IPC_SET: 1850 if (!mac_biba_dominate_effective(subj, obj)) 1851 return (EACCES); 1852 break; 1853 1854 case IPC_STAT: 1855 case SHM_STAT: 1856 if (!mac_biba_dominate_effective(obj, subj)) 1857 return (EACCES); 1858 break; 1859 1860 default: 1861 return (EACCES); 1862 } 1863 1864 return (0); 1865 } 1866 1867 static int 1868 mac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 1869 struct label *shmseglabel, int shmflg) 1870 { 1871 struct mac_biba *subj, *obj; 1872 1873 if (!mac_biba_enabled) 1874 return (0); 1875 1876 subj = SLOT(cred->cr_label); 1877 obj = SLOT(shmseglabel); 1878 1879 if (!mac_biba_dominate_effective(obj, subj)) 1880 return (EACCES); 1881 1882 return (0); 1883 } 1884 1885 static int 1886 mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1887 struct label *label) 1888 { 1889 struct mac_biba *subj, *obj; 1890 int error; 1891 1892 if (!mac_biba_enabled) 1893 return (0); 1894 1895 subj = SLOT(cred->cr_label); 1896 1897 error = mac_biba_subject_privileged(subj); 1898 if (error) 1899 return (error); 1900 1901 obj = SLOT(label); 1902 if (!mac_biba_high_effective(obj)) 1903 return (EACCES); 1904 1905 return (0); 1906 } 1907 1908 1909 static int 1910 mac_biba_check_kld_unload(struct ucred *cred) 1911 { 1912 struct mac_biba *subj; 1913 1914 if (!mac_biba_enabled) 1915 return (0); 1916 1917 subj = SLOT(cred->cr_label); 1918 1919 return (mac_biba_subject_privileged(subj)); 1920 } 1921 1922 static int 1923 mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1924 struct label *mntlabel) 1925 { 1926 struct mac_biba *subj, *obj; 1927 1928 if (!mac_biba_enabled) 1929 return (0); 1930 1931 subj = SLOT(cred->cr_label); 1932 obj = SLOT(mntlabel); 1933 1934 if (!mac_biba_dominate_effective(obj, subj)) 1935 return (EACCES); 1936 1937 return (0); 1938 } 1939 1940 static int 1941 mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1942 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1943 { 1944 1945 if(!mac_biba_enabled) 1946 return (0); 1947 1948 /* XXX: This will be implemented soon... */ 1949 1950 return (0); 1951 } 1952 1953 static int 1954 mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp, 1955 struct label *pipelabel) 1956 { 1957 struct mac_biba *subj, *obj; 1958 1959 if (!mac_biba_enabled) 1960 return (0); 1961 1962 subj = SLOT(cred->cr_label); 1963 obj = SLOT((pipelabel)); 1964 1965 if (!mac_biba_dominate_effective(obj, subj)) 1966 return (EACCES); 1967 1968 return (0); 1969 } 1970 1971 static int 1972 mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1973 struct label *pipelabel) 1974 { 1975 struct mac_biba *subj, *obj; 1976 1977 if (!mac_biba_enabled) 1978 return (0); 1979 1980 subj = SLOT(cred->cr_label); 1981 obj = SLOT((pipelabel)); 1982 1983 if (!mac_biba_dominate_effective(obj, subj)) 1984 return (EACCES); 1985 1986 return (0); 1987 } 1988 1989 static int 1990 mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1991 struct label *pipelabel, struct label *newlabel) 1992 { 1993 struct mac_biba *subj, *obj, *new; 1994 int error; 1995 1996 new = SLOT(newlabel); 1997 subj = SLOT(cred->cr_label); 1998 obj = SLOT(pipelabel); 1999 2000 /* 2001 * If there is a Biba label update for a pipe, it must be a 2002 * effective update. 2003 */ 2004 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2005 if (error) 2006 return (error); 2007 2008 /* 2009 * To perform a relabel of a pipe (Biba label or not), Biba must 2010 * authorize the relabel. 2011 */ 2012 if (!mac_biba_effective_in_range(obj, subj)) 2013 return (EPERM); 2014 2015 /* 2016 * If the Biba label is to be changed, authorize as appropriate. 2017 */ 2018 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2019 /* 2020 * To change the Biba label on a pipe, the new pipe label 2021 * must be in the subject range. 2022 */ 2023 if (!mac_biba_effective_in_range(new, subj)) 2024 return (EPERM); 2025 2026 /* 2027 * To change the Biba label on a pipe to be EQUAL, the 2028 * subject must have appropriate privilege. 2029 */ 2030 if (mac_biba_contains_equal(new)) { 2031 error = mac_biba_subject_privileged(subj); 2032 if (error) 2033 return (error); 2034 } 2035 } 2036 2037 return (0); 2038 } 2039 2040 static int 2041 mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp, 2042 struct label *pipelabel) 2043 { 2044 struct mac_biba *subj, *obj; 2045 2046 if (!mac_biba_enabled) 2047 return (0); 2048 2049 subj = SLOT(cred->cr_label); 2050 obj = SLOT((pipelabel)); 2051 2052 if (!mac_biba_dominate_effective(obj, subj)) 2053 return (EACCES); 2054 2055 return (0); 2056 } 2057 2058 static int 2059 mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp, 2060 struct label *pipelabel) 2061 { 2062 struct mac_biba *subj, *obj; 2063 2064 if (!mac_biba_enabled) 2065 return (0); 2066 2067 subj = SLOT(cred->cr_label); 2068 obj = SLOT((pipelabel)); 2069 2070 if (!mac_biba_dominate_effective(subj, obj)) 2071 return (EACCES); 2072 2073 return (0); 2074 } 2075 2076 static int 2077 mac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr, 2078 struct label *ks_label) 2079 { 2080 struct mac_biba *subj, *obj; 2081 2082 if (!mac_biba_enabled) 2083 return (0); 2084 2085 subj = SLOT(cred->cr_label); 2086 obj = SLOT(ks_label); 2087 2088 if (!mac_biba_dominate_effective(subj, obj)) 2089 return (EACCES); 2090 2091 return (0); 2092 } 2093 2094 static int 2095 mac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr, 2096 struct label *ks_label) 2097 { 2098 struct mac_biba *subj, *obj; 2099 2100 if (!mac_biba_enabled) 2101 return (0); 2102 2103 subj = SLOT(cred->cr_label); 2104 obj = SLOT(ks_label); 2105 2106 if (!mac_biba_dominate_effective(obj, subj)) 2107 return (EACCES); 2108 2109 return (0); 2110 } 2111 2112 static int 2113 mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 2114 { 2115 struct mac_biba *subj, *obj; 2116 2117 if (!mac_biba_enabled) 2118 return (0); 2119 2120 subj = SLOT(cred->cr_label); 2121 obj = SLOT(proc->p_ucred->cr_label); 2122 2123 /* XXX: range checks */ 2124 if (!mac_biba_dominate_effective(obj, subj)) 2125 return (ESRCH); 2126 if (!mac_biba_dominate_effective(subj, obj)) 2127 return (EACCES); 2128 2129 return (0); 2130 } 2131 2132 static int 2133 mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 2134 { 2135 struct mac_biba *subj, *obj; 2136 2137 if (!mac_biba_enabled) 2138 return (0); 2139 2140 subj = SLOT(cred->cr_label); 2141 obj = SLOT(proc->p_ucred->cr_label); 2142 2143 /* XXX: range checks */ 2144 if (!mac_biba_dominate_effective(obj, subj)) 2145 return (ESRCH); 2146 if (!mac_biba_dominate_effective(subj, obj)) 2147 return (EACCES); 2148 2149 return (0); 2150 } 2151 2152 static int 2153 mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2154 { 2155 struct mac_biba *subj, *obj; 2156 2157 if (!mac_biba_enabled) 2158 return (0); 2159 2160 subj = SLOT(cred->cr_label); 2161 obj = SLOT(proc->p_ucred->cr_label); 2162 2163 /* XXX: range checks */ 2164 if (!mac_biba_dominate_effective(obj, subj)) 2165 return (ESRCH); 2166 if (!mac_biba_dominate_effective(subj, obj)) 2167 return (EACCES); 2168 2169 return (0); 2170 } 2171 2172 static int 2173 mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 2174 struct mbuf *m, struct label *mbuflabel) 2175 { 2176 struct mac_biba *p, *s; 2177 2178 if (!mac_biba_enabled) 2179 return (0); 2180 2181 p = SLOT(mbuflabel); 2182 s = SLOT(socketlabel); 2183 2184 return (mac_biba_equal_effective(p, s) ? 0 : EACCES); 2185 } 2186 2187 static int 2188 mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 2189 struct label *socketlabel, struct label *newlabel) 2190 { 2191 struct mac_biba *subj, *obj, *new; 2192 int error; 2193 2194 new = SLOT(newlabel); 2195 subj = SLOT(cred->cr_label); 2196 obj = SLOT(socketlabel); 2197 2198 /* 2199 * If there is a Biba label update for the socket, it may be 2200 * an update of effective. 2201 */ 2202 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2203 if (error) 2204 return (error); 2205 2206 /* 2207 * To relabel a socket, the old socket effective must be in the subject 2208 * range. 2209 */ 2210 if (!mac_biba_effective_in_range(obj, subj)) 2211 return (EPERM); 2212 2213 /* 2214 * If the Biba label is to be changed, authorize as appropriate. 2215 */ 2216 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2217 /* 2218 * To relabel a socket, the new socket effective must be in 2219 * the subject range. 2220 */ 2221 if (!mac_biba_effective_in_range(new, subj)) 2222 return (EPERM); 2223 2224 /* 2225 * To change the Biba label on the socket to contain EQUAL, 2226 * the subject must have appropriate privilege. 2227 */ 2228 if (mac_biba_contains_equal(new)) { 2229 error = mac_biba_subject_privileged(subj); 2230 if (error) 2231 return (error); 2232 } 2233 } 2234 2235 return (0); 2236 } 2237 2238 static int 2239 mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 2240 struct label *socketlabel) 2241 { 2242 struct mac_biba *subj, *obj; 2243 2244 if (!mac_biba_enabled) 2245 return (0); 2246 2247 subj = SLOT(cred->cr_label); 2248 obj = SLOT(socketlabel); 2249 2250 if (!mac_biba_dominate_effective(obj, subj)) 2251 return (ENOENT); 2252 2253 return (0); 2254 } 2255 2256 static int 2257 mac_biba_check_sysarch_ioperm(struct ucred *cred) 2258 { 2259 struct mac_biba *subj; 2260 int error; 2261 2262 if (!mac_biba_enabled) 2263 return (0); 2264 2265 subj = SLOT(cred->cr_label); 2266 2267 error = mac_biba_subject_privileged(subj); 2268 if (error) 2269 return (error); 2270 2271 return (0); 2272 } 2273 2274 static int 2275 mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 2276 struct label *label) 2277 { 2278 struct mac_biba *subj, *obj; 2279 int error; 2280 2281 if (!mac_biba_enabled) 2282 return (0); 2283 2284 subj = SLOT(cred->cr_label); 2285 2286 error = mac_biba_subject_privileged(subj); 2287 if (error) 2288 return (error); 2289 2290 if (label == NULL) 2291 return (0); 2292 2293 obj = SLOT(label); 2294 if (!mac_biba_high_effective(obj)) 2295 return (EACCES); 2296 2297 return (0); 2298 } 2299 2300 static int 2301 mac_biba_check_system_settime(struct ucred *cred) 2302 { 2303 struct mac_biba *subj; 2304 int error; 2305 2306 if (!mac_biba_enabled) 2307 return (0); 2308 2309 subj = SLOT(cred->cr_label); 2310 2311 error = mac_biba_subject_privileged(subj); 2312 if (error) 2313 return (error); 2314 2315 return (0); 2316 } 2317 2318 static int 2319 mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 2320 struct label *label) 2321 { 2322 struct mac_biba *subj, *obj; 2323 int error; 2324 2325 if (!mac_biba_enabled) 2326 return (0); 2327 2328 subj = SLOT(cred->cr_label); 2329 obj = SLOT(label); 2330 2331 error = mac_biba_subject_privileged(subj); 2332 if (error) 2333 return (error); 2334 2335 if (!mac_biba_high_effective(obj)) 2336 return (EACCES); 2337 2338 return (0); 2339 } 2340 2341 static int 2342 mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 2343 struct label *label) 2344 { 2345 struct mac_biba *subj, *obj; 2346 int error; 2347 2348 if (!mac_biba_enabled) 2349 return (0); 2350 2351 subj = SLOT(cred->cr_label); 2352 obj = SLOT(label); 2353 2354 error = mac_biba_subject_privileged(subj); 2355 if (error) 2356 return (error); 2357 2358 return (0); 2359 } 2360 2361 static int 2362 mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2363 void *arg1, int arg2, struct sysctl_req *req) 2364 { 2365 struct mac_biba *subj; 2366 int error; 2367 2368 if (!mac_biba_enabled) 2369 return (0); 2370 2371 subj = SLOT(cred->cr_label); 2372 2373 /* 2374 * Treat sysctl variables without CTLFLAG_ANYBODY flag as 2375 * biba/high, but also require privilege to change them. 2376 */ 2377 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2378 if (!mac_biba_subject_dominate_high(subj)) 2379 return (EACCES); 2380 2381 error = mac_biba_subject_privileged(subj); 2382 if (error) 2383 return (error); 2384 } 2385 2386 return (0); 2387 } 2388 2389 static int 2390 mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2391 struct label *dlabel) 2392 { 2393 struct mac_biba *subj, *obj; 2394 2395 if (!mac_biba_enabled) 2396 return (0); 2397 2398 subj = SLOT(cred->cr_label); 2399 obj = SLOT(dlabel); 2400 2401 if (!mac_biba_dominate_effective(obj, subj)) 2402 return (EACCES); 2403 2404 return (0); 2405 } 2406 2407 static int 2408 mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2409 struct label *dlabel) 2410 { 2411 struct mac_biba *subj, *obj; 2412 2413 if (!mac_biba_enabled) 2414 return (0); 2415 2416 subj = SLOT(cred->cr_label); 2417 obj = SLOT(dlabel); 2418 2419 if (!mac_biba_dominate_effective(obj, subj)) 2420 return (EACCES); 2421 2422 return (0); 2423 } 2424 2425 static int 2426 mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2427 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2428 { 2429 struct mac_biba *subj, *obj; 2430 2431 if (!mac_biba_enabled) 2432 return (0); 2433 2434 subj = SLOT(cred->cr_label); 2435 obj = SLOT(dlabel); 2436 2437 if (!mac_biba_dominate_effective(subj, obj)) 2438 return (EACCES); 2439 2440 return (0); 2441 } 2442 2443 static int 2444 mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2445 struct label *dlabel, struct vnode *vp, struct label *label, 2446 struct componentname *cnp) 2447 { 2448 struct mac_biba *subj, *obj; 2449 2450 if (!mac_biba_enabled) 2451 return (0); 2452 2453 subj = SLOT(cred->cr_label); 2454 obj = SLOT(dlabel); 2455 2456 if (!mac_biba_dominate_effective(subj, obj)) 2457 return (EACCES); 2458 2459 obj = SLOT(label); 2460 2461 if (!mac_biba_dominate_effective(subj, obj)) 2462 return (EACCES); 2463 2464 return (0); 2465 } 2466 2467 static int 2468 mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2469 struct label *label, acl_type_t type) 2470 { 2471 struct mac_biba *subj, *obj; 2472 2473 if (!mac_biba_enabled) 2474 return (0); 2475 2476 subj = SLOT(cred->cr_label); 2477 obj = SLOT(label); 2478 2479 if (!mac_biba_dominate_effective(subj, obj)) 2480 return (EACCES); 2481 2482 return (0); 2483 } 2484 2485 static int 2486 mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2487 struct label *label, int attrnamespace, const char *name) 2488 { 2489 struct mac_biba *subj, *obj; 2490 2491 if (!mac_biba_enabled) 2492 return (0); 2493 2494 subj = SLOT(cred->cr_label); 2495 obj = SLOT(label); 2496 2497 if (!mac_biba_dominate_effective(subj, obj)) 2498 return (EACCES); 2499 2500 return (0); 2501 } 2502 2503 static int 2504 mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2505 struct label *label, struct image_params *imgp, 2506 struct label *execlabel) 2507 { 2508 struct mac_biba *subj, *obj, *exec; 2509 int error; 2510 2511 if (execlabel != NULL) { 2512 /* 2513 * We currently don't permit labels to be changed at 2514 * exec-time as part of Biba, so disallow non-NULL 2515 * Biba label elements in the execlabel. 2516 */ 2517 exec = SLOT(execlabel); 2518 error = biba_atmostflags(exec, 0); 2519 if (error) 2520 return (error); 2521 } 2522 2523 if (!mac_biba_enabled) 2524 return (0); 2525 2526 subj = SLOT(cred->cr_label); 2527 obj = SLOT(label); 2528 2529 if (!mac_biba_dominate_effective(obj, subj)) 2530 return (EACCES); 2531 2532 return (0); 2533 } 2534 2535 static int 2536 mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2537 struct label *label, acl_type_t type) 2538 { 2539 struct mac_biba *subj, *obj; 2540 2541 if (!mac_biba_enabled) 2542 return (0); 2543 2544 subj = SLOT(cred->cr_label); 2545 obj = SLOT(label); 2546 2547 if (!mac_biba_dominate_effective(obj, subj)) 2548 return (EACCES); 2549 2550 return (0); 2551 } 2552 2553 static int 2554 mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2555 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2556 { 2557 struct mac_biba *subj, *obj; 2558 2559 if (!mac_biba_enabled) 2560 return (0); 2561 2562 subj = SLOT(cred->cr_label); 2563 obj = SLOT(label); 2564 2565 if (!mac_biba_dominate_effective(obj, subj)) 2566 return (EACCES); 2567 2568 return (0); 2569 } 2570 2571 static int 2572 mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2573 struct label *dlabel, struct vnode *vp, struct label *label, 2574 struct componentname *cnp) 2575 { 2576 struct mac_biba *subj, *obj; 2577 2578 if (!mac_biba_enabled) 2579 return (0); 2580 2581 subj = SLOT(cred->cr_label); 2582 obj = SLOT(dlabel); 2583 2584 if (!mac_biba_dominate_effective(subj, obj)) 2585 return (EACCES); 2586 2587 obj = SLOT(label); 2588 2589 if (!mac_biba_dominate_effective(subj, obj)) 2590 return (EACCES); 2591 2592 return (0); 2593 } 2594 2595 static int 2596 mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2597 struct label *label, int attrnamespace) 2598 { 2599 struct mac_biba *subj, *obj; 2600 2601 if (!mac_biba_enabled) 2602 return (0); 2603 2604 subj = SLOT(cred->cr_label); 2605 obj = SLOT(label); 2606 2607 if (!mac_biba_dominate_effective(obj, subj)) 2608 return (EACCES); 2609 2610 return (0); 2611 } 2612 2613 static int 2614 mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2615 struct label *dlabel, struct componentname *cnp) 2616 { 2617 struct mac_biba *subj, *obj; 2618 2619 if (!mac_biba_enabled) 2620 return (0); 2621 2622 subj = SLOT(cred->cr_label); 2623 obj = SLOT(dlabel); 2624 2625 if (!mac_biba_dominate_effective(obj, subj)) 2626 return (EACCES); 2627 2628 return (0); 2629 } 2630 2631 static int 2632 mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2633 struct label *label, int prot, int flags) 2634 { 2635 struct mac_biba *subj, *obj; 2636 2637 /* 2638 * Rely on the use of open()-time protections to handle 2639 * non-revocation cases. 2640 */ 2641 if (!mac_biba_enabled || !revocation_enabled) 2642 return (0); 2643 2644 subj = SLOT(cred->cr_label); 2645 obj = SLOT(label); 2646 2647 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2648 if (!mac_biba_dominate_effective(obj, subj)) 2649 return (EACCES); 2650 } 2651 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2652 if (!mac_biba_dominate_effective(subj, obj)) 2653 return (EACCES); 2654 } 2655 2656 return (0); 2657 } 2658 2659 static int 2660 mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2661 struct label *vnodelabel, int acc_mode) 2662 { 2663 struct mac_biba *subj, *obj; 2664 2665 if (!mac_biba_enabled) 2666 return (0); 2667 2668 subj = SLOT(cred->cr_label); 2669 obj = SLOT(vnodelabel); 2670 2671 /* XXX privilege override for admin? */ 2672 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2673 if (!mac_biba_dominate_effective(obj, subj)) 2674 return (EACCES); 2675 } 2676 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2677 if (!mac_biba_dominate_effective(subj, obj)) 2678 return (EACCES); 2679 } 2680 2681 return (0); 2682 } 2683 2684 static int 2685 mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2686 struct vnode *vp, struct label *label) 2687 { 2688 struct mac_biba *subj, *obj; 2689 2690 if (!mac_biba_enabled || !revocation_enabled) 2691 return (0); 2692 2693 subj = SLOT(active_cred->cr_label); 2694 obj = SLOT(label); 2695 2696 if (!mac_biba_dominate_effective(obj, subj)) 2697 return (EACCES); 2698 2699 return (0); 2700 } 2701 2702 static int 2703 mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2704 struct vnode *vp, struct label *label) 2705 { 2706 struct mac_biba *subj, *obj; 2707 2708 if (!mac_biba_enabled || !revocation_enabled) 2709 return (0); 2710 2711 subj = SLOT(active_cred->cr_label); 2712 obj = SLOT(label); 2713 2714 if (!mac_biba_dominate_effective(obj, subj)) 2715 return (EACCES); 2716 2717 return (0); 2718 } 2719 2720 static int 2721 mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2722 struct label *dlabel) 2723 { 2724 struct mac_biba *subj, *obj; 2725 2726 if (!mac_biba_enabled) 2727 return (0); 2728 2729 subj = SLOT(cred->cr_label); 2730 obj = SLOT(dlabel); 2731 2732 if (!mac_biba_dominate_effective(obj, subj)) 2733 return (EACCES); 2734 2735 return (0); 2736 } 2737 2738 static int 2739 mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2740 struct label *label) 2741 { 2742 struct mac_biba *subj, *obj; 2743 2744 if (!mac_biba_enabled) 2745 return (0); 2746 2747 subj = SLOT(cred->cr_label); 2748 obj = SLOT(label); 2749 2750 if (!mac_biba_dominate_effective(obj, subj)) 2751 return (EACCES); 2752 2753 return (0); 2754 } 2755 2756 static int 2757 mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2758 struct label *vnodelabel, struct label *newlabel) 2759 { 2760 struct mac_biba *old, *new, *subj; 2761 int error; 2762 2763 old = SLOT(vnodelabel); 2764 new = SLOT(newlabel); 2765 subj = SLOT(cred->cr_label); 2766 2767 /* 2768 * If there is a Biba label update for the vnode, it must be a 2769 * effective label. 2770 */ 2771 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2772 if (error) 2773 return (error); 2774 2775 /* 2776 * To perform a relabel of the vnode (Biba label or not), Biba must 2777 * authorize the relabel. 2778 */ 2779 if (!mac_biba_effective_in_range(old, subj)) 2780 return (EPERM); 2781 2782 /* 2783 * If the Biba label is to be changed, authorize as appropriate. 2784 */ 2785 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2786 /* 2787 * To change the Biba label on a vnode, the new vnode label 2788 * must be in the subject range. 2789 */ 2790 if (!mac_biba_effective_in_range(new, subj)) 2791 return (EPERM); 2792 2793 /* 2794 * To change the Biba label on the vnode to be EQUAL, 2795 * the subject must have appropriate privilege. 2796 */ 2797 if (mac_biba_contains_equal(new)) { 2798 error = mac_biba_subject_privileged(subj); 2799 if (error) 2800 return (error); 2801 } 2802 } 2803 2804 return (0); 2805 } 2806 2807 static int 2808 mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2809 struct label *dlabel, struct vnode *vp, struct label *label, 2810 struct componentname *cnp) 2811 { 2812 struct mac_biba *subj, *obj; 2813 2814 if (!mac_biba_enabled) 2815 return (0); 2816 2817 subj = SLOT(cred->cr_label); 2818 obj = SLOT(dlabel); 2819 2820 if (!mac_biba_dominate_effective(subj, obj)) 2821 return (EACCES); 2822 2823 obj = SLOT(label); 2824 2825 if (!mac_biba_dominate_effective(subj, obj)) 2826 return (EACCES); 2827 2828 return (0); 2829 } 2830 2831 static int 2832 mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2833 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2834 struct componentname *cnp) 2835 { 2836 struct mac_biba *subj, *obj; 2837 2838 if (!mac_biba_enabled) 2839 return (0); 2840 2841 subj = SLOT(cred->cr_label); 2842 obj = SLOT(dlabel); 2843 2844 if (!mac_biba_dominate_effective(subj, obj)) 2845 return (EACCES); 2846 2847 if (vp != NULL) { 2848 obj = SLOT(label); 2849 2850 if (!mac_biba_dominate_effective(subj, obj)) 2851 return (EACCES); 2852 } 2853 2854 return (0); 2855 } 2856 2857 static int 2858 mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2859 struct label *label) 2860 { 2861 struct mac_biba *subj, *obj; 2862 2863 if (!mac_biba_enabled) 2864 return (0); 2865 2866 subj = SLOT(cred->cr_label); 2867 obj = SLOT(label); 2868 2869 if (!mac_biba_dominate_effective(subj, obj)) 2870 return (EACCES); 2871 2872 return (0); 2873 } 2874 2875 static int 2876 mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2877 struct label *label, acl_type_t type, struct acl *acl) 2878 { 2879 struct mac_biba *subj, *obj; 2880 2881 if (!mac_biba_enabled) 2882 return (0); 2883 2884 subj = SLOT(cred->cr_label); 2885 obj = SLOT(label); 2886 2887 if (!mac_biba_dominate_effective(subj, obj)) 2888 return (EACCES); 2889 2890 return (0); 2891 } 2892 2893 static int 2894 mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2895 struct label *vnodelabel, int attrnamespace, const char *name, 2896 struct uio *uio) 2897 { 2898 struct mac_biba *subj, *obj; 2899 2900 if (!mac_biba_enabled) 2901 return (0); 2902 2903 subj = SLOT(cred->cr_label); 2904 obj = SLOT(vnodelabel); 2905 2906 if (!mac_biba_dominate_effective(subj, obj)) 2907 return (EACCES); 2908 2909 /* XXX: protect the MAC EA in a special way? */ 2910 2911 return (0); 2912 } 2913 2914 static int 2915 mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2916 struct label *vnodelabel, u_long flags) 2917 { 2918 struct mac_biba *subj, *obj; 2919 2920 if (!mac_biba_enabled) 2921 return (0); 2922 2923 subj = SLOT(cred->cr_label); 2924 obj = SLOT(vnodelabel); 2925 2926 if (!mac_biba_dominate_effective(subj, obj)) 2927 return (EACCES); 2928 2929 return (0); 2930 } 2931 2932 static int 2933 mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2934 struct label *vnodelabel, mode_t mode) 2935 { 2936 struct mac_biba *subj, *obj; 2937 2938 if (!mac_biba_enabled) 2939 return (0); 2940 2941 subj = SLOT(cred->cr_label); 2942 obj = SLOT(vnodelabel); 2943 2944 if (!mac_biba_dominate_effective(subj, obj)) 2945 return (EACCES); 2946 2947 return (0); 2948 } 2949 2950 static int 2951 mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2952 struct label *vnodelabel, uid_t uid, gid_t gid) 2953 { 2954 struct mac_biba *subj, *obj; 2955 2956 if (!mac_biba_enabled) 2957 return (0); 2958 2959 subj = SLOT(cred->cr_label); 2960 obj = SLOT(vnodelabel); 2961 2962 if (!mac_biba_dominate_effective(subj, obj)) 2963 return (EACCES); 2964 2965 return (0); 2966 } 2967 2968 static int 2969 mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2970 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2971 { 2972 struct mac_biba *subj, *obj; 2973 2974 if (!mac_biba_enabled) 2975 return (0); 2976 2977 subj = SLOT(cred->cr_label); 2978 obj = SLOT(vnodelabel); 2979 2980 if (!mac_biba_dominate_effective(subj, obj)) 2981 return (EACCES); 2982 2983 return (0); 2984 } 2985 2986 static int 2987 mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2988 struct vnode *vp, struct label *vnodelabel) 2989 { 2990 struct mac_biba *subj, *obj; 2991 2992 if (!mac_biba_enabled) 2993 return (0); 2994 2995 subj = SLOT(active_cred->cr_label); 2996 obj = SLOT(vnodelabel); 2997 2998 if (!mac_biba_dominate_effective(obj, subj)) 2999 return (EACCES); 3000 3001 return (0); 3002 } 3003 3004 static int 3005 mac_biba_check_vnode_write(struct ucred *active_cred, 3006 struct ucred *file_cred, struct vnode *vp, struct label *label) 3007 { 3008 struct mac_biba *subj, *obj; 3009 3010 if (!mac_biba_enabled || !revocation_enabled) 3011 return (0); 3012 3013 subj = SLOT(active_cred->cr_label); 3014 obj = SLOT(label); 3015 3016 if (!mac_biba_dominate_effective(subj, obj)) 3017 return (EACCES); 3018 3019 return (0); 3020 } 3021 3022 static struct mac_policy_ops mac_biba_ops = 3023 { 3024 .mpo_init = mac_biba_init, 3025 .mpo_init_bpfdesc_label = mac_biba_init_label, 3026 .mpo_init_cred_label = mac_biba_init_label, 3027 .mpo_init_devfsdirent_label = mac_biba_init_label, 3028 .mpo_init_ifnet_label = mac_biba_init_label, 3029 .mpo_init_inpcb_label = mac_biba_init_label_waitcheck, 3030 .mpo_init_sysv_msgmsg_label = mac_biba_init_label, 3031 .mpo_init_sysv_msgqueue_label = mac_biba_init_label, 3032 .mpo_init_sysv_sem_label = mac_biba_init_label, 3033 .mpo_init_sysv_shm_label = mac_biba_init_label, 3034 .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 3035 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 3036 .mpo_init_mount_label = mac_biba_init_label, 3037 .mpo_init_mount_fs_label = mac_biba_init_label, 3038 .mpo_init_pipe_label = mac_biba_init_label, 3039 .mpo_init_posix_sem_label = mac_biba_init_label, 3040 .mpo_init_socket_label = mac_biba_init_label_waitcheck, 3041 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 3042 .mpo_init_vnode_label = mac_biba_init_label, 3043 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 3044 .mpo_destroy_cred_label = mac_biba_destroy_label, 3045 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 3046 .mpo_destroy_ifnet_label = mac_biba_destroy_label, 3047 .mpo_destroy_inpcb_label = mac_biba_destroy_label, 3048 .mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label, 3049 .mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label, 3050 .mpo_destroy_sysv_sem_label = mac_biba_destroy_label, 3051 .mpo_destroy_sysv_shm_label = mac_biba_destroy_label, 3052 .mpo_destroy_ipq_label = mac_biba_destroy_label, 3053 .mpo_destroy_mbuf_label = mac_biba_destroy_label, 3054 .mpo_destroy_mount_label = mac_biba_destroy_label, 3055 .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 3056 .mpo_destroy_pipe_label = mac_biba_destroy_label, 3057 .mpo_destroy_posix_sem_label = mac_biba_destroy_label, 3058 .mpo_destroy_socket_label = mac_biba_destroy_label, 3059 .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 3060 .mpo_destroy_vnode_label = mac_biba_destroy_label, 3061 .mpo_copy_cred_label = mac_biba_copy_label, 3062 .mpo_copy_ifnet_label = mac_biba_copy_label, 3063 .mpo_copy_mbuf_label = mac_biba_copy_label, 3064 .mpo_copy_pipe_label = mac_biba_copy_label, 3065 .mpo_copy_socket_label = mac_biba_copy_label, 3066 .mpo_copy_vnode_label = mac_biba_copy_label, 3067 .mpo_externalize_cred_label = mac_biba_externalize_label, 3068 .mpo_externalize_ifnet_label = mac_biba_externalize_label, 3069 .mpo_externalize_pipe_label = mac_biba_externalize_label, 3070 .mpo_externalize_socket_label = mac_biba_externalize_label, 3071 .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 3072 .mpo_externalize_vnode_label = mac_biba_externalize_label, 3073 .mpo_internalize_cred_label = mac_biba_internalize_label, 3074 .mpo_internalize_ifnet_label = mac_biba_internalize_label, 3075 .mpo_internalize_pipe_label = mac_biba_internalize_label, 3076 .mpo_internalize_socket_label = mac_biba_internalize_label, 3077 .mpo_internalize_vnode_label = mac_biba_internalize_label, 3078 .mpo_create_devfs_device = mac_biba_create_devfs_device, 3079 .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 3080 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 3081 .mpo_create_mount = mac_biba_create_mount, 3082 .mpo_relabel_vnode = mac_biba_relabel_vnode, 3083 .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 3084 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 3085 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 3086 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 3087 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 3088 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 3089 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 3090 .mpo_create_pipe = mac_biba_create_pipe, 3091 .mpo_create_posix_sem = mac_biba_create_posix_sem, 3092 .mpo_create_socket = mac_biba_create_socket, 3093 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 3094 .mpo_relabel_pipe = mac_biba_relabel_pipe, 3095 .mpo_relabel_socket = mac_biba_relabel_socket, 3096 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 3097 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 3098 .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 3099 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 3100 .mpo_create_fragment = mac_biba_create_fragment, 3101 .mpo_create_ifnet = mac_biba_create_ifnet, 3102 .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket, 3103 .mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg, 3104 .mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue, 3105 .mpo_create_sysv_sem = mac_biba_create_sysv_sem, 3106 .mpo_create_sysv_shm = mac_biba_create_sysv_shm, 3107 .mpo_create_ipq = mac_biba_create_ipq, 3108 .mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb, 3109 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 3110 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 3111 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 3112 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 3113 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 3114 .mpo_fragment_match = mac_biba_fragment_match, 3115 .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 3116 .mpo_update_ipq = mac_biba_update_ipq, 3117 .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel, 3118 .mpo_create_proc0 = mac_biba_create_proc0, 3119 .mpo_create_proc1 = mac_biba_create_proc1, 3120 .mpo_relabel_cred = mac_biba_relabel_cred, 3121 .mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg, 3122 .mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue, 3123 .mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem, 3124 .mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm, 3125 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 3126 .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 3127 .mpo_check_cred_visible = mac_biba_check_cred_visible, 3128 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 3129 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 3130 .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver, 3131 .mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv, 3132 .mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid, 3133 .mpo_check_sysv_msqget = mac_biba_check_sysv_msqget, 3134 .mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd, 3135 .mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv, 3136 .mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl, 3137 .mpo_check_sysv_semctl = mac_biba_check_sysv_semctl, 3138 .mpo_check_sysv_semget = mac_biba_check_sysv_semget, 3139 .mpo_check_sysv_semop = mac_biba_check_sysv_semop, 3140 .mpo_check_sysv_shmat = mac_biba_check_sysv_shmat, 3141 .mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl, 3142 .mpo_check_sysv_shmget = mac_biba_check_sysv_shmget, 3143 .mpo_check_kld_load = mac_biba_check_kld_load, 3144 .mpo_check_kld_unload = mac_biba_check_kld_unload, 3145 .mpo_check_mount_stat = mac_biba_check_mount_stat, 3146 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 3147 .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 3148 .mpo_check_pipe_read = mac_biba_check_pipe_read, 3149 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 3150 .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 3151 .mpo_check_pipe_write = mac_biba_check_pipe_write, 3152 .mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write, 3153 .mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly, 3154 .mpo_check_posix_sem_open = mac_biba_check_posix_sem_write, 3155 .mpo_check_posix_sem_post = mac_biba_check_posix_sem_write, 3156 .mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write, 3157 .mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write, 3158 .mpo_check_proc_debug = mac_biba_check_proc_debug, 3159 .mpo_check_proc_sched = mac_biba_check_proc_sched, 3160 .mpo_check_proc_signal = mac_biba_check_proc_signal, 3161 .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 3162 .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 3163 .mpo_check_socket_visible = mac_biba_check_socket_visible, 3164 .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 3165 .mpo_check_system_acct = mac_biba_check_system_acct, 3166 .mpo_check_system_settime = mac_biba_check_system_settime, 3167 .mpo_check_system_swapon = mac_biba_check_system_swapon, 3168 .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 3169 .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 3170 .mpo_check_vnode_access = mac_biba_check_vnode_open, 3171 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 3172 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 3173 .mpo_check_vnode_create = mac_biba_check_vnode_create, 3174 .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 3175 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 3176 .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr, 3177 .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 3178 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 3179 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 3180 .mpo_check_vnode_link = mac_biba_check_vnode_link, 3181 .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr, 3182 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 3183 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 3184 .mpo_check_vnode_open = mac_biba_check_vnode_open, 3185 .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 3186 .mpo_check_vnode_read = mac_biba_check_vnode_read, 3187 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 3188 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 3189 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 3190 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 3191 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 3192 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 3193 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 3194 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 3195 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 3196 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 3197 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 3198 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 3199 .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 3200 .mpo_check_vnode_write = mac_biba_check_vnode_write, 3201 }; 3202 3203 MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 3204 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot); 3205