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