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