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