1/*- 2 * Copyright (c) 1999-2002, 2007-2011 Robert N. M. Watson 3 * Copyright (c) 2001-2005 McAfee, Inc. 4 * Copyright (c) 2006 SPARTA, Inc. 5 * All rights reserved. 6 * 7 * This software was developed by Robert Watson for the TrustedBSD Project. 8 * 9 * This software was developed for the FreeBSD Project in part by McAfee 10 * Research, the Security Research Division of McAfee, Inc. under 11 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 12 * CHATS research program. 13 * 14 * This software was enhanced by SPARTA ISSO under SPAWAR contract 15 * N66001-04-C-6019 ("SEFOS"). 16 * 17 * This software was developed at the University of Cambridge Computer 18 * Laboratory with support from a grant from Google, Inc. 19 * 20 * Redistribution and use in source and binary forms, with or without 21 * modification, are permitted provided that the following conditions 22 * are met: 23 * 1. Redistributions of source code must retain the above copyright 24 * notice, this list of conditions and the following disclaimer. 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * $FreeBSD$ 42 */ 43 44/* 45 * Developed by the TrustedBSD Project. 46 * 47 * Biba fixed label mandatory integrity policy. 48 */ 49 50#include <sys/param.h> 51#include <sys/conf.h> 52#include <sys/extattr.h> 53#include <sys/kernel.h> 54#include <sys/ksem.h> 55#include <sys/malloc.h> 56#include <sys/mman.h> 57#include <sys/mount.h> 58#include <sys/priv.h> 59#include <sys/proc.h> 60#include <sys/sbuf.h> 61#include <sys/systm.h> 62#include <sys/sysproto.h> 63#include <sys/sysent.h> 64#include <sys/systm.h> 65#include <sys/vnode.h> 66#include <sys/file.h> 67#include <sys/socket.h> 68#include <sys/socketvar.h> 69#include <sys/pipe.h> 70#include <sys/sx.h> 71#include <sys/sysctl.h> 72#include <sys/msg.h> 73#include <sys/sem.h> 74#include <sys/shm.h> 75 76#include <fs/devfs/devfs.h> 77 78#include <net/bpfdesc.h> 79#include <net/if.h> 80#include <net/if_types.h> 81#include <net/if_var.h> 82 83#include <netinet/in.h> 84#include <netinet/in_pcb.h> 85#include <netinet/ip_var.h> 86 87#include <vm/uma.h> 88#include <vm/vm.h> 89 90#include <security/mac/mac_policy.h> 91#include <security/mac_biba/mac_biba.h> 92 93SYSCTL_DECL(_security_mac); 94 95static SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 96 "TrustedBSD mac_biba policy controls"); 97 98static int biba_label_size = sizeof(struct mac_biba); 99SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 100 &biba_label_size, 0, "Size of struct mac_biba"); 101 102static int biba_enabled = 1; 103SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RWTUN, &biba_enabled, 104 0, "Enforce MAC/Biba policy"); 105 106static int destroyed_not_inited; 107SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 108 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 109 110static int trust_all_interfaces = 0; 111SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RDTUN, 112 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 113 114static char trusted_interfaces[128]; 115SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RDTUN, 116 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 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_RWTUN, &ptys_equal, 124 0, "Label pty devices as biba/equal on create"); 125 126static int interfaces_equal = 1; 127SYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RWTUN, 128 &interfaces_equal, 0, "Label network interfaces as biba/equal on create"); 129 130static int revocation_enabled = 0; 131SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RWTUN, 132 &revocation_enabled, 0, "Revoke access to objects on relabel"); 133 134static int biba_slot; 135#define SLOT(l) ((struct mac_biba *)mac_label_get((l), biba_slot)) 136#define SLOT_SET(l, val) mac_label_set((l), 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 *mb) 159{ 160 161 if (mb != NULL) 162 uma_zfree(zone_biba, mb); 163 else 164 atomic_add_int(&destroyed_not_inited, 1); 165} 166 167static int 168biba_atmostflags(struct mac_biba *mb, int flags) 169{ 170 171 if ((mb->mb_flags & flags) != mb->mb_flags) 172 return (EINVAL); 173 return (0); 174} 175 176static int 177biba_dominate_element(struct mac_biba_element *a, struct mac_biba_element *b) 178{ 179 int bit; 180 181 switch (a->mbe_type) { 182 case MAC_BIBA_TYPE_EQUAL: 183 case MAC_BIBA_TYPE_HIGH: 184 return (1); 185 186 case MAC_BIBA_TYPE_LOW: 187 switch (b->mbe_type) { 188 case MAC_BIBA_TYPE_GRADE: 189 case MAC_BIBA_TYPE_HIGH: 190 return (0); 191 192 case MAC_BIBA_TYPE_EQUAL: 193 case MAC_BIBA_TYPE_LOW: 194 return (1); 195 196 default: 197 panic("biba_dominate_element: b->mbe_type invalid"); 198 } 199 200 case MAC_BIBA_TYPE_GRADE: 201 switch (b->mbe_type) { 202 case MAC_BIBA_TYPE_EQUAL: 203 case MAC_BIBA_TYPE_LOW: 204 return (1); 205 206 case MAC_BIBA_TYPE_HIGH: 207 return (0); 208 209 case MAC_BIBA_TYPE_GRADE: 210 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 211 if (!MAC_BIBA_BIT_TEST(bit, 212 a->mbe_compartments) && 213 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 214 return (0); 215 return (a->mbe_grade >= b->mbe_grade); 216 217 default: 218 panic("biba_dominate_element: b->mbe_type invalid"); 219 } 220 221 default: 222 panic("biba_dominate_element: a->mbe_type invalid"); 223 } 224 225 return (0); 226} 227 228static int 229biba_subject_dominate_high(struct mac_biba *mb) 230{ 231 struct mac_biba_element *element; 232 233 KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 234 ("biba_effective_in_range: mb not effective")); 235 element = &mb->mb_effective; 236 237 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 238 element->mbe_type == MAC_BIBA_TYPE_HIGH); 239} 240 241static int 242biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 243{ 244 245 return (biba_dominate_element(&rangeb->mb_rangehigh, 246 &rangea->mb_rangehigh) && 247 biba_dominate_element(&rangea->mb_rangelow, 248 &rangeb->mb_rangelow)); 249} 250 251static int 252biba_effective_in_range(struct mac_biba *effective, struct mac_biba *range) 253{ 254 255 KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 256 ("biba_effective_in_range: a not effective")); 257 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 258 ("biba_effective_in_range: b not range")); 259 260 return (biba_dominate_element(&range->mb_rangehigh, 261 &effective->mb_effective) && 262 biba_dominate_element(&effective->mb_effective, 263 &range->mb_rangelow)); 264 265 return (1); 266} 267 268static int 269biba_dominate_effective(struct mac_biba *a, struct mac_biba *b) 270{ 271 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 272 ("biba_dominate_effective: a not effective")); 273 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 274 ("biba_dominate_effective: b not effective")); 275 276 return (biba_dominate_element(&a->mb_effective, &b->mb_effective)); 277} 278 279static int 280biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 281{ 282 283 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 284 b->mbe_type == MAC_BIBA_TYPE_EQUAL) 285 return (1); 286 287 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 288} 289 290static int 291biba_equal_effective(struct mac_biba *a, struct mac_biba *b) 292{ 293 294 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 295 ("biba_equal_effective: a not effective")); 296 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 297 ("biba_equal_effective: b not effective")); 298 299 return (biba_equal_element(&a->mb_effective, &b->mb_effective)); 300} 301 302static int 303biba_contains_equal(struct mac_biba *mb) 304{ 305 306 if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 307 if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 308 return (1); 309 } 310 311 if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 312 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 313 return (1); 314 if (mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 315 return (1); 316 } 317 318 return (0); 319} 320 321static int 322biba_subject_privileged(struct mac_biba *mb) 323{ 324 325 KASSERT((mb->mb_flags & MAC_BIBA_FLAGS_BOTH) == MAC_BIBA_FLAGS_BOTH, 326 ("biba_subject_privileged: subject doesn't have both labels")); 327 328 /* If the effective is EQUAL, it's ok. */ 329 if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 330 return (0); 331 332 /* If either range endpoint is EQUAL, it's ok. */ 333 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 334 mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 335 return (0); 336 337 /* If the range is low-high, it's ok. */ 338 if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 339 mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 340 return (0); 341 342 /* It's not ok. */ 343 return (EPERM); 344} 345 346static int 347biba_high_effective(struct mac_biba *mb) 348{ 349 350 KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 351 ("biba_equal_effective: mb not effective")); 352 353 return (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH); 354} 355 356static int 357biba_valid(struct mac_biba *mb) 358{ 359 360 if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 361 switch (mb->mb_effective.mbe_type) { 362 case MAC_BIBA_TYPE_GRADE: 363 break; 364 365 case MAC_BIBA_TYPE_EQUAL: 366 case MAC_BIBA_TYPE_HIGH: 367 case MAC_BIBA_TYPE_LOW: 368 if (mb->mb_effective.mbe_grade != 0 || 369 !MAC_BIBA_BIT_SET_EMPTY( 370 mb->mb_effective.mbe_compartments)) 371 return (EINVAL); 372 break; 373 374 default: 375 return (EINVAL); 376 } 377 } else { 378 if (mb->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF) 379 return (EINVAL); 380 } 381 382 if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 383 switch (mb->mb_rangelow.mbe_type) { 384 case MAC_BIBA_TYPE_GRADE: 385 break; 386 387 case MAC_BIBA_TYPE_EQUAL: 388 case MAC_BIBA_TYPE_HIGH: 389 case MAC_BIBA_TYPE_LOW: 390 if (mb->mb_rangelow.mbe_grade != 0 || 391 !MAC_BIBA_BIT_SET_EMPTY( 392 mb->mb_rangelow.mbe_compartments)) 393 return (EINVAL); 394 break; 395 396 default: 397 return (EINVAL); 398 } 399 400 switch (mb->mb_rangehigh.mbe_type) { 401 case MAC_BIBA_TYPE_GRADE: 402 break; 403 404 case MAC_BIBA_TYPE_EQUAL: 405 case MAC_BIBA_TYPE_HIGH: 406 case MAC_BIBA_TYPE_LOW: 407 if (mb->mb_rangehigh.mbe_grade != 0 || 408 !MAC_BIBA_BIT_SET_EMPTY( 409 mb->mb_rangehigh.mbe_compartments)) 410 return (EINVAL); 411 break; 412 413 default: 414 return (EINVAL); 415 } 416 if (!biba_dominate_element(&mb->mb_rangehigh, 417 &mb->mb_rangelow)) 418 return (EINVAL); 419 } else { 420 if (mb->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 421 mb->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 422 return (EINVAL); 423 } 424 425 return (0); 426} 427 428static void 429biba_set_range(struct mac_biba *mb, u_short typelow, u_short gradelow, 430 u_char *compartmentslow, u_short typehigh, u_short gradehigh, 431 u_char *compartmentshigh) 432{ 433 434 mb->mb_rangelow.mbe_type = typelow; 435 mb->mb_rangelow.mbe_grade = gradelow; 436 if (compartmentslow != NULL) 437 memcpy(mb->mb_rangelow.mbe_compartments, compartmentslow, 438 sizeof(mb->mb_rangelow.mbe_compartments)); 439 mb->mb_rangehigh.mbe_type = typehigh; 440 mb->mb_rangehigh.mbe_grade = gradehigh; 441 if (compartmentshigh != NULL) 442 memcpy(mb->mb_rangehigh.mbe_compartments, compartmentshigh, 443 sizeof(mb->mb_rangehigh.mbe_compartments)); 444 mb->mb_flags |= MAC_BIBA_FLAG_RANGE; 445} 446 447static void 448biba_set_effective(struct mac_biba *mb, u_short type, u_short grade, 449 u_char *compartments) 450{ 451 452 mb->mb_effective.mbe_type = type; 453 mb->mb_effective.mbe_grade = grade; 454 if (compartments != NULL) 455 memcpy(mb->mb_effective.mbe_compartments, compartments, 456 sizeof(mb->mb_effective.mbe_compartments)); 457 mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 458} 459 460static void 461biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 462{ 463 464 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 465 ("biba_copy_range: labelfrom not range")); 466 467 labelto->mb_rangelow = labelfrom->mb_rangelow; 468 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 469 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 470} 471 472static void 473biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto) 474{ 475 476 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 477 ("biba_copy_effective: labelfrom not effective")); 478 479 labelto->mb_effective = labelfrom->mb_effective; 480 labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 481} 482 483static void 484biba_copy(struct mac_biba *source, struct mac_biba *dest) 485{ 486 487 if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) 488 biba_copy_effective(source, dest); 489 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 490 biba_copy_range(source, dest); 491} 492 493/* 494 * Policy module operations. 495 */ 496static void 497biba_init(struct mac_policy_conf *conf) 498{ 499 500 zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL, 501 NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 502} 503 504/* 505 * Label operations. 506 */ 507static void 508biba_init_label(struct label *label) 509{ 510 511 SLOT_SET(label, biba_alloc(M_WAITOK)); 512} 513 514static int 515biba_init_label_waitcheck(struct label *label, int flag) 516{ 517 518 SLOT_SET(label, biba_alloc(flag)); 519 if (SLOT(label) == NULL) 520 return (ENOMEM); 521 522 return (0); 523} 524 525static void 526biba_destroy_label(struct label *label) 527{ 528 529 biba_free(SLOT(label)); 530 SLOT_SET(label, NULL); 531} 532 533/* 534 * biba_element_to_string() accepts an sbuf and Biba element. It converts 535 * the Biba element to a string and stores the result in the sbuf; if there 536 * isn't space in the sbuf, -1 is returned. 537 */ 538static int 539biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element) 540{ 541 int i, first; 542 543 switch (element->mbe_type) { 544 case MAC_BIBA_TYPE_HIGH: 545 return (sbuf_printf(sb, "high")); 546 547 case MAC_BIBA_TYPE_LOW: 548 return (sbuf_printf(sb, "low")); 549 550 case MAC_BIBA_TYPE_EQUAL: 551 return (sbuf_printf(sb, "equal")); 552 553 case MAC_BIBA_TYPE_GRADE: 554 if (sbuf_printf(sb, "%d", element->mbe_grade) == -1) 555 return (-1); 556 557 first = 1; 558 for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) { 559 if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) { 560 if (first) { 561 if (sbuf_putc(sb, ':') == -1) 562 return (-1); 563 if (sbuf_printf(sb, "%d", i) == -1) 564 return (-1); 565 first = 0; 566 } else { 567 if (sbuf_printf(sb, "+%d", i) == -1) 568 return (-1); 569 } 570 } 571 } 572 return (0); 573 574 default: 575 panic("biba_element_to_string: invalid type (%d)", 576 element->mbe_type); 577 } 578} 579 580/* 581 * biba_to_string() converts a Biba label to a string, and places the results 582 * in the passed sbuf. It returns 0 on success, or EINVAL if there isn't 583 * room in the sbuf. Note: the sbuf will be modified even in a failure case, 584 * so the caller may need to revert the sbuf by restoring the offset if 585 * that's undesired. 586 */ 587static int 588biba_to_string(struct sbuf *sb, struct mac_biba *mb) 589{ 590 591 if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 592 if (biba_element_to_string(sb, &mb->mb_effective) == -1) 593 return (EINVAL); 594 } 595 596 if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 597 if (sbuf_putc(sb, '(') == -1) 598 return (EINVAL); 599 600 if (biba_element_to_string(sb, &mb->mb_rangelow) == -1) 601 return (EINVAL); 602 603 if (sbuf_putc(sb, '-') == -1) 604 return (EINVAL); 605 606 if (biba_element_to_string(sb, &mb->mb_rangehigh) == -1) 607 return (EINVAL); 608 609 if (sbuf_putc(sb, ')') == -1) 610 return (EINVAL); 611 } 612 613 return (0); 614} 615 616static int 617biba_externalize_label(struct label *label, char *element_name, 618 struct sbuf *sb, int *claimed) 619{ 620 struct mac_biba *mb; 621 622 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 623 return (0); 624 625 (*claimed)++; 626 627 mb = SLOT(label); 628 return (biba_to_string(sb, mb)); 629} 630 631static int 632biba_parse_element(struct mac_biba_element *element, char *string) 633{ 634 char *compartment, *end, *grade; 635 int value; 636 637 if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { 638 element->mbe_type = MAC_BIBA_TYPE_HIGH; 639 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 640 } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { 641 element->mbe_type = MAC_BIBA_TYPE_LOW; 642 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 643 } else if (strcmp(string, "equal") == 0 || 644 strcmp(string, "eq") == 0) { 645 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 646 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 647 } else { 648 element->mbe_type = MAC_BIBA_TYPE_GRADE; 649 650 /* 651 * Numeric grade piece of the element. 652 */ 653 grade = strsep(&string, ":"); 654 value = strtol(grade, &end, 10); 655 if (end == grade || *end != '\0') 656 return (EINVAL); 657 if (value < 0 || value > 65535) 658 return (EINVAL); 659 element->mbe_grade = value; 660 661 /* 662 * Optional compartment piece of the element. If none are 663 * included, we assume that the label has no compartments. 664 */ 665 if (string == NULL) 666 return (0); 667 if (*string == '\0') 668 return (0); 669 670 while ((compartment = strsep(&string, "+")) != NULL) { 671 value = strtol(compartment, &end, 10); 672 if (compartment == end || *end != '\0') 673 return (EINVAL); 674 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 675 return (EINVAL); 676 MAC_BIBA_BIT_SET(value, element->mbe_compartments); 677 } 678 } 679 680 return (0); 681} 682 683/* 684 * Note: destructively consumes the string, make a local copy before calling 685 * if that's a problem. 686 */ 687static int 688biba_parse(struct mac_biba *mb, char *string) 689{ 690 char *rangehigh, *rangelow, *effective; 691 int error; 692 693 effective = strsep(&string, "("); 694 if (*effective == '\0') 695 effective = NULL; 696 697 if (string != NULL) { 698 rangelow = strsep(&string, "-"); 699 if (string == NULL) 700 return (EINVAL); 701 rangehigh = strsep(&string, ")"); 702 if (string == NULL) 703 return (EINVAL); 704 if (*string != '\0') 705 return (EINVAL); 706 } else { 707 rangelow = NULL; 708 rangehigh = NULL; 709 } 710 711 KASSERT((rangelow != NULL && rangehigh != NULL) || 712 (rangelow == NULL && rangehigh == NULL), 713 ("biba_parse: range mismatch")); 714 715 bzero(mb, sizeof(*mb)); 716 if (effective != NULL) { 717 error = biba_parse_element(&mb->mb_effective, effective); 718 if (error) 719 return (error); 720 mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 721 } 722 723 if (rangelow != NULL) { 724 error = biba_parse_element(&mb->mb_rangelow, rangelow); 725 if (error) 726 return (error); 727 error = biba_parse_element(&mb->mb_rangehigh, rangehigh); 728 if (error) 729 return (error); 730 mb->mb_flags |= MAC_BIBA_FLAG_RANGE; 731 } 732 733 error = biba_valid(mb); 734 if (error) 735 return (error); 736 737 return (0); 738} 739 740static int 741biba_internalize_label(struct label *label, char *element_name, 742 char *element_data, int *claimed) 743{ 744 struct mac_biba *mb, mb_temp; 745 int error; 746 747 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 748 return (0); 749 750 (*claimed)++; 751 752 error = biba_parse(&mb_temp, element_data); 753 if (error) 754 return (error); 755 756 mb = SLOT(label); 757 *mb = mb_temp; 758 759 return (0); 760} 761 762static void 763biba_copy_label(struct label *src, struct label *dest) 764{ 765 766 *SLOT(dest) = *SLOT(src); 767} 768 769/* 770 * Object-specific entry point implementations are sorted alphabetically by 771 * object type name and then by operation. 772 */ 773static int 774biba_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 775 struct ifnet *ifp, struct label *ifplabel) 776{ 777 struct mac_biba *a, *b; 778 779 if (!biba_enabled) 780 return (0); 781 782 a = SLOT(dlabel); 783 b = SLOT(ifplabel); 784 785 if (biba_equal_effective(a, b)) 786 return (0); 787 return (EACCES); 788} 789 790static void 791biba_bpfdesc_create(struct ucred *cred, struct bpf_d *d, 792 struct label *dlabel) 793{ 794 struct mac_biba *source, *dest; 795 796 source = SLOT(cred->cr_label); 797 dest = SLOT(dlabel); 798 799 biba_copy_effective(source, dest); 800} 801 802static void 803biba_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 804 struct mbuf *m, struct label *mlabel) 805{ 806 struct mac_biba *source, *dest; 807 808 source = SLOT(dlabel); 809 dest = SLOT(mlabel); 810 811 biba_copy_effective(source, dest); 812} 813 814static void 815biba_cred_associate_nfsd(struct ucred *cred) 816{ 817 struct mac_biba *label; 818 819 label = SLOT(cred->cr_label); 820 biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL); 821 biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 822 0, NULL); 823} 824 825static int 826biba_cred_check_relabel(struct ucred *cred, struct label *newlabel) 827{ 828 struct mac_biba *subj, *new; 829 int error; 830 831 subj = SLOT(cred->cr_label); 832 new = SLOT(newlabel); 833 834 /* 835 * If there is a Biba label update for the credential, it may 836 * be an update of the effective, range, or both. 837 */ 838 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 839 if (error) 840 return (error); 841 842 /* 843 * If the Biba label is to be changed, authorize as appropriate. 844 */ 845 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 846 /* 847 * If the change request modifies both the Biba label 848 * effective and range, check that the new effective will be 849 * in the new range. 850 */ 851 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 852 MAC_BIBA_FLAGS_BOTH && 853 !biba_effective_in_range(new, new)) 854 return (EINVAL); 855 856 /* 857 * To change the Biba effective label on a credential, the 858 * new effective label must be in the current range. 859 */ 860 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE && 861 !biba_effective_in_range(new, subj)) 862 return (EPERM); 863 864 /* 865 * To change the Biba range on a credential, the new range 866 * label must be in the current range. 867 */ 868 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 869 !biba_range_in_range(new, subj)) 870 return (EPERM); 871 872 /* 873 * To have EQUAL in any component of the new credential Biba 874 * label, the subject must already have EQUAL in their label. 875 */ 876 if (biba_contains_equal(new)) { 877 error = biba_subject_privileged(subj); 878 if (error) 879 return (error); 880 } 881 } 882 883 return (0); 884} 885 886static int 887biba_cred_check_visible(struct ucred *u1, struct ucred *u2) 888{ 889 struct mac_biba *subj, *obj; 890 891 if (!biba_enabled) 892 return (0); 893 894 subj = SLOT(u1->cr_label); 895 obj = SLOT(u2->cr_label); 896 897 /* XXX: range */ 898 if (!biba_dominate_effective(obj, subj)) 899 return (ESRCH); 900 901 return (0); 902} 903 904static void 905biba_cred_create_init(struct ucred *cred) 906{ 907 struct mac_biba *dest; 908 909 dest = SLOT(cred->cr_label); 910 911 biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 912 biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 913 0, NULL); 914} 915 916static void 917biba_cred_create_swapper(struct ucred *cred) 918{ 919 struct mac_biba *dest; 920 921 dest = SLOT(cred->cr_label); 922 923 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 924 biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 925 0, NULL); 926} 927 928static void 929biba_cred_relabel(struct ucred *cred, struct label *newlabel) 930{ 931 struct mac_biba *source, *dest; 932 933 source = SLOT(newlabel); 934 dest = SLOT(cred->cr_label); 935 936 biba_copy(source, dest); 937} 938 939static void 940biba_devfs_create_device(struct ucred *cred, struct mount *mp, 941 struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 942{ 943 struct mac_biba *mb; 944 const char *dn; 945 int biba_type; 946 947 mb = SLOT(delabel); 948 dn = devtoname(dev); 949 if (strcmp(dn, "null") == 0 || 950 strcmp(dn, "zero") == 0 || 951 strcmp(dn, "random") == 0 || 952 strncmp(dn, "fd/", strlen("fd/")) == 0) 953 biba_type = MAC_BIBA_TYPE_EQUAL; 954 else if (ptys_equal && 955 (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 956 strncmp(dn, "pts/", strlen("pts/")) == 0 || 957 strncmp(dn, "ptyp", strlen("ptyp")) == 0)) 958 biba_type = MAC_BIBA_TYPE_EQUAL; 959 else 960 biba_type = MAC_BIBA_TYPE_HIGH; 961 biba_set_effective(mb, biba_type, 0, NULL); 962} 963 964static void 965biba_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 966 struct devfs_dirent *de, struct label *delabel) 967{ 968 struct mac_biba *mb; 969 970 mb = SLOT(delabel); 971 972 biba_set_effective(mb, MAC_BIBA_TYPE_HIGH, 0, NULL); 973} 974 975static void 976biba_devfs_create_symlink(struct ucred *cred, struct mount *mp, 977 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 978 struct label *delabel) 979{ 980 struct mac_biba *source, *dest; 981 982 source = SLOT(cred->cr_label); 983 dest = SLOT(delabel); 984 985 biba_copy_effective(source, dest); 986} 987 988static void 989biba_devfs_update(struct mount *mp, struct devfs_dirent *de, 990 struct label *delabel, struct vnode *vp, struct label *vplabel) 991{ 992 struct mac_biba *source, *dest; 993 994 source = SLOT(vplabel); 995 dest = SLOT(delabel); 996 997 biba_copy(source, dest); 998} 999 1000static void 1001biba_devfs_vnode_associate(struct mount *mp, struct label *mntlabel, 1002 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 1003 struct label *vplabel) 1004{ 1005 struct mac_biba *source, *dest; 1006 1007 source = SLOT(delabel); 1008 dest = SLOT(vplabel); 1009 1010 biba_copy_effective(source, dest); 1011} 1012 1013static int 1014biba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1015 struct label *ifplabel, struct label *newlabel) 1016{ 1017 struct mac_biba *subj, *new; 1018 int error; 1019 1020 subj = SLOT(cred->cr_label); 1021 new = SLOT(newlabel); 1022 1023 /* 1024 * If there is a Biba label update for the interface, it may be an 1025 * update of the effective, range, or both. 1026 */ 1027 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1028 if (error) 1029 return (error); 1030 1031 /* 1032 * Relabling network interfaces requires Biba privilege. 1033 */ 1034 error = biba_subject_privileged(subj); 1035 if (error) 1036 return (error); 1037 1038 return (0); 1039} 1040 1041static int 1042biba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1043 struct mbuf *m, struct label *mlabel) 1044{ 1045 struct mac_biba *p, *i; 1046 1047 if (!biba_enabled) 1048 return (0); 1049 1050 p = SLOT(mlabel); 1051 i = SLOT(ifplabel); 1052 1053 return (biba_effective_in_range(p, i) ? 0 : EACCES); 1054} 1055 1056static void 1057biba_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1058{ 1059 char tifname[IFNAMSIZ], *p, *q; 1060 char tiflist[sizeof(trusted_interfaces)]; 1061 struct mac_biba *dest; 1062 int len, type; 1063 1064 dest = SLOT(ifplabel); 1065 1066 if (ifp->if_type == IFT_LOOP || interfaces_equal != 0) { 1067 type = MAC_BIBA_TYPE_EQUAL; 1068 goto set; 1069 } 1070 1071 if (trust_all_interfaces) { 1072 type = MAC_BIBA_TYPE_HIGH; 1073 goto set; 1074 } 1075 1076 type = MAC_BIBA_TYPE_LOW; 1077 1078 if (trusted_interfaces[0] == '\0' || 1079 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1080 goto set; 1081 1082 bzero(tiflist, sizeof(tiflist)); 1083 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1084 if(*p != ' ' && *p != '\t') 1085 *q = *p; 1086 1087 for (p = q = tiflist;; p++) { 1088 if (*p == ',' || *p == '\0') { 1089 len = p - q; 1090 if (len < IFNAMSIZ) { 1091 bzero(tifname, sizeof(tifname)); 1092 bcopy(q, tifname, len); 1093 if (strcmp(tifname, ifp->if_xname) == 0) { 1094 type = MAC_BIBA_TYPE_HIGH; 1095 break; 1096 } 1097 } else { 1098 *p = '\0'; 1099 printf("mac_biba warning: interface name " 1100 "\"%s\" is too long (must be < %d)\n", 1101 q, IFNAMSIZ); 1102 } 1103 if (*p == '\0') 1104 break; 1105 q = p + 1; 1106 } 1107 } 1108set: 1109 biba_set_effective(dest, type, 0, NULL); 1110 biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1111} 1112 1113static void 1114biba_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1115 struct mbuf *m, struct label *mlabel) 1116{ 1117 struct mac_biba *source, *dest; 1118 1119 source = SLOT(ifplabel); 1120 dest = SLOT(mlabel); 1121 1122 biba_copy_effective(source, dest); 1123} 1124 1125static void 1126biba_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1127 struct label *ifplabel, struct label *newlabel) 1128{ 1129 struct mac_biba *source, *dest; 1130 1131 source = SLOT(newlabel); 1132 dest = SLOT(ifplabel); 1133 1134 biba_copy(source, dest); 1135} 1136 1137static int 1138biba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1139 struct mbuf *m, struct label *mlabel) 1140{ 1141 struct mac_biba *p, *i; 1142 1143 if (!biba_enabled) 1144 return (0); 1145 1146 p = SLOT(mlabel); 1147 i = SLOT(inplabel); 1148 1149 return (biba_equal_effective(p, i) ? 0 : EACCES); 1150} 1151 1152static int 1153biba_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 1154 struct label *inplabel) 1155{ 1156 struct mac_biba *subj, *obj; 1157 1158 if (!biba_enabled) 1159 return (0); 1160 1161 subj = SLOT(cred->cr_label); 1162 obj = SLOT(inplabel); 1163 1164 if (!biba_dominate_effective(obj, subj)) 1165 return (ENOENT); 1166 1167 return (0); 1168} 1169 1170static void 1171biba_inpcb_create(struct socket *so, struct label *solabel, 1172 struct inpcb *inp, struct label *inplabel) 1173{ 1174 struct mac_biba *source, *dest; 1175 1176 source = SLOT(solabel); 1177 dest = SLOT(inplabel); 1178 1179 SOCK_LOCK(so); 1180 biba_copy_effective(source, dest); 1181 SOCK_UNLOCK(so); 1182} 1183 1184static void 1185biba_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1186 struct mbuf *m, struct label *mlabel) 1187{ 1188 struct mac_biba *source, *dest; 1189 1190 source = SLOT(inplabel); 1191 dest = SLOT(mlabel); 1192 1193 biba_copy_effective(source, dest); 1194} 1195 1196static void 1197biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1198 struct inpcb *inp, struct label *inplabel) 1199{ 1200 struct mac_biba *source, *dest; 1201 1202 SOCK_LOCK_ASSERT(so); 1203 1204 source = SLOT(solabel); 1205 dest = SLOT(inplabel); 1206 1207 biba_copy(source, dest); 1208} 1209 1210static void 1211biba_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1212 struct label *q6label) 1213{ 1214 struct mac_biba *source, *dest; 1215 1216 source = SLOT(mlabel); 1217 dest = SLOT(q6label); 1218 1219 biba_copy_effective(source, dest); 1220} 1221 1222static int 1223biba_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1224 struct label *q6label) 1225{ 1226 struct mac_biba *a, *b; 1227 1228 a = SLOT(q6label); 1229 b = SLOT(mlabel); 1230 1231 return (biba_equal_effective(a, b)); 1232} 1233 1234static void 1235biba_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1236 struct label *mlabel) 1237{ 1238 struct mac_biba *source, *dest; 1239 1240 source = SLOT(q6label); 1241 dest = SLOT(mlabel); 1242 1243 /* Just use the head, since we require them all to match. */ 1244 biba_copy_effective(source, dest); 1245} 1246 1247static void 1248biba_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1249 struct label *q6label) 1250{ 1251 1252 /* NOOP: we only accept matching labels, so no need to update */ 1253} 1254 1255static void 1256biba_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1257 struct label *qlabel) 1258{ 1259 struct mac_biba *source, *dest; 1260 1261 source = SLOT(mlabel); 1262 dest = SLOT(qlabel); 1263 1264 biba_copy_effective(source, dest); 1265} 1266 1267static int 1268biba_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1269 struct label *qlabel) 1270{ 1271 struct mac_biba *a, *b; 1272 1273 a = SLOT(qlabel); 1274 b = SLOT(mlabel); 1275 1276 return (biba_equal_effective(a, b)); 1277} 1278 1279static void 1280biba_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1281 struct label *mlabel) 1282{ 1283 struct mac_biba *source, *dest; 1284 1285 source = SLOT(qlabel); 1286 dest = SLOT(mlabel); 1287 1288 /* Just use the head, since we require them all to match. */ 1289 biba_copy_effective(source, dest); 1290} 1291 1292static void 1293biba_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1294 struct label *qlabel) 1295{ 1296 1297 /* NOOP: we only accept matching labels, so no need to update */ 1298} 1299 1300static int 1301biba_kld_check_load(struct ucred *cred, struct vnode *vp, 1302 struct label *vplabel) 1303{ 1304 struct mac_biba *subj, *obj; 1305 int error; 1306 1307 if (!biba_enabled) 1308 return (0); 1309 1310 subj = SLOT(cred->cr_label); 1311 1312 error = biba_subject_privileged(subj); 1313 if (error) 1314 return (error); 1315 1316 obj = SLOT(vplabel); 1317 if (!biba_high_effective(obj)) 1318 return (EACCES); 1319 1320 return (0); 1321} 1322 1323static int 1324biba_mount_check_stat(struct ucred *cred, struct mount *mp, 1325 struct label *mplabel) 1326{ 1327 struct mac_biba *subj, *obj; 1328 1329 if (!biba_enabled) 1330 return (0); 1331 1332 subj = SLOT(cred->cr_label); 1333 obj = SLOT(mplabel); 1334 1335 if (!biba_dominate_effective(obj, subj)) 1336 return (EACCES); 1337 1338 return (0); 1339} 1340 1341static void 1342biba_mount_create(struct ucred *cred, struct mount *mp, 1343 struct label *mplabel) 1344{ 1345 struct mac_biba *source, *dest; 1346 1347 source = SLOT(cred->cr_label); 1348 dest = SLOT(mplabel); 1349 1350 biba_copy_effective(source, dest); 1351} 1352 1353static void 1354biba_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1355 struct mbuf *m, struct label *mlabel) 1356{ 1357 struct mac_biba *dest; 1358 1359 dest = SLOT(mlabel); 1360 1361 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1362} 1363 1364static void 1365biba_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1366 struct mbuf *msend, struct label *msendlabel) 1367{ 1368 struct mac_biba *source, *dest; 1369 1370 source = SLOT(mrecvlabel); 1371 dest = SLOT(msendlabel); 1372 1373 biba_copy_effective(source, dest); 1374} 1375 1376static void 1377biba_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1378{ 1379 struct mac_biba *dest; 1380 1381 dest = SLOT(mlabel); 1382 1383 /* XXX: where is the label for the firewall really coming from? */ 1384 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1385} 1386 1387static void 1388biba_netinet_fragment(struct mbuf *m, struct label *mlabel, 1389 struct mbuf *frag, struct label *fraglabel) 1390{ 1391 struct mac_biba *source, *dest; 1392 1393 source = SLOT(mlabel); 1394 dest = SLOT(fraglabel); 1395 1396 biba_copy_effective(source, dest); 1397} 1398 1399static void 1400biba_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1401 struct mbuf *msend, struct label *msendlabel) 1402{ 1403 struct mac_biba *source, *dest; 1404 1405 source = SLOT(mrecvlabel); 1406 dest = SLOT(msendlabel); 1407 1408 biba_copy_effective(source, dest); 1409} 1410 1411static void 1412biba_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1413 struct mbuf *m, struct label *mlabel) 1414{ 1415 struct mac_biba *dest; 1416 1417 dest = SLOT(mlabel); 1418 1419 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1420} 1421 1422static void 1423biba_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1424 struct mbuf *m, struct label *mlabel) 1425{ 1426 struct mac_biba *dest; 1427 1428 dest = SLOT(mlabel); 1429 1430 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1431} 1432 1433static int 1434biba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1435 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1436{ 1437 1438 if(!biba_enabled) 1439 return (0); 1440 1441 /* XXX: This will be implemented soon... */ 1442 1443 return (0); 1444} 1445 1446static int 1447biba_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1448 struct label *pplabel) 1449{ 1450 struct mac_biba *subj, *obj; 1451 1452 if (!biba_enabled) 1453 return (0); 1454 1455 subj = SLOT(cred->cr_label); 1456 obj = SLOT(pplabel); 1457 1458 if (!biba_dominate_effective(obj, subj)) 1459 return (EACCES); 1460 1461 return (0); 1462} 1463 1464static int 1465biba_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1466 struct label *pplabel) 1467{ 1468 struct mac_biba *subj, *obj; 1469 1470 if (!biba_enabled) 1471 return (0); 1472 1473 subj = SLOT(cred->cr_label); 1474 obj = SLOT(pplabel); 1475 1476 if (!biba_dominate_effective(obj, subj)) 1477 return (EACCES); 1478 1479 return (0); 1480} 1481 1482static int 1483biba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1484 struct label *pplabel, struct label *newlabel) 1485{ 1486 struct mac_biba *subj, *obj, *new; 1487 int error; 1488 1489 new = SLOT(newlabel); 1490 subj = SLOT(cred->cr_label); 1491 obj = SLOT(pplabel); 1492 1493 /* 1494 * If there is a Biba label update for a pipe, it must be a effective 1495 * update. 1496 */ 1497 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 1498 if (error) 1499 return (error); 1500 1501 /* 1502 * To perform a relabel of a pipe (Biba label or not), Biba must 1503 * authorize the relabel. 1504 */ 1505 if (!biba_effective_in_range(obj, subj)) 1506 return (EPERM); 1507 1508 /* 1509 * If the Biba label is to be changed, authorize as appropriate. 1510 */ 1511 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 1512 /* 1513 * To change the Biba label on a pipe, the new pipe label 1514 * must be in the subject range. 1515 */ 1516 if (!biba_effective_in_range(new, subj)) 1517 return (EPERM); 1518 1519 /* 1520 * To change the Biba label on a pipe to be EQUAL, the 1521 * subject must have appropriate privilege. 1522 */ 1523 if (biba_contains_equal(new)) { 1524 error = biba_subject_privileged(subj); 1525 if (error) 1526 return (error); 1527 } 1528 } 1529 1530 return (0); 1531} 1532 1533static int 1534biba_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 1535 struct label *pplabel) 1536{ 1537 struct mac_biba *subj, *obj; 1538 1539 if (!biba_enabled) 1540 return (0); 1541 1542 subj = SLOT(cred->cr_label); 1543 obj = SLOT(pplabel); 1544 1545 if (!biba_dominate_effective(obj, subj)) 1546 return (EACCES); 1547 1548 return (0); 1549} 1550 1551static int 1552biba_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1553 struct label *pplabel) 1554{ 1555 struct mac_biba *subj, *obj; 1556 1557 if (!biba_enabled) 1558 return (0); 1559 1560 subj = SLOT(cred->cr_label); 1561 obj = SLOT(pplabel); 1562 1563 if (!biba_dominate_effective(subj, obj)) 1564 return (EACCES); 1565 1566 return (0); 1567} 1568 1569static void 1570biba_pipe_create(struct ucred *cred, struct pipepair *pp, 1571 struct label *pplabel) 1572{ 1573 struct mac_biba *source, *dest; 1574 1575 source = SLOT(cred->cr_label); 1576 dest = SLOT(pplabel); 1577 1578 biba_copy_effective(source, dest); 1579} 1580 1581static void 1582biba_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1583 struct label *pplabel, struct label *newlabel) 1584{ 1585 struct mac_biba *source, *dest; 1586 1587 source = SLOT(newlabel); 1588 dest = SLOT(pplabel); 1589 1590 biba_copy(source, dest); 1591} 1592 1593static int 1594biba_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks, 1595 struct label *kslabel) 1596{ 1597 struct mac_biba *subj, *obj; 1598 1599 if (!biba_enabled) 1600 return (0); 1601 1602 subj = SLOT(cred->cr_label); 1603 obj = SLOT(kslabel); 1604 1605 if (!biba_dominate_effective(subj, obj)) 1606 return (EACCES); 1607 1608 return (0); 1609} 1610 1611static int 1612biba_posixsem_check_setmode(struct ucred *cred, struct ksem *ks, 1613 struct label *kslabel, mode_t mode) 1614{ 1615 struct mac_biba *subj, *obj; 1616 1617 if (!biba_enabled) 1618 return (0); 1619 1620 subj = SLOT(cred->cr_label); 1621 obj = SLOT(kslabel); 1622 1623 if (!biba_dominate_effective(subj, obj)) 1624 return (EACCES); 1625 1626 return (0); 1627} 1628 1629static int 1630biba_posixsem_check_setowner(struct ucred *cred, struct ksem *ks, 1631 struct label *kslabel, uid_t uid, gid_t gid) 1632{ 1633 struct mac_biba *subj, *obj; 1634 1635 if (!biba_enabled) 1636 return (0); 1637 1638 subj = SLOT(cred->cr_label); 1639 obj = SLOT(kslabel); 1640 1641 if (!biba_dominate_effective(subj, obj)) 1642 return (EACCES); 1643 1644 return (0); 1645} 1646 1647static int 1648biba_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred, 1649 struct ksem *ks, struct label *kslabel) 1650{ 1651 struct mac_biba *subj, *obj; 1652 1653 if (!biba_enabled) 1654 return (0); 1655 1656 subj = SLOT(active_cred->cr_label); 1657 obj = SLOT(kslabel); 1658 1659 if (!biba_dominate_effective(subj, obj)) 1660 return (EACCES); 1661 1662 return (0); 1663} 1664 1665static int 1666biba_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred, 1667 struct ksem *ks, struct label *kslabel) 1668{ 1669 struct mac_biba *subj, *obj; 1670 1671 if (!biba_enabled) 1672 return (0); 1673 1674 subj = SLOT(active_cred->cr_label); 1675 obj = SLOT(kslabel); 1676 1677 if (!biba_dominate_effective(obj, subj)) 1678 return (EACCES); 1679 1680 return (0); 1681} 1682 1683static void 1684biba_posixsem_create(struct ucred *cred, struct ksem *ks, 1685 struct label *kslabel) 1686{ 1687 struct mac_biba *source, *dest; 1688 1689 source = SLOT(cred->cr_label); 1690 dest = SLOT(kslabel); 1691 1692 biba_copy_effective(source, dest); 1693} 1694 1695static int 1696biba_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd, 1697 struct label *shmlabel, int prot, int flags) 1698{ 1699 struct mac_biba *subj, *obj; 1700 1701 if (!biba_enabled || !revocation_enabled) 1702 return (0); 1703 1704 subj = SLOT(cred->cr_label); 1705 obj = SLOT(shmlabel); 1706 1707 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 1708 if (!biba_dominate_effective(obj, subj)) 1709 return (EACCES); 1710 } 1711 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 1712 if (!biba_dominate_effective(subj, obj)) 1713 return (EACCES); 1714 } 1715 1716 return (0); 1717} 1718 1719static int 1720biba_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd, 1721 struct label *shmlabel, accmode_t accmode) 1722{ 1723 struct mac_biba *subj, *obj; 1724 1725 if (!biba_enabled) 1726 return (0); 1727 1728 subj = SLOT(cred->cr_label); 1729 obj = SLOT(shmlabel); 1730 1731 if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 1732 if (!biba_dominate_effective(obj, subj)) 1733 return (EACCES); 1734 } 1735 if (accmode & VMODIFY_PERMS) { 1736 if (!biba_dominate_effective(subj, obj)) 1737 return (EACCES); 1738 } 1739 1740 return (0); 1741} 1742 1743static int 1744biba_posixshm_check_read(struct ucred *active_cred, struct ucred *file_cred, 1745 struct shmfd *vp, struct label *shmlabel) 1746{ 1747 struct mac_biba *subj, *obj; 1748 1749 if (!biba_enabled || !revocation_enabled) 1750 return (0); 1751 1752 subj = SLOT(active_cred->cr_label); 1753 obj = SLOT(shmlabel); 1754 1755 if (!biba_dominate_effective(obj, subj)) 1756 return (EACCES); 1757 1758 return (0); 1759} 1760 1761static int 1762biba_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd, 1763 struct label *shmlabel, mode_t mode) 1764{ 1765 struct mac_biba *subj, *obj; 1766 1767 if (!biba_enabled) 1768 return (0); 1769 1770 subj = SLOT(cred->cr_label); 1771 obj = SLOT(shmlabel); 1772 1773 if (!biba_dominate_effective(subj, obj)) 1774 return (EACCES); 1775 1776 return (0); 1777} 1778 1779static int 1780biba_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd, 1781 struct label *shmlabel, uid_t uid, gid_t gid) 1782{ 1783 struct mac_biba *subj, *obj; 1784 1785 if (!biba_enabled) 1786 return (0); 1787 1788 subj = SLOT(cred->cr_label); 1789 obj = SLOT(shmlabel); 1790 1791 if (!biba_dominate_effective(subj, obj)) 1792 return (EACCES); 1793 1794 return (0); 1795} 1796 1797static int 1798biba_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred, 1799 struct shmfd *shmfd, struct label *shmlabel) 1800{ 1801 struct mac_biba *subj, *obj; 1802 1803 if (!biba_enabled) 1804 return (0); 1805 1806 subj = SLOT(active_cred->cr_label); 1807 obj = SLOT(shmlabel); 1808 1809 if (!biba_dominate_effective(obj, subj)) 1810 return (EACCES); 1811 1812 return (0); 1813} 1814 1815static int 1816biba_posixshm_check_truncate(struct ucred *active_cred, 1817 struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel) 1818{ 1819 struct mac_biba *subj, *obj; 1820 1821 if (!biba_enabled) 1822 return (0); 1823 1824 subj = SLOT(active_cred->cr_label); 1825 obj = SLOT(shmlabel); 1826 1827 if (!biba_dominate_effective(subj, obj)) 1828 return (EACCES); 1829 1830 return (0); 1831} 1832 1833static int 1834biba_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd, 1835 struct label *shmlabel) 1836{ 1837 struct mac_biba *subj, *obj; 1838 1839 if (!biba_enabled) 1840 return (0); 1841 1842 subj = SLOT(cred->cr_label); 1843 obj = SLOT(shmlabel); 1844 1845 if (!biba_dominate_effective(subj, obj)) 1846 return (EACCES); 1847 1848 return (0); 1849} 1850 1851static int 1852biba_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred, 1853 struct shmfd *vp, struct label *shmlabel) 1854{ 1855 struct mac_biba *subj, *obj; 1856 1857 if (!biba_enabled || !revocation_enabled) 1858 return (0); 1859 1860 subj = SLOT(active_cred->cr_label); 1861 obj = SLOT(shmlabel); 1862 1863 if (!biba_dominate_effective(obj, subj)) 1864 return (EACCES); 1865 1866 return (0); 1867} 1868 1869static void 1870biba_posixshm_create(struct ucred *cred, struct shmfd *shmfd, 1871 struct label *shmlabel) 1872{ 1873 struct mac_biba *source, *dest; 1874 1875 source = SLOT(cred->cr_label); 1876 dest = SLOT(shmlabel); 1877 1878 biba_copy_effective(source, dest); 1879} 1880 1881/* 1882 * Some system privileges are allowed regardless of integrity grade; others 1883 * are allowed only when running with privilege with respect to the Biba 1884 * policy as they might otherwise allow bypassing of the integrity policy. 1885 */ 1886static int 1887biba_priv_check(struct ucred *cred, int priv) 1888{ 1889 struct mac_biba *subj; 1890 int error; 1891 1892 if (!biba_enabled) 1893 return (0); 1894 1895 /* 1896 * Exempt only specific privileges from the Biba integrity policy. 1897 */ 1898 switch (priv) { 1899 case PRIV_KTRACE: 1900 case PRIV_MSGBUF: 1901 1902 /* 1903 * Allow processes to manipulate basic process audit properties, and 1904 * to submit audit records. 1905 */ 1906 case PRIV_AUDIT_GETAUDIT: 1907 case PRIV_AUDIT_SETAUDIT: 1908 case PRIV_AUDIT_SUBMIT: 1909 1910 /* 1911 * Allow processes to manipulate their regular UNIX credentials. 1912 */ 1913 case PRIV_CRED_SETUID: 1914 case PRIV_CRED_SETEUID: 1915 case PRIV_CRED_SETGID: 1916 case PRIV_CRED_SETEGID: 1917 case PRIV_CRED_SETGROUPS: 1918 case PRIV_CRED_SETREUID: 1919 case PRIV_CRED_SETREGID: 1920 case PRIV_CRED_SETRESUID: 1921 case PRIV_CRED_SETRESGID: 1922 1923 /* 1924 * Allow processes to perform system monitoring. 1925 */ 1926 case PRIV_SEEOTHERGIDS: 1927 case PRIV_SEEOTHERUIDS: 1928 break; 1929 1930 /* 1931 * Allow access to general process debugging facilities. We 1932 * separately control debugging based on MAC label. 1933 */ 1934 case PRIV_DEBUG_DIFFCRED: 1935 case PRIV_DEBUG_SUGID: 1936 case PRIV_DEBUG_UNPRIV: 1937 1938 /* 1939 * Allow manipulating jails. 1940 */ 1941 case PRIV_JAIL_ATTACH: 1942 1943 /* 1944 * Allow privilege with respect to the Partition policy, but not the 1945 * Privs policy. 1946 */ 1947 case PRIV_MAC_PARTITION: 1948 1949 /* 1950 * Allow privilege with respect to process resource limits and login 1951 * context. 1952 */ 1953 case PRIV_PROC_LIMIT: 1954 case PRIV_PROC_SETLOGIN: 1955 case PRIV_PROC_SETRLIMIT: 1956 1957 /* 1958 * Allow System V and POSIX IPC privileges. 1959 */ 1960 case PRIV_IPC_READ: 1961 case PRIV_IPC_WRITE: 1962 case PRIV_IPC_ADMIN: 1963 case PRIV_IPC_MSGSIZE: 1964 case PRIV_MQ_ADMIN: 1965 1966 /* 1967 * Allow certain scheduler manipulations -- possibly this should be 1968 * controlled by more fine-grained policy, as potentially low 1969 * integrity processes can deny CPU to higher integrity ones. 1970 */ 1971 case PRIV_SCHED_DIFFCRED: 1972 case PRIV_SCHED_SETPRIORITY: 1973 case PRIV_SCHED_RTPRIO: 1974 case PRIV_SCHED_SETPOLICY: 1975 case PRIV_SCHED_SET: 1976 case PRIV_SCHED_SETPARAM: 1977 1978 /* 1979 * More IPC privileges. 1980 */ 1981 case PRIV_SEM_WRITE: 1982 1983 /* 1984 * Allow signaling privileges subject to integrity policy. 1985 */ 1986 case PRIV_SIGNAL_DIFFCRED: 1987 case PRIV_SIGNAL_SUGID: 1988 1989 /* 1990 * Allow access to only limited sysctls from lower integrity levels; 1991 * piggy-back on the Jail definition. 1992 */ 1993 case PRIV_SYSCTL_WRITEJAIL: 1994 1995 /* 1996 * Allow TTY-based privileges, subject to general device access using 1997 * labels on TTY device nodes, but not console privilege. 1998 */ 1999 case PRIV_TTY_DRAINWAIT: 2000 case PRIV_TTY_DTRWAIT: 2001 case PRIV_TTY_EXCLUSIVE: 2002 case PRIV_TTY_STI: 2003 case PRIV_TTY_SETA: 2004 2005 /* 2006 * Grant most VFS privileges, as almost all are in practice bounded 2007 * by more specific checks using labels. 2008 */ 2009 case PRIV_VFS_READ: 2010 case PRIV_VFS_WRITE: 2011 case PRIV_VFS_ADMIN: 2012 case PRIV_VFS_EXEC: 2013 case PRIV_VFS_LOOKUP: 2014 case PRIV_VFS_CHFLAGS_DEV: 2015 case PRIV_VFS_CHOWN: 2016 case PRIV_VFS_CHROOT: 2017 case PRIV_VFS_RETAINSUGID: 2018 case PRIV_VFS_EXCEEDQUOTA: 2019 case PRIV_VFS_FCHROOT: 2020 case PRIV_VFS_FHOPEN: 2021 case PRIV_VFS_FHSTATFS: 2022 case PRIV_VFS_GENERATION: 2023 case PRIV_VFS_GETFH: 2024 case PRIV_VFS_GETQUOTA: 2025 case PRIV_VFS_LINK: 2026 case PRIV_VFS_MOUNT: 2027 case PRIV_VFS_MOUNT_OWNER: 2028 case PRIV_VFS_MOUNT_PERM: 2029 case PRIV_VFS_MOUNT_SUIDDIR: 2030 case PRIV_VFS_MOUNT_NONUSER: 2031 case PRIV_VFS_SETGID: 2032 case PRIV_VFS_STICKYFILE: 2033 case PRIV_VFS_SYSFLAGS: 2034 case PRIV_VFS_UNMOUNT: 2035 2036 /* 2037 * Allow VM privileges; it would be nice if these were subject to 2038 * resource limits. 2039 */ 2040 case PRIV_VM_MADV_PROTECT: 2041 case PRIV_VM_MLOCK: 2042 case PRIV_VM_MUNLOCK: 2043 case PRIV_VM_SWAP_NOQUOTA: 2044 case PRIV_VM_SWAP_NORLIMIT: 2045 2046 /* 2047 * Allow some but not all network privileges. In general, dont allow 2048 * reconfiguring the network stack, just normal use. 2049 */ 2050 case PRIV_NETINET_RESERVEDPORT: 2051 case PRIV_NETINET_RAW: 2052 case PRIV_NETINET_REUSEPORT: 2053 break; 2054 2055 /* 2056 * All remaining system privileges are allow only if the process 2057 * holds privilege with respect to the Biba policy. 2058 */ 2059 default: 2060 subj = SLOT(cred->cr_label); 2061 error = biba_subject_privileged(subj); 2062 if (error) 2063 return (error); 2064 } 2065 return (0); 2066} 2067 2068static int 2069biba_proc_check_debug(struct ucred *cred, struct proc *p) 2070{ 2071 struct mac_biba *subj, *obj; 2072 2073 if (!biba_enabled) 2074 return (0); 2075 2076 subj = SLOT(cred->cr_label); 2077 obj = SLOT(p->p_ucred->cr_label); 2078 2079 /* XXX: range checks */ 2080 if (!biba_dominate_effective(obj, subj)) 2081 return (ESRCH); 2082 if (!biba_dominate_effective(subj, obj)) 2083 return (EACCES); 2084 2085 return (0); 2086} 2087 2088static int 2089biba_proc_check_sched(struct ucred *cred, struct proc *p) 2090{ 2091 struct mac_biba *subj, *obj; 2092 2093 if (!biba_enabled) 2094 return (0); 2095 2096 subj = SLOT(cred->cr_label); 2097 obj = SLOT(p->p_ucred->cr_label); 2098 2099 /* XXX: range checks */ 2100 if (!biba_dominate_effective(obj, subj)) 2101 return (ESRCH); 2102 if (!biba_dominate_effective(subj, obj)) 2103 return (EACCES); 2104 2105 return (0); 2106} 2107 2108static int 2109biba_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 2110{ 2111 struct mac_biba *subj, *obj; 2112 2113 if (!biba_enabled) 2114 return (0); 2115 2116 subj = SLOT(cred->cr_label); 2117 obj = SLOT(p->p_ucred->cr_label); 2118 2119 /* XXX: range checks */ 2120 if (!biba_dominate_effective(obj, subj)) 2121 return (ESRCH); 2122 if (!biba_dominate_effective(subj, obj)) 2123 return (EACCES); 2124 2125 return (0); 2126} 2127 2128static int 2129biba_socket_check_deliver(struct socket *so, struct label *solabel, 2130 struct mbuf *m, struct label *mlabel) 2131{ 2132 struct mac_biba *p, *s; 2133 int error; 2134 2135 if (!biba_enabled) 2136 return (0); 2137 2138 p = SLOT(mlabel); 2139 s = SLOT(solabel); 2140 2141 SOCK_LOCK(so); 2142 error = biba_equal_effective(p, s) ? 0 : EACCES; 2143 SOCK_UNLOCK(so); 2144 return (error); 2145} 2146 2147static int 2148biba_socket_check_relabel(struct ucred *cred, struct socket *so, 2149 struct label *solabel, struct label *newlabel) 2150{ 2151 struct mac_biba *subj, *obj, *new; 2152 int error; 2153 2154 SOCK_LOCK_ASSERT(so); 2155 2156 new = SLOT(newlabel); 2157 subj = SLOT(cred->cr_label); 2158 obj = SLOT(solabel); 2159 2160 /* 2161 * If there is a Biba label update for the socket, it may be an 2162 * update of effective. 2163 */ 2164 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2165 if (error) 2166 return (error); 2167 2168 /* 2169 * To relabel a socket, the old socket effective must be in the 2170 * subject range. 2171 */ 2172 if (!biba_effective_in_range(obj, subj)) 2173 return (EPERM); 2174 2175 /* 2176 * If the Biba label is to be changed, authorize as appropriate. 2177 */ 2178 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2179 /* 2180 * To relabel a socket, the new socket effective must be in 2181 * the subject range. 2182 */ 2183 if (!biba_effective_in_range(new, subj)) 2184 return (EPERM); 2185 2186 /* 2187 * To change the Biba label on the socket to contain EQUAL, 2188 * the subject must have appropriate privilege. 2189 */ 2190 if (biba_contains_equal(new)) { 2191 error = biba_subject_privileged(subj); 2192 if (error) 2193 return (error); 2194 } 2195 } 2196 2197 return (0); 2198} 2199 2200static int 2201biba_socket_check_visible(struct ucred *cred, struct socket *so, 2202 struct label *solabel) 2203{ 2204 struct mac_biba *subj, *obj; 2205 2206 if (!biba_enabled) 2207 return (0); 2208 2209 subj = SLOT(cred->cr_label); 2210 obj = SLOT(solabel); 2211 2212 SOCK_LOCK(so); 2213 if (!biba_dominate_effective(obj, subj)) { 2214 SOCK_UNLOCK(so); 2215 return (ENOENT); 2216 } 2217 SOCK_UNLOCK(so); 2218 2219 return (0); 2220} 2221 2222static void 2223biba_socket_create(struct ucred *cred, struct socket *so, 2224 struct label *solabel) 2225{ 2226 struct mac_biba *source, *dest; 2227 2228 source = SLOT(cred->cr_label); 2229 dest = SLOT(solabel); 2230 2231 biba_copy_effective(source, dest); 2232} 2233 2234static void 2235biba_socket_create_mbuf(struct socket *so, struct label *solabel, 2236 struct mbuf *m, struct label *mlabel) 2237{ 2238 struct mac_biba *source, *dest; 2239 2240 source = SLOT(solabel); 2241 dest = SLOT(mlabel); 2242 2243 SOCK_LOCK(so); 2244 biba_copy_effective(source, dest); 2245 SOCK_UNLOCK(so); 2246} 2247 2248static void 2249biba_socket_newconn(struct socket *oldso, struct label *oldsolabel, 2250 struct socket *newso, struct label *newsolabel) 2251{ 2252 struct mac_biba source, *dest; 2253 2254 SOCK_LOCK(oldso); 2255 source = *SLOT(oldsolabel); 2256 SOCK_UNLOCK(oldso); 2257 2258 dest = SLOT(newsolabel); 2259 2260 SOCK_LOCK(newso); 2261 biba_copy_effective(&source, dest); 2262 SOCK_UNLOCK(newso); 2263} 2264 2265static void 2266biba_socket_relabel(struct ucred *cred, struct socket *so, 2267 struct label *solabel, struct label *newlabel) 2268{ 2269 struct mac_biba *source, *dest; 2270 2271 SOCK_LOCK_ASSERT(so); 2272 2273 source = SLOT(newlabel); 2274 dest = SLOT(solabel); 2275 2276 biba_copy(source, dest); 2277} 2278 2279static void 2280biba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 2281 struct socket *so, struct label *sopeerlabel) 2282{ 2283 struct mac_biba *source, *dest; 2284 2285 source = SLOT(mlabel); 2286 dest = SLOT(sopeerlabel); 2287 2288 SOCK_LOCK(so); 2289 biba_copy_effective(source, dest); 2290 SOCK_UNLOCK(so); 2291} 2292 2293static void 2294biba_socketpeer_set_from_socket(struct socket *oldso, 2295 struct label *oldsolabel, struct socket *newso, 2296 struct label *newsopeerlabel) 2297{ 2298 struct mac_biba source, *dest; 2299 2300 SOCK_LOCK(oldso); 2301 source = *SLOT(oldsolabel); 2302 SOCK_UNLOCK(oldso); 2303 dest = SLOT(newsopeerlabel); 2304 2305 SOCK_LOCK(newso); 2306 biba_copy_effective(&source, dest); 2307 SOCK_UNLOCK(newso); 2308} 2309 2310static void 2311biba_syncache_create(struct label *label, struct inpcb *inp) 2312{ 2313 struct mac_biba *source, *dest; 2314 2315 source = SLOT(inp->inp_label); 2316 dest = SLOT(label); 2317 biba_copy_effective(source, dest); 2318} 2319 2320static void 2321biba_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2322 struct label *mlabel) 2323{ 2324 struct mac_biba *source, *dest; 2325 2326 source = SLOT(sc_label); 2327 dest = SLOT(mlabel); 2328 biba_copy_effective(source, dest); 2329} 2330 2331static int 2332biba_system_check_acct(struct ucred *cred, struct vnode *vp, 2333 struct label *vplabel) 2334{ 2335 struct mac_biba *subj, *obj; 2336 int error; 2337 2338 if (!biba_enabled) 2339 return (0); 2340 2341 subj = SLOT(cred->cr_label); 2342 2343 error = biba_subject_privileged(subj); 2344 if (error) 2345 return (error); 2346 2347 if (vplabel == NULL) 2348 return (0); 2349 2350 obj = SLOT(vplabel); 2351 if (!biba_high_effective(obj)) 2352 return (EACCES); 2353 2354 return (0); 2355} 2356 2357static int 2358biba_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2359 struct label *vplabel) 2360{ 2361 struct mac_biba *subj, *obj; 2362 int error; 2363 2364 if (!biba_enabled) 2365 return (0); 2366 2367 subj = SLOT(cred->cr_label); 2368 2369 error = biba_subject_privileged(subj); 2370 if (error) 2371 return (error); 2372 2373 if (vplabel == NULL) 2374 return (0); 2375 2376 obj = SLOT(vplabel); 2377 if (!biba_high_effective(obj)) 2378 return (EACCES); 2379 2380 return (0); 2381} 2382 2383static int 2384biba_system_check_auditon(struct ucred *cred, int cmd) 2385{ 2386 struct mac_biba *subj; 2387 int error; 2388 2389 if (!biba_enabled) 2390 return (0); 2391 2392 subj = SLOT(cred->cr_label); 2393 2394 error = biba_subject_privileged(subj); 2395 if (error) 2396 return (error); 2397 2398 return (0); 2399} 2400 2401static int 2402biba_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2403 struct label *label) 2404{ 2405 struct mac_biba *subj; 2406 int error; 2407 2408 if (!biba_enabled) 2409 return (0); 2410 2411 subj = SLOT(cred->cr_label); 2412 2413 error = biba_subject_privileged(subj); 2414 if (error) 2415 return (error); 2416 2417 return (0); 2418} 2419 2420static int 2421biba_system_check_swapon(struct ucred *cred, struct vnode *vp, 2422 struct label *vplabel) 2423{ 2424 struct mac_biba *subj, *obj; 2425 int error; 2426 2427 if (!biba_enabled) 2428 return (0); 2429 2430 subj = SLOT(cred->cr_label); 2431 obj = SLOT(vplabel); 2432 2433 error = biba_subject_privileged(subj); 2434 if (error) 2435 return (error); 2436 2437 if (!biba_high_effective(obj)) 2438 return (EACCES); 2439 2440 return (0); 2441} 2442 2443static int 2444biba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2445 void *arg1, int arg2, struct sysctl_req *req) 2446{ 2447 struct mac_biba *subj; 2448 int error; 2449 2450 if (!biba_enabled) 2451 return (0); 2452 2453 subj = SLOT(cred->cr_label); 2454 2455 /* 2456 * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high, 2457 * but also require privilege to change them. 2458 */ 2459 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2460 if (!biba_subject_dominate_high(subj)) 2461 return (EACCES); 2462 2463 error = biba_subject_privileged(subj); 2464 if (error) 2465 return (error); 2466 } 2467 2468 return (0); 2469} 2470 2471static void 2472biba_sysvmsg_cleanup(struct label *msglabel) 2473{ 2474 2475 bzero(SLOT(msglabel), sizeof(struct mac_biba)); 2476} 2477 2478static void 2479biba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2480 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 2481{ 2482 struct mac_biba *source, *dest; 2483 2484 /* Ignore the msgq label */ 2485 source = SLOT(cred->cr_label); 2486 dest = SLOT(msglabel); 2487 2488 biba_copy_effective(source, dest); 2489} 2490 2491static int 2492biba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 2493 struct label *msglabel) 2494{ 2495 struct mac_biba *subj, *obj; 2496 2497 if (!biba_enabled) 2498 return (0); 2499 2500 subj = SLOT(cred->cr_label); 2501 obj = SLOT(msglabel); 2502 2503 if (!biba_dominate_effective(obj, subj)) 2504 return (EACCES); 2505 2506 return (0); 2507} 2508 2509static int 2510biba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 2511 struct label *msglabel) 2512{ 2513 struct mac_biba *subj, *obj; 2514 2515 if (!biba_enabled) 2516 return (0); 2517 2518 subj = SLOT(cred->cr_label); 2519 obj = SLOT(msglabel); 2520 2521 if (!biba_dominate_effective(subj, obj)) 2522 return (EACCES); 2523 2524 return (0); 2525} 2526 2527static int 2528biba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 2529 struct label *msqklabel) 2530{ 2531 struct mac_biba *subj, *obj; 2532 2533 if (!biba_enabled) 2534 return (0); 2535 2536 subj = SLOT(cred->cr_label); 2537 obj = SLOT(msqklabel); 2538 2539 if (!biba_dominate_effective(obj, subj)) 2540 return (EACCES); 2541 2542 return (0); 2543} 2544 2545static int 2546biba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 2547 struct label *msqklabel) 2548{ 2549 struct mac_biba *subj, *obj; 2550 2551 if (!biba_enabled) 2552 return (0); 2553 2554 subj = SLOT(cred->cr_label); 2555 obj = SLOT(msqklabel); 2556 2557 if (!biba_dominate_effective(subj, obj)) 2558 return (EACCES); 2559 2560 return (0); 2561} 2562 2563static int 2564biba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 2565 struct label *msqklabel) 2566{ 2567 struct mac_biba *subj, *obj; 2568 2569 if (!biba_enabled) 2570 return (0); 2571 2572 subj = SLOT(cred->cr_label); 2573 obj = SLOT(msqklabel); 2574 2575 if (!biba_dominate_effective(obj, subj)) 2576 return (EACCES); 2577 2578 return (0); 2579} 2580 2581static int 2582biba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 2583 struct label *msqklabel, int cmd) 2584{ 2585 struct mac_biba *subj, *obj; 2586 2587 if (!biba_enabled) 2588 return (0); 2589 2590 subj = SLOT(cred->cr_label); 2591 obj = SLOT(msqklabel); 2592 2593 switch(cmd) { 2594 case IPC_RMID: 2595 case IPC_SET: 2596 if (!biba_dominate_effective(subj, obj)) 2597 return (EACCES); 2598 break; 2599 2600 case IPC_STAT: 2601 if (!biba_dominate_effective(obj, subj)) 2602 return (EACCES); 2603 break; 2604 2605 default: 2606 return (EACCES); 2607 } 2608 2609 return (0); 2610} 2611 2612static void 2613biba_sysvmsq_cleanup(struct label *msqlabel) 2614{ 2615 2616 bzero(SLOT(msqlabel), sizeof(struct mac_biba)); 2617} 2618 2619static void 2620biba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2621 struct label *msqlabel) 2622{ 2623 struct mac_biba *source, *dest; 2624 2625 source = SLOT(cred->cr_label); 2626 dest = SLOT(msqlabel); 2627 2628 biba_copy_effective(source, dest); 2629} 2630 2631static int 2632biba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 2633 struct label *semaklabel, int cmd) 2634{ 2635 struct mac_biba *subj, *obj; 2636 2637 if (!biba_enabled) 2638 return (0); 2639 2640 subj = SLOT(cred->cr_label); 2641 obj = SLOT(semaklabel); 2642 2643 switch(cmd) { 2644 case IPC_RMID: 2645 case IPC_SET: 2646 case SETVAL: 2647 case SETALL: 2648 if (!biba_dominate_effective(subj, obj)) 2649 return (EACCES); 2650 break; 2651 2652 case IPC_STAT: 2653 case GETVAL: 2654 case GETPID: 2655 case GETNCNT: 2656 case GETZCNT: 2657 case GETALL: 2658 if (!biba_dominate_effective(obj, subj)) 2659 return (EACCES); 2660 break; 2661 2662 default: 2663 return (EACCES); 2664 } 2665 2666 return (0); 2667} 2668 2669static int 2670biba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 2671 struct label *semaklabel) 2672{ 2673 struct mac_biba *subj, *obj; 2674 2675 if (!biba_enabled) 2676 return (0); 2677 2678 subj = SLOT(cred->cr_label); 2679 obj = SLOT(semaklabel); 2680 2681 if (!biba_dominate_effective(obj, subj)) 2682 return (EACCES); 2683 2684 return (0); 2685} 2686 2687static int 2688biba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2689 struct label *semaklabel, size_t accesstype) 2690{ 2691 struct mac_biba *subj, *obj; 2692 2693 if (!biba_enabled) 2694 return (0); 2695 2696 subj = SLOT(cred->cr_label); 2697 obj = SLOT(semaklabel); 2698 2699 if (accesstype & SEM_R) 2700 if (!biba_dominate_effective(obj, subj)) 2701 return (EACCES); 2702 2703 if (accesstype & SEM_A) 2704 if (!biba_dominate_effective(subj, obj)) 2705 return (EACCES); 2706 2707 return (0); 2708} 2709 2710static void 2711biba_sysvsem_cleanup(struct label *semalabel) 2712{ 2713 2714 bzero(SLOT(semalabel), sizeof(struct mac_biba)); 2715} 2716 2717static void 2718biba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2719 struct label *semalabel) 2720{ 2721 struct mac_biba *source, *dest; 2722 2723 source = SLOT(cred->cr_label); 2724 dest = SLOT(semalabel); 2725 2726 biba_copy_effective(source, dest); 2727} 2728 2729static int 2730biba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2731 struct label *shmseglabel, int shmflg) 2732{ 2733 struct mac_biba *subj, *obj; 2734 2735 if (!biba_enabled) 2736 return (0); 2737 2738 subj = SLOT(cred->cr_label); 2739 obj = SLOT(shmseglabel); 2740 2741 if (!biba_dominate_effective(obj, subj)) 2742 return (EACCES); 2743 if ((shmflg & SHM_RDONLY) == 0) { 2744 if (!biba_dominate_effective(subj, obj)) 2745 return (EACCES); 2746 } 2747 2748 return (0); 2749} 2750 2751static int 2752biba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2753 struct label *shmseglabel, int cmd) 2754{ 2755 struct mac_biba *subj, *obj; 2756 2757 if (!biba_enabled) 2758 return (0); 2759 2760 subj = SLOT(cred->cr_label); 2761 obj = SLOT(shmseglabel); 2762 2763 switch(cmd) { 2764 case IPC_RMID: 2765 case IPC_SET: 2766 if (!biba_dominate_effective(subj, obj)) 2767 return (EACCES); 2768 break; 2769 2770 case IPC_STAT: 2771 case SHM_STAT: 2772 if (!biba_dominate_effective(obj, subj)) 2773 return (EACCES); 2774 break; 2775 2776 default: 2777 return (EACCES); 2778 } 2779 2780 return (0); 2781} 2782 2783static int 2784biba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2785 struct label *shmseglabel, int shmflg) 2786{ 2787 struct mac_biba *subj, *obj; 2788 2789 if (!biba_enabled) 2790 return (0); 2791 2792 subj = SLOT(cred->cr_label); 2793 obj = SLOT(shmseglabel); 2794 2795 if (!biba_dominate_effective(obj, subj)) 2796 return (EACCES); 2797 2798 return (0); 2799} 2800 2801static void 2802biba_sysvshm_cleanup(struct label *shmlabel) 2803{ 2804 2805 bzero(SLOT(shmlabel), sizeof(struct mac_biba)); 2806} 2807 2808static void 2809biba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2810 struct label *shmlabel) 2811{ 2812 struct mac_biba *source, *dest; 2813 2814 source = SLOT(cred->cr_label); 2815 dest = SLOT(shmlabel); 2816 2817 biba_copy_effective(source, dest); 2818} 2819 2820static int 2821biba_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2822 struct vnode *vp, struct label *vplabel) 2823{ 2824 struct mac_biba mb_temp, *source, *dest; 2825 int buflen, error; 2826 2827 source = SLOT(mplabel); 2828 dest = SLOT(vplabel); 2829 2830 buflen = sizeof(mb_temp); 2831 bzero(&mb_temp, buflen); 2832 2833 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 2834 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread); 2835 if (error == ENOATTR || error == EOPNOTSUPP) { 2836 /* Fall back to the mntlabel. */ 2837 biba_copy_effective(source, dest); 2838 return (0); 2839 } else if (error) 2840 return (error); 2841 2842 if (buflen != sizeof(mb_temp)) { 2843 printf("biba_vnode_associate_extattr: bad size %d\n", 2844 buflen); 2845 return (EPERM); 2846 } 2847 if (biba_valid(&mb_temp) != 0) { 2848 printf("biba_vnode_associate_extattr: invalid\n"); 2849 return (EPERM); 2850 } 2851 if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != 2852 MAC_BIBA_FLAG_EFFECTIVE) { 2853 printf("biba_vnode_associate_extattr: not effective\n"); 2854 return (EPERM); 2855 } 2856 2857 biba_copy_effective(&mb_temp, dest); 2858 return (0); 2859} 2860 2861static void 2862biba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2863 struct vnode *vp, struct label *vplabel) 2864{ 2865 struct mac_biba *source, *dest; 2866 2867 source = SLOT(mplabel); 2868 dest = SLOT(vplabel); 2869 2870 biba_copy_effective(source, dest); 2871} 2872 2873static int 2874biba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2875 struct label *dvplabel) 2876{ 2877 struct mac_biba *subj, *obj; 2878 2879 if (!biba_enabled) 2880 return (0); 2881 2882 subj = SLOT(cred->cr_label); 2883 obj = SLOT(dvplabel); 2884 2885 if (!biba_dominate_effective(obj, subj)) 2886 return (EACCES); 2887 2888 return (0); 2889} 2890 2891static int 2892biba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2893 struct label *dvplabel) 2894{ 2895 struct mac_biba *subj, *obj; 2896 2897 if (!biba_enabled) 2898 return (0); 2899 2900 subj = SLOT(cred->cr_label); 2901 obj = SLOT(dvplabel); 2902 2903 if (!biba_dominate_effective(obj, subj)) 2904 return (EACCES); 2905 2906 return (0); 2907} 2908 2909static int 2910biba_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2911 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2912{ 2913 struct mac_biba *subj, *obj; 2914 2915 if (!biba_enabled) 2916 return (0); 2917 2918 subj = SLOT(cred->cr_label); 2919 obj = SLOT(dvplabel); 2920 2921 if (!biba_dominate_effective(subj, obj)) 2922 return (EACCES); 2923 2924 return (0); 2925} 2926 2927static int 2928biba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2929 struct label *vplabel, acl_type_t type) 2930{ 2931 struct mac_biba *subj, *obj; 2932 2933 if (!biba_enabled) 2934 return (0); 2935 2936 subj = SLOT(cred->cr_label); 2937 obj = SLOT(vplabel); 2938 2939 if (!biba_dominate_effective(subj, obj)) 2940 return (EACCES); 2941 2942 return (0); 2943} 2944 2945static int 2946biba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2947 struct label *vplabel, int attrnamespace, const char *name) 2948{ 2949 struct mac_biba *subj, *obj; 2950 2951 if (!biba_enabled) 2952 return (0); 2953 2954 subj = SLOT(cred->cr_label); 2955 obj = SLOT(vplabel); 2956 2957 if (!biba_dominate_effective(subj, obj)) 2958 return (EACCES); 2959 2960 return (0); 2961} 2962 2963static int 2964biba_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2965 struct label *vplabel, struct image_params *imgp, 2966 struct label *execlabel) 2967{ 2968 struct mac_biba *subj, *obj, *exec; 2969 int error; 2970 2971 if (execlabel != NULL) { 2972 /* 2973 * We currently don't permit labels to be changed at 2974 * exec-time as part of Biba, so disallow non-NULL Biba label 2975 * elements in the execlabel. 2976 */ 2977 exec = SLOT(execlabel); 2978 error = biba_atmostflags(exec, 0); 2979 if (error) 2980 return (error); 2981 } 2982 2983 if (!biba_enabled) 2984 return (0); 2985 2986 subj = SLOT(cred->cr_label); 2987 obj = SLOT(vplabel); 2988 2989 if (!biba_dominate_effective(obj, subj)) 2990 return (EACCES); 2991 2992 return (0); 2993} 2994 2995static int 2996biba_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2997 struct label *vplabel, acl_type_t type) 2998{ 2999 struct mac_biba *subj, *obj; 3000 3001 if (!biba_enabled) 3002 return (0); 3003 3004 subj = SLOT(cred->cr_label); 3005 obj = SLOT(vplabel); 3006 3007 if (!biba_dominate_effective(obj, subj)) 3008 return (EACCES); 3009 3010 return (0); 3011} 3012 3013static int 3014biba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 3015 struct label *vplabel, int attrnamespace, const char *name) 3016{ 3017 struct mac_biba *subj, *obj; 3018 3019 if (!biba_enabled) 3020 return (0); 3021 3022 subj = SLOT(cred->cr_label); 3023 obj = SLOT(vplabel); 3024 3025 if (!biba_dominate_effective(obj, subj)) 3026 return (EACCES); 3027 3028 return (0); 3029} 3030 3031static int 3032biba_vnode_check_link(struct ucred *cred, struct vnode *dvp, 3033 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3034 struct componentname *cnp) 3035{ 3036 struct mac_biba *subj, *obj; 3037 3038 if (!biba_enabled) 3039 return (0); 3040 3041 subj = SLOT(cred->cr_label); 3042 obj = SLOT(dvplabel); 3043 3044 if (!biba_dominate_effective(subj, obj)) 3045 return (EACCES); 3046 3047 obj = SLOT(vplabel); 3048 3049 if (!biba_dominate_effective(subj, obj)) 3050 return (EACCES); 3051 3052 return (0); 3053} 3054 3055static int 3056biba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 3057 struct label *vplabel, int attrnamespace) 3058{ 3059 struct mac_biba *subj, *obj; 3060 3061 if (!biba_enabled) 3062 return (0); 3063 3064 subj = SLOT(cred->cr_label); 3065 obj = SLOT(vplabel); 3066 3067 if (!biba_dominate_effective(obj, subj)) 3068 return (EACCES); 3069 3070 return (0); 3071} 3072 3073static int 3074biba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 3075 struct label *dvplabel, struct componentname *cnp) 3076{ 3077 struct mac_biba *subj, *obj; 3078 3079 if (!biba_enabled) 3080 return (0); 3081 3082 subj = SLOT(cred->cr_label); 3083 obj = SLOT(dvplabel); 3084 3085 if (!biba_dominate_effective(obj, subj)) 3086 return (EACCES); 3087 3088 return (0); 3089} 3090 3091static int 3092biba_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 3093 struct label *vplabel, int prot, int flags) 3094{ 3095 struct mac_biba *subj, *obj; 3096 3097 /* 3098 * Rely on the use of open()-time protections to handle 3099 * non-revocation cases. 3100 */ 3101 if (!biba_enabled || !revocation_enabled) 3102 return (0); 3103 3104 subj = SLOT(cred->cr_label); 3105 obj = SLOT(vplabel); 3106 3107 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 3108 if (!biba_dominate_effective(obj, subj)) 3109 return (EACCES); 3110 } 3111 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 3112 if (!biba_dominate_effective(subj, obj)) 3113 return (EACCES); 3114 } 3115 3116 return (0); 3117} 3118 3119static int 3120biba_vnode_check_open(struct ucred *cred, struct vnode *vp, 3121 struct label *vplabel, accmode_t accmode) 3122{ 3123 struct mac_biba *subj, *obj; 3124 3125 if (!biba_enabled) 3126 return (0); 3127 3128 subj = SLOT(cred->cr_label); 3129 obj = SLOT(vplabel); 3130 3131 /* XXX privilege override for admin? */ 3132 if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 3133 if (!biba_dominate_effective(obj, subj)) 3134 return (EACCES); 3135 } 3136 if (accmode & VMODIFY_PERMS) { 3137 if (!biba_dominate_effective(subj, obj)) 3138 return (EACCES); 3139 } 3140 3141 return (0); 3142} 3143 3144static int 3145biba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 3146 struct vnode *vp, struct label *vplabel) 3147{ 3148 struct mac_biba *subj, *obj; 3149 3150 if (!biba_enabled || !revocation_enabled) 3151 return (0); 3152 3153 subj = SLOT(active_cred->cr_label); 3154 obj = SLOT(vplabel); 3155 3156 if (!biba_dominate_effective(obj, subj)) 3157 return (EACCES); 3158 3159 return (0); 3160} 3161 3162static int 3163biba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 3164 struct vnode *vp, struct label *vplabel) 3165{ 3166 struct mac_biba *subj, *obj; 3167 3168 if (!biba_enabled || !revocation_enabled) 3169 return (0); 3170 3171 subj = SLOT(active_cred->cr_label); 3172 obj = SLOT(vplabel); 3173 3174 if (!biba_dominate_effective(obj, subj)) 3175 return (EACCES); 3176 3177 return (0); 3178} 3179 3180static int 3181biba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 3182 struct label *dvplabel) 3183{ 3184 struct mac_biba *subj, *obj; 3185 3186 if (!biba_enabled) 3187 return (0); 3188 3189 subj = SLOT(cred->cr_label); 3190 obj = SLOT(dvplabel); 3191 3192 if (!biba_dominate_effective(obj, subj)) 3193 return (EACCES); 3194 3195 return (0); 3196} 3197 3198static int 3199biba_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 3200 struct label *vplabel) 3201{ 3202 struct mac_biba *subj, *obj; 3203 3204 if (!biba_enabled) 3205 return (0); 3206 3207 subj = SLOT(cred->cr_label); 3208 obj = SLOT(vplabel); 3209 3210 if (!biba_dominate_effective(obj, subj)) 3211 return (EACCES); 3212 3213 return (0); 3214} 3215 3216static int 3217biba_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 3218 struct label *vplabel, struct label *newlabel) 3219{ 3220 struct mac_biba *old, *new, *subj; 3221 int error; 3222 3223 old = SLOT(vplabel); 3224 new = SLOT(newlabel); 3225 subj = SLOT(cred->cr_label); 3226 3227 /* 3228 * If there is a Biba label update for the vnode, it must be a 3229 * effective label. 3230 */ 3231 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 3232 if (error) 3233 return (error); 3234 3235 /* 3236 * To perform a relabel of the vnode (Biba label or not), Biba must 3237 * authorize the relabel. 3238 */ 3239 if (!biba_effective_in_range(old, subj)) 3240 return (EPERM); 3241 3242 /* 3243 * If the Biba label is to be changed, authorize as appropriate. 3244 */ 3245 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 3246 /* 3247 * To change the Biba label on a vnode, the new vnode label 3248 * must be in the subject range. 3249 */ 3250 if (!biba_effective_in_range(new, subj)) 3251 return (EPERM); 3252 3253 /* 3254 * To change the Biba label on the vnode to be EQUAL, the 3255 * subject must have appropriate privilege. 3256 */ 3257 if (biba_contains_equal(new)) { 3258 error = biba_subject_privileged(subj); 3259 if (error) 3260 return (error); 3261 } 3262 } 3263 3264 return (0); 3265} 3266 3267static int 3268biba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 3269 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3270 struct componentname *cnp) 3271{ 3272 struct mac_biba *subj, *obj; 3273 3274 if (!biba_enabled) 3275 return (0); 3276 3277 subj = SLOT(cred->cr_label); 3278 obj = SLOT(dvplabel); 3279 3280 if (!biba_dominate_effective(subj, obj)) 3281 return (EACCES); 3282 3283 obj = SLOT(vplabel); 3284 3285 if (!biba_dominate_effective(subj, obj)) 3286 return (EACCES); 3287 3288 return (0); 3289} 3290 3291static int 3292biba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 3293 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3294 int samedir, struct componentname *cnp) 3295{ 3296 struct mac_biba *subj, *obj; 3297 3298 if (!biba_enabled) 3299 return (0); 3300 3301 subj = SLOT(cred->cr_label); 3302 obj = SLOT(dvplabel); 3303 3304 if (!biba_dominate_effective(subj, obj)) 3305 return (EACCES); 3306 3307 if (vp != NULL) { 3308 obj = SLOT(vplabel); 3309 3310 if (!biba_dominate_effective(subj, obj)) 3311 return (EACCES); 3312 } 3313 3314 return (0); 3315} 3316 3317static int 3318biba_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 3319 struct label *vplabel) 3320{ 3321 struct mac_biba *subj, *obj; 3322 3323 if (!biba_enabled) 3324 return (0); 3325 3326 subj = SLOT(cred->cr_label); 3327 obj = SLOT(vplabel); 3328 3329 if (!biba_dominate_effective(subj, obj)) 3330 return (EACCES); 3331 3332 return (0); 3333} 3334 3335static int 3336biba_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 3337 struct label *vplabel, acl_type_t type, struct acl *acl) 3338{ 3339 struct mac_biba *subj, *obj; 3340 3341 if (!biba_enabled) 3342 return (0); 3343 3344 subj = SLOT(cred->cr_label); 3345 obj = SLOT(vplabel); 3346 3347 if (!biba_dominate_effective(subj, obj)) 3348 return (EACCES); 3349 3350 return (0); 3351} 3352 3353static int 3354biba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 3355 struct label *vplabel, int attrnamespace, const char *name) 3356{ 3357 struct mac_biba *subj, *obj; 3358 3359 if (!biba_enabled) 3360 return (0); 3361 3362 subj = SLOT(cred->cr_label); 3363 obj = SLOT(vplabel); 3364 3365 if (!biba_dominate_effective(subj, obj)) 3366 return (EACCES); 3367 3368 /* XXX: protect the MAC EA in a special way? */ 3369 3370 return (0); 3371} 3372 3373static int 3374biba_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 3375 struct label *vplabel, u_long flags) 3376{ 3377 struct mac_biba *subj, *obj; 3378 3379 if (!biba_enabled) 3380 return (0); 3381 3382 subj = SLOT(cred->cr_label); 3383 obj = SLOT(vplabel); 3384 3385 if (!biba_dominate_effective(subj, obj)) 3386 return (EACCES); 3387 3388 return (0); 3389} 3390 3391static int 3392biba_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 3393 struct label *vplabel, mode_t mode) 3394{ 3395 struct mac_biba *subj, *obj; 3396 3397 if (!biba_enabled) 3398 return (0); 3399 3400 subj = SLOT(cred->cr_label); 3401 obj = SLOT(vplabel); 3402 3403 if (!biba_dominate_effective(subj, obj)) 3404 return (EACCES); 3405 3406 return (0); 3407} 3408 3409static int 3410biba_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 3411 struct label *vplabel, uid_t uid, gid_t gid) 3412{ 3413 struct mac_biba *subj, *obj; 3414 3415 if (!biba_enabled) 3416 return (0); 3417 3418 subj = SLOT(cred->cr_label); 3419 obj = SLOT(vplabel); 3420 3421 if (!biba_dominate_effective(subj, obj)) 3422 return (EACCES); 3423 3424 return (0); 3425} 3426 3427static int 3428biba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 3429 struct label *vplabel, struct timespec atime, struct timespec mtime) 3430{ 3431 struct mac_biba *subj, *obj; 3432 3433 if (!biba_enabled) 3434 return (0); 3435 3436 subj = SLOT(cred->cr_label); 3437 obj = SLOT(vplabel); 3438 3439 if (!biba_dominate_effective(subj, obj)) 3440 return (EACCES); 3441 3442 return (0); 3443} 3444 3445static int 3446biba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 3447 struct vnode *vp, struct label *vplabel) 3448{ 3449 struct mac_biba *subj, *obj; 3450 3451 if (!biba_enabled) 3452 return (0); 3453 3454 subj = SLOT(active_cred->cr_label); 3455 obj = SLOT(vplabel); 3456 3457 if (!biba_dominate_effective(obj, subj)) 3458 return (EACCES); 3459 3460 return (0); 3461} 3462 3463static int 3464biba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 3465 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3466 struct componentname *cnp) 3467{ 3468 struct mac_biba *subj, *obj; 3469 3470 if (!biba_enabled) 3471 return (0); 3472 3473 subj = SLOT(cred->cr_label); 3474 obj = SLOT(dvplabel); 3475 3476 if (!biba_dominate_effective(subj, obj)) 3477 return (EACCES); 3478 3479 obj = SLOT(vplabel); 3480 3481 if (!biba_dominate_effective(subj, obj)) 3482 return (EACCES); 3483 3484 return (0); 3485} 3486 3487static int 3488biba_vnode_check_write(struct ucred *active_cred, 3489 struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 3490{ 3491 struct mac_biba *subj, *obj; 3492 3493 if (!biba_enabled || !revocation_enabled) 3494 return (0); 3495 3496 subj = SLOT(active_cred->cr_label); 3497 obj = SLOT(vplabel); 3498 3499 if (!biba_dominate_effective(subj, obj)) 3500 return (EACCES); 3501 3502 return (0); 3503} 3504 3505static int 3506biba_vnode_create_extattr(struct ucred *cred, struct mount *mp, 3507 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 3508 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 3509{ 3510 struct mac_biba *source, *dest, mb_temp; 3511 size_t buflen; 3512 int error; 3513 3514 buflen = sizeof(mb_temp); 3515 bzero(&mb_temp, buflen); 3516 3517 source = SLOT(cred->cr_label); 3518 dest = SLOT(vplabel); 3519 biba_copy_effective(source, &mb_temp); 3520 3521 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 3522 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread); 3523 if (error == 0) 3524 biba_copy_effective(source, dest); 3525 return (error); 3526} 3527 3528static void 3529biba_vnode_relabel(struct ucred *cred, struct vnode *vp, 3530 struct label *vplabel, struct label *newlabel) 3531{ 3532 struct mac_biba *source, *dest; 3533 3534 source = SLOT(newlabel); 3535 dest = SLOT(vplabel); 3536 3537 biba_copy(source, dest); 3538} 3539 3540static int 3541biba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 3542 struct label *vplabel, struct label *intlabel) 3543{ 3544 struct mac_biba *source, mb_temp; 3545 size_t buflen; 3546 int error; 3547 3548 buflen = sizeof(mb_temp); 3549 bzero(&mb_temp, buflen); 3550 3551 source = SLOT(intlabel); 3552 if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0) 3553 return (0); 3554 3555 biba_copy_effective(source, &mb_temp); 3556 3557 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 3558 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread); 3559 return (error); 3560} 3561 3562static struct mac_policy_ops mac_biba_ops = 3563{ 3564 .mpo_init = biba_init, 3565 3566 .mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive, 3567 .mpo_bpfdesc_create = biba_bpfdesc_create, 3568 .mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf, 3569 .mpo_bpfdesc_destroy_label = biba_destroy_label, 3570 .mpo_bpfdesc_init_label = biba_init_label, 3571 3572 .mpo_cred_associate_nfsd = biba_cred_associate_nfsd, 3573 .mpo_cred_check_relabel = biba_cred_check_relabel, 3574 .mpo_cred_check_visible = biba_cred_check_visible, 3575 .mpo_cred_copy_label = biba_copy_label, 3576 .mpo_cred_create_init = biba_cred_create_init, 3577 .mpo_cred_create_swapper = biba_cred_create_swapper, 3578 .mpo_cred_destroy_label = biba_destroy_label, 3579 .mpo_cred_externalize_label = biba_externalize_label, 3580 .mpo_cred_init_label = biba_init_label, 3581 .mpo_cred_internalize_label = biba_internalize_label, 3582 .mpo_cred_relabel = biba_cred_relabel, 3583 3584 .mpo_devfs_create_device = biba_devfs_create_device, 3585 .mpo_devfs_create_directory = biba_devfs_create_directory, 3586 .mpo_devfs_create_symlink = biba_devfs_create_symlink, 3587 .mpo_devfs_destroy_label = biba_destroy_label, 3588 .mpo_devfs_init_label = biba_init_label, 3589 .mpo_devfs_update = biba_devfs_update, 3590 .mpo_devfs_vnode_associate = biba_devfs_vnode_associate, 3591 3592 .mpo_ifnet_check_relabel = biba_ifnet_check_relabel, 3593 .mpo_ifnet_check_transmit = biba_ifnet_check_transmit, 3594 .mpo_ifnet_copy_label = biba_copy_label, 3595 .mpo_ifnet_create = biba_ifnet_create, 3596 .mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf, 3597 .mpo_ifnet_destroy_label = biba_destroy_label, 3598 .mpo_ifnet_externalize_label = biba_externalize_label, 3599 .mpo_ifnet_init_label = biba_init_label, 3600 .mpo_ifnet_internalize_label = biba_internalize_label, 3601 .mpo_ifnet_relabel = biba_ifnet_relabel, 3602 3603 .mpo_inpcb_check_deliver = biba_inpcb_check_deliver, 3604 .mpo_inpcb_check_visible = biba_inpcb_check_visible, 3605 .mpo_inpcb_create = biba_inpcb_create, 3606 .mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf, 3607 .mpo_inpcb_destroy_label = biba_destroy_label, 3608 .mpo_inpcb_init_label = biba_init_label_waitcheck, 3609 .mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel, 3610 3611 .mpo_ip6q_create = biba_ip6q_create, 3612 .mpo_ip6q_destroy_label = biba_destroy_label, 3613 .mpo_ip6q_init_label = biba_init_label_waitcheck, 3614 .mpo_ip6q_match = biba_ip6q_match, 3615 .mpo_ip6q_reassemble = biba_ip6q_reassemble, 3616 .mpo_ip6q_update = biba_ip6q_update, 3617 3618 .mpo_ipq_create = biba_ipq_create, 3619 .mpo_ipq_destroy_label = biba_destroy_label, 3620 .mpo_ipq_init_label = biba_init_label_waitcheck, 3621 .mpo_ipq_match = biba_ipq_match, 3622 .mpo_ipq_reassemble = biba_ipq_reassemble, 3623 .mpo_ipq_update = biba_ipq_update, 3624 3625 .mpo_kld_check_load = biba_kld_check_load, 3626 3627 .mpo_mbuf_copy_label = biba_copy_label, 3628 .mpo_mbuf_destroy_label = biba_destroy_label, 3629 .mpo_mbuf_init_label = biba_init_label_waitcheck, 3630 3631 .mpo_mount_check_stat = biba_mount_check_stat, 3632 .mpo_mount_create = biba_mount_create, 3633 .mpo_mount_destroy_label = biba_destroy_label, 3634 .mpo_mount_init_label = biba_init_label, 3635 3636 .mpo_netinet_arp_send = biba_netinet_arp_send, 3637 .mpo_netinet_firewall_reply = biba_netinet_firewall_reply, 3638 .mpo_netinet_firewall_send = biba_netinet_firewall_send, 3639 .mpo_netinet_fragment = biba_netinet_fragment, 3640 .mpo_netinet_icmp_reply = biba_netinet_icmp_reply, 3641 .mpo_netinet_igmp_send = biba_netinet_igmp_send, 3642 3643 .mpo_netinet6_nd6_send = biba_netinet6_nd6_send, 3644 3645 .mpo_pipe_check_ioctl = biba_pipe_check_ioctl, 3646 .mpo_pipe_check_poll = biba_pipe_check_poll, 3647 .mpo_pipe_check_read = biba_pipe_check_read, 3648 .mpo_pipe_check_relabel = biba_pipe_check_relabel, 3649 .mpo_pipe_check_stat = biba_pipe_check_stat, 3650 .mpo_pipe_check_write = biba_pipe_check_write, 3651 .mpo_pipe_copy_label = biba_copy_label, 3652 .mpo_pipe_create = biba_pipe_create, 3653 .mpo_pipe_destroy_label = biba_destroy_label, 3654 .mpo_pipe_externalize_label = biba_externalize_label, 3655 .mpo_pipe_init_label = biba_init_label, 3656 .mpo_pipe_internalize_label = biba_internalize_label, 3657 .mpo_pipe_relabel = biba_pipe_relabel, 3658 3659 .mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly, 3660 .mpo_posixsem_check_open = biba_posixsem_check_openunlink, 3661 .mpo_posixsem_check_post = biba_posixsem_check_write, 3662 .mpo_posixsem_check_setmode = biba_posixsem_check_setmode, 3663 .mpo_posixsem_check_setowner = biba_posixsem_check_setowner, 3664 .mpo_posixsem_check_stat = biba_posixsem_check_rdonly, 3665 .mpo_posixsem_check_unlink = biba_posixsem_check_openunlink, 3666 .mpo_posixsem_check_wait = biba_posixsem_check_write, 3667 .mpo_posixsem_create = biba_posixsem_create, 3668 .mpo_posixsem_destroy_label = biba_destroy_label, 3669 .mpo_posixsem_init_label = biba_init_label, 3670 3671 .mpo_posixshm_check_mmap = biba_posixshm_check_mmap, 3672 .mpo_posixshm_check_open = biba_posixshm_check_open, 3673 .mpo_posixshm_check_read = biba_posixshm_check_read, 3674 .mpo_posixshm_check_setmode = biba_posixshm_check_setmode, 3675 .mpo_posixshm_check_setowner = biba_posixshm_check_setowner, 3676 .mpo_posixshm_check_stat = biba_posixshm_check_stat, 3677 .mpo_posixshm_check_truncate = biba_posixshm_check_truncate, 3678 .mpo_posixshm_check_unlink = biba_posixshm_check_unlink, 3679 .mpo_posixshm_check_write = biba_posixshm_check_write, 3680 .mpo_posixshm_create = biba_posixshm_create, 3681 .mpo_posixshm_destroy_label = biba_destroy_label, 3682 .mpo_posixshm_init_label = biba_init_label, 3683 3684 .mpo_priv_check = biba_priv_check, 3685 3686 .mpo_proc_check_debug = biba_proc_check_debug, 3687 .mpo_proc_check_sched = biba_proc_check_sched, 3688 .mpo_proc_check_signal = biba_proc_check_signal, 3689 3690 .mpo_socket_check_deliver = biba_socket_check_deliver, 3691 .mpo_socket_check_relabel = biba_socket_check_relabel, 3692 .mpo_socket_check_visible = biba_socket_check_visible, 3693 .mpo_socket_copy_label = biba_copy_label, 3694 .mpo_socket_create = biba_socket_create, 3695 .mpo_socket_create_mbuf = biba_socket_create_mbuf, 3696 .mpo_socket_destroy_label = biba_destroy_label, 3697 .mpo_socket_externalize_label = biba_externalize_label, 3698 .mpo_socket_init_label = biba_init_label_waitcheck, 3699 .mpo_socket_internalize_label = biba_internalize_label, 3700 .mpo_socket_newconn = biba_socket_newconn, 3701 .mpo_socket_relabel = biba_socket_relabel, 3702 3703 .mpo_socketpeer_destroy_label = biba_destroy_label, 3704 .mpo_socketpeer_externalize_label = biba_externalize_label, 3705 .mpo_socketpeer_init_label = biba_init_label_waitcheck, 3706 .mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf, 3707 .mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket, 3708 3709 .mpo_syncache_create = biba_syncache_create, 3710 .mpo_syncache_create_mbuf = biba_syncache_create_mbuf, 3711 .mpo_syncache_destroy_label = biba_destroy_label, 3712 .mpo_syncache_init_label = biba_init_label_waitcheck, 3713 3714 .mpo_system_check_acct = biba_system_check_acct, 3715 .mpo_system_check_auditctl = biba_system_check_auditctl, 3716 .mpo_system_check_auditon = biba_system_check_auditon, 3717 .mpo_system_check_swapoff = biba_system_check_swapoff, 3718 .mpo_system_check_swapon = biba_system_check_swapon, 3719 .mpo_system_check_sysctl = biba_system_check_sysctl, 3720 3721 .mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup, 3722 .mpo_sysvmsg_create = biba_sysvmsg_create, 3723 .mpo_sysvmsg_destroy_label = biba_destroy_label, 3724 .mpo_sysvmsg_init_label = biba_init_label, 3725 3726 .mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv, 3727 .mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid, 3728 .mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget, 3729 .mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd, 3730 .mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv, 3731 .mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl, 3732 .mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup, 3733 .mpo_sysvmsq_create = biba_sysvmsq_create, 3734 .mpo_sysvmsq_destroy_label = biba_destroy_label, 3735 .mpo_sysvmsq_init_label = biba_init_label, 3736 3737 .mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl, 3738 .mpo_sysvsem_check_semget = biba_sysvsem_check_semget, 3739 .mpo_sysvsem_check_semop = biba_sysvsem_check_semop, 3740 .mpo_sysvsem_cleanup = biba_sysvsem_cleanup, 3741 .mpo_sysvsem_create = biba_sysvsem_create, 3742 .mpo_sysvsem_destroy_label = biba_destroy_label, 3743 .mpo_sysvsem_init_label = biba_init_label, 3744 3745 .mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat, 3746 .mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl, 3747 .mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget, 3748 .mpo_sysvshm_cleanup = biba_sysvshm_cleanup, 3749 .mpo_sysvshm_create = biba_sysvshm_create, 3750 .mpo_sysvshm_destroy_label = biba_destroy_label, 3751 .mpo_sysvshm_init_label = biba_init_label, 3752 3753 .mpo_vnode_associate_extattr = biba_vnode_associate_extattr, 3754 .mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel, 3755 .mpo_vnode_check_access = biba_vnode_check_open, 3756 .mpo_vnode_check_chdir = biba_vnode_check_chdir, 3757 .mpo_vnode_check_chroot = biba_vnode_check_chroot, 3758 .mpo_vnode_check_create = biba_vnode_check_create, 3759 .mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl, 3760 .mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr, 3761 .mpo_vnode_check_exec = biba_vnode_check_exec, 3762 .mpo_vnode_check_getacl = biba_vnode_check_getacl, 3763 .mpo_vnode_check_getextattr = biba_vnode_check_getextattr, 3764 .mpo_vnode_check_link = biba_vnode_check_link, 3765 .mpo_vnode_check_listextattr = biba_vnode_check_listextattr, 3766 .mpo_vnode_check_lookup = biba_vnode_check_lookup, 3767 .mpo_vnode_check_mmap = biba_vnode_check_mmap, 3768 .mpo_vnode_check_open = biba_vnode_check_open, 3769 .mpo_vnode_check_poll = biba_vnode_check_poll, 3770 .mpo_vnode_check_read = biba_vnode_check_read, 3771 .mpo_vnode_check_readdir = biba_vnode_check_readdir, 3772 .mpo_vnode_check_readlink = biba_vnode_check_readlink, 3773 .mpo_vnode_check_relabel = biba_vnode_check_relabel, 3774 .mpo_vnode_check_rename_from = biba_vnode_check_rename_from, 3775 .mpo_vnode_check_rename_to = biba_vnode_check_rename_to, 3776 .mpo_vnode_check_revoke = biba_vnode_check_revoke, 3777 .mpo_vnode_check_setacl = biba_vnode_check_setacl, 3778 .mpo_vnode_check_setextattr = biba_vnode_check_setextattr, 3779 .mpo_vnode_check_setflags = biba_vnode_check_setflags, 3780 .mpo_vnode_check_setmode = biba_vnode_check_setmode, 3781 .mpo_vnode_check_setowner = biba_vnode_check_setowner, 3782 .mpo_vnode_check_setutimes = biba_vnode_check_setutimes, 3783 .mpo_vnode_check_stat = biba_vnode_check_stat, 3784 .mpo_vnode_check_unlink = biba_vnode_check_unlink, 3785 .mpo_vnode_check_write = biba_vnode_check_write, 3786 .mpo_vnode_create_extattr = biba_vnode_create_extattr, 3787 .mpo_vnode_copy_label = biba_copy_label, 3788 .mpo_vnode_destroy_label = biba_destroy_label, 3789 .mpo_vnode_externalize_label = biba_externalize_label, 3790 .mpo_vnode_init_label = biba_init_label, 3791 .mpo_vnode_internalize_label = biba_internalize_label, 3792 .mpo_vnode_relabel = biba_vnode_relabel, 3793 .mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr, 3794}; 3795 3796MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 3797 MPC_LOADTIME_FLAG_NOTLATE, &biba_slot); 3798