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