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