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