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