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