mac_biba.c revision 147091
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 147091 2005-06-07 05:03:28Z 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 mount *mp, struct cdev *dev, 784 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_from_mbuf(struct mbuf *oldmbuf, 1289 struct label *oldmbuflabel, struct mbuf *newmbuf, 1290 struct label *newmbuflabel) 1291{ 1292 struct mac_biba *source, *dest; 1293 1294 source = SLOT(oldmbuflabel); 1295 dest = SLOT(newmbuflabel); 1296 1297 /* 1298 * Because the source mbuf may not yet have been "created", 1299 * just initialized, we do a conditional copy. Since we don't 1300 * allow mbufs to have ranges, do a KASSERT to make sure that 1301 * doesn't happen. 1302 */ 1303 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1304 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1305 mac_biba_copy(source, dest); 1306} 1307 1308static void 1309mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1310 struct mbuf *mbuf, struct label *mbuflabel) 1311{ 1312 struct mac_biba *dest; 1313 1314 dest = SLOT(mbuflabel); 1315 1316 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1317} 1318 1319static void 1320mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1321 struct mbuf *mbuf, struct label *mbuflabel) 1322{ 1323 struct mac_biba *source, *dest; 1324 1325 source = SLOT(bpflabel); 1326 dest = SLOT(mbuflabel); 1327 1328 mac_biba_copy_effective(source, dest); 1329} 1330 1331static void 1332mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1333 struct mbuf *m, struct label *mbuflabel) 1334{ 1335 struct mac_biba *source, *dest; 1336 1337 source = SLOT(ifnetlabel); 1338 dest = SLOT(mbuflabel); 1339 1340 mac_biba_copy_effective(source, dest); 1341} 1342 1343static void 1344mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1345 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1346 struct mbuf *newmbuf, struct label *newmbuflabel) 1347{ 1348 struct mac_biba *source, *dest; 1349 1350 source = SLOT(oldmbuflabel); 1351 dest = SLOT(newmbuflabel); 1352 1353 mac_biba_copy_effective(source, dest); 1354} 1355 1356static void 1357mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1358 struct mbuf *newmbuf, struct label *newmbuflabel) 1359{ 1360 struct mac_biba *source, *dest; 1361 1362 source = SLOT(oldmbuflabel); 1363 dest = SLOT(newmbuflabel); 1364 1365 mac_biba_copy_effective(source, dest); 1366} 1367 1368static int 1369mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1370 struct ipq *ipq, struct label *ipqlabel) 1371{ 1372 struct mac_biba *a, *b; 1373 1374 a = SLOT(ipqlabel); 1375 b = SLOT(fragmentlabel); 1376 1377 return (mac_biba_equal_effective(a, b)); 1378} 1379 1380static void 1381mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1382 struct label *ifnetlabel, struct label *newlabel) 1383{ 1384 struct mac_biba *source, *dest; 1385 1386 source = SLOT(newlabel); 1387 dest = SLOT(ifnetlabel); 1388 1389 mac_biba_copy(source, dest); 1390} 1391 1392static void 1393mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1394 struct ipq *ipq, struct label *ipqlabel) 1395{ 1396 1397 /* NOOP: we only accept matching labels, so no need to update */ 1398} 1399 1400static void 1401mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1402 struct inpcb *inp, struct label *inplabel) 1403{ 1404 struct mac_biba *source, *dest; 1405 1406 source = SLOT(solabel); 1407 dest = SLOT(inplabel); 1408 1409 mac_biba_copy(source, dest); 1410} 1411 1412/* 1413 * Labeling event operations: processes. 1414 */ 1415static void 1416mac_biba_create_proc0(struct ucred *cred) 1417{ 1418 struct mac_biba *dest; 1419 1420 dest = SLOT(cred->cr_label); 1421 1422 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1423 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1424 MAC_BIBA_TYPE_HIGH, 0, NULL); 1425} 1426 1427static void 1428mac_biba_create_proc1(struct ucred *cred) 1429{ 1430 struct mac_biba *dest; 1431 1432 dest = SLOT(cred->cr_label); 1433 1434 mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1435 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1436 MAC_BIBA_TYPE_HIGH, 0, NULL); 1437} 1438 1439static void 1440mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1441{ 1442 struct mac_biba *source, *dest; 1443 1444 source = SLOT(newlabel); 1445 dest = SLOT(cred->cr_label); 1446 1447 mac_biba_copy(source, dest); 1448} 1449 1450/* 1451 * Label cleanup/flush operations 1452 */ 1453static void 1454mac_biba_cleanup_sysv_msgmsg(struct label *msglabel) 1455{ 1456 1457 bzero(SLOT(msglabel), sizeof(struct mac_biba)); 1458} 1459 1460static void 1461mac_biba_cleanup_sysv_msgqueue(struct label *msqlabel) 1462{ 1463 1464 bzero(SLOT(msqlabel), sizeof(struct mac_biba)); 1465} 1466 1467static void 1468mac_biba_cleanup_sysv_sem(struct label *semalabel) 1469{ 1470 1471 bzero(SLOT(semalabel), sizeof(struct mac_biba)); 1472} 1473 1474static void 1475mac_biba_cleanup_sysv_shm(struct label *shmlabel) 1476{ 1477 bzero(SLOT(shmlabel), sizeof(struct mac_biba)); 1478} 1479 1480/* 1481 * Access control checks. 1482 */ 1483static int 1484mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1485 struct ifnet *ifnet, struct label *ifnetlabel) 1486{ 1487 struct mac_biba *a, *b; 1488 1489 if (!mac_biba_enabled) 1490 return (0); 1491 1492 a = SLOT(bpflabel); 1493 b = SLOT(ifnetlabel); 1494 1495 if (mac_biba_equal_effective(a, b)) 1496 return (0); 1497 return (EACCES); 1498} 1499 1500static int 1501mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1502{ 1503 struct mac_biba *subj, *new; 1504 int error; 1505 1506 subj = SLOT(cred->cr_label); 1507 new = SLOT(newlabel); 1508 1509 /* 1510 * If there is a Biba label update for the credential, it may 1511 * be an update of the effective, range, or both. 1512 */ 1513 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1514 if (error) 1515 return (error); 1516 1517 /* 1518 * If the Biba label is to be changed, authorize as appropriate. 1519 */ 1520 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1521 /* 1522 * If the change request modifies both the Biba label 1523 * effective and range, check that the new effective will be 1524 * in the new range. 1525 */ 1526 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1527 MAC_BIBA_FLAGS_BOTH && 1528 !mac_biba_effective_in_range(new, new)) 1529 return (EINVAL); 1530 1531 /* 1532 * To change the Biba effective label on a credential, the 1533 * new effective label must be in the current range. 1534 */ 1535 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE && 1536 !mac_biba_effective_in_range(new, subj)) 1537 return (EPERM); 1538 1539 /* 1540 * To change the Biba range on a credential, the new 1541 * range label must be in the current range. 1542 */ 1543 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1544 !mac_biba_range_in_range(new, subj)) 1545 return (EPERM); 1546 1547 /* 1548 * To have EQUAL in any component of the new credential 1549 * Biba label, the subject must already have EQUAL in 1550 * their label. 1551 */ 1552 if (mac_biba_contains_equal(new)) { 1553 error = mac_biba_subject_privileged(subj); 1554 if (error) 1555 return (error); 1556 } 1557 } 1558 1559 return (0); 1560} 1561 1562static int 1563mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1564{ 1565 struct mac_biba *subj, *obj; 1566 1567 if (!mac_biba_enabled) 1568 return (0); 1569 1570 subj = SLOT(u1->cr_label); 1571 obj = SLOT(u2->cr_label); 1572 1573 /* XXX: range */ 1574 if (!mac_biba_dominate_effective(obj, subj)) 1575 return (ESRCH); 1576 1577 return (0); 1578} 1579 1580static int 1581mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1582 struct label *ifnetlabel, struct label *newlabel) 1583{ 1584 struct mac_biba *subj, *new; 1585 int error; 1586 1587 subj = SLOT(cred->cr_label); 1588 new = SLOT(newlabel); 1589 1590 /* 1591 * If there is a Biba label update for the interface, it may 1592 * be an update of the effective, range, or both. 1593 */ 1594 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1595 if (error) 1596 return (error); 1597 1598 /* 1599 * Relabling network interfaces requires Biba privilege. 1600 */ 1601 error = mac_biba_subject_privileged(subj); 1602 if (error) 1603 return (error); 1604 1605 return (0); 1606} 1607 1608static int 1609mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1610 struct mbuf *m, struct label *mbuflabel) 1611{ 1612 struct mac_biba *p, *i; 1613 1614 if (!mac_biba_enabled) 1615 return (0); 1616 1617 p = SLOT(mbuflabel); 1618 i = SLOT(ifnetlabel); 1619 1620 return (mac_biba_effective_in_range(p, i) ? 0 : EACCES); 1621} 1622 1623static int 1624mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1625 struct mbuf *m, struct label *mlabel) 1626{ 1627 struct mac_biba *p, *i; 1628 1629 if (!mac_biba_enabled) 1630 return (0); 1631 1632 p = SLOT(mlabel); 1633 i = SLOT(inplabel); 1634 1635 return (mac_biba_equal_effective(p, i) ? 0 : EACCES); 1636} 1637 1638static int 1639mac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr, 1640 struct label *msglabel) 1641{ 1642 struct mac_biba *subj, *obj; 1643 1644 if (!mac_biba_enabled) 1645 return (0); 1646 1647 subj = SLOT(cred->cr_label); 1648 obj = SLOT(msglabel); 1649 1650 if (!mac_biba_dominate_effective(obj, subj)) 1651 return (EACCES); 1652 1653 return (0); 1654} 1655 1656static int 1657mac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr, 1658 struct label *msglabel) 1659{ 1660 struct mac_biba *subj, *obj; 1661 1662 if (!mac_biba_enabled) 1663 return (0); 1664 1665 subj = SLOT(cred->cr_label); 1666 obj = SLOT(msglabel); 1667 1668 if (!mac_biba_dominate_effective(subj, obj)) 1669 return (EACCES); 1670 1671 return (0); 1672} 1673 1674static int 1675mac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1676 struct label *msqklabel) 1677{ 1678 struct mac_biba *subj, *obj; 1679 1680 if (!mac_biba_enabled) 1681 return (0); 1682 1683 subj = SLOT(cred->cr_label); 1684 obj = SLOT(msqklabel); 1685 1686 if (!mac_biba_dominate_effective(obj, subj)) 1687 return (EACCES); 1688 1689 return (0); 1690} 1691 1692static int 1693mac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1694 struct label *msqklabel) 1695{ 1696 struct mac_biba *subj, *obj; 1697 1698 if (!mac_biba_enabled) 1699 return (0); 1700 1701 subj = SLOT(cred->cr_label); 1702 obj = SLOT(msqklabel); 1703 1704 if (!mac_biba_dominate_effective(subj, obj)) 1705 return (EACCES); 1706 1707 return (0); 1708} 1709 1710static int 1711mac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1712 struct label *msqklabel) 1713{ 1714 struct mac_biba *subj, *obj; 1715 1716 if (!mac_biba_enabled) 1717 return (0); 1718 1719 subj = SLOT(cred->cr_label); 1720 obj = SLOT(msqklabel); 1721 1722 if (!mac_biba_dominate_effective(obj, subj)) 1723 return (EACCES); 1724 1725 return (0); 1726} 1727 1728 1729static int 1730mac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1731 struct label *msqklabel, int cmd) 1732{ 1733 struct mac_biba *subj, *obj; 1734 1735 if (!mac_biba_enabled) 1736 return (0); 1737 1738 subj = SLOT(cred->cr_label); 1739 obj = SLOT(msqklabel); 1740 1741 switch(cmd) { 1742 case IPC_RMID: 1743 case IPC_SET: 1744 if (!mac_biba_dominate_effective(subj, obj)) 1745 return (EACCES); 1746 break; 1747 1748 case IPC_STAT: 1749 if (!mac_biba_dominate_effective(obj, subj)) 1750 return (EACCES); 1751 break; 1752 1753 default: 1754 return (EACCES); 1755 } 1756 1757 return (0); 1758} 1759 1760static int 1761mac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1762 struct label *semaklabel, int cmd) 1763{ 1764 struct mac_biba *subj, *obj; 1765 1766 if (!mac_biba_enabled) 1767 return (0); 1768 1769 subj = SLOT(cred->cr_label); 1770 obj = SLOT(semaklabel); 1771 1772 switch(cmd) { 1773 case IPC_RMID: 1774 case IPC_SET: 1775 case SETVAL: 1776 case SETALL: 1777 if (!mac_biba_dominate_effective(subj, obj)) 1778 return (EACCES); 1779 break; 1780 1781 case IPC_STAT: 1782 case GETVAL: 1783 case GETPID: 1784 case GETNCNT: 1785 case GETZCNT: 1786 case GETALL: 1787 if (!mac_biba_dominate_effective(obj, subj)) 1788 return (EACCES); 1789 break; 1790 1791 default: 1792 return (EACCES); 1793 } 1794 1795 return (0); 1796} 1797 1798 1799static int 1800mac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr, 1801 struct label *semaklabel) 1802{ 1803 struct mac_biba *subj, *obj; 1804 1805 if (!mac_biba_enabled) 1806 return (0); 1807 1808 subj = SLOT(cred->cr_label); 1809 obj = SLOT(semaklabel); 1810 1811 if (!mac_biba_dominate_effective(obj, subj)) 1812 return (EACCES); 1813 1814 return (0); 1815} 1816 1817 1818static int 1819mac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr, 1820 struct label *semaklabel, size_t accesstype) 1821{ 1822 struct mac_biba *subj, *obj; 1823 1824 if (!mac_biba_enabled) 1825 return (0); 1826 1827 subj = SLOT(cred->cr_label); 1828 obj = SLOT(semaklabel); 1829 1830 if (accesstype & SEM_R) 1831 if (!mac_biba_dominate_effective(obj, subj)) 1832 return (EACCES); 1833 1834 if (accesstype & SEM_A) 1835 if (!mac_biba_dominate_effective(subj, obj)) 1836 return (EACCES); 1837 1838 return (0); 1839} 1840 1841static int 1842mac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 1843 struct label *shmseglabel, int shmflg) 1844{ 1845 struct mac_biba *subj, *obj; 1846 1847 if (!mac_biba_enabled) 1848 return (0); 1849 1850 subj = SLOT(cred->cr_label); 1851 obj = SLOT(shmseglabel); 1852 1853 if (!mac_biba_dominate_effective(obj, subj)) 1854 return (EACCES); 1855 if ((shmflg & SHM_RDONLY) == 0) { 1856 if (!mac_biba_dominate_effective(subj, obj)) 1857 return (EACCES); 1858 } 1859 1860 return (0); 1861} 1862 1863static int 1864mac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 1865 struct label *shmseglabel, int cmd) 1866{ 1867 struct mac_biba *subj, *obj; 1868 1869 if (!mac_biba_enabled) 1870 return (0); 1871 1872 subj = SLOT(cred->cr_label); 1873 obj = SLOT(shmseglabel); 1874 1875 switch(cmd) { 1876 case IPC_RMID: 1877 case IPC_SET: 1878 if (!mac_biba_dominate_effective(subj, obj)) 1879 return (EACCES); 1880 break; 1881 1882 case IPC_STAT: 1883 case SHM_STAT: 1884 if (!mac_biba_dominate_effective(obj, subj)) 1885 return (EACCES); 1886 break; 1887 1888 default: 1889 return (EACCES); 1890 } 1891 1892 return (0); 1893} 1894 1895static int 1896mac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 1897 struct label *shmseglabel, int shmflg) 1898{ 1899 struct mac_biba *subj, *obj; 1900 1901 if (!mac_biba_enabled) 1902 return (0); 1903 1904 subj = SLOT(cred->cr_label); 1905 obj = SLOT(shmseglabel); 1906 1907 if (!mac_biba_dominate_effective(obj, subj)) 1908 return (EACCES); 1909 1910 return (0); 1911} 1912 1913static int 1914mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1915 struct label *label) 1916{ 1917 struct mac_biba *subj, *obj; 1918 int error; 1919 1920 if (!mac_biba_enabled) 1921 return (0); 1922 1923 subj = SLOT(cred->cr_label); 1924 1925 error = mac_biba_subject_privileged(subj); 1926 if (error) 1927 return (error); 1928 1929 obj = SLOT(label); 1930 if (!mac_biba_high_effective(obj)) 1931 return (EACCES); 1932 1933 return (0); 1934} 1935 1936 1937static int 1938mac_biba_check_kld_unload(struct ucred *cred) 1939{ 1940 struct mac_biba *subj; 1941 1942 if (!mac_biba_enabled) 1943 return (0); 1944 1945 subj = SLOT(cred->cr_label); 1946 1947 return (mac_biba_subject_privileged(subj)); 1948} 1949 1950static int 1951mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1952 struct label *mntlabel) 1953{ 1954 struct mac_biba *subj, *obj; 1955 1956 if (!mac_biba_enabled) 1957 return (0); 1958 1959 subj = SLOT(cred->cr_label); 1960 obj = SLOT(mntlabel); 1961 1962 if (!mac_biba_dominate_effective(obj, subj)) 1963 return (EACCES); 1964 1965 return (0); 1966} 1967 1968static int 1969mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1970 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1971{ 1972 1973 if(!mac_biba_enabled) 1974 return (0); 1975 1976 /* XXX: This will be implemented soon... */ 1977 1978 return (0); 1979} 1980 1981static int 1982mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp, 1983 struct label *pipelabel) 1984{ 1985 struct mac_biba *subj, *obj; 1986 1987 if (!mac_biba_enabled) 1988 return (0); 1989 1990 subj = SLOT(cred->cr_label); 1991 obj = SLOT((pipelabel)); 1992 1993 if (!mac_biba_dominate_effective(obj, subj)) 1994 return (EACCES); 1995 1996 return (0); 1997} 1998 1999static int 2000mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp, 2001 struct label *pipelabel) 2002{ 2003 struct mac_biba *subj, *obj; 2004 2005 if (!mac_biba_enabled) 2006 return (0); 2007 2008 subj = SLOT(cred->cr_label); 2009 obj = SLOT((pipelabel)); 2010 2011 if (!mac_biba_dominate_effective(obj, subj)) 2012 return (EACCES); 2013 2014 return (0); 2015} 2016 2017static int 2018mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 2019 struct label *pipelabel, struct label *newlabel) 2020{ 2021 struct mac_biba *subj, *obj, *new; 2022 int error; 2023 2024 new = SLOT(newlabel); 2025 subj = SLOT(cred->cr_label); 2026 obj = SLOT(pipelabel); 2027 2028 /* 2029 * If there is a Biba label update for a pipe, it must be a 2030 * effective update. 2031 */ 2032 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2033 if (error) 2034 return (error); 2035 2036 /* 2037 * To perform a relabel of a pipe (Biba label or not), Biba must 2038 * authorize the relabel. 2039 */ 2040 if (!mac_biba_effective_in_range(obj, subj)) 2041 return (EPERM); 2042 2043 /* 2044 * If the Biba label is to be changed, authorize as appropriate. 2045 */ 2046 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2047 /* 2048 * To change the Biba label on a pipe, the new pipe label 2049 * must be in the subject range. 2050 */ 2051 if (!mac_biba_effective_in_range(new, subj)) 2052 return (EPERM); 2053 2054 /* 2055 * To change the Biba label on a pipe to be EQUAL, the 2056 * subject must have appropriate privilege. 2057 */ 2058 if (mac_biba_contains_equal(new)) { 2059 error = mac_biba_subject_privileged(subj); 2060 if (error) 2061 return (error); 2062 } 2063 } 2064 2065 return (0); 2066} 2067 2068static int 2069mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp, 2070 struct label *pipelabel) 2071{ 2072 struct mac_biba *subj, *obj; 2073 2074 if (!mac_biba_enabled) 2075 return (0); 2076 2077 subj = SLOT(cred->cr_label); 2078 obj = SLOT((pipelabel)); 2079 2080 if (!mac_biba_dominate_effective(obj, subj)) 2081 return (EACCES); 2082 2083 return (0); 2084} 2085 2086static int 2087mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp, 2088 struct label *pipelabel) 2089{ 2090 struct mac_biba *subj, *obj; 2091 2092 if (!mac_biba_enabled) 2093 return (0); 2094 2095 subj = SLOT(cred->cr_label); 2096 obj = SLOT((pipelabel)); 2097 2098 if (!mac_biba_dominate_effective(subj, obj)) 2099 return (EACCES); 2100 2101 return (0); 2102} 2103 2104static int 2105mac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr, 2106 struct label *ks_label) 2107{ 2108 struct mac_biba *subj, *obj; 2109 2110 if (!mac_biba_enabled) 2111 return (0); 2112 2113 subj = SLOT(cred->cr_label); 2114 obj = SLOT(ks_label); 2115 2116 if (!mac_biba_dominate_effective(subj, obj)) 2117 return (EACCES); 2118 2119 return (0); 2120} 2121 2122static int 2123mac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr, 2124 struct label *ks_label) 2125{ 2126 struct mac_biba *subj, *obj; 2127 2128 if (!mac_biba_enabled) 2129 return (0); 2130 2131 subj = SLOT(cred->cr_label); 2132 obj = SLOT(ks_label); 2133 2134 if (!mac_biba_dominate_effective(obj, subj)) 2135 return (EACCES); 2136 2137 return (0); 2138} 2139 2140static int 2141mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 2142{ 2143 struct mac_biba *subj, *obj; 2144 2145 if (!mac_biba_enabled) 2146 return (0); 2147 2148 subj = SLOT(cred->cr_label); 2149 obj = SLOT(proc->p_ucred->cr_label); 2150 2151 /* XXX: range checks */ 2152 if (!mac_biba_dominate_effective(obj, subj)) 2153 return (ESRCH); 2154 if (!mac_biba_dominate_effective(subj, obj)) 2155 return (EACCES); 2156 2157 return (0); 2158} 2159 2160static int 2161mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 2162{ 2163 struct mac_biba *subj, *obj; 2164 2165 if (!mac_biba_enabled) 2166 return (0); 2167 2168 subj = SLOT(cred->cr_label); 2169 obj = SLOT(proc->p_ucred->cr_label); 2170 2171 /* XXX: range checks */ 2172 if (!mac_biba_dominate_effective(obj, subj)) 2173 return (ESRCH); 2174 if (!mac_biba_dominate_effective(subj, obj)) 2175 return (EACCES); 2176 2177 return (0); 2178} 2179 2180static int 2181mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2182{ 2183 struct mac_biba *subj, *obj; 2184 2185 if (!mac_biba_enabled) 2186 return (0); 2187 2188 subj = SLOT(cred->cr_label); 2189 obj = SLOT(proc->p_ucred->cr_label); 2190 2191 /* XXX: range checks */ 2192 if (!mac_biba_dominate_effective(obj, subj)) 2193 return (ESRCH); 2194 if (!mac_biba_dominate_effective(subj, obj)) 2195 return (EACCES); 2196 2197 return (0); 2198} 2199 2200static int 2201mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 2202 struct mbuf *m, struct label *mbuflabel) 2203{ 2204 struct mac_biba *p, *s; 2205 2206 if (!mac_biba_enabled) 2207 return (0); 2208 2209 p = SLOT(mbuflabel); 2210 s = SLOT(socketlabel); 2211 2212 return (mac_biba_equal_effective(p, s) ? 0 : EACCES); 2213} 2214 2215static int 2216mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 2217 struct label *socketlabel, struct label *newlabel) 2218{ 2219 struct mac_biba *subj, *obj, *new; 2220 int error; 2221 2222 new = SLOT(newlabel); 2223 subj = SLOT(cred->cr_label); 2224 obj = SLOT(socketlabel); 2225 2226 /* 2227 * If there is a Biba label update for the socket, it may be 2228 * an update of effective. 2229 */ 2230 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2231 if (error) 2232 return (error); 2233 2234 /* 2235 * To relabel a socket, the old socket effective must be in the subject 2236 * range. 2237 */ 2238 if (!mac_biba_effective_in_range(obj, subj)) 2239 return (EPERM); 2240 2241 /* 2242 * If the Biba label is to be changed, authorize as appropriate. 2243 */ 2244 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2245 /* 2246 * To relabel a socket, the new socket effective must be in 2247 * the subject range. 2248 */ 2249 if (!mac_biba_effective_in_range(new, subj)) 2250 return (EPERM); 2251 2252 /* 2253 * To change the Biba label on the socket to contain EQUAL, 2254 * the subject must have appropriate privilege. 2255 */ 2256 if (mac_biba_contains_equal(new)) { 2257 error = mac_biba_subject_privileged(subj); 2258 if (error) 2259 return (error); 2260 } 2261 } 2262 2263 return (0); 2264} 2265 2266static int 2267mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 2268 struct label *socketlabel) 2269{ 2270 struct mac_biba *subj, *obj; 2271 2272 if (!mac_biba_enabled) 2273 return (0); 2274 2275 subj = SLOT(cred->cr_label); 2276 obj = SLOT(socketlabel); 2277 2278 if (!mac_biba_dominate_effective(obj, subj)) 2279 return (ENOENT); 2280 2281 return (0); 2282} 2283 2284static int 2285mac_biba_check_sysarch_ioperm(struct ucred *cred) 2286{ 2287 struct mac_biba *subj; 2288 int error; 2289 2290 if (!mac_biba_enabled) 2291 return (0); 2292 2293 subj = SLOT(cred->cr_label); 2294 2295 error = mac_biba_subject_privileged(subj); 2296 if (error) 2297 return (error); 2298 2299 return (0); 2300} 2301 2302static int 2303mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 2304 struct label *label) 2305{ 2306 struct mac_biba *subj, *obj; 2307 int error; 2308 2309 if (!mac_biba_enabled) 2310 return (0); 2311 2312 subj = SLOT(cred->cr_label); 2313 2314 error = mac_biba_subject_privileged(subj); 2315 if (error) 2316 return (error); 2317 2318 if (label == NULL) 2319 return (0); 2320 2321 obj = SLOT(label); 2322 if (!mac_biba_high_effective(obj)) 2323 return (EACCES); 2324 2325 return (0); 2326} 2327 2328static int 2329mac_biba_check_system_settime(struct ucred *cred) 2330{ 2331 struct mac_biba *subj; 2332 int error; 2333 2334 if (!mac_biba_enabled) 2335 return (0); 2336 2337 subj = SLOT(cred->cr_label); 2338 2339 error = mac_biba_subject_privileged(subj); 2340 if (error) 2341 return (error); 2342 2343 return (0); 2344} 2345 2346static int 2347mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 2348 struct label *label) 2349{ 2350 struct mac_biba *subj, *obj; 2351 int error; 2352 2353 if (!mac_biba_enabled) 2354 return (0); 2355 2356 subj = SLOT(cred->cr_label); 2357 obj = SLOT(label); 2358 2359 error = mac_biba_subject_privileged(subj); 2360 if (error) 2361 return (error); 2362 2363 if (!mac_biba_high_effective(obj)) 2364 return (EACCES); 2365 2366 return (0); 2367} 2368 2369static int 2370mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 2371 struct label *label) 2372{ 2373 struct mac_biba *subj, *obj; 2374 int error; 2375 2376 if (!mac_biba_enabled) 2377 return (0); 2378 2379 subj = SLOT(cred->cr_label); 2380 obj = SLOT(label); 2381 2382 error = mac_biba_subject_privileged(subj); 2383 if (error) 2384 return (error); 2385 2386 return (0); 2387} 2388 2389static int 2390mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2391 void *arg1, int arg2, struct sysctl_req *req) 2392{ 2393 struct mac_biba *subj; 2394 int error; 2395 2396 if (!mac_biba_enabled) 2397 return (0); 2398 2399 subj = SLOT(cred->cr_label); 2400 2401 /* 2402 * Treat sysctl variables without CTLFLAG_ANYBODY flag as 2403 * biba/high, but also require privilege to change them. 2404 */ 2405 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2406 if (!mac_biba_subject_dominate_high(subj)) 2407 return (EACCES); 2408 2409 error = mac_biba_subject_privileged(subj); 2410 if (error) 2411 return (error); 2412 } 2413 2414 return (0); 2415} 2416 2417static int 2418mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2419 struct label *dlabel) 2420{ 2421 struct mac_biba *subj, *obj; 2422 2423 if (!mac_biba_enabled) 2424 return (0); 2425 2426 subj = SLOT(cred->cr_label); 2427 obj = SLOT(dlabel); 2428 2429 if (!mac_biba_dominate_effective(obj, subj)) 2430 return (EACCES); 2431 2432 return (0); 2433} 2434 2435static int 2436mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2437 struct label *dlabel) 2438{ 2439 struct mac_biba *subj, *obj; 2440 2441 if (!mac_biba_enabled) 2442 return (0); 2443 2444 subj = SLOT(cred->cr_label); 2445 obj = SLOT(dlabel); 2446 2447 if (!mac_biba_dominate_effective(obj, subj)) 2448 return (EACCES); 2449 2450 return (0); 2451} 2452 2453static int 2454mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2455 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2456{ 2457 struct mac_biba *subj, *obj; 2458 2459 if (!mac_biba_enabled) 2460 return (0); 2461 2462 subj = SLOT(cred->cr_label); 2463 obj = SLOT(dlabel); 2464 2465 if (!mac_biba_dominate_effective(subj, obj)) 2466 return (EACCES); 2467 2468 return (0); 2469} 2470 2471static int 2472mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2473 struct label *dlabel, struct vnode *vp, struct label *label, 2474 struct componentname *cnp) 2475{ 2476 struct mac_biba *subj, *obj; 2477 2478 if (!mac_biba_enabled) 2479 return (0); 2480 2481 subj = SLOT(cred->cr_label); 2482 obj = SLOT(dlabel); 2483 2484 if (!mac_biba_dominate_effective(subj, obj)) 2485 return (EACCES); 2486 2487 obj = SLOT(label); 2488 2489 if (!mac_biba_dominate_effective(subj, obj)) 2490 return (EACCES); 2491 2492 return (0); 2493} 2494 2495static int 2496mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2497 struct label *label, acl_type_t type) 2498{ 2499 struct mac_biba *subj, *obj; 2500 2501 if (!mac_biba_enabled) 2502 return (0); 2503 2504 subj = SLOT(cred->cr_label); 2505 obj = SLOT(label); 2506 2507 if (!mac_biba_dominate_effective(subj, obj)) 2508 return (EACCES); 2509 2510 return (0); 2511} 2512 2513static int 2514mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2515 struct label *label, int attrnamespace, const char *name) 2516{ 2517 struct mac_biba *subj, *obj; 2518 2519 if (!mac_biba_enabled) 2520 return (0); 2521 2522 subj = SLOT(cred->cr_label); 2523 obj = SLOT(label); 2524 2525 if (!mac_biba_dominate_effective(subj, obj)) 2526 return (EACCES); 2527 2528 return (0); 2529} 2530 2531static int 2532mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2533 struct label *label, struct image_params *imgp, 2534 struct label *execlabel) 2535{ 2536 struct mac_biba *subj, *obj, *exec; 2537 int error; 2538 2539 if (execlabel != NULL) { 2540 /* 2541 * We currently don't permit labels to be changed at 2542 * exec-time as part of Biba, so disallow non-NULL 2543 * Biba label elements in the execlabel. 2544 */ 2545 exec = SLOT(execlabel); 2546 error = biba_atmostflags(exec, 0); 2547 if (error) 2548 return (error); 2549 } 2550 2551 if (!mac_biba_enabled) 2552 return (0); 2553 2554 subj = SLOT(cred->cr_label); 2555 obj = SLOT(label); 2556 2557 if (!mac_biba_dominate_effective(obj, subj)) 2558 return (EACCES); 2559 2560 return (0); 2561} 2562 2563static int 2564mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2565 struct label *label, acl_type_t type) 2566{ 2567 struct mac_biba *subj, *obj; 2568 2569 if (!mac_biba_enabled) 2570 return (0); 2571 2572 subj = SLOT(cred->cr_label); 2573 obj = SLOT(label); 2574 2575 if (!mac_biba_dominate_effective(obj, subj)) 2576 return (EACCES); 2577 2578 return (0); 2579} 2580 2581static int 2582mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2583 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2584{ 2585 struct mac_biba *subj, *obj; 2586 2587 if (!mac_biba_enabled) 2588 return (0); 2589 2590 subj = SLOT(cred->cr_label); 2591 obj = SLOT(label); 2592 2593 if (!mac_biba_dominate_effective(obj, subj)) 2594 return (EACCES); 2595 2596 return (0); 2597} 2598 2599static int 2600mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2601 struct label *dlabel, struct vnode *vp, struct label *label, 2602 struct componentname *cnp) 2603{ 2604 struct mac_biba *subj, *obj; 2605 2606 if (!mac_biba_enabled) 2607 return (0); 2608 2609 subj = SLOT(cred->cr_label); 2610 obj = SLOT(dlabel); 2611 2612 if (!mac_biba_dominate_effective(subj, obj)) 2613 return (EACCES); 2614 2615 obj = SLOT(label); 2616 2617 if (!mac_biba_dominate_effective(subj, obj)) 2618 return (EACCES); 2619 2620 return (0); 2621} 2622 2623static int 2624mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2625 struct label *label, int attrnamespace) 2626{ 2627 struct mac_biba *subj, *obj; 2628 2629 if (!mac_biba_enabled) 2630 return (0); 2631 2632 subj = SLOT(cred->cr_label); 2633 obj = SLOT(label); 2634 2635 if (!mac_biba_dominate_effective(obj, subj)) 2636 return (EACCES); 2637 2638 return (0); 2639} 2640 2641static int 2642mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2643 struct label *dlabel, struct componentname *cnp) 2644{ 2645 struct mac_biba *subj, *obj; 2646 2647 if (!mac_biba_enabled) 2648 return (0); 2649 2650 subj = SLOT(cred->cr_label); 2651 obj = SLOT(dlabel); 2652 2653 if (!mac_biba_dominate_effective(obj, subj)) 2654 return (EACCES); 2655 2656 return (0); 2657} 2658 2659static int 2660mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2661 struct label *label, int prot, int flags) 2662{ 2663 struct mac_biba *subj, *obj; 2664 2665 /* 2666 * Rely on the use of open()-time protections to handle 2667 * non-revocation cases. 2668 */ 2669 if (!mac_biba_enabled || !revocation_enabled) 2670 return (0); 2671 2672 subj = SLOT(cred->cr_label); 2673 obj = SLOT(label); 2674 2675 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2676 if (!mac_biba_dominate_effective(obj, subj)) 2677 return (EACCES); 2678 } 2679 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2680 if (!mac_biba_dominate_effective(subj, obj)) 2681 return (EACCES); 2682 } 2683 2684 return (0); 2685} 2686 2687static int 2688mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2689 struct label *vnodelabel, int acc_mode) 2690{ 2691 struct mac_biba *subj, *obj; 2692 2693 if (!mac_biba_enabled) 2694 return (0); 2695 2696 subj = SLOT(cred->cr_label); 2697 obj = SLOT(vnodelabel); 2698 2699 /* XXX privilege override for admin? */ 2700 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2701 if (!mac_biba_dominate_effective(obj, subj)) 2702 return (EACCES); 2703 } 2704 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2705 if (!mac_biba_dominate_effective(subj, obj)) 2706 return (EACCES); 2707 } 2708 2709 return (0); 2710} 2711 2712static int 2713mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2714 struct vnode *vp, struct label *label) 2715{ 2716 struct mac_biba *subj, *obj; 2717 2718 if (!mac_biba_enabled || !revocation_enabled) 2719 return (0); 2720 2721 subj = SLOT(active_cred->cr_label); 2722 obj = SLOT(label); 2723 2724 if (!mac_biba_dominate_effective(obj, subj)) 2725 return (EACCES); 2726 2727 return (0); 2728} 2729 2730static int 2731mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2732 struct vnode *vp, struct label *label) 2733{ 2734 struct mac_biba *subj, *obj; 2735 2736 if (!mac_biba_enabled || !revocation_enabled) 2737 return (0); 2738 2739 subj = SLOT(active_cred->cr_label); 2740 obj = SLOT(label); 2741 2742 if (!mac_biba_dominate_effective(obj, subj)) 2743 return (EACCES); 2744 2745 return (0); 2746} 2747 2748static int 2749mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2750 struct label *dlabel) 2751{ 2752 struct mac_biba *subj, *obj; 2753 2754 if (!mac_biba_enabled) 2755 return (0); 2756 2757 subj = SLOT(cred->cr_label); 2758 obj = SLOT(dlabel); 2759 2760 if (!mac_biba_dominate_effective(obj, subj)) 2761 return (EACCES); 2762 2763 return (0); 2764} 2765 2766static int 2767mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2768 struct label *label) 2769{ 2770 struct mac_biba *subj, *obj; 2771 2772 if (!mac_biba_enabled) 2773 return (0); 2774 2775 subj = SLOT(cred->cr_label); 2776 obj = SLOT(label); 2777 2778 if (!mac_biba_dominate_effective(obj, subj)) 2779 return (EACCES); 2780 2781 return (0); 2782} 2783 2784static int 2785mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2786 struct label *vnodelabel, struct label *newlabel) 2787{ 2788 struct mac_biba *old, *new, *subj; 2789 int error; 2790 2791 old = SLOT(vnodelabel); 2792 new = SLOT(newlabel); 2793 subj = SLOT(cred->cr_label); 2794 2795 /* 2796 * If there is a Biba label update for the vnode, it must be a 2797 * effective label. 2798 */ 2799 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2800 if (error) 2801 return (error); 2802 2803 /* 2804 * To perform a relabel of the vnode (Biba label or not), Biba must 2805 * authorize the relabel. 2806 */ 2807 if (!mac_biba_effective_in_range(old, subj)) 2808 return (EPERM); 2809 2810 /* 2811 * If the Biba label is to be changed, authorize as appropriate. 2812 */ 2813 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2814 /* 2815 * To change the Biba label on a vnode, the new vnode label 2816 * must be in the subject range. 2817 */ 2818 if (!mac_biba_effective_in_range(new, subj)) 2819 return (EPERM); 2820 2821 /* 2822 * To change the Biba label on the vnode to be EQUAL, 2823 * the subject must have appropriate privilege. 2824 */ 2825 if (mac_biba_contains_equal(new)) { 2826 error = mac_biba_subject_privileged(subj); 2827 if (error) 2828 return (error); 2829 } 2830 } 2831 2832 return (0); 2833} 2834 2835static int 2836mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2837 struct label *dlabel, struct vnode *vp, struct label *label, 2838 struct componentname *cnp) 2839{ 2840 struct mac_biba *subj, *obj; 2841 2842 if (!mac_biba_enabled) 2843 return (0); 2844 2845 subj = SLOT(cred->cr_label); 2846 obj = SLOT(dlabel); 2847 2848 if (!mac_biba_dominate_effective(subj, obj)) 2849 return (EACCES); 2850 2851 obj = SLOT(label); 2852 2853 if (!mac_biba_dominate_effective(subj, obj)) 2854 return (EACCES); 2855 2856 return (0); 2857} 2858 2859static int 2860mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2861 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2862 struct componentname *cnp) 2863{ 2864 struct mac_biba *subj, *obj; 2865 2866 if (!mac_biba_enabled) 2867 return (0); 2868 2869 subj = SLOT(cred->cr_label); 2870 obj = SLOT(dlabel); 2871 2872 if (!mac_biba_dominate_effective(subj, obj)) 2873 return (EACCES); 2874 2875 if (vp != NULL) { 2876 obj = SLOT(label); 2877 2878 if (!mac_biba_dominate_effective(subj, obj)) 2879 return (EACCES); 2880 } 2881 2882 return (0); 2883} 2884 2885static int 2886mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2887 struct label *label) 2888{ 2889 struct mac_biba *subj, *obj; 2890 2891 if (!mac_biba_enabled) 2892 return (0); 2893 2894 subj = SLOT(cred->cr_label); 2895 obj = SLOT(label); 2896 2897 if (!mac_biba_dominate_effective(subj, obj)) 2898 return (EACCES); 2899 2900 return (0); 2901} 2902 2903static int 2904mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2905 struct label *label, acl_type_t type, struct acl *acl) 2906{ 2907 struct mac_biba *subj, *obj; 2908 2909 if (!mac_biba_enabled) 2910 return (0); 2911 2912 subj = SLOT(cred->cr_label); 2913 obj = SLOT(label); 2914 2915 if (!mac_biba_dominate_effective(subj, obj)) 2916 return (EACCES); 2917 2918 return (0); 2919} 2920 2921static int 2922mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2923 struct label *vnodelabel, int attrnamespace, const char *name, 2924 struct uio *uio) 2925{ 2926 struct mac_biba *subj, *obj; 2927 2928 if (!mac_biba_enabled) 2929 return (0); 2930 2931 subj = SLOT(cred->cr_label); 2932 obj = SLOT(vnodelabel); 2933 2934 if (!mac_biba_dominate_effective(subj, obj)) 2935 return (EACCES); 2936 2937 /* XXX: protect the MAC EA in a special way? */ 2938 2939 return (0); 2940} 2941 2942static int 2943mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2944 struct label *vnodelabel, u_long flags) 2945{ 2946 struct mac_biba *subj, *obj; 2947 2948 if (!mac_biba_enabled) 2949 return (0); 2950 2951 subj = SLOT(cred->cr_label); 2952 obj = SLOT(vnodelabel); 2953 2954 if (!mac_biba_dominate_effective(subj, obj)) 2955 return (EACCES); 2956 2957 return (0); 2958} 2959 2960static int 2961mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2962 struct label *vnodelabel, mode_t mode) 2963{ 2964 struct mac_biba *subj, *obj; 2965 2966 if (!mac_biba_enabled) 2967 return (0); 2968 2969 subj = SLOT(cred->cr_label); 2970 obj = SLOT(vnodelabel); 2971 2972 if (!mac_biba_dominate_effective(subj, obj)) 2973 return (EACCES); 2974 2975 return (0); 2976} 2977 2978static int 2979mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2980 struct label *vnodelabel, uid_t uid, gid_t gid) 2981{ 2982 struct mac_biba *subj, *obj; 2983 2984 if (!mac_biba_enabled) 2985 return (0); 2986 2987 subj = SLOT(cred->cr_label); 2988 obj = SLOT(vnodelabel); 2989 2990 if (!mac_biba_dominate_effective(subj, obj)) 2991 return (EACCES); 2992 2993 return (0); 2994} 2995 2996static int 2997mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2998 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2999{ 3000 struct mac_biba *subj, *obj; 3001 3002 if (!mac_biba_enabled) 3003 return (0); 3004 3005 subj = SLOT(cred->cr_label); 3006 obj = SLOT(vnodelabel); 3007 3008 if (!mac_biba_dominate_effective(subj, obj)) 3009 return (EACCES); 3010 3011 return (0); 3012} 3013 3014static int 3015mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 3016 struct vnode *vp, struct label *vnodelabel) 3017{ 3018 struct mac_biba *subj, *obj; 3019 3020 if (!mac_biba_enabled) 3021 return (0); 3022 3023 subj = SLOT(active_cred->cr_label); 3024 obj = SLOT(vnodelabel); 3025 3026 if (!mac_biba_dominate_effective(obj, subj)) 3027 return (EACCES); 3028 3029 return (0); 3030} 3031 3032static int 3033mac_biba_check_vnode_write(struct ucred *active_cred, 3034 struct ucred *file_cred, struct vnode *vp, struct label *label) 3035{ 3036 struct mac_biba *subj, *obj; 3037 3038 if (!mac_biba_enabled || !revocation_enabled) 3039 return (0); 3040 3041 subj = SLOT(active_cred->cr_label); 3042 obj = SLOT(label); 3043 3044 if (!mac_biba_dominate_effective(subj, obj)) 3045 return (EACCES); 3046 3047 return (0); 3048} 3049 3050static struct mac_policy_ops mac_biba_ops = 3051{ 3052 .mpo_init = mac_biba_init, 3053 .mpo_init_bpfdesc_label = mac_biba_init_label, 3054 .mpo_init_cred_label = mac_biba_init_label, 3055 .mpo_init_devfsdirent_label = mac_biba_init_label, 3056 .mpo_init_ifnet_label = mac_biba_init_label, 3057 .mpo_init_inpcb_label = mac_biba_init_label_waitcheck, 3058 .mpo_init_sysv_msgmsg_label = mac_biba_init_label, 3059 .mpo_init_sysv_msgqueue_label = mac_biba_init_label, 3060 .mpo_init_sysv_sem_label = mac_biba_init_label, 3061 .mpo_init_sysv_shm_label = mac_biba_init_label, 3062 .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 3063 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 3064 .mpo_init_mount_label = mac_biba_init_label, 3065 .mpo_init_mount_fs_label = mac_biba_init_label, 3066 .mpo_init_pipe_label = mac_biba_init_label, 3067 .mpo_init_posix_sem_label = mac_biba_init_label, 3068 .mpo_init_socket_label = mac_biba_init_label_waitcheck, 3069 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 3070 .mpo_init_vnode_label = mac_biba_init_label, 3071 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 3072 .mpo_destroy_cred_label = mac_biba_destroy_label, 3073 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 3074 .mpo_destroy_ifnet_label = mac_biba_destroy_label, 3075 .mpo_destroy_inpcb_label = mac_biba_destroy_label, 3076 .mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label, 3077 .mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label, 3078 .mpo_destroy_sysv_sem_label = mac_biba_destroy_label, 3079 .mpo_destroy_sysv_shm_label = mac_biba_destroy_label, 3080 .mpo_destroy_ipq_label = mac_biba_destroy_label, 3081 .mpo_destroy_mbuf_label = mac_biba_destroy_label, 3082 .mpo_destroy_mount_label = mac_biba_destroy_label, 3083 .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 3084 .mpo_destroy_pipe_label = mac_biba_destroy_label, 3085 .mpo_destroy_posix_sem_label = mac_biba_destroy_label, 3086 .mpo_destroy_socket_label = mac_biba_destroy_label, 3087 .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 3088 .mpo_destroy_vnode_label = mac_biba_destroy_label, 3089 .mpo_copy_cred_label = mac_biba_copy_label, 3090 .mpo_copy_ifnet_label = mac_biba_copy_label, 3091 .mpo_copy_mbuf_label = mac_biba_copy_label, 3092 .mpo_copy_pipe_label = mac_biba_copy_label, 3093 .mpo_copy_socket_label = mac_biba_copy_label, 3094 .mpo_copy_vnode_label = mac_biba_copy_label, 3095 .mpo_externalize_cred_label = mac_biba_externalize_label, 3096 .mpo_externalize_ifnet_label = mac_biba_externalize_label, 3097 .mpo_externalize_pipe_label = mac_biba_externalize_label, 3098 .mpo_externalize_socket_label = mac_biba_externalize_label, 3099 .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 3100 .mpo_externalize_vnode_label = mac_biba_externalize_label, 3101 .mpo_internalize_cred_label = mac_biba_internalize_label, 3102 .mpo_internalize_ifnet_label = mac_biba_internalize_label, 3103 .mpo_internalize_pipe_label = mac_biba_internalize_label, 3104 .mpo_internalize_socket_label = mac_biba_internalize_label, 3105 .mpo_internalize_vnode_label = mac_biba_internalize_label, 3106 .mpo_create_devfs_device = mac_biba_create_devfs_device, 3107 .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 3108 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 3109 .mpo_create_mount = mac_biba_create_mount, 3110 .mpo_create_root_mount = mac_biba_create_root_mount, 3111 .mpo_relabel_vnode = mac_biba_relabel_vnode, 3112 .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 3113 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 3114 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 3115 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 3116 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 3117 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 3118 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 3119 .mpo_create_pipe = mac_biba_create_pipe, 3120 .mpo_create_posix_sem = mac_biba_create_posix_sem, 3121 .mpo_create_socket = mac_biba_create_socket, 3122 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 3123 .mpo_relabel_pipe = mac_biba_relabel_pipe, 3124 .mpo_relabel_socket = mac_biba_relabel_socket, 3125 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 3126 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 3127 .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 3128 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 3129 .mpo_create_fragment = mac_biba_create_fragment, 3130 .mpo_create_ifnet = mac_biba_create_ifnet, 3131 .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket, 3132 .mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg, 3133 .mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue, 3134 .mpo_create_sysv_sem = mac_biba_create_sysv_sem, 3135 .mpo_create_sysv_shm = mac_biba_create_sysv_shm, 3136 .mpo_create_ipq = mac_biba_create_ipq, 3137 .mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb, 3138 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 3139 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 3140 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 3141 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 3142 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 3143 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 3144 .mpo_fragment_match = mac_biba_fragment_match, 3145 .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 3146 .mpo_update_ipq = mac_biba_update_ipq, 3147 .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel, 3148 .mpo_create_proc0 = mac_biba_create_proc0, 3149 .mpo_create_proc1 = mac_biba_create_proc1, 3150 .mpo_relabel_cred = mac_biba_relabel_cred, 3151 .mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg, 3152 .mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue, 3153 .mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem, 3154 .mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm, 3155 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 3156 .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 3157 .mpo_check_cred_visible = mac_biba_check_cred_visible, 3158 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 3159 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 3160 .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver, 3161 .mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv, 3162 .mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid, 3163 .mpo_check_sysv_msqget = mac_biba_check_sysv_msqget, 3164 .mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd, 3165 .mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv, 3166 .mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl, 3167 .mpo_check_sysv_semctl = mac_biba_check_sysv_semctl, 3168 .mpo_check_sysv_semget = mac_biba_check_sysv_semget, 3169 .mpo_check_sysv_semop = mac_biba_check_sysv_semop, 3170 .mpo_check_sysv_shmat = mac_biba_check_sysv_shmat, 3171 .mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl, 3172 .mpo_check_sysv_shmget = mac_biba_check_sysv_shmget, 3173 .mpo_check_kld_load = mac_biba_check_kld_load, 3174 .mpo_check_kld_unload = mac_biba_check_kld_unload, 3175 .mpo_check_mount_stat = mac_biba_check_mount_stat, 3176 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 3177 .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 3178 .mpo_check_pipe_read = mac_biba_check_pipe_read, 3179 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 3180 .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 3181 .mpo_check_pipe_write = mac_biba_check_pipe_write, 3182 .mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write, 3183 .mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly, 3184 .mpo_check_posix_sem_open = mac_biba_check_posix_sem_write, 3185 .mpo_check_posix_sem_post = mac_biba_check_posix_sem_write, 3186 .mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write, 3187 .mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write, 3188 .mpo_check_proc_debug = mac_biba_check_proc_debug, 3189 .mpo_check_proc_sched = mac_biba_check_proc_sched, 3190 .mpo_check_proc_signal = mac_biba_check_proc_signal, 3191 .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 3192 .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 3193 .mpo_check_socket_visible = mac_biba_check_socket_visible, 3194 .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 3195 .mpo_check_system_acct = mac_biba_check_system_acct, 3196 .mpo_check_system_settime = mac_biba_check_system_settime, 3197 .mpo_check_system_swapon = mac_biba_check_system_swapon, 3198 .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 3199 .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 3200 .mpo_check_vnode_access = mac_biba_check_vnode_open, 3201 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 3202 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 3203 .mpo_check_vnode_create = mac_biba_check_vnode_create, 3204 .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 3205 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 3206 .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr, 3207 .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 3208 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 3209 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 3210 .mpo_check_vnode_link = mac_biba_check_vnode_link, 3211 .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr, 3212 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 3213 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 3214 .mpo_check_vnode_open = mac_biba_check_vnode_open, 3215 .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 3216 .mpo_check_vnode_read = mac_biba_check_vnode_read, 3217 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 3218 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 3219 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 3220 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 3221 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 3222 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 3223 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 3224 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 3225 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 3226 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 3227 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 3228 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 3229 .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 3230 .mpo_check_vnode_write = mac_biba_check_vnode_write, 3231}; 3232 3233MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 3234 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot); 3235