mac_biba.c revision 263140
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 263140 2014-03-14 02:58:48Z glebius $ 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 const char *dn; 952 int biba_type; 953 954 mb = SLOT(delabel); 955 dn = devtoname(dev); 956 if (strcmp(dn, "null") == 0 || 957 strcmp(dn, "zero") == 0 || 958 strcmp(dn, "random") == 0 || 959 strncmp(dn, "fd/", strlen("fd/")) == 0) 960 biba_type = MAC_BIBA_TYPE_EQUAL; 961 else if (ptys_equal && 962 (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 963 strncmp(dn, "pts/", strlen("pts/")) == 0 || 964 strncmp(dn, "ptyp", strlen("ptyp")) == 0)) 965 biba_type = MAC_BIBA_TYPE_EQUAL; 966 else 967 biba_type = MAC_BIBA_TYPE_HIGH; 968 biba_set_effective(mb, biba_type, 0, NULL); 969} 970 971static void 972biba_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 973 struct devfs_dirent *de, struct label *delabel) 974{ 975 struct mac_biba *mb; 976 977 mb = SLOT(delabel); 978 979 biba_set_effective(mb, MAC_BIBA_TYPE_HIGH, 0, NULL); 980} 981 982static void 983biba_devfs_create_symlink(struct ucred *cred, struct mount *mp, 984 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 985 struct label *delabel) 986{ 987 struct mac_biba *source, *dest; 988 989 source = SLOT(cred->cr_label); 990 dest = SLOT(delabel); 991 992 biba_copy_effective(source, dest); 993} 994 995static void 996biba_devfs_update(struct mount *mp, struct devfs_dirent *de, 997 struct label *delabel, struct vnode *vp, struct label *vplabel) 998{ 999 struct mac_biba *source, *dest; 1000 1001 source = SLOT(vplabel); 1002 dest = SLOT(delabel); 1003 1004 biba_copy(source, dest); 1005} 1006 1007static void 1008biba_devfs_vnode_associate(struct mount *mp, struct label *mntlabel, 1009 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 1010 struct label *vplabel) 1011{ 1012 struct mac_biba *source, *dest; 1013 1014 source = SLOT(delabel); 1015 dest = SLOT(vplabel); 1016 1017 biba_copy_effective(source, dest); 1018} 1019 1020static int 1021biba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1022 struct label *ifplabel, struct label *newlabel) 1023{ 1024 struct mac_biba *subj, *new; 1025 int error; 1026 1027 subj = SLOT(cred->cr_label); 1028 new = SLOT(newlabel); 1029 1030 /* 1031 * If there is a Biba label update for the interface, it may be an 1032 * update of the effective, range, or both. 1033 */ 1034 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1035 if (error) 1036 return (error); 1037 1038 /* 1039 * Relabling network interfaces requires Biba privilege. 1040 */ 1041 error = biba_subject_privileged(subj); 1042 if (error) 1043 return (error); 1044 1045 return (0); 1046} 1047 1048static int 1049biba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1050 struct mbuf *m, struct label *mlabel) 1051{ 1052 struct mac_biba *p, *i; 1053 1054 if (!biba_enabled) 1055 return (0); 1056 1057 p = SLOT(mlabel); 1058 i = SLOT(ifplabel); 1059 1060 return (biba_effective_in_range(p, i) ? 0 : EACCES); 1061} 1062 1063static void 1064biba_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1065{ 1066 char tifname[IFNAMSIZ], *p, *q; 1067 char tiflist[sizeof(trusted_interfaces)]; 1068 struct mac_biba *dest; 1069 int len, type; 1070 1071 dest = SLOT(ifplabel); 1072 1073 if (ifp->if_type == IFT_LOOP || interfaces_equal != 0) { 1074 type = MAC_BIBA_TYPE_EQUAL; 1075 goto set; 1076 } 1077 1078 if (trust_all_interfaces) { 1079 type = MAC_BIBA_TYPE_HIGH; 1080 goto set; 1081 } 1082 1083 type = MAC_BIBA_TYPE_LOW; 1084 1085 if (trusted_interfaces[0] == '\0' || 1086 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1087 goto set; 1088 1089 bzero(tiflist, sizeof(tiflist)); 1090 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1091 if(*p != ' ' && *p != '\t') 1092 *q = *p; 1093 1094 for (p = q = tiflist;; p++) { 1095 if (*p == ',' || *p == '\0') { 1096 len = p - q; 1097 if (len < IFNAMSIZ) { 1098 bzero(tifname, sizeof(tifname)); 1099 bcopy(q, tifname, len); 1100 if (strcmp(tifname, ifp->if_xname) == 0) { 1101 type = MAC_BIBA_TYPE_HIGH; 1102 break; 1103 } 1104 } else { 1105 *p = '\0'; 1106 printf("mac_biba warning: interface name " 1107 "\"%s\" is too long (must be < %d)\n", 1108 q, IFNAMSIZ); 1109 } 1110 if (*p == '\0') 1111 break; 1112 q = p + 1; 1113 } 1114 } 1115set: 1116 biba_set_effective(dest, type, 0, NULL); 1117 biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1118} 1119 1120static void 1121biba_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1122 struct mbuf *m, struct label *mlabel) 1123{ 1124 struct mac_biba *source, *dest; 1125 1126 source = SLOT(ifplabel); 1127 dest = SLOT(mlabel); 1128 1129 biba_copy_effective(source, dest); 1130} 1131 1132static void 1133biba_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1134 struct label *ifplabel, struct label *newlabel) 1135{ 1136 struct mac_biba *source, *dest; 1137 1138 source = SLOT(newlabel); 1139 dest = SLOT(ifplabel); 1140 1141 biba_copy(source, dest); 1142} 1143 1144static int 1145biba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1146 struct mbuf *m, struct label *mlabel) 1147{ 1148 struct mac_biba *p, *i; 1149 1150 if (!biba_enabled) 1151 return (0); 1152 1153 p = SLOT(mlabel); 1154 i = SLOT(inplabel); 1155 1156 return (biba_equal_effective(p, i) ? 0 : EACCES); 1157} 1158 1159static int 1160biba_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 1161 struct label *inplabel) 1162{ 1163 struct mac_biba *subj, *obj; 1164 1165 if (!biba_enabled) 1166 return (0); 1167 1168 subj = SLOT(cred->cr_label); 1169 obj = SLOT(inplabel); 1170 1171 if (!biba_dominate_effective(obj, subj)) 1172 return (ENOENT); 1173 1174 return (0); 1175} 1176 1177static void 1178biba_inpcb_create(struct socket *so, struct label *solabel, 1179 struct inpcb *inp, struct label *inplabel) 1180{ 1181 struct mac_biba *source, *dest; 1182 1183 source = SLOT(solabel); 1184 dest = SLOT(inplabel); 1185 1186 SOCK_LOCK(so); 1187 biba_copy_effective(source, dest); 1188 SOCK_UNLOCK(so); 1189} 1190 1191static void 1192biba_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1193 struct mbuf *m, struct label *mlabel) 1194{ 1195 struct mac_biba *source, *dest; 1196 1197 source = SLOT(inplabel); 1198 dest = SLOT(mlabel); 1199 1200 biba_copy_effective(source, dest); 1201} 1202 1203static void 1204biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1205 struct inpcb *inp, struct label *inplabel) 1206{ 1207 struct mac_biba *source, *dest; 1208 1209 SOCK_LOCK_ASSERT(so); 1210 1211 source = SLOT(solabel); 1212 dest = SLOT(inplabel); 1213 1214 biba_copy(source, dest); 1215} 1216 1217static void 1218biba_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1219 struct label *q6label) 1220{ 1221 struct mac_biba *source, *dest; 1222 1223 source = SLOT(mlabel); 1224 dest = SLOT(q6label); 1225 1226 biba_copy_effective(source, dest); 1227} 1228 1229static int 1230biba_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1231 struct label *q6label) 1232{ 1233 struct mac_biba *a, *b; 1234 1235 a = SLOT(q6label); 1236 b = SLOT(mlabel); 1237 1238 return (biba_equal_effective(a, b)); 1239} 1240 1241static void 1242biba_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1243 struct label *mlabel) 1244{ 1245 struct mac_biba *source, *dest; 1246 1247 source = SLOT(q6label); 1248 dest = SLOT(mlabel); 1249 1250 /* Just use the head, since we require them all to match. */ 1251 biba_copy_effective(source, dest); 1252} 1253 1254static void 1255biba_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1256 struct label *q6label) 1257{ 1258 1259 /* NOOP: we only accept matching labels, so no need to update */ 1260} 1261 1262static void 1263biba_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1264 struct label *qlabel) 1265{ 1266 struct mac_biba *source, *dest; 1267 1268 source = SLOT(mlabel); 1269 dest = SLOT(qlabel); 1270 1271 biba_copy_effective(source, dest); 1272} 1273 1274static int 1275biba_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1276 struct label *qlabel) 1277{ 1278 struct mac_biba *a, *b; 1279 1280 a = SLOT(qlabel); 1281 b = SLOT(mlabel); 1282 1283 return (biba_equal_effective(a, b)); 1284} 1285 1286static void 1287biba_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1288 struct label *mlabel) 1289{ 1290 struct mac_biba *source, *dest; 1291 1292 source = SLOT(qlabel); 1293 dest = SLOT(mlabel); 1294 1295 /* Just use the head, since we require them all to match. */ 1296 biba_copy_effective(source, dest); 1297} 1298 1299static void 1300biba_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1301 struct label *qlabel) 1302{ 1303 1304 /* NOOP: we only accept matching labels, so no need to update */ 1305} 1306 1307static int 1308biba_kld_check_load(struct ucred *cred, struct vnode *vp, 1309 struct label *vplabel) 1310{ 1311 struct mac_biba *subj, *obj; 1312 int error; 1313 1314 if (!biba_enabled) 1315 return (0); 1316 1317 subj = SLOT(cred->cr_label); 1318 1319 error = biba_subject_privileged(subj); 1320 if (error) 1321 return (error); 1322 1323 obj = SLOT(vplabel); 1324 if (!biba_high_effective(obj)) 1325 return (EACCES); 1326 1327 return (0); 1328} 1329 1330static int 1331biba_mount_check_stat(struct ucred *cred, struct mount *mp, 1332 struct label *mplabel) 1333{ 1334 struct mac_biba *subj, *obj; 1335 1336 if (!biba_enabled) 1337 return (0); 1338 1339 subj = SLOT(cred->cr_label); 1340 obj = SLOT(mplabel); 1341 1342 if (!biba_dominate_effective(obj, subj)) 1343 return (EACCES); 1344 1345 return (0); 1346} 1347 1348static void 1349biba_mount_create(struct ucred *cred, struct mount *mp, 1350 struct label *mplabel) 1351{ 1352 struct mac_biba *source, *dest; 1353 1354 source = SLOT(cred->cr_label); 1355 dest = SLOT(mplabel); 1356 1357 biba_copy_effective(source, dest); 1358} 1359 1360static void 1361biba_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel, 1362 struct mbuf *m, struct label *mlabel) 1363{ 1364 struct mac_biba *dest; 1365 1366 dest = SLOT(mlabel); 1367 1368 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1369} 1370 1371static void 1372biba_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1373 struct mbuf *m, struct label *mlabel) 1374{ 1375 struct mac_biba *dest; 1376 1377 dest = SLOT(mlabel); 1378 1379 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1380} 1381 1382static void 1383biba_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1384 struct mbuf *msend, struct label *msendlabel) 1385{ 1386 struct mac_biba *source, *dest; 1387 1388 source = SLOT(mrecvlabel); 1389 dest = SLOT(msendlabel); 1390 1391 biba_copy_effective(source, dest); 1392} 1393 1394static void 1395biba_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1396{ 1397 struct mac_biba *dest; 1398 1399 dest = SLOT(mlabel); 1400 1401 /* XXX: where is the label for the firewall really coming from? */ 1402 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1403} 1404 1405static void 1406biba_netinet_fragment(struct mbuf *m, struct label *mlabel, 1407 struct mbuf *frag, struct label *fraglabel) 1408{ 1409 struct mac_biba *source, *dest; 1410 1411 source = SLOT(mlabel); 1412 dest = SLOT(fraglabel); 1413 1414 biba_copy_effective(source, dest); 1415} 1416 1417static void 1418biba_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1419 struct mbuf *msend, struct label *msendlabel) 1420{ 1421 struct mac_biba *source, *dest; 1422 1423 source = SLOT(mrecvlabel); 1424 dest = SLOT(msendlabel); 1425 1426 biba_copy_effective(source, dest); 1427} 1428 1429static void 1430biba_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1431 struct mbuf *m, struct label *mlabel) 1432{ 1433 struct mac_biba *dest; 1434 1435 dest = SLOT(mlabel); 1436 1437 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1438} 1439 1440static void 1441biba_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1442 struct mbuf *m, struct label *mlabel) 1443{ 1444 struct mac_biba *dest; 1445 1446 dest = SLOT(mlabel); 1447 1448 biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1449} 1450 1451static int 1452biba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1453 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1454{ 1455 1456 if(!biba_enabled) 1457 return (0); 1458 1459 /* XXX: This will be implemented soon... */ 1460 1461 return (0); 1462} 1463 1464static int 1465biba_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1466 struct label *pplabel) 1467{ 1468 struct mac_biba *subj, *obj; 1469 1470 if (!biba_enabled) 1471 return (0); 1472 1473 subj = SLOT(cred->cr_label); 1474 obj = SLOT(pplabel); 1475 1476 if (!biba_dominate_effective(obj, subj)) 1477 return (EACCES); 1478 1479 return (0); 1480} 1481 1482static int 1483biba_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1484 struct label *pplabel) 1485{ 1486 struct mac_biba *subj, *obj; 1487 1488 if (!biba_enabled) 1489 return (0); 1490 1491 subj = SLOT(cred->cr_label); 1492 obj = SLOT(pplabel); 1493 1494 if (!biba_dominate_effective(obj, subj)) 1495 return (EACCES); 1496 1497 return (0); 1498} 1499 1500static int 1501biba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1502 struct label *pplabel, struct label *newlabel) 1503{ 1504 struct mac_biba *subj, *obj, *new; 1505 int error; 1506 1507 new = SLOT(newlabel); 1508 subj = SLOT(cred->cr_label); 1509 obj = SLOT(pplabel); 1510 1511 /* 1512 * If there is a Biba label update for a pipe, it must be a effective 1513 * update. 1514 */ 1515 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 1516 if (error) 1517 return (error); 1518 1519 /* 1520 * To perform a relabel of a pipe (Biba label or not), Biba must 1521 * authorize the relabel. 1522 */ 1523 if (!biba_effective_in_range(obj, subj)) 1524 return (EPERM); 1525 1526 /* 1527 * If the Biba label is to be changed, authorize as appropriate. 1528 */ 1529 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 1530 /* 1531 * To change the Biba label on a pipe, the new pipe label 1532 * must be in the subject range. 1533 */ 1534 if (!biba_effective_in_range(new, subj)) 1535 return (EPERM); 1536 1537 /* 1538 * To change the Biba label on a pipe to be EQUAL, the 1539 * subject must have appropriate privilege. 1540 */ 1541 if (biba_contains_equal(new)) { 1542 error = biba_subject_privileged(subj); 1543 if (error) 1544 return (error); 1545 } 1546 } 1547 1548 return (0); 1549} 1550 1551static int 1552biba_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 1553 struct label *pplabel) 1554{ 1555 struct mac_biba *subj, *obj; 1556 1557 if (!biba_enabled) 1558 return (0); 1559 1560 subj = SLOT(cred->cr_label); 1561 obj = SLOT(pplabel); 1562 1563 if (!biba_dominate_effective(obj, subj)) 1564 return (EACCES); 1565 1566 return (0); 1567} 1568 1569static int 1570biba_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1571 struct label *pplabel) 1572{ 1573 struct mac_biba *subj, *obj; 1574 1575 if (!biba_enabled) 1576 return (0); 1577 1578 subj = SLOT(cred->cr_label); 1579 obj = SLOT(pplabel); 1580 1581 if (!biba_dominate_effective(subj, obj)) 1582 return (EACCES); 1583 1584 return (0); 1585} 1586 1587static void 1588biba_pipe_create(struct ucred *cred, struct pipepair *pp, 1589 struct label *pplabel) 1590{ 1591 struct mac_biba *source, *dest; 1592 1593 source = SLOT(cred->cr_label); 1594 dest = SLOT(pplabel); 1595 1596 biba_copy_effective(source, dest); 1597} 1598 1599static void 1600biba_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1601 struct label *pplabel, struct label *newlabel) 1602{ 1603 struct mac_biba *source, *dest; 1604 1605 source = SLOT(newlabel); 1606 dest = SLOT(pplabel); 1607 1608 biba_copy(source, dest); 1609} 1610 1611static int 1612biba_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks, 1613 struct label *kslabel) 1614{ 1615 struct mac_biba *subj, *obj; 1616 1617 if (!biba_enabled) 1618 return (0); 1619 1620 subj = SLOT(cred->cr_label); 1621 obj = SLOT(kslabel); 1622 1623 if (!biba_dominate_effective(subj, obj)) 1624 return (EACCES); 1625 1626 return (0); 1627} 1628 1629static int 1630biba_posixsem_check_setmode(struct ucred *cred, struct ksem *ks, 1631 struct label *kslabel, mode_t mode) 1632{ 1633 struct mac_biba *subj, *obj; 1634 1635 if (!biba_enabled) 1636 return (0); 1637 1638 subj = SLOT(cred->cr_label); 1639 obj = SLOT(kslabel); 1640 1641 if (!biba_dominate_effective(subj, obj)) 1642 return (EACCES); 1643 1644 return (0); 1645} 1646 1647static int 1648biba_posixsem_check_setowner(struct ucred *cred, struct ksem *ks, 1649 struct label *kslabel, uid_t uid, gid_t gid) 1650{ 1651 struct mac_biba *subj, *obj; 1652 1653 if (!biba_enabled) 1654 return (0); 1655 1656 subj = SLOT(cred->cr_label); 1657 obj = SLOT(kslabel); 1658 1659 if (!biba_dominate_effective(subj, obj)) 1660 return (EACCES); 1661 1662 return (0); 1663} 1664 1665static int 1666biba_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred, 1667 struct ksem *ks, struct label *kslabel) 1668{ 1669 struct mac_biba *subj, *obj; 1670 1671 if (!biba_enabled) 1672 return (0); 1673 1674 subj = SLOT(active_cred->cr_label); 1675 obj = SLOT(kslabel); 1676 1677 if (!biba_dominate_effective(subj, obj)) 1678 return (EACCES); 1679 1680 return (0); 1681} 1682 1683static int 1684biba_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred, 1685 struct ksem *ks, struct label *kslabel) 1686{ 1687 struct mac_biba *subj, *obj; 1688 1689 if (!biba_enabled) 1690 return (0); 1691 1692 subj = SLOT(active_cred->cr_label); 1693 obj = SLOT(kslabel); 1694 1695 if (!biba_dominate_effective(obj, subj)) 1696 return (EACCES); 1697 1698 return (0); 1699} 1700 1701static void 1702biba_posixsem_create(struct ucred *cred, struct ksem *ks, 1703 struct label *kslabel) 1704{ 1705 struct mac_biba *source, *dest; 1706 1707 source = SLOT(cred->cr_label); 1708 dest = SLOT(kslabel); 1709 1710 biba_copy_effective(source, dest); 1711} 1712 1713static int 1714biba_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd, 1715 struct label *shmlabel, int prot, int flags) 1716{ 1717 struct mac_biba *subj, *obj; 1718 1719 if (!biba_enabled || !revocation_enabled) 1720 return (0); 1721 1722 subj = SLOT(cred->cr_label); 1723 obj = SLOT(shmlabel); 1724 1725 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 1726 if (!biba_dominate_effective(obj, subj)) 1727 return (EACCES); 1728 } 1729 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 1730 if (!biba_dominate_effective(subj, obj)) 1731 return (EACCES); 1732 } 1733 1734 return (0); 1735} 1736 1737static int 1738biba_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd, 1739 struct label *shmlabel, accmode_t accmode) 1740{ 1741 struct mac_biba *subj, *obj; 1742 1743 if (!biba_enabled) 1744 return (0); 1745 1746 subj = SLOT(cred->cr_label); 1747 obj = SLOT(shmlabel); 1748 1749 if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 1750 if (!biba_dominate_effective(obj, subj)) 1751 return (EACCES); 1752 } 1753 if (accmode & VMODIFY_PERMS) { 1754 if (!biba_dominate_effective(subj, obj)) 1755 return (EACCES); 1756 } 1757 1758 return (0); 1759} 1760 1761static int 1762biba_posixshm_check_read(struct ucred *active_cred, struct ucred *file_cred, 1763 struct shmfd *vp, struct label *shmlabel) 1764{ 1765 struct mac_biba *subj, *obj; 1766 1767 if (!biba_enabled || !revocation_enabled) 1768 return (0); 1769 1770 subj = SLOT(active_cred->cr_label); 1771 obj = SLOT(shmlabel); 1772 1773 if (!biba_dominate_effective(obj, subj)) 1774 return (EACCES); 1775 1776 return (0); 1777} 1778 1779static int 1780biba_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd, 1781 struct label *shmlabel, mode_t mode) 1782{ 1783 struct mac_biba *subj, *obj; 1784 1785 if (!biba_enabled) 1786 return (0); 1787 1788 subj = SLOT(cred->cr_label); 1789 obj = SLOT(shmlabel); 1790 1791 if (!biba_dominate_effective(subj, obj)) 1792 return (EACCES); 1793 1794 return (0); 1795} 1796 1797static int 1798biba_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd, 1799 struct label *shmlabel, uid_t uid, gid_t gid) 1800{ 1801 struct mac_biba *subj, *obj; 1802 1803 if (!biba_enabled) 1804 return (0); 1805 1806 subj = SLOT(cred->cr_label); 1807 obj = SLOT(shmlabel); 1808 1809 if (!biba_dominate_effective(subj, obj)) 1810 return (EACCES); 1811 1812 return (0); 1813} 1814 1815static int 1816biba_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred, 1817 struct shmfd *shmfd, struct label *shmlabel) 1818{ 1819 struct mac_biba *subj, *obj; 1820 1821 if (!biba_enabled) 1822 return (0); 1823 1824 subj = SLOT(active_cred->cr_label); 1825 obj = SLOT(shmlabel); 1826 1827 if (!biba_dominate_effective(obj, subj)) 1828 return (EACCES); 1829 1830 return (0); 1831} 1832 1833static int 1834biba_posixshm_check_truncate(struct ucred *active_cred, 1835 struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel) 1836{ 1837 struct mac_biba *subj, *obj; 1838 1839 if (!biba_enabled) 1840 return (0); 1841 1842 subj = SLOT(active_cred->cr_label); 1843 obj = SLOT(shmlabel); 1844 1845 if (!biba_dominate_effective(subj, obj)) 1846 return (EACCES); 1847 1848 return (0); 1849} 1850 1851static int 1852biba_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd, 1853 struct label *shmlabel) 1854{ 1855 struct mac_biba *subj, *obj; 1856 1857 if (!biba_enabled) 1858 return (0); 1859 1860 subj = SLOT(cred->cr_label); 1861 obj = SLOT(shmlabel); 1862 1863 if (!biba_dominate_effective(subj, obj)) 1864 return (EACCES); 1865 1866 return (0); 1867} 1868 1869static int 1870biba_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred, 1871 struct shmfd *vp, struct label *shmlabel) 1872{ 1873 struct mac_biba *subj, *obj; 1874 1875 if (!biba_enabled || !revocation_enabled) 1876 return (0); 1877 1878 subj = SLOT(active_cred->cr_label); 1879 obj = SLOT(shmlabel); 1880 1881 if (!biba_dominate_effective(obj, subj)) 1882 return (EACCES); 1883 1884 return (0); 1885} 1886 1887static void 1888biba_posixshm_create(struct ucred *cred, struct shmfd *shmfd, 1889 struct label *shmlabel) 1890{ 1891 struct mac_biba *source, *dest; 1892 1893 source = SLOT(cred->cr_label); 1894 dest = SLOT(shmlabel); 1895 1896 biba_copy_effective(source, dest); 1897} 1898 1899/* 1900 * Some system privileges are allowed regardless of integrity grade; others 1901 * are allowed only when running with privilege with respect to the Biba 1902 * policy as they might otherwise allow bypassing of the integrity policy. 1903 */ 1904static int 1905biba_priv_check(struct ucred *cred, int priv) 1906{ 1907 struct mac_biba *subj; 1908 int error; 1909 1910 if (!biba_enabled) 1911 return (0); 1912 1913 /* 1914 * Exempt only specific privileges from the Biba integrity policy. 1915 */ 1916 switch (priv) { 1917 case PRIV_KTRACE: 1918 case PRIV_MSGBUF: 1919 1920 /* 1921 * Allow processes to manipulate basic process audit properties, and 1922 * to submit audit records. 1923 */ 1924 case PRIV_AUDIT_GETAUDIT: 1925 case PRIV_AUDIT_SETAUDIT: 1926 case PRIV_AUDIT_SUBMIT: 1927 1928 /* 1929 * Allow processes to manipulate their regular UNIX credentials. 1930 */ 1931 case PRIV_CRED_SETUID: 1932 case PRIV_CRED_SETEUID: 1933 case PRIV_CRED_SETGID: 1934 case PRIV_CRED_SETEGID: 1935 case PRIV_CRED_SETGROUPS: 1936 case PRIV_CRED_SETREUID: 1937 case PRIV_CRED_SETREGID: 1938 case PRIV_CRED_SETRESUID: 1939 case PRIV_CRED_SETRESGID: 1940 1941 /* 1942 * Allow processes to perform system monitoring. 1943 */ 1944 case PRIV_SEEOTHERGIDS: 1945 case PRIV_SEEOTHERUIDS: 1946 break; 1947 1948 /* 1949 * Allow access to general process debugging facilities. We 1950 * separately control debugging based on MAC label. 1951 */ 1952 case PRIV_DEBUG_DIFFCRED: 1953 case PRIV_DEBUG_SUGID: 1954 case PRIV_DEBUG_UNPRIV: 1955 1956 /* 1957 * Allow manipulating jails. 1958 */ 1959 case PRIV_JAIL_ATTACH: 1960 1961 /* 1962 * Allow privilege with respect to the Partition policy, but not the 1963 * Privs policy. 1964 */ 1965 case PRIV_MAC_PARTITION: 1966 1967 /* 1968 * Allow privilege with respect to process resource limits and login 1969 * context. 1970 */ 1971 case PRIV_PROC_LIMIT: 1972 case PRIV_PROC_SETLOGIN: 1973 case PRIV_PROC_SETRLIMIT: 1974 1975 /* 1976 * Allow System V and POSIX IPC privileges. 1977 */ 1978 case PRIV_IPC_READ: 1979 case PRIV_IPC_WRITE: 1980 case PRIV_IPC_ADMIN: 1981 case PRIV_IPC_MSGSIZE: 1982 case PRIV_MQ_ADMIN: 1983 1984 /* 1985 * Allow certain scheduler manipulations -- possibly this should be 1986 * controlled by more fine-grained policy, as potentially low 1987 * integrity processes can deny CPU to higher integrity ones. 1988 */ 1989 case PRIV_SCHED_DIFFCRED: 1990 case PRIV_SCHED_SETPRIORITY: 1991 case PRIV_SCHED_RTPRIO: 1992 case PRIV_SCHED_SETPOLICY: 1993 case PRIV_SCHED_SET: 1994 case PRIV_SCHED_SETPARAM: 1995 1996 /* 1997 * More IPC privileges. 1998 */ 1999 case PRIV_SEM_WRITE: 2000 2001 /* 2002 * Allow signaling privileges subject to integrity policy. 2003 */ 2004 case PRIV_SIGNAL_DIFFCRED: 2005 case PRIV_SIGNAL_SUGID: 2006 2007 /* 2008 * Allow access to only limited sysctls from lower integrity levels; 2009 * piggy-back on the Jail definition. 2010 */ 2011 case PRIV_SYSCTL_WRITEJAIL: 2012 2013 /* 2014 * Allow TTY-based privileges, subject to general device access using 2015 * labels on TTY device nodes, but not console privilege. 2016 */ 2017 case PRIV_TTY_DRAINWAIT: 2018 case PRIV_TTY_DTRWAIT: 2019 case PRIV_TTY_EXCLUSIVE: 2020 case PRIV_TTY_STI: 2021 case PRIV_TTY_SETA: 2022 2023 /* 2024 * Grant most VFS privileges, as almost all are in practice bounded 2025 * by more specific checks using labels. 2026 */ 2027 case PRIV_VFS_READ: 2028 case PRIV_VFS_WRITE: 2029 case PRIV_VFS_ADMIN: 2030 case PRIV_VFS_EXEC: 2031 case PRIV_VFS_LOOKUP: 2032 case PRIV_VFS_CHFLAGS_DEV: 2033 case PRIV_VFS_CHOWN: 2034 case PRIV_VFS_CHROOT: 2035 case PRIV_VFS_RETAINSUGID: 2036 case PRIV_VFS_EXCEEDQUOTA: 2037 case PRIV_VFS_FCHROOT: 2038 case PRIV_VFS_FHOPEN: 2039 case PRIV_VFS_FHSTATFS: 2040 case PRIV_VFS_GENERATION: 2041 case PRIV_VFS_GETFH: 2042 case PRIV_VFS_GETQUOTA: 2043 case PRIV_VFS_LINK: 2044 case PRIV_VFS_MOUNT: 2045 case PRIV_VFS_MOUNT_OWNER: 2046 case PRIV_VFS_MOUNT_PERM: 2047 case PRIV_VFS_MOUNT_SUIDDIR: 2048 case PRIV_VFS_MOUNT_NONUSER: 2049 case PRIV_VFS_SETGID: 2050 case PRIV_VFS_STICKYFILE: 2051 case PRIV_VFS_SYSFLAGS: 2052 case PRIV_VFS_UNMOUNT: 2053 2054 /* 2055 * Allow VM privileges; it would be nice if these were subject to 2056 * resource limits. 2057 */ 2058 case PRIV_VM_MADV_PROTECT: 2059 case PRIV_VM_MLOCK: 2060 case PRIV_VM_MUNLOCK: 2061 case PRIV_VM_SWAP_NOQUOTA: 2062 case PRIV_VM_SWAP_NORLIMIT: 2063 2064 /* 2065 * Allow some but not all network privileges. In general, dont allow 2066 * reconfiguring the network stack, just normal use. 2067 */ 2068 case PRIV_NETATALK_RESERVEDPORT: 2069 case PRIV_NETINET_RESERVEDPORT: 2070 case PRIV_NETINET_RAW: 2071 case PRIV_NETINET_REUSEPORT: 2072 break; 2073 2074 /* 2075 * All remaining system privileges are allow only if the process 2076 * holds privilege with respect to the Biba policy. 2077 */ 2078 default: 2079 subj = SLOT(cred->cr_label); 2080 error = biba_subject_privileged(subj); 2081 if (error) 2082 return (error); 2083 } 2084 return (0); 2085} 2086 2087static int 2088biba_proc_check_debug(struct ucred *cred, struct proc *p) 2089{ 2090 struct mac_biba *subj, *obj; 2091 2092 if (!biba_enabled) 2093 return (0); 2094 2095 subj = SLOT(cred->cr_label); 2096 obj = SLOT(p->p_ucred->cr_label); 2097 2098 /* XXX: range checks */ 2099 if (!biba_dominate_effective(obj, subj)) 2100 return (ESRCH); 2101 if (!biba_dominate_effective(subj, obj)) 2102 return (EACCES); 2103 2104 return (0); 2105} 2106 2107static int 2108biba_proc_check_sched(struct ucred *cred, struct proc *p) 2109{ 2110 struct mac_biba *subj, *obj; 2111 2112 if (!biba_enabled) 2113 return (0); 2114 2115 subj = SLOT(cred->cr_label); 2116 obj = SLOT(p->p_ucred->cr_label); 2117 2118 /* XXX: range checks */ 2119 if (!biba_dominate_effective(obj, subj)) 2120 return (ESRCH); 2121 if (!biba_dominate_effective(subj, obj)) 2122 return (EACCES); 2123 2124 return (0); 2125} 2126 2127static int 2128biba_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 2129{ 2130 struct mac_biba *subj, *obj; 2131 2132 if (!biba_enabled) 2133 return (0); 2134 2135 subj = SLOT(cred->cr_label); 2136 obj = SLOT(p->p_ucred->cr_label); 2137 2138 /* XXX: range checks */ 2139 if (!biba_dominate_effective(obj, subj)) 2140 return (ESRCH); 2141 if (!biba_dominate_effective(subj, obj)) 2142 return (EACCES); 2143 2144 return (0); 2145} 2146 2147static int 2148biba_socket_check_deliver(struct socket *so, struct label *solabel, 2149 struct mbuf *m, struct label *mlabel) 2150{ 2151 struct mac_biba *p, *s; 2152 int error; 2153 2154 if (!biba_enabled) 2155 return (0); 2156 2157 p = SLOT(mlabel); 2158 s = SLOT(solabel); 2159 2160 SOCK_LOCK(so); 2161 error = biba_equal_effective(p, s) ? 0 : EACCES; 2162 SOCK_UNLOCK(so); 2163 return (error); 2164} 2165 2166static int 2167biba_socket_check_relabel(struct ucred *cred, struct socket *so, 2168 struct label *solabel, struct label *newlabel) 2169{ 2170 struct mac_biba *subj, *obj, *new; 2171 int error; 2172 2173 SOCK_LOCK_ASSERT(so); 2174 2175 new = SLOT(newlabel); 2176 subj = SLOT(cred->cr_label); 2177 obj = SLOT(solabel); 2178 2179 /* 2180 * If there is a Biba label update for the socket, it may be an 2181 * update of effective. 2182 */ 2183 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2184 if (error) 2185 return (error); 2186 2187 /* 2188 * To relabel a socket, the old socket effective must be in the 2189 * subject range. 2190 */ 2191 if (!biba_effective_in_range(obj, subj)) 2192 return (EPERM); 2193 2194 /* 2195 * If the Biba label is to be changed, authorize as appropriate. 2196 */ 2197 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2198 /* 2199 * To relabel a socket, the new socket effective must be in 2200 * the subject range. 2201 */ 2202 if (!biba_effective_in_range(new, subj)) 2203 return (EPERM); 2204 2205 /* 2206 * To change the Biba label on the socket to contain EQUAL, 2207 * the subject must have appropriate privilege. 2208 */ 2209 if (biba_contains_equal(new)) { 2210 error = biba_subject_privileged(subj); 2211 if (error) 2212 return (error); 2213 } 2214 } 2215 2216 return (0); 2217} 2218 2219static int 2220biba_socket_check_visible(struct ucred *cred, struct socket *so, 2221 struct label *solabel) 2222{ 2223 struct mac_biba *subj, *obj; 2224 2225 if (!biba_enabled) 2226 return (0); 2227 2228 subj = SLOT(cred->cr_label); 2229 obj = SLOT(solabel); 2230 2231 SOCK_LOCK(so); 2232 if (!biba_dominate_effective(obj, subj)) { 2233 SOCK_UNLOCK(so); 2234 return (ENOENT); 2235 } 2236 SOCK_UNLOCK(so); 2237 2238 return (0); 2239} 2240 2241static void 2242biba_socket_create(struct ucred *cred, struct socket *so, 2243 struct label *solabel) 2244{ 2245 struct mac_biba *source, *dest; 2246 2247 source = SLOT(cred->cr_label); 2248 dest = SLOT(solabel); 2249 2250 biba_copy_effective(source, dest); 2251} 2252 2253static void 2254biba_socket_create_mbuf(struct socket *so, struct label *solabel, 2255 struct mbuf *m, struct label *mlabel) 2256{ 2257 struct mac_biba *source, *dest; 2258 2259 source = SLOT(solabel); 2260 dest = SLOT(mlabel); 2261 2262 SOCK_LOCK(so); 2263 biba_copy_effective(source, dest); 2264 SOCK_UNLOCK(so); 2265} 2266 2267static void 2268biba_socket_newconn(struct socket *oldso, struct label *oldsolabel, 2269 struct socket *newso, struct label *newsolabel) 2270{ 2271 struct mac_biba source, *dest; 2272 2273 SOCK_LOCK(oldso); 2274 source = *SLOT(oldsolabel); 2275 SOCK_UNLOCK(oldso); 2276 2277 dest = SLOT(newsolabel); 2278 2279 SOCK_LOCK(newso); 2280 biba_copy_effective(&source, dest); 2281 SOCK_UNLOCK(newso); 2282} 2283 2284static void 2285biba_socket_relabel(struct ucred *cred, struct socket *so, 2286 struct label *solabel, struct label *newlabel) 2287{ 2288 struct mac_biba *source, *dest; 2289 2290 SOCK_LOCK_ASSERT(so); 2291 2292 source = SLOT(newlabel); 2293 dest = SLOT(solabel); 2294 2295 biba_copy(source, dest); 2296} 2297 2298static void 2299biba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 2300 struct socket *so, struct label *sopeerlabel) 2301{ 2302 struct mac_biba *source, *dest; 2303 2304 source = SLOT(mlabel); 2305 dest = SLOT(sopeerlabel); 2306 2307 SOCK_LOCK(so); 2308 biba_copy_effective(source, dest); 2309 SOCK_UNLOCK(so); 2310} 2311 2312static void 2313biba_socketpeer_set_from_socket(struct socket *oldso, 2314 struct label *oldsolabel, struct socket *newso, 2315 struct label *newsopeerlabel) 2316{ 2317 struct mac_biba source, *dest; 2318 2319 SOCK_LOCK(oldso); 2320 source = *SLOT(oldsolabel); 2321 SOCK_UNLOCK(oldso); 2322 dest = SLOT(newsopeerlabel); 2323 2324 SOCK_LOCK(newso); 2325 biba_copy_effective(&source, dest); 2326 SOCK_UNLOCK(newso); 2327} 2328 2329static void 2330biba_syncache_create(struct label *label, struct inpcb *inp) 2331{ 2332 struct mac_biba *source, *dest; 2333 2334 source = SLOT(inp->inp_label); 2335 dest = SLOT(label); 2336 biba_copy_effective(source, dest); 2337} 2338 2339static void 2340biba_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2341 struct label *mlabel) 2342{ 2343 struct mac_biba *source, *dest; 2344 2345 source = SLOT(sc_label); 2346 dest = SLOT(mlabel); 2347 biba_copy_effective(source, dest); 2348} 2349 2350static int 2351biba_system_check_acct(struct ucred *cred, struct vnode *vp, 2352 struct label *vplabel) 2353{ 2354 struct mac_biba *subj, *obj; 2355 int error; 2356 2357 if (!biba_enabled) 2358 return (0); 2359 2360 subj = SLOT(cred->cr_label); 2361 2362 error = biba_subject_privileged(subj); 2363 if (error) 2364 return (error); 2365 2366 if (vplabel == NULL) 2367 return (0); 2368 2369 obj = SLOT(vplabel); 2370 if (!biba_high_effective(obj)) 2371 return (EACCES); 2372 2373 return (0); 2374} 2375 2376static int 2377biba_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2378 struct label *vplabel) 2379{ 2380 struct mac_biba *subj, *obj; 2381 int error; 2382 2383 if (!biba_enabled) 2384 return (0); 2385 2386 subj = SLOT(cred->cr_label); 2387 2388 error = biba_subject_privileged(subj); 2389 if (error) 2390 return (error); 2391 2392 if (vplabel == NULL) 2393 return (0); 2394 2395 obj = SLOT(vplabel); 2396 if (!biba_high_effective(obj)) 2397 return (EACCES); 2398 2399 return (0); 2400} 2401 2402static int 2403biba_system_check_auditon(struct ucred *cred, int cmd) 2404{ 2405 struct mac_biba *subj; 2406 int error; 2407 2408 if (!biba_enabled) 2409 return (0); 2410 2411 subj = SLOT(cred->cr_label); 2412 2413 error = biba_subject_privileged(subj); 2414 if (error) 2415 return (error); 2416 2417 return (0); 2418} 2419 2420static int 2421biba_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2422 struct label *label) 2423{ 2424 struct mac_biba *subj; 2425 int error; 2426 2427 if (!biba_enabled) 2428 return (0); 2429 2430 subj = SLOT(cred->cr_label); 2431 2432 error = biba_subject_privileged(subj); 2433 if (error) 2434 return (error); 2435 2436 return (0); 2437} 2438 2439static int 2440biba_system_check_swapon(struct ucred *cred, struct vnode *vp, 2441 struct label *vplabel) 2442{ 2443 struct mac_biba *subj, *obj; 2444 int error; 2445 2446 if (!biba_enabled) 2447 return (0); 2448 2449 subj = SLOT(cred->cr_label); 2450 obj = SLOT(vplabel); 2451 2452 error = biba_subject_privileged(subj); 2453 if (error) 2454 return (error); 2455 2456 if (!biba_high_effective(obj)) 2457 return (EACCES); 2458 2459 return (0); 2460} 2461 2462static int 2463biba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2464 void *arg1, int arg2, struct sysctl_req *req) 2465{ 2466 struct mac_biba *subj; 2467 int error; 2468 2469 if (!biba_enabled) 2470 return (0); 2471 2472 subj = SLOT(cred->cr_label); 2473 2474 /* 2475 * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high, 2476 * but also require privilege to change them. 2477 */ 2478 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2479 if (!biba_subject_dominate_high(subj)) 2480 return (EACCES); 2481 2482 error = biba_subject_privileged(subj); 2483 if (error) 2484 return (error); 2485 } 2486 2487 return (0); 2488} 2489 2490static void 2491biba_sysvmsg_cleanup(struct label *msglabel) 2492{ 2493 2494 bzero(SLOT(msglabel), sizeof(struct mac_biba)); 2495} 2496 2497static void 2498biba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2499 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 2500{ 2501 struct mac_biba *source, *dest; 2502 2503 /* Ignore the msgq label */ 2504 source = SLOT(cred->cr_label); 2505 dest = SLOT(msglabel); 2506 2507 biba_copy_effective(source, dest); 2508} 2509 2510static int 2511biba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 2512 struct label *msglabel) 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(msglabel); 2521 2522 if (!biba_dominate_effective(obj, subj)) 2523 return (EACCES); 2524 2525 return (0); 2526} 2527 2528static int 2529biba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 2530 struct label *msglabel) 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(msglabel); 2539 2540 if (!biba_dominate_effective(subj, obj)) 2541 return (EACCES); 2542 2543 return (0); 2544} 2545 2546static int 2547biba_sysvmsq_check_msqget(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_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 2566 struct label *msqklabel) 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 if (!biba_dominate_effective(subj, obj)) 2577 return (EACCES); 2578 2579 return (0); 2580} 2581 2582static int 2583biba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 2584 struct label *msqklabel) 2585{ 2586 struct mac_biba *subj, *obj; 2587 2588 if (!biba_enabled) 2589 return (0); 2590 2591 subj = SLOT(cred->cr_label); 2592 obj = SLOT(msqklabel); 2593 2594 if (!biba_dominate_effective(obj, subj)) 2595 return (EACCES); 2596 2597 return (0); 2598} 2599 2600static int 2601biba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 2602 struct label *msqklabel, int cmd) 2603{ 2604 struct mac_biba *subj, *obj; 2605 2606 if (!biba_enabled) 2607 return (0); 2608 2609 subj = SLOT(cred->cr_label); 2610 obj = SLOT(msqklabel); 2611 2612 switch(cmd) { 2613 case IPC_RMID: 2614 case IPC_SET: 2615 if (!biba_dominate_effective(subj, obj)) 2616 return (EACCES); 2617 break; 2618 2619 case IPC_STAT: 2620 if (!biba_dominate_effective(obj, subj)) 2621 return (EACCES); 2622 break; 2623 2624 default: 2625 return (EACCES); 2626 } 2627 2628 return (0); 2629} 2630 2631static void 2632biba_sysvmsq_cleanup(struct label *msqlabel) 2633{ 2634 2635 bzero(SLOT(msqlabel), sizeof(struct mac_biba)); 2636} 2637 2638static void 2639biba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2640 struct label *msqlabel) 2641{ 2642 struct mac_biba *source, *dest; 2643 2644 source = SLOT(cred->cr_label); 2645 dest = SLOT(msqlabel); 2646 2647 biba_copy_effective(source, dest); 2648} 2649 2650static int 2651biba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 2652 struct label *semaklabel, int cmd) 2653{ 2654 struct mac_biba *subj, *obj; 2655 2656 if (!biba_enabled) 2657 return (0); 2658 2659 subj = SLOT(cred->cr_label); 2660 obj = SLOT(semaklabel); 2661 2662 switch(cmd) { 2663 case IPC_RMID: 2664 case IPC_SET: 2665 case SETVAL: 2666 case SETALL: 2667 if (!biba_dominate_effective(subj, obj)) 2668 return (EACCES); 2669 break; 2670 2671 case IPC_STAT: 2672 case GETVAL: 2673 case GETPID: 2674 case GETNCNT: 2675 case GETZCNT: 2676 case GETALL: 2677 if (!biba_dominate_effective(obj, subj)) 2678 return (EACCES); 2679 break; 2680 2681 default: 2682 return (EACCES); 2683 } 2684 2685 return (0); 2686} 2687 2688static int 2689biba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 2690 struct label *semaklabel) 2691{ 2692 struct mac_biba *subj, *obj; 2693 2694 if (!biba_enabled) 2695 return (0); 2696 2697 subj = SLOT(cred->cr_label); 2698 obj = SLOT(semaklabel); 2699 2700 if (!biba_dominate_effective(obj, subj)) 2701 return (EACCES); 2702 2703 return (0); 2704} 2705 2706static int 2707biba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2708 struct label *semaklabel, size_t accesstype) 2709{ 2710 struct mac_biba *subj, *obj; 2711 2712 if (!biba_enabled) 2713 return (0); 2714 2715 subj = SLOT(cred->cr_label); 2716 obj = SLOT(semaklabel); 2717 2718 if (accesstype & SEM_R) 2719 if (!biba_dominate_effective(obj, subj)) 2720 return (EACCES); 2721 2722 if (accesstype & SEM_A) 2723 if (!biba_dominate_effective(subj, obj)) 2724 return (EACCES); 2725 2726 return (0); 2727} 2728 2729static void 2730biba_sysvsem_cleanup(struct label *semalabel) 2731{ 2732 2733 bzero(SLOT(semalabel), sizeof(struct mac_biba)); 2734} 2735 2736static void 2737biba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2738 struct label *semalabel) 2739{ 2740 struct mac_biba *source, *dest; 2741 2742 source = SLOT(cred->cr_label); 2743 dest = SLOT(semalabel); 2744 2745 biba_copy_effective(source, dest); 2746} 2747 2748static int 2749biba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2750 struct label *shmseglabel, int shmflg) 2751{ 2752 struct mac_biba *subj, *obj; 2753 2754 if (!biba_enabled) 2755 return (0); 2756 2757 subj = SLOT(cred->cr_label); 2758 obj = SLOT(shmseglabel); 2759 2760 if (!biba_dominate_effective(obj, subj)) 2761 return (EACCES); 2762 if ((shmflg & SHM_RDONLY) == 0) { 2763 if (!biba_dominate_effective(subj, obj)) 2764 return (EACCES); 2765 } 2766 2767 return (0); 2768} 2769 2770static int 2771biba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2772 struct label *shmseglabel, int cmd) 2773{ 2774 struct mac_biba *subj, *obj; 2775 2776 if (!biba_enabled) 2777 return (0); 2778 2779 subj = SLOT(cred->cr_label); 2780 obj = SLOT(shmseglabel); 2781 2782 switch(cmd) { 2783 case IPC_RMID: 2784 case IPC_SET: 2785 if (!biba_dominate_effective(subj, obj)) 2786 return (EACCES); 2787 break; 2788 2789 case IPC_STAT: 2790 case SHM_STAT: 2791 if (!biba_dominate_effective(obj, subj)) 2792 return (EACCES); 2793 break; 2794 2795 default: 2796 return (EACCES); 2797 } 2798 2799 return (0); 2800} 2801 2802static int 2803biba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2804 struct label *shmseglabel, int shmflg) 2805{ 2806 struct mac_biba *subj, *obj; 2807 2808 if (!biba_enabled) 2809 return (0); 2810 2811 subj = SLOT(cred->cr_label); 2812 obj = SLOT(shmseglabel); 2813 2814 if (!biba_dominate_effective(obj, subj)) 2815 return (EACCES); 2816 2817 return (0); 2818} 2819 2820static void 2821biba_sysvshm_cleanup(struct label *shmlabel) 2822{ 2823 2824 bzero(SLOT(shmlabel), sizeof(struct mac_biba)); 2825} 2826 2827static void 2828biba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2829 struct label *shmlabel) 2830{ 2831 struct mac_biba *source, *dest; 2832 2833 source = SLOT(cred->cr_label); 2834 dest = SLOT(shmlabel); 2835 2836 biba_copy_effective(source, dest); 2837} 2838 2839static int 2840biba_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2841 struct vnode *vp, struct label *vplabel) 2842{ 2843 struct mac_biba mb_temp, *source, *dest; 2844 int buflen, error; 2845 2846 source = SLOT(mplabel); 2847 dest = SLOT(vplabel); 2848 2849 buflen = sizeof(mb_temp); 2850 bzero(&mb_temp, buflen); 2851 2852 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 2853 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread); 2854 if (error == ENOATTR || error == EOPNOTSUPP) { 2855 /* Fall back to the mntlabel. */ 2856 biba_copy_effective(source, dest); 2857 return (0); 2858 } else if (error) 2859 return (error); 2860 2861 if (buflen != sizeof(mb_temp)) { 2862 printf("biba_vnode_associate_extattr: bad size %d\n", 2863 buflen); 2864 return (EPERM); 2865 } 2866 if (biba_valid(&mb_temp) != 0) { 2867 printf("biba_vnode_associate_extattr: invalid\n"); 2868 return (EPERM); 2869 } 2870 if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != 2871 MAC_BIBA_FLAG_EFFECTIVE) { 2872 printf("biba_vnode_associate_extattr: not effective\n"); 2873 return (EPERM); 2874 } 2875 2876 biba_copy_effective(&mb_temp, dest); 2877 return (0); 2878} 2879 2880static void 2881biba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2882 struct vnode *vp, struct label *vplabel) 2883{ 2884 struct mac_biba *source, *dest; 2885 2886 source = SLOT(mplabel); 2887 dest = SLOT(vplabel); 2888 2889 biba_copy_effective(source, dest); 2890} 2891 2892static int 2893biba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2894 struct label *dvplabel) 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(obj, subj)) 2905 return (EACCES); 2906 2907 return (0); 2908} 2909 2910static int 2911biba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2912 struct label *dvplabel) 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(dvplabel); 2921 2922 if (!biba_dominate_effective(obj, subj)) 2923 return (EACCES); 2924 2925 return (0); 2926} 2927 2928static int 2929biba_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2930 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 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(dvplabel); 2939 2940 if (!biba_dominate_effective(subj, obj)) 2941 return (EACCES); 2942 2943 return (0); 2944} 2945 2946static int 2947biba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2948 struct label *vplabel, acl_type_t type) 2949{ 2950 struct mac_biba *subj, *obj; 2951 2952 if (!biba_enabled) 2953 return (0); 2954 2955 subj = SLOT(cred->cr_label); 2956 obj = SLOT(vplabel); 2957 2958 if (!biba_dominate_effective(subj, obj)) 2959 return (EACCES); 2960 2961 return (0); 2962} 2963 2964static int 2965biba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2966 struct label *vplabel, int attrnamespace, const char *name) 2967{ 2968 struct mac_biba *subj, *obj; 2969 2970 if (!biba_enabled) 2971 return (0); 2972 2973 subj = SLOT(cred->cr_label); 2974 obj = SLOT(vplabel); 2975 2976 if (!biba_dominate_effective(subj, obj)) 2977 return (EACCES); 2978 2979 return (0); 2980} 2981 2982static int 2983biba_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2984 struct label *vplabel, struct image_params *imgp, 2985 struct label *execlabel) 2986{ 2987 struct mac_biba *subj, *obj, *exec; 2988 int error; 2989 2990 if (execlabel != NULL) { 2991 /* 2992 * We currently don't permit labels to be changed at 2993 * exec-time as part of Biba, so disallow non-NULL Biba label 2994 * elements in the execlabel. 2995 */ 2996 exec = SLOT(execlabel); 2997 error = biba_atmostflags(exec, 0); 2998 if (error) 2999 return (error); 3000 } 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_getacl(struct ucred *cred, struct vnode *vp, 3016 struct label *vplabel, acl_type_t type) 3017{ 3018 struct mac_biba *subj, *obj; 3019 3020 if (!biba_enabled) 3021 return (0); 3022 3023 subj = SLOT(cred->cr_label); 3024 obj = SLOT(vplabel); 3025 3026 if (!biba_dominate_effective(obj, subj)) 3027 return (EACCES); 3028 3029 return (0); 3030} 3031 3032static int 3033biba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 3034 struct label *vplabel, int attrnamespace, const char *name) 3035{ 3036 struct mac_biba *subj, *obj; 3037 3038 if (!biba_enabled) 3039 return (0); 3040 3041 subj = SLOT(cred->cr_label); 3042 obj = SLOT(vplabel); 3043 3044 if (!biba_dominate_effective(obj, subj)) 3045 return (EACCES); 3046 3047 return (0); 3048} 3049 3050static int 3051biba_vnode_check_link(struct ucred *cred, struct vnode *dvp, 3052 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3053 struct componentname *cnp) 3054{ 3055 struct mac_biba *subj, *obj; 3056 3057 if (!biba_enabled) 3058 return (0); 3059 3060 subj = SLOT(cred->cr_label); 3061 obj = SLOT(dvplabel); 3062 3063 if (!biba_dominate_effective(subj, obj)) 3064 return (EACCES); 3065 3066 obj = SLOT(vplabel); 3067 3068 if (!biba_dominate_effective(subj, obj)) 3069 return (EACCES); 3070 3071 return (0); 3072} 3073 3074static int 3075biba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 3076 struct label *vplabel, int attrnamespace) 3077{ 3078 struct mac_biba *subj, *obj; 3079 3080 if (!biba_enabled) 3081 return (0); 3082 3083 subj = SLOT(cred->cr_label); 3084 obj = SLOT(vplabel); 3085 3086 if (!biba_dominate_effective(obj, subj)) 3087 return (EACCES); 3088 3089 return (0); 3090} 3091 3092static int 3093biba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 3094 struct label *dvplabel, struct componentname *cnp) 3095{ 3096 struct mac_biba *subj, *obj; 3097 3098 if (!biba_enabled) 3099 return (0); 3100 3101 subj = SLOT(cred->cr_label); 3102 obj = SLOT(dvplabel); 3103 3104 if (!biba_dominate_effective(obj, subj)) 3105 return (EACCES); 3106 3107 return (0); 3108} 3109 3110static int 3111biba_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 3112 struct label *vplabel, int prot, int flags) 3113{ 3114 struct mac_biba *subj, *obj; 3115 3116 /* 3117 * Rely on the use of open()-time protections to handle 3118 * non-revocation cases. 3119 */ 3120 if (!biba_enabled || !revocation_enabled) 3121 return (0); 3122 3123 subj = SLOT(cred->cr_label); 3124 obj = SLOT(vplabel); 3125 3126 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 3127 if (!biba_dominate_effective(obj, subj)) 3128 return (EACCES); 3129 } 3130 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 3131 if (!biba_dominate_effective(subj, obj)) 3132 return (EACCES); 3133 } 3134 3135 return (0); 3136} 3137 3138static int 3139biba_vnode_check_open(struct ucred *cred, struct vnode *vp, 3140 struct label *vplabel, accmode_t accmode) 3141{ 3142 struct mac_biba *subj, *obj; 3143 3144 if (!biba_enabled) 3145 return (0); 3146 3147 subj = SLOT(cred->cr_label); 3148 obj = SLOT(vplabel); 3149 3150 /* XXX privilege override for admin? */ 3151 if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 3152 if (!biba_dominate_effective(obj, subj)) 3153 return (EACCES); 3154 } 3155 if (accmode & VMODIFY_PERMS) { 3156 if (!biba_dominate_effective(subj, obj)) 3157 return (EACCES); 3158 } 3159 3160 return (0); 3161} 3162 3163static int 3164biba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 3165 struct vnode *vp, struct label *vplabel) 3166{ 3167 struct mac_biba *subj, *obj; 3168 3169 if (!biba_enabled || !revocation_enabled) 3170 return (0); 3171 3172 subj = SLOT(active_cred->cr_label); 3173 obj = SLOT(vplabel); 3174 3175 if (!biba_dominate_effective(obj, subj)) 3176 return (EACCES); 3177 3178 return (0); 3179} 3180 3181static int 3182biba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 3183 struct vnode *vp, struct label *vplabel) 3184{ 3185 struct mac_biba *subj, *obj; 3186 3187 if (!biba_enabled || !revocation_enabled) 3188 return (0); 3189 3190 subj = SLOT(active_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_readdir(struct ucred *cred, struct vnode *dvp, 3201 struct label *dvplabel) 3202{ 3203 struct mac_biba *subj, *obj; 3204 3205 if (!biba_enabled) 3206 return (0); 3207 3208 subj = SLOT(cred->cr_label); 3209 obj = SLOT(dvplabel); 3210 3211 if (!biba_dominate_effective(obj, subj)) 3212 return (EACCES); 3213 3214 return (0); 3215} 3216 3217static int 3218biba_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 3219 struct label *vplabel) 3220{ 3221 struct mac_biba *subj, *obj; 3222 3223 if (!biba_enabled) 3224 return (0); 3225 3226 subj = SLOT(cred->cr_label); 3227 obj = SLOT(vplabel); 3228 3229 if (!biba_dominate_effective(obj, subj)) 3230 return (EACCES); 3231 3232 return (0); 3233} 3234 3235static int 3236biba_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 3237 struct label *vplabel, struct label *newlabel) 3238{ 3239 struct mac_biba *old, *new, *subj; 3240 int error; 3241 3242 old = SLOT(vplabel); 3243 new = SLOT(newlabel); 3244 subj = SLOT(cred->cr_label); 3245 3246 /* 3247 * If there is a Biba label update for the vnode, it must be a 3248 * effective label. 3249 */ 3250 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 3251 if (error) 3252 return (error); 3253 3254 /* 3255 * To perform a relabel of the vnode (Biba label or not), Biba must 3256 * authorize the relabel. 3257 */ 3258 if (!biba_effective_in_range(old, subj)) 3259 return (EPERM); 3260 3261 /* 3262 * If the Biba label is to be changed, authorize as appropriate. 3263 */ 3264 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 3265 /* 3266 * To change the Biba label on a vnode, the new vnode label 3267 * must be in the subject range. 3268 */ 3269 if (!biba_effective_in_range(new, subj)) 3270 return (EPERM); 3271 3272 /* 3273 * To change the Biba label on the vnode to be EQUAL, the 3274 * subject must have appropriate privilege. 3275 */ 3276 if (biba_contains_equal(new)) { 3277 error = biba_subject_privileged(subj); 3278 if (error) 3279 return (error); 3280 } 3281 } 3282 3283 return (0); 3284} 3285 3286static int 3287biba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 3288 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3289 struct componentname *cnp) 3290{ 3291 struct mac_biba *subj, *obj; 3292 3293 if (!biba_enabled) 3294 return (0); 3295 3296 subj = SLOT(cred->cr_label); 3297 obj = SLOT(dvplabel); 3298 3299 if (!biba_dominate_effective(subj, obj)) 3300 return (EACCES); 3301 3302 obj = SLOT(vplabel); 3303 3304 if (!biba_dominate_effective(subj, obj)) 3305 return (EACCES); 3306 3307 return (0); 3308} 3309 3310static int 3311biba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 3312 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3313 int samedir, struct componentname *cnp) 3314{ 3315 struct mac_biba *subj, *obj; 3316 3317 if (!biba_enabled) 3318 return (0); 3319 3320 subj = SLOT(cred->cr_label); 3321 obj = SLOT(dvplabel); 3322 3323 if (!biba_dominate_effective(subj, obj)) 3324 return (EACCES); 3325 3326 if (vp != NULL) { 3327 obj = SLOT(vplabel); 3328 3329 if (!biba_dominate_effective(subj, obj)) 3330 return (EACCES); 3331 } 3332 3333 return (0); 3334} 3335 3336static int 3337biba_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 3338 struct label *vplabel) 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 return (0); 3352} 3353 3354static int 3355biba_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 3356 struct label *vplabel, acl_type_t type, struct acl *acl) 3357{ 3358 struct mac_biba *subj, *obj; 3359 3360 if (!biba_enabled) 3361 return (0); 3362 3363 subj = SLOT(cred->cr_label); 3364 obj = SLOT(vplabel); 3365 3366 if (!biba_dominate_effective(subj, obj)) 3367 return (EACCES); 3368 3369 return (0); 3370} 3371 3372static int 3373biba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 3374 struct label *vplabel, int attrnamespace, const char *name) 3375{ 3376 struct mac_biba *subj, *obj; 3377 3378 if (!biba_enabled) 3379 return (0); 3380 3381 subj = SLOT(cred->cr_label); 3382 obj = SLOT(vplabel); 3383 3384 if (!biba_dominate_effective(subj, obj)) 3385 return (EACCES); 3386 3387 /* XXX: protect the MAC EA in a special way? */ 3388 3389 return (0); 3390} 3391 3392static int 3393biba_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 3394 struct label *vplabel, u_long flags) 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_setmode(struct ucred *cred, struct vnode *vp, 3412 struct label *vplabel, mode_t mode) 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_setowner(struct ucred *cred, struct vnode *vp, 3430 struct label *vplabel, uid_t uid, gid_t gid) 3431{ 3432 struct mac_biba *subj, *obj; 3433 3434 if (!biba_enabled) 3435 return (0); 3436 3437 subj = SLOT(cred->cr_label); 3438 obj = SLOT(vplabel); 3439 3440 if (!biba_dominate_effective(subj, obj)) 3441 return (EACCES); 3442 3443 return (0); 3444} 3445 3446static int 3447biba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 3448 struct label *vplabel, struct timespec atime, struct timespec mtime) 3449{ 3450 struct mac_biba *subj, *obj; 3451 3452 if (!biba_enabled) 3453 return (0); 3454 3455 subj = SLOT(cred->cr_label); 3456 obj = SLOT(vplabel); 3457 3458 if (!biba_dominate_effective(subj, obj)) 3459 return (EACCES); 3460 3461 return (0); 3462} 3463 3464static int 3465biba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 3466 struct vnode *vp, struct label *vplabel) 3467{ 3468 struct mac_biba *subj, *obj; 3469 3470 if (!biba_enabled) 3471 return (0); 3472 3473 subj = SLOT(active_cred->cr_label); 3474 obj = SLOT(vplabel); 3475 3476 if (!biba_dominate_effective(obj, subj)) 3477 return (EACCES); 3478 3479 return (0); 3480} 3481 3482static int 3483biba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 3484 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3485 struct componentname *cnp) 3486{ 3487 struct mac_biba *subj, *obj; 3488 3489 if (!biba_enabled) 3490 return (0); 3491 3492 subj = SLOT(cred->cr_label); 3493 obj = SLOT(dvplabel); 3494 3495 if (!biba_dominate_effective(subj, obj)) 3496 return (EACCES); 3497 3498 obj = SLOT(vplabel); 3499 3500 if (!biba_dominate_effective(subj, obj)) 3501 return (EACCES); 3502 3503 return (0); 3504} 3505 3506static int 3507biba_vnode_check_write(struct ucred *active_cred, 3508 struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 3509{ 3510 struct mac_biba *subj, *obj; 3511 3512 if (!biba_enabled || !revocation_enabled) 3513 return (0); 3514 3515 subj = SLOT(active_cred->cr_label); 3516 obj = SLOT(vplabel); 3517 3518 if (!biba_dominate_effective(subj, obj)) 3519 return (EACCES); 3520 3521 return (0); 3522} 3523 3524static int 3525biba_vnode_create_extattr(struct ucred *cred, struct mount *mp, 3526 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 3527 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 3528{ 3529 struct mac_biba *source, *dest, mb_temp; 3530 size_t buflen; 3531 int error; 3532 3533 buflen = sizeof(mb_temp); 3534 bzero(&mb_temp, buflen); 3535 3536 source = SLOT(cred->cr_label); 3537 dest = SLOT(vplabel); 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 if (error == 0) 3543 biba_copy_effective(source, dest); 3544 return (error); 3545} 3546 3547static void 3548biba_vnode_relabel(struct ucred *cred, struct vnode *vp, 3549 struct label *vplabel, struct label *newlabel) 3550{ 3551 struct mac_biba *source, *dest; 3552 3553 source = SLOT(newlabel); 3554 dest = SLOT(vplabel); 3555 3556 biba_copy(source, dest); 3557} 3558 3559static int 3560biba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 3561 struct label *vplabel, struct label *intlabel) 3562{ 3563 struct mac_biba *source, mb_temp; 3564 size_t buflen; 3565 int error; 3566 3567 buflen = sizeof(mb_temp); 3568 bzero(&mb_temp, buflen); 3569 3570 source = SLOT(intlabel); 3571 if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0) 3572 return (0); 3573 3574 biba_copy_effective(source, &mb_temp); 3575 3576 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 3577 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread); 3578 return (error); 3579} 3580 3581static struct mac_policy_ops mac_biba_ops = 3582{ 3583 .mpo_init = biba_init, 3584 3585 .mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive, 3586 .mpo_bpfdesc_create = biba_bpfdesc_create, 3587 .mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf, 3588 .mpo_bpfdesc_destroy_label = biba_destroy_label, 3589 .mpo_bpfdesc_init_label = biba_init_label, 3590 3591 .mpo_cred_associate_nfsd = biba_cred_associate_nfsd, 3592 .mpo_cred_check_relabel = biba_cred_check_relabel, 3593 .mpo_cred_check_visible = biba_cred_check_visible, 3594 .mpo_cred_copy_label = biba_copy_label, 3595 .mpo_cred_create_init = biba_cred_create_init, 3596 .mpo_cred_create_swapper = biba_cred_create_swapper, 3597 .mpo_cred_destroy_label = biba_destroy_label, 3598 .mpo_cred_externalize_label = biba_externalize_label, 3599 .mpo_cred_init_label = biba_init_label, 3600 .mpo_cred_internalize_label = biba_internalize_label, 3601 .mpo_cred_relabel = biba_cred_relabel, 3602 3603 .mpo_devfs_create_device = biba_devfs_create_device, 3604 .mpo_devfs_create_directory = biba_devfs_create_directory, 3605 .mpo_devfs_create_symlink = biba_devfs_create_symlink, 3606 .mpo_devfs_destroy_label = biba_destroy_label, 3607 .mpo_devfs_init_label = biba_init_label, 3608 .mpo_devfs_update = biba_devfs_update, 3609 .mpo_devfs_vnode_associate = biba_devfs_vnode_associate, 3610 3611 .mpo_ifnet_check_relabel = biba_ifnet_check_relabel, 3612 .mpo_ifnet_check_transmit = biba_ifnet_check_transmit, 3613 .mpo_ifnet_copy_label = biba_copy_label, 3614 .mpo_ifnet_create = biba_ifnet_create, 3615 .mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf, 3616 .mpo_ifnet_destroy_label = biba_destroy_label, 3617 .mpo_ifnet_externalize_label = biba_externalize_label, 3618 .mpo_ifnet_init_label = biba_init_label, 3619 .mpo_ifnet_internalize_label = biba_internalize_label, 3620 .mpo_ifnet_relabel = biba_ifnet_relabel, 3621 3622 .mpo_inpcb_check_deliver = biba_inpcb_check_deliver, 3623 .mpo_inpcb_check_visible = biba_inpcb_check_visible, 3624 .mpo_inpcb_create = biba_inpcb_create, 3625 .mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf, 3626 .mpo_inpcb_destroy_label = biba_destroy_label, 3627 .mpo_inpcb_init_label = biba_init_label_waitcheck, 3628 .mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel, 3629 3630 .mpo_ip6q_create = biba_ip6q_create, 3631 .mpo_ip6q_destroy_label = biba_destroy_label, 3632 .mpo_ip6q_init_label = biba_init_label_waitcheck, 3633 .mpo_ip6q_match = biba_ip6q_match, 3634 .mpo_ip6q_reassemble = biba_ip6q_reassemble, 3635 .mpo_ip6q_update = biba_ip6q_update, 3636 3637 .mpo_ipq_create = biba_ipq_create, 3638 .mpo_ipq_destroy_label = biba_destroy_label, 3639 .mpo_ipq_init_label = biba_init_label_waitcheck, 3640 .mpo_ipq_match = biba_ipq_match, 3641 .mpo_ipq_reassemble = biba_ipq_reassemble, 3642 .mpo_ipq_update = biba_ipq_update, 3643 3644 .mpo_kld_check_load = biba_kld_check_load, 3645 3646 .mpo_mbuf_copy_label = biba_copy_label, 3647 .mpo_mbuf_destroy_label = biba_destroy_label, 3648 .mpo_mbuf_init_label = biba_init_label_waitcheck, 3649 3650 .mpo_mount_check_stat = biba_mount_check_stat, 3651 .mpo_mount_create = biba_mount_create, 3652 .mpo_mount_destroy_label = biba_destroy_label, 3653 .mpo_mount_init_label = biba_init_label, 3654 3655 .mpo_netatalk_aarp_send = biba_netatalk_aarp_send, 3656 3657 .mpo_netinet_arp_send = biba_netinet_arp_send, 3658 .mpo_netinet_firewall_reply = biba_netinet_firewall_reply, 3659 .mpo_netinet_firewall_send = biba_netinet_firewall_send, 3660 .mpo_netinet_fragment = biba_netinet_fragment, 3661 .mpo_netinet_icmp_reply = biba_netinet_icmp_reply, 3662 .mpo_netinet_igmp_send = biba_netinet_igmp_send, 3663 3664 .mpo_netinet6_nd6_send = biba_netinet6_nd6_send, 3665 3666 .mpo_pipe_check_ioctl = biba_pipe_check_ioctl, 3667 .mpo_pipe_check_poll = biba_pipe_check_poll, 3668 .mpo_pipe_check_read = biba_pipe_check_read, 3669 .mpo_pipe_check_relabel = biba_pipe_check_relabel, 3670 .mpo_pipe_check_stat = biba_pipe_check_stat, 3671 .mpo_pipe_check_write = biba_pipe_check_write, 3672 .mpo_pipe_copy_label = biba_copy_label, 3673 .mpo_pipe_create = biba_pipe_create, 3674 .mpo_pipe_destroy_label = biba_destroy_label, 3675 .mpo_pipe_externalize_label = biba_externalize_label, 3676 .mpo_pipe_init_label = biba_init_label, 3677 .mpo_pipe_internalize_label = biba_internalize_label, 3678 .mpo_pipe_relabel = biba_pipe_relabel, 3679 3680 .mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly, 3681 .mpo_posixsem_check_open = biba_posixsem_check_openunlink, 3682 .mpo_posixsem_check_post = biba_posixsem_check_write, 3683 .mpo_posixsem_check_setmode = biba_posixsem_check_setmode, 3684 .mpo_posixsem_check_setowner = biba_posixsem_check_setowner, 3685 .mpo_posixsem_check_stat = biba_posixsem_check_rdonly, 3686 .mpo_posixsem_check_unlink = biba_posixsem_check_openunlink, 3687 .mpo_posixsem_check_wait = biba_posixsem_check_write, 3688 .mpo_posixsem_create = biba_posixsem_create, 3689 .mpo_posixsem_destroy_label = biba_destroy_label, 3690 .mpo_posixsem_init_label = biba_init_label, 3691 3692 .mpo_posixshm_check_mmap = biba_posixshm_check_mmap, 3693 .mpo_posixshm_check_open = biba_posixshm_check_open, 3694 .mpo_posixshm_check_read = biba_posixshm_check_read, 3695 .mpo_posixshm_check_setmode = biba_posixshm_check_setmode, 3696 .mpo_posixshm_check_setowner = biba_posixshm_check_setowner, 3697 .mpo_posixshm_check_stat = biba_posixshm_check_stat, 3698 .mpo_posixshm_check_truncate = biba_posixshm_check_truncate, 3699 .mpo_posixshm_check_unlink = biba_posixshm_check_unlink, 3700 .mpo_posixshm_check_write = biba_posixshm_check_write, 3701 .mpo_posixshm_create = biba_posixshm_create, 3702 .mpo_posixshm_destroy_label = biba_destroy_label, 3703 .mpo_posixshm_init_label = biba_init_label, 3704 3705 .mpo_priv_check = biba_priv_check, 3706 3707 .mpo_proc_check_debug = biba_proc_check_debug, 3708 .mpo_proc_check_sched = biba_proc_check_sched, 3709 .mpo_proc_check_signal = biba_proc_check_signal, 3710 3711 .mpo_socket_check_deliver = biba_socket_check_deliver, 3712 .mpo_socket_check_relabel = biba_socket_check_relabel, 3713 .mpo_socket_check_visible = biba_socket_check_visible, 3714 .mpo_socket_copy_label = biba_copy_label, 3715 .mpo_socket_create = biba_socket_create, 3716 .mpo_socket_create_mbuf = biba_socket_create_mbuf, 3717 .mpo_socket_destroy_label = biba_destroy_label, 3718 .mpo_socket_externalize_label = biba_externalize_label, 3719 .mpo_socket_init_label = biba_init_label_waitcheck, 3720 .mpo_socket_internalize_label = biba_internalize_label, 3721 .mpo_socket_newconn = biba_socket_newconn, 3722 .mpo_socket_relabel = biba_socket_relabel, 3723 3724 .mpo_socketpeer_destroy_label = biba_destroy_label, 3725 .mpo_socketpeer_externalize_label = biba_externalize_label, 3726 .mpo_socketpeer_init_label = biba_init_label_waitcheck, 3727 .mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf, 3728 .mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket, 3729 3730 .mpo_syncache_create = biba_syncache_create, 3731 .mpo_syncache_create_mbuf = biba_syncache_create_mbuf, 3732 .mpo_syncache_destroy_label = biba_destroy_label, 3733 .mpo_syncache_init_label = biba_init_label_waitcheck, 3734 3735 .mpo_system_check_acct = biba_system_check_acct, 3736 .mpo_system_check_auditctl = biba_system_check_auditctl, 3737 .mpo_system_check_auditon = biba_system_check_auditon, 3738 .mpo_system_check_swapoff = biba_system_check_swapoff, 3739 .mpo_system_check_swapon = biba_system_check_swapon, 3740 .mpo_system_check_sysctl = biba_system_check_sysctl, 3741 3742 .mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup, 3743 .mpo_sysvmsg_create = biba_sysvmsg_create, 3744 .mpo_sysvmsg_destroy_label = biba_destroy_label, 3745 .mpo_sysvmsg_init_label = biba_init_label, 3746 3747 .mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv, 3748 .mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid, 3749 .mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget, 3750 .mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd, 3751 .mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv, 3752 .mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl, 3753 .mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup, 3754 .mpo_sysvmsq_create = biba_sysvmsq_create, 3755 .mpo_sysvmsq_destroy_label = biba_destroy_label, 3756 .mpo_sysvmsq_init_label = biba_init_label, 3757 3758 .mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl, 3759 .mpo_sysvsem_check_semget = biba_sysvsem_check_semget, 3760 .mpo_sysvsem_check_semop = biba_sysvsem_check_semop, 3761 .mpo_sysvsem_cleanup = biba_sysvsem_cleanup, 3762 .mpo_sysvsem_create = biba_sysvsem_create, 3763 .mpo_sysvsem_destroy_label = biba_destroy_label, 3764 .mpo_sysvsem_init_label = biba_init_label, 3765 3766 .mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat, 3767 .mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl, 3768 .mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget, 3769 .mpo_sysvshm_cleanup = biba_sysvshm_cleanup, 3770 .mpo_sysvshm_create = biba_sysvshm_create, 3771 .mpo_sysvshm_destroy_label = biba_destroy_label, 3772 .mpo_sysvshm_init_label = biba_init_label, 3773 3774 .mpo_vnode_associate_extattr = biba_vnode_associate_extattr, 3775 .mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel, 3776 .mpo_vnode_check_access = biba_vnode_check_open, 3777 .mpo_vnode_check_chdir = biba_vnode_check_chdir, 3778 .mpo_vnode_check_chroot = biba_vnode_check_chroot, 3779 .mpo_vnode_check_create = biba_vnode_check_create, 3780 .mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl, 3781 .mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr, 3782 .mpo_vnode_check_exec = biba_vnode_check_exec, 3783 .mpo_vnode_check_getacl = biba_vnode_check_getacl, 3784 .mpo_vnode_check_getextattr = biba_vnode_check_getextattr, 3785 .mpo_vnode_check_link = biba_vnode_check_link, 3786 .mpo_vnode_check_listextattr = biba_vnode_check_listextattr, 3787 .mpo_vnode_check_lookup = biba_vnode_check_lookup, 3788 .mpo_vnode_check_mmap = biba_vnode_check_mmap, 3789 .mpo_vnode_check_open = biba_vnode_check_open, 3790 .mpo_vnode_check_poll = biba_vnode_check_poll, 3791 .mpo_vnode_check_read = biba_vnode_check_read, 3792 .mpo_vnode_check_readdir = biba_vnode_check_readdir, 3793 .mpo_vnode_check_readlink = biba_vnode_check_readlink, 3794 .mpo_vnode_check_relabel = biba_vnode_check_relabel, 3795 .mpo_vnode_check_rename_from = biba_vnode_check_rename_from, 3796 .mpo_vnode_check_rename_to = biba_vnode_check_rename_to, 3797 .mpo_vnode_check_revoke = biba_vnode_check_revoke, 3798 .mpo_vnode_check_setacl = biba_vnode_check_setacl, 3799 .mpo_vnode_check_setextattr = biba_vnode_check_setextattr, 3800 .mpo_vnode_check_setflags = biba_vnode_check_setflags, 3801 .mpo_vnode_check_setmode = biba_vnode_check_setmode, 3802 .mpo_vnode_check_setowner = biba_vnode_check_setowner, 3803 .mpo_vnode_check_setutimes = biba_vnode_check_setutimes, 3804 .mpo_vnode_check_stat = biba_vnode_check_stat, 3805 .mpo_vnode_check_unlink = biba_vnode_check_unlink, 3806 .mpo_vnode_check_write = biba_vnode_check_write, 3807 .mpo_vnode_create_extattr = biba_vnode_create_extattr, 3808 .mpo_vnode_copy_label = biba_copy_label, 3809 .mpo_vnode_destroy_label = biba_destroy_label, 3810 .mpo_vnode_externalize_label = biba_externalize_label, 3811 .mpo_vnode_init_label = biba_init_label, 3812 .mpo_vnode_internalize_label = biba_internalize_label, 3813 .mpo_vnode_relabel = biba_vnode_relabel, 3814 .mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr, 3815}; 3816 3817MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 3818 MPC_LOADTIME_FLAG_NOTLATE, &biba_slot); 3819