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