mac_biba.c revision 168954
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 168954 2007-04-22 16:18:10Z 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) 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} 840 841static void 842mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 843 struct label *vnodelabel, struct label *label) 844{ 845 struct mac_biba *source, *dest; 846 847 source = SLOT(label); 848 dest = SLOT(vnodelabel); 849 850 mac_biba_copy(source, dest); 851} 852 853static void 854mac_biba_update_devfsdirent(struct mount *mp, 855 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 856 struct vnode *vp, struct label *vnodelabel) 857{ 858 struct mac_biba *source, *dest; 859 860 source = SLOT(vnodelabel); 861 dest = SLOT(direntlabel); 862 863 mac_biba_copy(source, dest); 864} 865 866static void 867mac_biba_associate_vnode_devfs(struct mount *mp, struct label *mntlabel, 868 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 869 struct label *vlabel) 870{ 871 struct mac_biba *source, *dest; 872 873 source = SLOT(delabel); 874 dest = SLOT(vlabel); 875 876 mac_biba_copy_effective(source, dest); 877} 878 879static int 880mac_biba_associate_vnode_extattr(struct mount *mp, struct label *mntlabel, 881 struct vnode *vp, struct label *vlabel) 882{ 883 struct mac_biba temp, *source, *dest; 884 int buflen, error; 885 886 source = SLOT(mntlabel); 887 dest = SLOT(vlabel); 888 889 buflen = sizeof(temp); 890 bzero(&temp, buflen); 891 892 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 893 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 894 if (error == ENOATTR || error == EOPNOTSUPP) { 895 /* Fall back to the mntlabel. */ 896 mac_biba_copy_effective(source, dest); 897 return (0); 898 } else if (error) 899 return (error); 900 901 if (buflen != sizeof(temp)) { 902 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 903 buflen); 904 return (EPERM); 905 } 906 if (mac_biba_valid(&temp) != 0) { 907 printf("mac_biba_associate_vnode_extattr: invalid\n"); 908 return (EPERM); 909 } 910 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) { 911 printf("mac_biba_associate_vnode_extattr: not effective\n"); 912 return (EPERM); 913 } 914 915 mac_biba_copy_effective(&temp, dest); 916 return (0); 917} 918 919static void 920mac_biba_associate_vnode_singlelabel(struct mount *mp, 921 struct label *mntlabel, struct vnode *vp, struct label *vlabel) 922{ 923 struct mac_biba *source, *dest; 924 925 source = SLOT(mntlabel); 926 dest = SLOT(vlabel); 927 928 mac_biba_copy_effective(source, dest); 929} 930 931static int 932mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 933 struct label *mntlabel, struct vnode *dvp, struct label *dlabel, 934 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 935{ 936 struct mac_biba *source, *dest, temp; 937 size_t buflen; 938 int error; 939 940 buflen = sizeof(temp); 941 bzero(&temp, buflen); 942 943 source = SLOT(cred->cr_label); 944 dest = SLOT(vlabel); 945 mac_biba_copy_effective(source, &temp); 946 947 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 948 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 949 if (error == 0) 950 mac_biba_copy_effective(source, dest); 951 return (error); 952} 953 954static int 955mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 956 struct label *vlabel, struct label *intlabel) 957{ 958 struct mac_biba *source, temp; 959 size_t buflen; 960 int error; 961 962 buflen = sizeof(temp); 963 bzero(&temp, buflen); 964 965 source = SLOT(intlabel); 966 if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0) 967 return (0); 968 969 mac_biba_copy_effective(source, &temp); 970 971 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 972 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 973 return (error); 974} 975 976/* 977 * Labeling event operations: IPC object. 978 */ 979static void 980mac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel, 981 struct inpcb *inp, struct label *inplabel) 982{ 983 struct mac_biba *source, *dest; 984 985 source = SLOT(solabel); 986 dest = SLOT(inplabel); 987 988 mac_biba_copy_effective(source, dest); 989} 990 991static void 992mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 993 struct mbuf *m, struct label *mbuflabel) 994{ 995 struct mac_biba *source, *dest; 996 997 source = SLOT(socketlabel); 998 dest = SLOT(mbuflabel); 999 1000 mac_biba_copy_effective(source, dest); 1001} 1002 1003static void 1004mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1005 struct label *socketlabel) 1006{ 1007 struct mac_biba *source, *dest; 1008 1009 source = SLOT(cred->cr_label); 1010 dest = SLOT(socketlabel); 1011 1012 mac_biba_copy_effective(source, dest); 1013} 1014 1015static void 1016mac_biba_create_pipe(struct ucred *cred, struct pipepair *pp, 1017 struct label *pipelabel) 1018{ 1019 struct mac_biba *source, *dest; 1020 1021 source = SLOT(cred->cr_label); 1022 dest = SLOT(pipelabel); 1023 1024 mac_biba_copy_effective(source, dest); 1025} 1026 1027static void 1028mac_biba_create_posix_sem(struct ucred *cred, struct ksem *ksemptr, 1029 struct label *ks_label) 1030{ 1031 struct mac_biba *source, *dest; 1032 1033 source = SLOT(cred->cr_label); 1034 dest = SLOT(ks_label); 1035 1036 mac_biba_copy_effective(source, dest); 1037} 1038 1039static void 1040mac_biba_create_socket_from_socket(struct socket *oldsocket, 1041 struct label *oldsocketlabel, struct socket *newsocket, 1042 struct label *newsocketlabel) 1043{ 1044 struct mac_biba *source, *dest; 1045 1046 source = SLOT(oldsocketlabel); 1047 dest = SLOT(newsocketlabel); 1048 1049 mac_biba_copy_effective(source, dest); 1050} 1051 1052static void 1053mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1054 struct label *socketlabel, struct label *newlabel) 1055{ 1056 struct mac_biba *source, *dest; 1057 1058 source = SLOT(newlabel); 1059 dest = SLOT(socketlabel); 1060 1061 mac_biba_copy(source, dest); 1062} 1063 1064static void 1065mac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1066 struct label *pipelabel, struct label *newlabel) 1067{ 1068 struct mac_biba *source, *dest; 1069 1070 source = SLOT(newlabel); 1071 dest = SLOT(pipelabel); 1072 1073 mac_biba_copy(source, dest); 1074} 1075 1076static void 1077mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1078 struct socket *socket, struct label *socketpeerlabel) 1079{ 1080 struct mac_biba *source, *dest; 1081 1082 source = SLOT(mbuflabel); 1083 dest = SLOT(socketpeerlabel); 1084 1085 mac_biba_copy_effective(source, dest); 1086} 1087 1088/* 1089 * Labeling event operations: System V IPC objects. 1090 */ 1091 1092static void 1093mac_biba_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, 1094 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1095{ 1096 struct mac_biba *source, *dest; 1097 1098 /* Ignore the msgq label */ 1099 source = SLOT(cred->cr_label); 1100 dest = SLOT(msglabel); 1101 1102 mac_biba_copy_effective(source, dest); 1103} 1104 1105static void 1106mac_biba_create_sysv_msgqueue(struct ucred *cred, 1107 struct msqid_kernel *msqkptr, struct label *msqlabel) 1108{ 1109 struct mac_biba *source, *dest; 1110 1111 source = SLOT(cred->cr_label); 1112 dest = SLOT(msqlabel); 1113 1114 mac_biba_copy_effective(source, dest); 1115} 1116 1117static void 1118mac_biba_create_sysv_sem(struct ucred *cred, struct semid_kernel *semakptr, 1119 struct label *semalabel) 1120{ 1121 struct mac_biba *source, *dest; 1122 1123 source = SLOT(cred->cr_label); 1124 dest = SLOT(semalabel); 1125 1126 mac_biba_copy_effective(source, dest); 1127} 1128 1129static void 1130mac_biba_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr, 1131 struct label *shmlabel) 1132{ 1133 struct mac_biba *source, *dest; 1134 1135 source = SLOT(cred->cr_label); 1136 dest = SLOT(shmlabel); 1137 1138 mac_biba_copy_effective(source, dest); 1139} 1140 1141/* 1142 * Labeling event operations: network objects. 1143 */ 1144static void 1145mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1146 struct label *oldsocketlabel, struct socket *newsocket, 1147 struct label *newsocketpeerlabel) 1148{ 1149 struct mac_biba *source, *dest; 1150 1151 source = SLOT(oldsocketlabel); 1152 dest = SLOT(newsocketpeerlabel); 1153 1154 mac_biba_copy_effective(source, dest); 1155} 1156 1157static void 1158mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1159 struct label *bpflabel) 1160{ 1161 struct mac_biba *source, *dest; 1162 1163 source = SLOT(cred->cr_label); 1164 dest = SLOT(bpflabel); 1165 1166 mac_biba_copy_effective(source, dest); 1167} 1168 1169static void 1170mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1171{ 1172 char tifname[IFNAMSIZ], *p, *q; 1173 char tiflist[sizeof(trusted_interfaces)]; 1174 struct mac_biba *dest; 1175 int len, type; 1176 1177 dest = SLOT(ifnetlabel); 1178 1179 if (ifnet->if_type == IFT_LOOP || interfaces_equal != 0) { 1180 type = MAC_BIBA_TYPE_EQUAL; 1181 goto set; 1182 } 1183 1184 if (trust_all_interfaces) { 1185 type = MAC_BIBA_TYPE_HIGH; 1186 goto set; 1187 } 1188 1189 type = MAC_BIBA_TYPE_LOW; 1190 1191 if (trusted_interfaces[0] == '\0' || 1192 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1193 goto set; 1194 1195 bzero(tiflist, sizeof(tiflist)); 1196 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1197 if(*p != ' ' && *p != '\t') 1198 *q = *p; 1199 1200 for (p = q = tiflist;; p++) { 1201 if (*p == ',' || *p == '\0') { 1202 len = p - q; 1203 if (len < IFNAMSIZ) { 1204 bzero(tifname, sizeof(tifname)); 1205 bcopy(q, tifname, len); 1206 if (strcmp(tifname, ifnet->if_xname) == 0) { 1207 type = MAC_BIBA_TYPE_HIGH; 1208 break; 1209 } 1210 } else { 1211 *p = '\0'; 1212 printf("mac_biba warning: interface name " 1213 "\"%s\" is too long (must be < %d)\n", 1214 q, IFNAMSIZ); 1215 } 1216 if (*p == '\0') 1217 break; 1218 q = p + 1; 1219 } 1220 } 1221set: 1222 mac_biba_set_effective(dest, type, 0, NULL); 1223 mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1224} 1225 1226static void 1227mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1228 struct ipq *ipq, struct label *ipqlabel) 1229{ 1230 struct mac_biba *source, *dest; 1231 1232 source = SLOT(fragmentlabel); 1233 dest = SLOT(ipqlabel); 1234 1235 mac_biba_copy_effective(source, dest); 1236} 1237 1238static void 1239mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1240 struct mbuf *datagram, struct label *datagramlabel) 1241{ 1242 struct mac_biba *source, *dest; 1243 1244 source = SLOT(ipqlabel); 1245 dest = SLOT(datagramlabel); 1246 1247 /* Just use the head, since we require them all to match. */ 1248 mac_biba_copy_effective(source, dest); 1249} 1250 1251static void 1252mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1253 struct mbuf *fragment, struct label *fragmentlabel) 1254{ 1255 struct mac_biba *source, *dest; 1256 1257 source = SLOT(datagramlabel); 1258 dest = SLOT(fragmentlabel); 1259 1260 mac_biba_copy_effective(source, dest); 1261} 1262 1263static void 1264mac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1265 struct mbuf *m, struct label *mlabel) 1266{ 1267 struct mac_biba *source, *dest; 1268 1269 source = SLOT(inplabel); 1270 dest = SLOT(mlabel); 1271 1272 mac_biba_copy_effective(source, dest); 1273} 1274 1275static void 1276mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1277 struct mbuf *mbuf, struct label *mbuflabel) 1278{ 1279 struct mac_biba *dest; 1280 1281 dest = SLOT(mbuflabel); 1282 1283 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1284} 1285 1286static void 1287mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1288 struct mbuf *mbuf, struct label *mbuflabel) 1289{ 1290 struct mac_biba *source, *dest; 1291 1292 source = SLOT(bpflabel); 1293 dest = SLOT(mbuflabel); 1294 1295 mac_biba_copy_effective(source, dest); 1296} 1297 1298static void 1299mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1300 struct mbuf *m, struct label *mbuflabel) 1301{ 1302 struct mac_biba *source, *dest; 1303 1304 source = SLOT(ifnetlabel); 1305 dest = SLOT(mbuflabel); 1306 1307 mac_biba_copy_effective(source, dest); 1308} 1309 1310static void 1311mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1312 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1313 struct mbuf *newmbuf, struct label *newmbuflabel) 1314{ 1315 struct mac_biba *source, *dest; 1316 1317 source = SLOT(oldmbuflabel); 1318 dest = SLOT(newmbuflabel); 1319 1320 mac_biba_copy_effective(source, dest); 1321} 1322 1323static void 1324mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1325 struct mbuf *newmbuf, struct label *newmbuflabel) 1326{ 1327 struct mac_biba *source, *dest; 1328 1329 source = SLOT(oldmbuflabel); 1330 dest = SLOT(newmbuflabel); 1331 1332 mac_biba_copy_effective(source, dest); 1333} 1334 1335static int 1336mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1337 struct ipq *ipq, struct label *ipqlabel) 1338{ 1339 struct mac_biba *a, *b; 1340 1341 a = SLOT(ipqlabel); 1342 b = SLOT(fragmentlabel); 1343 1344 return (mac_biba_equal_effective(a, b)); 1345} 1346 1347static void 1348mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1349 struct label *ifnetlabel, struct label *newlabel) 1350{ 1351 struct mac_biba *source, *dest; 1352 1353 source = SLOT(newlabel); 1354 dest = SLOT(ifnetlabel); 1355 1356 mac_biba_copy(source, dest); 1357} 1358 1359static void 1360mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1361 struct ipq *ipq, struct label *ipqlabel) 1362{ 1363 1364 /* NOOP: we only accept matching labels, so no need to update */ 1365} 1366 1367static void 1368mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1369 struct inpcb *inp, struct label *inplabel) 1370{ 1371 struct mac_biba *source, *dest; 1372 1373 source = SLOT(solabel); 1374 dest = SLOT(inplabel); 1375 1376 mac_biba_copy(source, dest); 1377} 1378 1379static void 1380mac_biba_create_mbuf_from_firewall(struct mbuf *m, struct label *label) 1381{ 1382 struct mac_biba *dest; 1383 1384 dest = SLOT(label); 1385 1386 /* XXX: where is the label for the firewall really comming from? */ 1387 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1388} 1389 1390/* 1391 * Labeling event operations: processes. 1392 */ 1393static void 1394mac_biba_create_proc0(struct ucred *cred) 1395{ 1396 struct mac_biba *dest; 1397 1398 dest = SLOT(cred->cr_label); 1399 1400 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1401 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1402 MAC_BIBA_TYPE_HIGH, 0, NULL); 1403} 1404 1405static void 1406mac_biba_create_proc1(struct ucred *cred) 1407{ 1408 struct mac_biba *dest; 1409 1410 dest = SLOT(cred->cr_label); 1411 1412 mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1413 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1414 MAC_BIBA_TYPE_HIGH, 0, NULL); 1415} 1416 1417static void 1418mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1419{ 1420 struct mac_biba *source, *dest; 1421 1422 source = SLOT(newlabel); 1423 dest = SLOT(cred->cr_label); 1424 1425 mac_biba_copy(source, dest); 1426} 1427 1428/* 1429 * Label cleanup/flush operations 1430 */ 1431static void 1432mac_biba_cleanup_sysv_msgmsg(struct label *msglabel) 1433{ 1434 1435 bzero(SLOT(msglabel), sizeof(struct mac_biba)); 1436} 1437 1438static void 1439mac_biba_cleanup_sysv_msgqueue(struct label *msqlabel) 1440{ 1441 1442 bzero(SLOT(msqlabel), sizeof(struct mac_biba)); 1443} 1444 1445static void 1446mac_biba_cleanup_sysv_sem(struct label *semalabel) 1447{ 1448 1449 bzero(SLOT(semalabel), sizeof(struct mac_biba)); 1450} 1451 1452static void 1453mac_biba_cleanup_sysv_shm(struct label *shmlabel) 1454{ 1455 bzero(SLOT(shmlabel), sizeof(struct mac_biba)); 1456} 1457 1458/* 1459 * Access control checks. 1460 */ 1461static int 1462mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1463 struct ifnet *ifnet, struct label *ifnetlabel) 1464{ 1465 struct mac_biba *a, *b; 1466 1467 if (!mac_biba_enabled) 1468 return (0); 1469 1470 a = SLOT(bpflabel); 1471 b = SLOT(ifnetlabel); 1472 1473 if (mac_biba_equal_effective(a, b)) 1474 return (0); 1475 return (EACCES); 1476} 1477 1478static int 1479mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1480{ 1481 struct mac_biba *subj, *new; 1482 int error; 1483 1484 subj = SLOT(cred->cr_label); 1485 new = SLOT(newlabel); 1486 1487 /* 1488 * If there is a Biba label update for the credential, it may 1489 * be an update of the effective, range, or both. 1490 */ 1491 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1492 if (error) 1493 return (error); 1494 1495 /* 1496 * If the Biba label is to be changed, authorize as appropriate. 1497 */ 1498 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1499 /* 1500 * If the change request modifies both the Biba label 1501 * effective and range, check that the new effective will be 1502 * in the new range. 1503 */ 1504 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1505 MAC_BIBA_FLAGS_BOTH && 1506 !mac_biba_effective_in_range(new, new)) 1507 return (EINVAL); 1508 1509 /* 1510 * To change the Biba effective label on a credential, the 1511 * new effective label must be in the current range. 1512 */ 1513 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE && 1514 !mac_biba_effective_in_range(new, subj)) 1515 return (EPERM); 1516 1517 /* 1518 * To change the Biba range on a credential, the new 1519 * range label must be in the current range. 1520 */ 1521 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1522 !mac_biba_range_in_range(new, subj)) 1523 return (EPERM); 1524 1525 /* 1526 * To have EQUAL in any component of the new credential 1527 * Biba label, the subject must already have EQUAL in 1528 * their label. 1529 */ 1530 if (mac_biba_contains_equal(new)) { 1531 error = mac_biba_subject_privileged(subj); 1532 if (error) 1533 return (error); 1534 } 1535 } 1536 1537 return (0); 1538} 1539 1540static int 1541mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1542{ 1543 struct mac_biba *subj, *obj; 1544 1545 if (!mac_biba_enabled) 1546 return (0); 1547 1548 subj = SLOT(u1->cr_label); 1549 obj = SLOT(u2->cr_label); 1550 1551 /* XXX: range */ 1552 if (!mac_biba_dominate_effective(obj, subj)) 1553 return (ESRCH); 1554 1555 return (0); 1556} 1557 1558static int 1559mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1560 struct label *ifnetlabel, struct label *newlabel) 1561{ 1562 struct mac_biba *subj, *new; 1563 int error; 1564 1565 subj = SLOT(cred->cr_label); 1566 new = SLOT(newlabel); 1567 1568 /* 1569 * If there is a Biba label update for the interface, it may 1570 * be an update of the effective, range, or both. 1571 */ 1572 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1573 if (error) 1574 return (error); 1575 1576 /* 1577 * Relabling network interfaces requires Biba privilege. 1578 */ 1579 error = mac_biba_subject_privileged(subj); 1580 if (error) 1581 return (error); 1582 1583 return (0); 1584} 1585 1586static int 1587mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1588 struct mbuf *m, struct label *mbuflabel) 1589{ 1590 struct mac_biba *p, *i; 1591 1592 if (!mac_biba_enabled) 1593 return (0); 1594 1595 p = SLOT(mbuflabel); 1596 i = SLOT(ifnetlabel); 1597 1598 return (mac_biba_effective_in_range(p, i) ? 0 : EACCES); 1599} 1600 1601static int 1602mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1603 struct mbuf *m, struct label *mlabel) 1604{ 1605 struct mac_biba *p, *i; 1606 1607 if (!mac_biba_enabled) 1608 return (0); 1609 1610 p = SLOT(mlabel); 1611 i = SLOT(inplabel); 1612 1613 return (mac_biba_equal_effective(p, i) ? 0 : EACCES); 1614} 1615 1616static int 1617mac_biba_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr, 1618 struct label *msglabel) 1619{ 1620 struct mac_biba *subj, *obj; 1621 1622 if (!mac_biba_enabled) 1623 return (0); 1624 1625 subj = SLOT(cred->cr_label); 1626 obj = SLOT(msglabel); 1627 1628 if (!mac_biba_dominate_effective(obj, subj)) 1629 return (EACCES); 1630 1631 return (0); 1632} 1633 1634static int 1635mac_biba_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr, 1636 struct label *msglabel) 1637{ 1638 struct mac_biba *subj, *obj; 1639 1640 if (!mac_biba_enabled) 1641 return (0); 1642 1643 subj = SLOT(cred->cr_label); 1644 obj = SLOT(msglabel); 1645 1646 if (!mac_biba_dominate_effective(subj, obj)) 1647 return (EACCES); 1648 1649 return (0); 1650} 1651 1652static int 1653mac_biba_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1654 struct label *msqklabel) 1655{ 1656 struct mac_biba *subj, *obj; 1657 1658 if (!mac_biba_enabled) 1659 return (0); 1660 1661 subj = SLOT(cred->cr_label); 1662 obj = SLOT(msqklabel); 1663 1664 if (!mac_biba_dominate_effective(obj, subj)) 1665 return (EACCES); 1666 1667 return (0); 1668} 1669 1670static int 1671mac_biba_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1672 struct label *msqklabel) 1673{ 1674 struct mac_biba *subj, *obj; 1675 1676 if (!mac_biba_enabled) 1677 return (0); 1678 1679 subj = SLOT(cred->cr_label); 1680 obj = SLOT(msqklabel); 1681 1682 if (!mac_biba_dominate_effective(subj, obj)) 1683 return (EACCES); 1684 1685 return (0); 1686} 1687 1688static int 1689mac_biba_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1690 struct label *msqklabel) 1691{ 1692 struct mac_biba *subj, *obj; 1693 1694 if (!mac_biba_enabled) 1695 return (0); 1696 1697 subj = SLOT(cred->cr_label); 1698 obj = SLOT(msqklabel); 1699 1700 if (!mac_biba_dominate_effective(obj, subj)) 1701 return (EACCES); 1702 1703 return (0); 1704} 1705 1706 1707static int 1708mac_biba_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1709 struct label *msqklabel, int cmd) 1710{ 1711 struct mac_biba *subj, *obj; 1712 1713 if (!mac_biba_enabled) 1714 return (0); 1715 1716 subj = SLOT(cred->cr_label); 1717 obj = SLOT(msqklabel); 1718 1719 switch(cmd) { 1720 case IPC_RMID: 1721 case IPC_SET: 1722 if (!mac_biba_dominate_effective(subj, obj)) 1723 return (EACCES); 1724 break; 1725 1726 case IPC_STAT: 1727 if (!mac_biba_dominate_effective(obj, subj)) 1728 return (EACCES); 1729 break; 1730 1731 default: 1732 return (EACCES); 1733 } 1734 1735 return (0); 1736} 1737 1738static int 1739mac_biba_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1740 struct label *semaklabel, int cmd) 1741{ 1742 struct mac_biba *subj, *obj; 1743 1744 if (!mac_biba_enabled) 1745 return (0); 1746 1747 subj = SLOT(cred->cr_label); 1748 obj = SLOT(semaklabel); 1749 1750 switch(cmd) { 1751 case IPC_RMID: 1752 case IPC_SET: 1753 case SETVAL: 1754 case SETALL: 1755 if (!mac_biba_dominate_effective(subj, obj)) 1756 return (EACCES); 1757 break; 1758 1759 case IPC_STAT: 1760 case GETVAL: 1761 case GETPID: 1762 case GETNCNT: 1763 case GETZCNT: 1764 case GETALL: 1765 if (!mac_biba_dominate_effective(obj, subj)) 1766 return (EACCES); 1767 break; 1768 1769 default: 1770 return (EACCES); 1771 } 1772 1773 return (0); 1774} 1775 1776 1777static int 1778mac_biba_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr, 1779 struct label *semaklabel) 1780{ 1781 struct mac_biba *subj, *obj; 1782 1783 if (!mac_biba_enabled) 1784 return (0); 1785 1786 subj = SLOT(cred->cr_label); 1787 obj = SLOT(semaklabel); 1788 1789 if (!mac_biba_dominate_effective(obj, subj)) 1790 return (EACCES); 1791 1792 return (0); 1793} 1794 1795 1796static int 1797mac_biba_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr, 1798 struct label *semaklabel, size_t accesstype) 1799{ 1800 struct mac_biba *subj, *obj; 1801 1802 if (!mac_biba_enabled) 1803 return (0); 1804 1805 subj = SLOT(cred->cr_label); 1806 obj = SLOT(semaklabel); 1807 1808 if (accesstype & SEM_R) 1809 if (!mac_biba_dominate_effective(obj, subj)) 1810 return (EACCES); 1811 1812 if (accesstype & SEM_A) 1813 if (!mac_biba_dominate_effective(subj, obj)) 1814 return (EACCES); 1815 1816 return (0); 1817} 1818 1819static int 1820mac_biba_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 1821 struct label *shmseglabel, int shmflg) 1822{ 1823 struct mac_biba *subj, *obj; 1824 1825 if (!mac_biba_enabled) 1826 return (0); 1827 1828 subj = SLOT(cred->cr_label); 1829 obj = SLOT(shmseglabel); 1830 1831 if (!mac_biba_dominate_effective(obj, subj)) 1832 return (EACCES); 1833 if ((shmflg & SHM_RDONLY) == 0) { 1834 if (!mac_biba_dominate_effective(subj, obj)) 1835 return (EACCES); 1836 } 1837 1838 return (0); 1839} 1840 1841static int 1842mac_biba_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 1843 struct label *shmseglabel, int cmd) 1844{ 1845 struct mac_biba *subj, *obj; 1846 1847 if (!mac_biba_enabled) 1848 return (0); 1849 1850 subj = SLOT(cred->cr_label); 1851 obj = SLOT(shmseglabel); 1852 1853 switch(cmd) { 1854 case IPC_RMID: 1855 case IPC_SET: 1856 if (!mac_biba_dominate_effective(subj, obj)) 1857 return (EACCES); 1858 break; 1859 1860 case IPC_STAT: 1861 case SHM_STAT: 1862 if (!mac_biba_dominate_effective(obj, subj)) 1863 return (EACCES); 1864 break; 1865 1866 default: 1867 return (EACCES); 1868 } 1869 1870 return (0); 1871} 1872 1873static int 1874mac_biba_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 1875 struct label *shmseglabel, int shmflg) 1876{ 1877 struct mac_biba *subj, *obj; 1878 1879 if (!mac_biba_enabled) 1880 return (0); 1881 1882 subj = SLOT(cred->cr_label); 1883 obj = SLOT(shmseglabel); 1884 1885 if (!mac_biba_dominate_effective(obj, subj)) 1886 return (EACCES); 1887 1888 return (0); 1889} 1890 1891static int 1892mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1893 struct label *label) 1894{ 1895 struct mac_biba *subj, *obj; 1896 int error; 1897 1898 if (!mac_biba_enabled) 1899 return (0); 1900 1901 subj = SLOT(cred->cr_label); 1902 1903 error = mac_biba_subject_privileged(subj); 1904 if (error) 1905 return (error); 1906 1907 obj = SLOT(label); 1908 if (!mac_biba_high_effective(obj)) 1909 return (EACCES); 1910 1911 return (0); 1912} 1913 1914 1915static int 1916mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1917 struct label *mntlabel) 1918{ 1919 struct mac_biba *subj, *obj; 1920 1921 if (!mac_biba_enabled) 1922 return (0); 1923 1924 subj = SLOT(cred->cr_label); 1925 obj = SLOT(mntlabel); 1926 1927 if (!mac_biba_dominate_effective(obj, subj)) 1928 return (EACCES); 1929 1930 return (0); 1931} 1932 1933static int 1934mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1935 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1936{ 1937 1938 if(!mac_biba_enabled) 1939 return (0); 1940 1941 /* XXX: This will be implemented soon... */ 1942 1943 return (0); 1944} 1945 1946static int 1947mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp, 1948 struct label *pipelabel) 1949{ 1950 struct mac_biba *subj, *obj; 1951 1952 if (!mac_biba_enabled) 1953 return (0); 1954 1955 subj = SLOT(cred->cr_label); 1956 obj = SLOT((pipelabel)); 1957 1958 if (!mac_biba_dominate_effective(obj, subj)) 1959 return (EACCES); 1960 1961 return (0); 1962} 1963 1964static int 1965mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1966 struct label *pipelabel) 1967{ 1968 struct mac_biba *subj, *obj; 1969 1970 if (!mac_biba_enabled) 1971 return (0); 1972 1973 subj = SLOT(cred->cr_label); 1974 obj = SLOT((pipelabel)); 1975 1976 if (!mac_biba_dominate_effective(obj, subj)) 1977 return (EACCES); 1978 1979 return (0); 1980} 1981 1982static int 1983mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1984 struct label *pipelabel, struct label *newlabel) 1985{ 1986 struct mac_biba *subj, *obj, *new; 1987 int error; 1988 1989 new = SLOT(newlabel); 1990 subj = SLOT(cred->cr_label); 1991 obj = SLOT(pipelabel); 1992 1993 /* 1994 * If there is a Biba label update for a pipe, it must be a 1995 * effective update. 1996 */ 1997 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 1998 if (error) 1999 return (error); 2000 2001 /* 2002 * To perform a relabel of a pipe (Biba label or not), Biba must 2003 * authorize the relabel. 2004 */ 2005 if (!mac_biba_effective_in_range(obj, subj)) 2006 return (EPERM); 2007 2008 /* 2009 * If the Biba label is to be changed, authorize as appropriate. 2010 */ 2011 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2012 /* 2013 * To change the Biba label on a pipe, the new pipe label 2014 * must be in the subject range. 2015 */ 2016 if (!mac_biba_effective_in_range(new, subj)) 2017 return (EPERM); 2018 2019 /* 2020 * To change the Biba label on a pipe to be EQUAL, the 2021 * subject must have appropriate privilege. 2022 */ 2023 if (mac_biba_contains_equal(new)) { 2024 error = mac_biba_subject_privileged(subj); 2025 if (error) 2026 return (error); 2027 } 2028 } 2029 2030 return (0); 2031} 2032 2033static int 2034mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp, 2035 struct label *pipelabel) 2036{ 2037 struct mac_biba *subj, *obj; 2038 2039 if (!mac_biba_enabled) 2040 return (0); 2041 2042 subj = SLOT(cred->cr_label); 2043 obj = SLOT((pipelabel)); 2044 2045 if (!mac_biba_dominate_effective(obj, subj)) 2046 return (EACCES); 2047 2048 return (0); 2049} 2050 2051static int 2052mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp, 2053 struct label *pipelabel) 2054{ 2055 struct mac_biba *subj, *obj; 2056 2057 if (!mac_biba_enabled) 2058 return (0); 2059 2060 subj = SLOT(cred->cr_label); 2061 obj = SLOT((pipelabel)); 2062 2063 if (!mac_biba_dominate_effective(subj, obj)) 2064 return (EACCES); 2065 2066 return (0); 2067} 2068 2069static int 2070mac_biba_check_posix_sem_write(struct ucred *cred, struct ksem *ksemptr, 2071 struct label *ks_label) 2072{ 2073 struct mac_biba *subj, *obj; 2074 2075 if (!mac_biba_enabled) 2076 return (0); 2077 2078 subj = SLOT(cred->cr_label); 2079 obj = SLOT(ks_label); 2080 2081 if (!mac_biba_dominate_effective(subj, obj)) 2082 return (EACCES); 2083 2084 return (0); 2085} 2086 2087static int 2088mac_biba_check_posix_sem_rdonly(struct ucred *cred, struct ksem *ksemptr, 2089 struct label *ks_label) 2090{ 2091 struct mac_biba *subj, *obj; 2092 2093 if (!mac_biba_enabled) 2094 return (0); 2095 2096 subj = SLOT(cred->cr_label); 2097 obj = SLOT(ks_label); 2098 2099 if (!mac_biba_dominate_effective(obj, subj)) 2100 return (EACCES); 2101 2102 return (0); 2103} 2104 2105static int 2106mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 2107{ 2108 struct mac_biba *subj, *obj; 2109 2110 if (!mac_biba_enabled) 2111 return (0); 2112 2113 subj = SLOT(cred->cr_label); 2114 obj = SLOT(proc->p_ucred->cr_label); 2115 2116 /* XXX: range checks */ 2117 if (!mac_biba_dominate_effective(obj, subj)) 2118 return (ESRCH); 2119 if (!mac_biba_dominate_effective(subj, obj)) 2120 return (EACCES); 2121 2122 return (0); 2123} 2124 2125static int 2126mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 2127{ 2128 struct mac_biba *subj, *obj; 2129 2130 if (!mac_biba_enabled) 2131 return (0); 2132 2133 subj = SLOT(cred->cr_label); 2134 obj = SLOT(proc->p_ucred->cr_label); 2135 2136 /* XXX: range checks */ 2137 if (!mac_biba_dominate_effective(obj, subj)) 2138 return (ESRCH); 2139 if (!mac_biba_dominate_effective(subj, obj)) 2140 return (EACCES); 2141 2142 return (0); 2143} 2144 2145static int 2146mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2147{ 2148 struct mac_biba *subj, *obj; 2149 2150 if (!mac_biba_enabled) 2151 return (0); 2152 2153 subj = SLOT(cred->cr_label); 2154 obj = SLOT(proc->p_ucred->cr_label); 2155 2156 /* XXX: range checks */ 2157 if (!mac_biba_dominate_effective(obj, subj)) 2158 return (ESRCH); 2159 if (!mac_biba_dominate_effective(subj, obj)) 2160 return (EACCES); 2161 2162 return (0); 2163} 2164 2165static int 2166mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 2167 struct mbuf *m, struct label *mbuflabel) 2168{ 2169 struct mac_biba *p, *s; 2170 2171 if (!mac_biba_enabled) 2172 return (0); 2173 2174 p = SLOT(mbuflabel); 2175 s = SLOT(socketlabel); 2176 2177 return (mac_biba_equal_effective(p, s) ? 0 : EACCES); 2178} 2179 2180static int 2181mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 2182 struct label *socketlabel, struct label *newlabel) 2183{ 2184 struct mac_biba *subj, *obj, *new; 2185 int error; 2186 2187 new = SLOT(newlabel); 2188 subj = SLOT(cred->cr_label); 2189 obj = SLOT(socketlabel); 2190 2191 /* 2192 * If there is a Biba label update for the socket, it may be 2193 * an update of effective. 2194 */ 2195 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2196 if (error) 2197 return (error); 2198 2199 /* 2200 * To relabel a socket, the old socket effective must be in the subject 2201 * range. 2202 */ 2203 if (!mac_biba_effective_in_range(obj, subj)) 2204 return (EPERM); 2205 2206 /* 2207 * If the Biba label is to be changed, authorize as appropriate. 2208 */ 2209 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2210 /* 2211 * To relabel a socket, the new socket effective must be in 2212 * the subject range. 2213 */ 2214 if (!mac_biba_effective_in_range(new, subj)) 2215 return (EPERM); 2216 2217 /* 2218 * To change the Biba label on the socket to contain EQUAL, 2219 * the subject must have appropriate privilege. 2220 */ 2221 if (mac_biba_contains_equal(new)) { 2222 error = mac_biba_subject_privileged(subj); 2223 if (error) 2224 return (error); 2225 } 2226 } 2227 2228 return (0); 2229} 2230 2231static int 2232mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 2233 struct label *socketlabel) 2234{ 2235 struct mac_biba *subj, *obj; 2236 2237 if (!mac_biba_enabled) 2238 return (0); 2239 2240 subj = SLOT(cred->cr_label); 2241 obj = SLOT(socketlabel); 2242 2243 if (!mac_biba_dominate_effective(obj, subj)) 2244 return (ENOENT); 2245 2246 return (0); 2247} 2248 2249/* 2250 * Some system privileges are allowed regardless of integrity grade; others 2251 * are allowed only when running with privilege with respect to the Biba 2252 * policy as they might otherwise allow bypassing of the integrity policy. 2253 */ 2254static int 2255mac_biba_priv_check(struct ucred *cred, int priv) 2256{ 2257 struct mac_biba *subj; 2258 int error; 2259 2260 if (!mac_biba_enabled) 2261 return (0); 2262 2263 /* 2264 * Exempt only specific privileges from the Biba integrity policy. 2265 */ 2266 switch (priv) { 2267 case PRIV_KTRACE: 2268 case PRIV_MSGBUF: 2269 2270 /* 2271 * Allow processes to manipulate basic process audit properties, and 2272 * to submit audit records. 2273 */ 2274 case PRIV_AUDIT_GETAUDIT: 2275 case PRIV_AUDIT_SETAUDIT: 2276 case PRIV_AUDIT_SUBMIT: 2277 2278 /* 2279 * Allow processes to manipulate their regular UNIX credentials. 2280 */ 2281 case PRIV_CRED_SETUID: 2282 case PRIV_CRED_SETEUID: 2283 case PRIV_CRED_SETGID: 2284 case PRIV_CRED_SETEGID: 2285 case PRIV_CRED_SETGROUPS: 2286 case PRIV_CRED_SETREUID: 2287 case PRIV_CRED_SETREGID: 2288 case PRIV_CRED_SETRESUID: 2289 case PRIV_CRED_SETRESGID: 2290 2291 /* 2292 * Allow processes to perform system monitoring. 2293 */ 2294 case PRIV_SEEOTHERGIDS: 2295 case PRIV_SEEOTHERUIDS: 2296 break; 2297 2298 /* 2299 * Allow access to general process debugging facilities. We 2300 * separately control debugging based on MAC label. 2301 */ 2302 case PRIV_DEBUG_DIFFCRED: 2303 case PRIV_DEBUG_SUGID: 2304 case PRIV_DEBUG_UNPRIV: 2305 2306 /* 2307 * Allow manipulating jails. 2308 */ 2309 case PRIV_JAIL_ATTACH: 2310 2311 /* 2312 * Allow privilege with respect to the Partition policy, but not the 2313 * Privs policy. 2314 */ 2315 case PRIV_MAC_PARTITION: 2316 2317 /* 2318 * Allow privilege with respect to process resource limits and login 2319 * context. 2320 */ 2321 case PRIV_PROC_LIMIT: 2322 case PRIV_PROC_SETLOGIN: 2323 case PRIV_PROC_SETRLIMIT: 2324 2325 /* 2326 * Allow System V and POSIX IPC privileges. 2327 */ 2328 case PRIV_IPC_READ: 2329 case PRIV_IPC_WRITE: 2330 case PRIV_IPC_ADMIN: 2331 case PRIV_IPC_MSGSIZE: 2332 case PRIV_MQ_ADMIN: 2333 2334 /* 2335 * Allow certain scheduler manipulations -- possibly this should be 2336 * controlled by more fine-grained policy, as potentially low 2337 * integrity processes can deny CPU to higher integrity ones. 2338 */ 2339 case PRIV_SCHED_DIFFCRED: 2340 case PRIV_SCHED_SETPRIORITY: 2341 case PRIV_SCHED_RTPRIO: 2342 case PRIV_SCHED_SETPOLICY: 2343 case PRIV_SCHED_SET: 2344 case PRIV_SCHED_SETPARAM: 2345 2346 /* 2347 * More IPC privileges. 2348 */ 2349 case PRIV_SEM_WRITE: 2350 2351 /* 2352 * Allow signaling privileges subject to integrity policy. 2353 */ 2354 case PRIV_SIGNAL_DIFFCRED: 2355 case PRIV_SIGNAL_SUGID: 2356 2357 /* 2358 * Allow access to only limited sysctls from lower integrity levels; 2359 * piggy-back on the Jail definition. 2360 */ 2361 case PRIV_SYSCTL_WRITEJAIL: 2362 2363 /* 2364 * Allow TTY-based privileges, subject to general device access using 2365 * labels on TTY device nodes, but not console privilege. 2366 */ 2367 case PRIV_TTY_DRAINWAIT: 2368 case PRIV_TTY_DTRWAIT: 2369 case PRIV_TTY_EXCLUSIVE: 2370 case PRIV_TTY_PRISON: 2371 case PRIV_TTY_STI: 2372 case PRIV_TTY_SETA: 2373 2374 /* 2375 * Grant most VFS privileges, as almost all are in practice bounded 2376 * by more specific checks using labels. 2377 */ 2378 case PRIV_VFS_READ: 2379 case PRIV_VFS_WRITE: 2380 case PRIV_VFS_ADMIN: 2381 case PRIV_VFS_EXEC: 2382 case PRIV_VFS_LOOKUP: 2383 case PRIV_VFS_CHFLAGS_DEV: 2384 case PRIV_VFS_CHOWN: 2385 case PRIV_VFS_CHROOT: 2386 case PRIV_VFS_RETAINSUGID: 2387 case PRIV_VFS_EXCEEDQUOTA: 2388 case PRIV_VFS_FCHROOT: 2389 case PRIV_VFS_FHOPEN: 2390 case PRIV_VFS_FHSTATFS: 2391 case PRIV_VFS_GENERATION: 2392 case PRIV_VFS_GETFH: 2393 case PRIV_VFS_GETQUOTA: 2394 case PRIV_VFS_LINK: 2395 case PRIV_VFS_MOUNT: 2396 case PRIV_VFS_MOUNT_OWNER: 2397 case PRIV_VFS_MOUNT_PERM: 2398 case PRIV_VFS_MOUNT_SUIDDIR: 2399 case PRIV_VFS_MOUNT_NONUSER: 2400 case PRIV_VFS_SETGID: 2401 case PRIV_VFS_STICKYFILE: 2402 case PRIV_VFS_SYSFLAGS: 2403 case PRIV_VFS_UNMOUNT: 2404 2405 /* 2406 * Allow VM privileges; it would be nice if these were subject to 2407 * resource limits. 2408 */ 2409 case PRIV_VM_MADV_PROTECT: 2410 case PRIV_VM_MLOCK: 2411 case PRIV_VM_MUNLOCK: 2412 2413 /* 2414 * Allow some but not all network privileges. In general, dont allow 2415 * reconfiguring the network stack, just normal use. 2416 */ 2417 case PRIV_NETATALK_RESERVEDPORT: 2418 case PRIV_NETINET_RESERVEDPORT: 2419 case PRIV_NETINET_RAW: 2420 case PRIV_NETINET_REUSEPORT: 2421 case PRIV_NETIPX_RESERVEDPORT: 2422 case PRIV_NETIPX_RAW: 2423 break; 2424 2425 /* 2426 * All remaining system privileges are allow only if the process 2427 * holds privilege with respect to the Biba policy. 2428 */ 2429 default: 2430 subj = SLOT(cred->cr_label); 2431 error = mac_biba_subject_privileged(subj); 2432 if (error) 2433 return (error); 2434 } 2435 return (0); 2436} 2437 2438static int 2439mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 2440 struct label *label) 2441{ 2442 struct mac_biba *subj, *obj; 2443 int error; 2444 2445 if (!mac_biba_enabled) 2446 return (0); 2447 2448 subj = SLOT(cred->cr_label); 2449 2450 error = mac_biba_subject_privileged(subj); 2451 if (error) 2452 return (error); 2453 2454 if (label == NULL) 2455 return (0); 2456 2457 obj = SLOT(label); 2458 if (!mac_biba_high_effective(obj)) 2459 return (EACCES); 2460 2461 return (0); 2462} 2463 2464static int 2465mac_biba_check_system_auditctl(struct ucred *cred, struct vnode *vp, 2466 struct label *vplabel) 2467{ 2468 struct mac_biba *subj, *obj; 2469 int error; 2470 2471 if (!mac_biba_enabled) 2472 return (0); 2473 2474 subj = SLOT(cred->cr_label); 2475 2476 error = mac_biba_subject_privileged(subj); 2477 if (error) 2478 return (error); 2479 2480 if (vplabel == NULL) 2481 return (0); 2482 2483 obj = SLOT(vplabel); 2484 if (!mac_biba_high_effective(obj)) 2485 return (EACCES); 2486 2487 return (0); 2488} 2489 2490static int 2491mac_biba_check_system_auditon(struct ucred *cred, int cmd) 2492{ 2493 struct mac_biba *subj; 2494 int error; 2495 2496 if (!mac_biba_enabled) 2497 return (0); 2498 2499 subj = SLOT(cred->cr_label); 2500 2501 error = mac_biba_subject_privileged(subj); 2502 if (error) 2503 return (error); 2504 2505 return (0); 2506} 2507 2508static int 2509mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 2510 struct label *label) 2511{ 2512 struct mac_biba *subj, *obj; 2513 int error; 2514 2515 if (!mac_biba_enabled) 2516 return (0); 2517 2518 subj = SLOT(cred->cr_label); 2519 obj = SLOT(label); 2520 2521 error = mac_biba_subject_privileged(subj); 2522 if (error) 2523 return (error); 2524 2525 if (!mac_biba_high_effective(obj)) 2526 return (EACCES); 2527 2528 return (0); 2529} 2530 2531static int 2532mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 2533 struct label *label) 2534{ 2535 struct mac_biba *subj; 2536 int error; 2537 2538 if (!mac_biba_enabled) 2539 return (0); 2540 2541 subj = SLOT(cred->cr_label); 2542 2543 error = mac_biba_subject_privileged(subj); 2544 if (error) 2545 return (error); 2546 2547 return (0); 2548} 2549 2550static int 2551mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2552 void *arg1, int arg2, struct sysctl_req *req) 2553{ 2554 struct mac_biba *subj; 2555 int error; 2556 2557 if (!mac_biba_enabled) 2558 return (0); 2559 2560 subj = SLOT(cred->cr_label); 2561 2562 /* 2563 * Treat sysctl variables without CTLFLAG_ANYBODY flag as 2564 * biba/high, but also require privilege to change them. 2565 */ 2566 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2567 if (!mac_biba_subject_dominate_high(subj)) 2568 return (EACCES); 2569 2570 error = mac_biba_subject_privileged(subj); 2571 if (error) 2572 return (error); 2573 } 2574 2575 return (0); 2576} 2577 2578static int 2579mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2580 struct label *dlabel) 2581{ 2582 struct mac_biba *subj, *obj; 2583 2584 if (!mac_biba_enabled) 2585 return (0); 2586 2587 subj = SLOT(cred->cr_label); 2588 obj = SLOT(dlabel); 2589 2590 if (!mac_biba_dominate_effective(obj, subj)) 2591 return (EACCES); 2592 2593 return (0); 2594} 2595 2596static int 2597mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2598 struct label *dlabel) 2599{ 2600 struct mac_biba *subj, *obj; 2601 2602 if (!mac_biba_enabled) 2603 return (0); 2604 2605 subj = SLOT(cred->cr_label); 2606 obj = SLOT(dlabel); 2607 2608 if (!mac_biba_dominate_effective(obj, subj)) 2609 return (EACCES); 2610 2611 return (0); 2612} 2613 2614static int 2615mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2616 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2617{ 2618 struct mac_biba *subj, *obj; 2619 2620 if (!mac_biba_enabled) 2621 return (0); 2622 2623 subj = SLOT(cred->cr_label); 2624 obj = SLOT(dlabel); 2625 2626 if (!mac_biba_dominate_effective(subj, obj)) 2627 return (EACCES); 2628 2629 return (0); 2630} 2631 2632static int 2633mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2634 struct label *dlabel, struct vnode *vp, struct label *label, 2635 struct componentname *cnp) 2636{ 2637 struct mac_biba *subj, *obj; 2638 2639 if (!mac_biba_enabled) 2640 return (0); 2641 2642 subj = SLOT(cred->cr_label); 2643 obj = SLOT(dlabel); 2644 2645 if (!mac_biba_dominate_effective(subj, obj)) 2646 return (EACCES); 2647 2648 obj = SLOT(label); 2649 2650 if (!mac_biba_dominate_effective(subj, obj)) 2651 return (EACCES); 2652 2653 return (0); 2654} 2655 2656static int 2657mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2658 struct label *label, acl_type_t type) 2659{ 2660 struct mac_biba *subj, *obj; 2661 2662 if (!mac_biba_enabled) 2663 return (0); 2664 2665 subj = SLOT(cred->cr_label); 2666 obj = SLOT(label); 2667 2668 if (!mac_biba_dominate_effective(subj, obj)) 2669 return (EACCES); 2670 2671 return (0); 2672} 2673 2674static int 2675mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2676 struct label *label, int attrnamespace, const char *name) 2677{ 2678 struct mac_biba *subj, *obj; 2679 2680 if (!mac_biba_enabled) 2681 return (0); 2682 2683 subj = SLOT(cred->cr_label); 2684 obj = SLOT(label); 2685 2686 if (!mac_biba_dominate_effective(subj, obj)) 2687 return (EACCES); 2688 2689 return (0); 2690} 2691 2692static int 2693mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2694 struct label *label, struct image_params *imgp, 2695 struct label *execlabel) 2696{ 2697 struct mac_biba *subj, *obj, *exec; 2698 int error; 2699 2700 if (execlabel != NULL) { 2701 /* 2702 * We currently don't permit labels to be changed at 2703 * exec-time as part of Biba, so disallow non-NULL 2704 * Biba label elements in the execlabel. 2705 */ 2706 exec = SLOT(execlabel); 2707 error = biba_atmostflags(exec, 0); 2708 if (error) 2709 return (error); 2710 } 2711 2712 if (!mac_biba_enabled) 2713 return (0); 2714 2715 subj = SLOT(cred->cr_label); 2716 obj = SLOT(label); 2717 2718 if (!mac_biba_dominate_effective(obj, subj)) 2719 return (EACCES); 2720 2721 return (0); 2722} 2723 2724static int 2725mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2726 struct label *label, acl_type_t type) 2727{ 2728 struct mac_biba *subj, *obj; 2729 2730 if (!mac_biba_enabled) 2731 return (0); 2732 2733 subj = SLOT(cred->cr_label); 2734 obj = SLOT(label); 2735 2736 if (!mac_biba_dominate_effective(obj, subj)) 2737 return (EACCES); 2738 2739 return (0); 2740} 2741 2742static int 2743mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2744 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2745{ 2746 struct mac_biba *subj, *obj; 2747 2748 if (!mac_biba_enabled) 2749 return (0); 2750 2751 subj = SLOT(cred->cr_label); 2752 obj = SLOT(label); 2753 2754 if (!mac_biba_dominate_effective(obj, subj)) 2755 return (EACCES); 2756 2757 return (0); 2758} 2759 2760static int 2761mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2762 struct label *dlabel, struct vnode *vp, struct label *label, 2763 struct componentname *cnp) 2764{ 2765 struct mac_biba *subj, *obj; 2766 2767 if (!mac_biba_enabled) 2768 return (0); 2769 2770 subj = SLOT(cred->cr_label); 2771 obj = SLOT(dlabel); 2772 2773 if (!mac_biba_dominate_effective(subj, obj)) 2774 return (EACCES); 2775 2776 obj = SLOT(label); 2777 2778 if (!mac_biba_dominate_effective(subj, obj)) 2779 return (EACCES); 2780 2781 return (0); 2782} 2783 2784static int 2785mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2786 struct label *label, int attrnamespace) 2787{ 2788 struct mac_biba *subj, *obj; 2789 2790 if (!mac_biba_enabled) 2791 return (0); 2792 2793 subj = SLOT(cred->cr_label); 2794 obj = SLOT(label); 2795 2796 if (!mac_biba_dominate_effective(obj, subj)) 2797 return (EACCES); 2798 2799 return (0); 2800} 2801 2802static int 2803mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2804 struct label *dlabel, struct componentname *cnp) 2805{ 2806 struct mac_biba *subj, *obj; 2807 2808 if (!mac_biba_enabled) 2809 return (0); 2810 2811 subj = SLOT(cred->cr_label); 2812 obj = SLOT(dlabel); 2813 2814 if (!mac_biba_dominate_effective(obj, subj)) 2815 return (EACCES); 2816 2817 return (0); 2818} 2819 2820static int 2821mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2822 struct label *label, int prot, int flags) 2823{ 2824 struct mac_biba *subj, *obj; 2825 2826 /* 2827 * Rely on the use of open()-time protections to handle 2828 * non-revocation cases. 2829 */ 2830 if (!mac_biba_enabled || !revocation_enabled) 2831 return (0); 2832 2833 subj = SLOT(cred->cr_label); 2834 obj = SLOT(label); 2835 2836 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2837 if (!mac_biba_dominate_effective(obj, subj)) 2838 return (EACCES); 2839 } 2840 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2841 if (!mac_biba_dominate_effective(subj, obj)) 2842 return (EACCES); 2843 } 2844 2845 return (0); 2846} 2847 2848static int 2849mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2850 struct label *vnodelabel, int acc_mode) 2851{ 2852 struct mac_biba *subj, *obj; 2853 2854 if (!mac_biba_enabled) 2855 return (0); 2856 2857 subj = SLOT(cred->cr_label); 2858 obj = SLOT(vnodelabel); 2859 2860 /* XXX privilege override for admin? */ 2861 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2862 if (!mac_biba_dominate_effective(obj, subj)) 2863 return (EACCES); 2864 } 2865 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2866 if (!mac_biba_dominate_effective(subj, obj)) 2867 return (EACCES); 2868 } 2869 2870 return (0); 2871} 2872 2873static int 2874mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2875 struct vnode *vp, struct label *label) 2876{ 2877 struct mac_biba *subj, *obj; 2878 2879 if (!mac_biba_enabled || !revocation_enabled) 2880 return (0); 2881 2882 subj = SLOT(active_cred->cr_label); 2883 obj = SLOT(label); 2884 2885 if (!mac_biba_dominate_effective(obj, subj)) 2886 return (EACCES); 2887 2888 return (0); 2889} 2890 2891static int 2892mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2893 struct vnode *vp, struct label *label) 2894{ 2895 struct mac_biba *subj, *obj; 2896 2897 if (!mac_biba_enabled || !revocation_enabled) 2898 return (0); 2899 2900 subj = SLOT(active_cred->cr_label); 2901 obj = SLOT(label); 2902 2903 if (!mac_biba_dominate_effective(obj, subj)) 2904 return (EACCES); 2905 2906 return (0); 2907} 2908 2909static int 2910mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2911 struct label *dlabel) 2912{ 2913 struct mac_biba *subj, *obj; 2914 2915 if (!mac_biba_enabled) 2916 return (0); 2917 2918 subj = SLOT(cred->cr_label); 2919 obj = SLOT(dlabel); 2920 2921 if (!mac_biba_dominate_effective(obj, subj)) 2922 return (EACCES); 2923 2924 return (0); 2925} 2926 2927static int 2928mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2929 struct label *label) 2930{ 2931 struct mac_biba *subj, *obj; 2932 2933 if (!mac_biba_enabled) 2934 return (0); 2935 2936 subj = SLOT(cred->cr_label); 2937 obj = SLOT(label); 2938 2939 if (!mac_biba_dominate_effective(obj, subj)) 2940 return (EACCES); 2941 2942 return (0); 2943} 2944 2945static int 2946mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2947 struct label *vnodelabel, struct label *newlabel) 2948{ 2949 struct mac_biba *old, *new, *subj; 2950 int error; 2951 2952 old = SLOT(vnodelabel); 2953 new = SLOT(newlabel); 2954 subj = SLOT(cred->cr_label); 2955 2956 /* 2957 * If there is a Biba label update for the vnode, it must be a 2958 * effective label. 2959 */ 2960 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2961 if (error) 2962 return (error); 2963 2964 /* 2965 * To perform a relabel of the vnode (Biba label or not), Biba must 2966 * authorize the relabel. 2967 */ 2968 if (!mac_biba_effective_in_range(old, subj)) 2969 return (EPERM); 2970 2971 /* 2972 * If the Biba label is to be changed, authorize as appropriate. 2973 */ 2974 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2975 /* 2976 * To change the Biba label on a vnode, the new vnode label 2977 * must be in the subject range. 2978 */ 2979 if (!mac_biba_effective_in_range(new, subj)) 2980 return (EPERM); 2981 2982 /* 2983 * To change the Biba label on the vnode to be EQUAL, 2984 * the subject must have appropriate privilege. 2985 */ 2986 if (mac_biba_contains_equal(new)) { 2987 error = mac_biba_subject_privileged(subj); 2988 if (error) 2989 return (error); 2990 } 2991 } 2992 2993 return (0); 2994} 2995 2996static int 2997mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2998 struct label *dlabel, struct vnode *vp, struct label *label, 2999 struct componentname *cnp) 3000{ 3001 struct mac_biba *subj, *obj; 3002 3003 if (!mac_biba_enabled) 3004 return (0); 3005 3006 subj = SLOT(cred->cr_label); 3007 obj = SLOT(dlabel); 3008 3009 if (!mac_biba_dominate_effective(subj, obj)) 3010 return (EACCES); 3011 3012 obj = SLOT(label); 3013 3014 if (!mac_biba_dominate_effective(subj, obj)) 3015 return (EACCES); 3016 3017 return (0); 3018} 3019 3020static int 3021mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 3022 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 3023 struct componentname *cnp) 3024{ 3025 struct mac_biba *subj, *obj; 3026 3027 if (!mac_biba_enabled) 3028 return (0); 3029 3030 subj = SLOT(cred->cr_label); 3031 obj = SLOT(dlabel); 3032 3033 if (!mac_biba_dominate_effective(subj, obj)) 3034 return (EACCES); 3035 3036 if (vp != NULL) { 3037 obj = SLOT(label); 3038 3039 if (!mac_biba_dominate_effective(subj, obj)) 3040 return (EACCES); 3041 } 3042 3043 return (0); 3044} 3045 3046static int 3047mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 3048 struct label *label) 3049{ 3050 struct mac_biba *subj, *obj; 3051 3052 if (!mac_biba_enabled) 3053 return (0); 3054 3055 subj = SLOT(cred->cr_label); 3056 obj = SLOT(label); 3057 3058 if (!mac_biba_dominate_effective(subj, obj)) 3059 return (EACCES); 3060 3061 return (0); 3062} 3063 3064static int 3065mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 3066 struct label *label, acl_type_t type, struct acl *acl) 3067{ 3068 struct mac_biba *subj, *obj; 3069 3070 if (!mac_biba_enabled) 3071 return (0); 3072 3073 subj = SLOT(cred->cr_label); 3074 obj = SLOT(label); 3075 3076 if (!mac_biba_dominate_effective(subj, obj)) 3077 return (EACCES); 3078 3079 return (0); 3080} 3081 3082static int 3083mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 3084 struct label *vnodelabel, int attrnamespace, const char *name, 3085 struct uio *uio) 3086{ 3087 struct mac_biba *subj, *obj; 3088 3089 if (!mac_biba_enabled) 3090 return (0); 3091 3092 subj = SLOT(cred->cr_label); 3093 obj = SLOT(vnodelabel); 3094 3095 if (!mac_biba_dominate_effective(subj, obj)) 3096 return (EACCES); 3097 3098 /* XXX: protect the MAC EA in a special way? */ 3099 3100 return (0); 3101} 3102 3103static int 3104mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 3105 struct label *vnodelabel, u_long flags) 3106{ 3107 struct mac_biba *subj, *obj; 3108 3109 if (!mac_biba_enabled) 3110 return (0); 3111 3112 subj = SLOT(cred->cr_label); 3113 obj = SLOT(vnodelabel); 3114 3115 if (!mac_biba_dominate_effective(subj, obj)) 3116 return (EACCES); 3117 3118 return (0); 3119} 3120 3121static int 3122mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 3123 struct label *vnodelabel, mode_t mode) 3124{ 3125 struct mac_biba *subj, *obj; 3126 3127 if (!mac_biba_enabled) 3128 return (0); 3129 3130 subj = SLOT(cred->cr_label); 3131 obj = SLOT(vnodelabel); 3132 3133 if (!mac_biba_dominate_effective(subj, obj)) 3134 return (EACCES); 3135 3136 return (0); 3137} 3138 3139static int 3140mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 3141 struct label *vnodelabel, uid_t uid, gid_t gid) 3142{ 3143 struct mac_biba *subj, *obj; 3144 3145 if (!mac_biba_enabled) 3146 return (0); 3147 3148 subj = SLOT(cred->cr_label); 3149 obj = SLOT(vnodelabel); 3150 3151 if (!mac_biba_dominate_effective(subj, obj)) 3152 return (EACCES); 3153 3154 return (0); 3155} 3156 3157static int 3158mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 3159 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 3160{ 3161 struct mac_biba *subj, *obj; 3162 3163 if (!mac_biba_enabled) 3164 return (0); 3165 3166 subj = SLOT(cred->cr_label); 3167 obj = SLOT(vnodelabel); 3168 3169 if (!mac_biba_dominate_effective(subj, obj)) 3170 return (EACCES); 3171 3172 return (0); 3173} 3174 3175static int 3176mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 3177 struct vnode *vp, struct label *vnodelabel) 3178{ 3179 struct mac_biba *subj, *obj; 3180 3181 if (!mac_biba_enabled) 3182 return (0); 3183 3184 subj = SLOT(active_cred->cr_label); 3185 obj = SLOT(vnodelabel); 3186 3187 if (!mac_biba_dominate_effective(obj, subj)) 3188 return (EACCES); 3189 3190 return (0); 3191} 3192 3193static int 3194mac_biba_check_vnode_write(struct ucred *active_cred, 3195 struct ucred *file_cred, struct vnode *vp, struct label *label) 3196{ 3197 struct mac_biba *subj, *obj; 3198 3199 if (!mac_biba_enabled || !revocation_enabled) 3200 return (0); 3201 3202 subj = SLOT(active_cred->cr_label); 3203 obj = SLOT(label); 3204 3205 if (!mac_biba_dominate_effective(subj, obj)) 3206 return (EACCES); 3207 3208 return (0); 3209} 3210 3211static void 3212mac_biba_associate_nfsd_label(struct ucred *cred) 3213{ 3214 struct mac_biba *label; 3215 3216 label = SLOT(cred->cr_label); 3217 mac_biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL); 3218 mac_biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, 3219 MAC_BIBA_TYPE_HIGH, 0, NULL); 3220} 3221 3222static void 3223mac_biba_init_syncache_from_inpcb(struct label *label, struct inpcb *inp) 3224{ 3225 struct mac_biba *source, *dest; 3226 3227 source = SLOT(inp->inp_label); 3228 dest = SLOT(label); 3229 mac_biba_copy_effective(source, dest); 3230} 3231 3232static void 3233mac_biba_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m, 3234 struct label *mbuf_label) 3235{ 3236 struct mac_biba *source, *dest; 3237 3238 source = SLOT(sc_label); 3239 dest = SLOT(mbuf_label); 3240 mac_biba_copy_effective(source, dest); 3241} 3242 3243static struct mac_policy_ops mac_biba_ops = 3244{ 3245 .mpo_init = mac_biba_init, 3246 .mpo_init_bpfdesc_label = mac_biba_init_label, 3247 .mpo_init_cred_label = mac_biba_init_label, 3248 .mpo_init_devfsdirent_label = mac_biba_init_label, 3249 .mpo_init_ifnet_label = mac_biba_init_label, 3250 .mpo_init_inpcb_label = mac_biba_init_label_waitcheck, 3251 .mpo_init_syncache_label = mac_biba_init_label_waitcheck, 3252 .mpo_init_sysv_msgmsg_label = mac_biba_init_label, 3253 .mpo_init_sysv_msgqueue_label = mac_biba_init_label, 3254 .mpo_init_sysv_sem_label = mac_biba_init_label, 3255 .mpo_init_sysv_shm_label = mac_biba_init_label, 3256 .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 3257 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 3258 .mpo_init_mount_label = mac_biba_init_label, 3259 .mpo_init_pipe_label = mac_biba_init_label, 3260 .mpo_init_posix_sem_label = mac_biba_init_label, 3261 .mpo_init_socket_label = mac_biba_init_label_waitcheck, 3262 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 3263 .mpo_init_syncache_from_inpcb = mac_biba_init_syncache_from_inpcb, 3264 .mpo_init_vnode_label = mac_biba_init_label, 3265 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 3266 .mpo_destroy_cred_label = mac_biba_destroy_label, 3267 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 3268 .mpo_destroy_ifnet_label = mac_biba_destroy_label, 3269 .mpo_destroy_inpcb_label = mac_biba_destroy_label, 3270 .mpo_destroy_syncache_label = mac_biba_destroy_label, 3271 .mpo_destroy_sysv_msgmsg_label = mac_biba_destroy_label, 3272 .mpo_destroy_sysv_msgqueue_label = mac_biba_destroy_label, 3273 .mpo_destroy_sysv_sem_label = mac_biba_destroy_label, 3274 .mpo_destroy_sysv_shm_label = mac_biba_destroy_label, 3275 .mpo_destroy_ipq_label = mac_biba_destroy_label, 3276 .mpo_destroy_mbuf_label = mac_biba_destroy_label, 3277 .mpo_destroy_mount_label = mac_biba_destroy_label, 3278 .mpo_destroy_pipe_label = mac_biba_destroy_label, 3279 .mpo_destroy_posix_sem_label = mac_biba_destroy_label, 3280 .mpo_destroy_socket_label = mac_biba_destroy_label, 3281 .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 3282 .mpo_destroy_vnode_label = mac_biba_destroy_label, 3283 .mpo_copy_cred_label = mac_biba_copy_label, 3284 .mpo_copy_ifnet_label = mac_biba_copy_label, 3285 .mpo_copy_mbuf_label = mac_biba_copy_label, 3286 .mpo_copy_pipe_label = mac_biba_copy_label, 3287 .mpo_copy_socket_label = mac_biba_copy_label, 3288 .mpo_copy_vnode_label = mac_biba_copy_label, 3289 .mpo_externalize_cred_label = mac_biba_externalize_label, 3290 .mpo_externalize_ifnet_label = mac_biba_externalize_label, 3291 .mpo_externalize_pipe_label = mac_biba_externalize_label, 3292 .mpo_externalize_socket_label = mac_biba_externalize_label, 3293 .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 3294 .mpo_externalize_vnode_label = mac_biba_externalize_label, 3295 .mpo_internalize_cred_label = mac_biba_internalize_label, 3296 .mpo_internalize_ifnet_label = mac_biba_internalize_label, 3297 .mpo_internalize_pipe_label = mac_biba_internalize_label, 3298 .mpo_internalize_socket_label = mac_biba_internalize_label, 3299 .mpo_internalize_vnode_label = mac_biba_internalize_label, 3300 .mpo_create_devfs_device = mac_biba_create_devfs_device, 3301 .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 3302 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 3303 .mpo_create_mount = mac_biba_create_mount, 3304 .mpo_relabel_vnode = mac_biba_relabel_vnode, 3305 .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 3306 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 3307 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 3308 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 3309 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 3310 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 3311 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 3312 .mpo_create_mbuf_from_syncache = mac_biba_create_mbuf_from_syncache, 3313 .mpo_create_pipe = mac_biba_create_pipe, 3314 .mpo_create_posix_sem = mac_biba_create_posix_sem, 3315 .mpo_create_socket = mac_biba_create_socket, 3316 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 3317 .mpo_relabel_pipe = mac_biba_relabel_pipe, 3318 .mpo_relabel_socket = mac_biba_relabel_socket, 3319 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 3320 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 3321 .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 3322 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 3323 .mpo_create_fragment = mac_biba_create_fragment, 3324 .mpo_create_ifnet = mac_biba_create_ifnet, 3325 .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket, 3326 .mpo_create_sysv_msgmsg = mac_biba_create_sysv_msgmsg, 3327 .mpo_create_sysv_msgqueue = mac_biba_create_sysv_msgqueue, 3328 .mpo_create_sysv_sem = mac_biba_create_sysv_sem, 3329 .mpo_create_sysv_shm = mac_biba_create_sysv_shm, 3330 .mpo_create_ipq = mac_biba_create_ipq, 3331 .mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb, 3332 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 3333 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 3334 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 3335 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 3336 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 3337 .mpo_fragment_match = mac_biba_fragment_match, 3338 .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 3339 .mpo_update_ipq = mac_biba_update_ipq, 3340 .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel, 3341 .mpo_create_proc0 = mac_biba_create_proc0, 3342 .mpo_create_proc1 = mac_biba_create_proc1, 3343 .mpo_relabel_cred = mac_biba_relabel_cred, 3344 .mpo_cleanup_sysv_msgmsg = mac_biba_cleanup_sysv_msgmsg, 3345 .mpo_cleanup_sysv_msgqueue = mac_biba_cleanup_sysv_msgqueue, 3346 .mpo_cleanup_sysv_sem = mac_biba_cleanup_sysv_sem, 3347 .mpo_cleanup_sysv_shm = mac_biba_cleanup_sysv_shm, 3348 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 3349 .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 3350 .mpo_check_cred_visible = mac_biba_check_cred_visible, 3351 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 3352 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 3353 .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver, 3354 .mpo_check_sysv_msgrcv = mac_biba_check_sysv_msgrcv, 3355 .mpo_check_sysv_msgrmid = mac_biba_check_sysv_msgrmid, 3356 .mpo_check_sysv_msqget = mac_biba_check_sysv_msqget, 3357 .mpo_check_sysv_msqsnd = mac_biba_check_sysv_msqsnd, 3358 .mpo_check_sysv_msqrcv = mac_biba_check_sysv_msqrcv, 3359 .mpo_check_sysv_msqctl = mac_biba_check_sysv_msqctl, 3360 .mpo_check_sysv_semctl = mac_biba_check_sysv_semctl, 3361 .mpo_check_sysv_semget = mac_biba_check_sysv_semget, 3362 .mpo_check_sysv_semop = mac_biba_check_sysv_semop, 3363 .mpo_check_sysv_shmat = mac_biba_check_sysv_shmat, 3364 .mpo_check_sysv_shmctl = mac_biba_check_sysv_shmctl, 3365 .mpo_check_sysv_shmget = mac_biba_check_sysv_shmget, 3366 .mpo_check_kld_load = mac_biba_check_kld_load, 3367 .mpo_check_mount_stat = mac_biba_check_mount_stat, 3368 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 3369 .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 3370 .mpo_check_pipe_read = mac_biba_check_pipe_read, 3371 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 3372 .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 3373 .mpo_check_pipe_write = mac_biba_check_pipe_write, 3374 .mpo_check_posix_sem_destroy = mac_biba_check_posix_sem_write, 3375 .mpo_check_posix_sem_getvalue = mac_biba_check_posix_sem_rdonly, 3376 .mpo_check_posix_sem_open = mac_biba_check_posix_sem_write, 3377 .mpo_check_posix_sem_post = mac_biba_check_posix_sem_write, 3378 .mpo_check_posix_sem_unlink = mac_biba_check_posix_sem_write, 3379 .mpo_check_posix_sem_wait = mac_biba_check_posix_sem_write, 3380 .mpo_check_proc_debug = mac_biba_check_proc_debug, 3381 .mpo_check_proc_sched = mac_biba_check_proc_sched, 3382 .mpo_check_proc_signal = mac_biba_check_proc_signal, 3383 .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 3384 .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 3385 .mpo_check_socket_visible = mac_biba_check_socket_visible, 3386 .mpo_check_system_acct = mac_biba_check_system_acct, 3387 .mpo_check_system_auditctl = mac_biba_check_system_auditctl, 3388 .mpo_check_system_auditon = mac_biba_check_system_auditon, 3389 .mpo_check_system_swapon = mac_biba_check_system_swapon, 3390 .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 3391 .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 3392 .mpo_check_vnode_access = mac_biba_check_vnode_open, 3393 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 3394 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 3395 .mpo_check_vnode_create = mac_biba_check_vnode_create, 3396 .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 3397 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 3398 .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr, 3399 .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 3400 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 3401 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 3402 .mpo_check_vnode_link = mac_biba_check_vnode_link, 3403 .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr, 3404 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 3405 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 3406 .mpo_check_vnode_open = mac_biba_check_vnode_open, 3407 .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 3408 .mpo_check_vnode_read = mac_biba_check_vnode_read, 3409 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 3410 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 3411 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 3412 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 3413 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 3414 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 3415 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 3416 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 3417 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 3418 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 3419 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 3420 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 3421 .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 3422 .mpo_check_vnode_write = mac_biba_check_vnode_write, 3423 .mpo_associate_nfsd_label = mac_biba_associate_nfsd_label, 3424 .mpo_create_mbuf_from_firewall = mac_biba_create_mbuf_from_firewall, 3425 .mpo_priv_check = mac_biba_priv_check, 3426}; 3427 3428MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 3429 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot); 3430