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