mac_biba.c revision 136774
1/*- 2 * Copyright (c) 1999-2002 Robert N. M. Watson 3 * Copyright (c) 2001-2004 Networks Associates Technology, 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 Network 9 * Associates Laboratories, the Security Research Division of Network 10 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 11 * as part of the DARPA 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 136774 2004-10-22 11:15:47Z rwatson $ 35 */ 36 37/* 38 * Developed by the TrustedBSD Project. 39 * Biba fixed label mandatory integrity policy. 40 */ 41 42#include <sys/types.h> 43#include <sys/param.h> 44#include <sys/acl.h> 45#include <sys/conf.h> 46#include <sys/extattr.h> 47#include <sys/kernel.h> 48#include <sys/mac.h> 49#include <sys/malloc.h> 50#include <sys/mount.h> 51#include <sys/proc.h> 52#include <sys/sbuf.h> 53#include <sys/systm.h> 54#include <sys/sysproto.h> 55#include <sys/sysent.h> 56#include <sys/systm.h> 57#include <sys/vnode.h> 58#include <sys/file.h> 59#include <sys/socket.h> 60#include <sys/socketvar.h> 61#include <sys/pipe.h> 62#include <sys/sysctl.h> 63 64#include <fs/devfs/devfs.h> 65 66#include <net/bpfdesc.h> 67#include <net/if.h> 68#include <net/if_types.h> 69#include <net/if_var.h> 70 71#include <netinet/in.h> 72#include <netinet/in_pcb.h> 73#include <netinet/ip_var.h> 74 75#include <vm/uma.h> 76#include <vm/vm.h> 77 78#include <sys/mac_policy.h> 79 80#include <security/mac_biba/mac_biba.h> 81 82SYSCTL_DECL(_security_mac); 83 84SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 85 "TrustedBSD mac_biba policy controls"); 86 87static int mac_biba_label_size = sizeof(struct mac_biba); 88SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 89 &mac_biba_label_size, 0, "Size of struct mac_biba"); 90 91static int mac_biba_enabled = 1; 92SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 93 &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 94TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 95 96static int destroyed_not_inited; 97SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 98 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 99 100static int trust_all_interfaces = 0; 101SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 102 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 103TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 104 105static char trusted_interfaces[128]; 106SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 107 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 108TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 109 sizeof(trusted_interfaces)); 110 111static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 112SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 113 &max_compartments, 0, "Maximum supported compartments"); 114 115static int ptys_equal = 0; 116SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 117 &ptys_equal, 0, "Label pty devices as biba/equal on create"); 118TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 119 120static int revocation_enabled = 0; 121SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 122 &revocation_enabled, 0, "Revoke access to objects on relabel"); 123TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 124 125static int mac_biba_slot; 126#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 127#define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_biba_slot).l_ptr = (val)) 128 129static uma_zone_t zone_biba; 130 131static __inline int 132biba_bit_set_empty(u_char *set) { 133 int i; 134 135 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 136 if (set[i] != 0) 137 return (0); 138 return (1); 139} 140 141static struct mac_biba * 142biba_alloc(int flag) 143{ 144 145 return (uma_zalloc(zone_biba, flag | M_ZERO)); 146} 147 148static void 149biba_free(struct mac_biba *mac_biba) 150{ 151 152 if (mac_biba != NULL) 153 uma_zfree(zone_biba, mac_biba); 154 else 155 atomic_add_int(&destroyed_not_inited, 1); 156} 157 158static int 159biba_atmostflags(struct mac_biba *mac_biba, int flags) 160{ 161 162 if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 163 return (EINVAL); 164 return (0); 165} 166 167static int 168mac_biba_dominate_element(struct mac_biba_element *a, 169 struct mac_biba_element *b) 170{ 171 int bit; 172 173 switch (a->mbe_type) { 174 case MAC_BIBA_TYPE_EQUAL: 175 case MAC_BIBA_TYPE_HIGH: 176 return (1); 177 178 case MAC_BIBA_TYPE_LOW: 179 switch (b->mbe_type) { 180 case MAC_BIBA_TYPE_GRADE: 181 case MAC_BIBA_TYPE_HIGH: 182 return (0); 183 184 case MAC_BIBA_TYPE_EQUAL: 185 case MAC_BIBA_TYPE_LOW: 186 return (1); 187 188 default: 189 panic("mac_biba_dominate_element: b->mbe_type invalid"); 190 } 191 192 case MAC_BIBA_TYPE_GRADE: 193 switch (b->mbe_type) { 194 case MAC_BIBA_TYPE_EQUAL: 195 case MAC_BIBA_TYPE_LOW: 196 return (1); 197 198 case MAC_BIBA_TYPE_HIGH: 199 return (0); 200 201 case MAC_BIBA_TYPE_GRADE: 202 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 203 if (!MAC_BIBA_BIT_TEST(bit, 204 a->mbe_compartments) && 205 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 206 return (0); 207 return (a->mbe_grade >= b->mbe_grade); 208 209 default: 210 panic("mac_biba_dominate_element: b->mbe_type invalid"); 211 } 212 213 default: 214 panic("mac_biba_dominate_element: a->mbe_type invalid"); 215 } 216 217 return (0); 218} 219 220static int 221mac_biba_subject_dominate_high(struct mac_biba *mac_biba) 222{ 223 struct mac_biba_element *element; 224 225 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 226 ("mac_biba_effective_in_range: mac_biba not effective")); 227 element = &mac_biba->mb_effective; 228 229 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 230 element->mbe_type == MAC_BIBA_TYPE_HIGH); 231} 232 233static int 234mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 235{ 236 237 return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 238 &rangea->mb_rangehigh) && 239 mac_biba_dominate_element(&rangea->mb_rangelow, 240 &rangeb->mb_rangelow)); 241} 242 243static int 244mac_biba_effective_in_range(struct mac_biba *effective, 245 struct mac_biba *range) 246{ 247 248 KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 249 ("mac_biba_effective_in_range: a not effective")); 250 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 251 ("mac_biba_effective_in_range: b not range")); 252 253 return (mac_biba_dominate_element(&range->mb_rangehigh, 254 &effective->mb_effective) && 255 mac_biba_dominate_element(&effective->mb_effective, 256 &range->mb_rangelow)); 257 258 return (1); 259} 260 261static int 262mac_biba_dominate_effective(struct mac_biba *a, struct mac_biba *b) 263{ 264 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 265 ("mac_biba_dominate_effective: a not effective")); 266 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 267 ("mac_biba_dominate_effective: b not effective")); 268 269 return (mac_biba_dominate_element(&a->mb_effective, &b->mb_effective)); 270} 271 272static int 273mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 274{ 275 276 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 277 b->mbe_type == MAC_BIBA_TYPE_EQUAL) 278 return (1); 279 280 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 281} 282 283static int 284mac_biba_equal_effective(struct mac_biba *a, struct mac_biba *b) 285{ 286 287 KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 288 ("mac_biba_equal_effective: a not effective")); 289 KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 290 ("mac_biba_equal_effective: b not effective")); 291 292 return (mac_biba_equal_element(&a->mb_effective, &b->mb_effective)); 293} 294 295static int 296mac_biba_contains_equal(struct mac_biba *mac_biba) 297{ 298 299 if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) 300 if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 301 return (1); 302 303 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 304 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 305 return (1); 306 if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 307 return (1); 308 } 309 310 return (0); 311} 312 313static int 314mac_biba_subject_privileged(struct mac_biba *mac_biba) 315{ 316 317 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 318 MAC_BIBA_FLAGS_BOTH, 319 ("mac_biba_subject_privileged: subject doesn't have both labels")); 320 321 /* If the effective is EQUAL, it's ok. */ 322 if (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 323 return (0); 324 325 /* If either range endpoint is EQUAL, it's ok. */ 326 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 327 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 328 return (0); 329 330 /* If the range is low-high, it's ok. */ 331 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 332 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 333 return (0); 334 335 /* It's not ok. */ 336 return (EPERM); 337} 338 339static int 340mac_biba_high_effective(struct mac_biba *mac_biba) 341{ 342 343 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 344 ("mac_biba_equal_effective: mac_biba not effective")); 345 346 return (mac_biba->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH); 347} 348 349static int 350mac_biba_valid(struct mac_biba *mac_biba) 351{ 352 353 if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 354 switch (mac_biba->mb_effective.mbe_type) { 355 case MAC_BIBA_TYPE_GRADE: 356 break; 357 358 case MAC_BIBA_TYPE_EQUAL: 359 case MAC_BIBA_TYPE_HIGH: 360 case MAC_BIBA_TYPE_LOW: 361 if (mac_biba->mb_effective.mbe_grade != 0 || 362 !MAC_BIBA_BIT_SET_EMPTY( 363 mac_biba->mb_effective.mbe_compartments)) 364 return (EINVAL); 365 break; 366 367 default: 368 return (EINVAL); 369 } 370 } else { 371 if (mac_biba->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF) 372 return (EINVAL); 373 } 374 375 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 376 switch (mac_biba->mb_rangelow.mbe_type) { 377 case MAC_BIBA_TYPE_GRADE: 378 break; 379 380 case MAC_BIBA_TYPE_EQUAL: 381 case MAC_BIBA_TYPE_HIGH: 382 case MAC_BIBA_TYPE_LOW: 383 if (mac_biba->mb_rangelow.mbe_grade != 0 || 384 !MAC_BIBA_BIT_SET_EMPTY( 385 mac_biba->mb_rangelow.mbe_compartments)) 386 return (EINVAL); 387 break; 388 389 default: 390 return (EINVAL); 391 } 392 393 switch (mac_biba->mb_rangehigh.mbe_type) { 394 case MAC_BIBA_TYPE_GRADE: 395 break; 396 397 case MAC_BIBA_TYPE_EQUAL: 398 case MAC_BIBA_TYPE_HIGH: 399 case MAC_BIBA_TYPE_LOW: 400 if (mac_biba->mb_rangehigh.mbe_grade != 0 || 401 !MAC_BIBA_BIT_SET_EMPTY( 402 mac_biba->mb_rangehigh.mbe_compartments)) 403 return (EINVAL); 404 break; 405 406 default: 407 return (EINVAL); 408 } 409 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 410 &mac_biba->mb_rangelow)) 411 return (EINVAL); 412 } else { 413 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 414 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 415 return (EINVAL); 416 } 417 418 return (0); 419} 420 421static void 422mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 423 u_short gradelow, u_char *compartmentslow, u_short typehigh, 424 u_short gradehigh, u_char *compartmentshigh) 425{ 426 427 mac_biba->mb_rangelow.mbe_type = typelow; 428 mac_biba->mb_rangelow.mbe_grade = gradelow; 429 if (compartmentslow != NULL) 430 memcpy(mac_biba->mb_rangelow.mbe_compartments, 431 compartmentslow, 432 sizeof(mac_biba->mb_rangelow.mbe_compartments)); 433 mac_biba->mb_rangehigh.mbe_type = typehigh; 434 mac_biba->mb_rangehigh.mbe_grade = gradehigh; 435 if (compartmentshigh != NULL) 436 memcpy(mac_biba->mb_rangehigh.mbe_compartments, 437 compartmentshigh, 438 sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 439 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 440} 441 442static void 443mac_biba_set_effective(struct mac_biba *mac_biba, u_short type, u_short grade, 444 u_char *compartments) 445{ 446 447 mac_biba->mb_effective.mbe_type = type; 448 mac_biba->mb_effective.mbe_grade = grade; 449 if (compartments != NULL) 450 memcpy(mac_biba->mb_effective.mbe_compartments, compartments, 451 sizeof(mac_biba->mb_effective.mbe_compartments)); 452 mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 453} 454 455static void 456mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 457{ 458 459 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 460 ("mac_biba_copy_range: labelfrom not range")); 461 462 labelto->mb_rangelow = labelfrom->mb_rangelow; 463 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 464 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 465} 466 467static void 468mac_biba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto) 469{ 470 471 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 472 ("mac_biba_copy_effective: labelfrom not effective")); 473 474 labelto->mb_effective = labelfrom->mb_effective; 475 labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 476} 477 478static void 479mac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 480{ 481 482 if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) 483 mac_biba_copy_effective(source, dest); 484 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 485 mac_biba_copy_range(source, dest); 486} 487 488/* 489 * Policy module operations. 490 */ 491static void 492mac_biba_init(struct mac_policy_conf *conf) 493{ 494 495 zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL, 496 NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 497} 498 499/* 500 * Label operations. 501 */ 502static void 503mac_biba_init_label(struct label *label) 504{ 505 506 SLOT_SET(label, biba_alloc(M_WAITOK)); 507} 508 509static int 510mac_biba_init_label_waitcheck(struct label *label, int flag) 511{ 512 513 SLOT_SET(label, biba_alloc(flag)); 514 if (SLOT(label) == NULL) 515 return (ENOMEM); 516 517 return (0); 518} 519 520static void 521mac_biba_destroy_label(struct label *label) 522{ 523 524 biba_free(SLOT(label)); 525 SLOT_SET(label, NULL); 526} 527 528/* 529 * mac_biba_element_to_string() accepts an sbuf and Biba element. It 530 * converts the Biba element to a string and stores the result in the 531 * sbuf; if there isn't space in the sbuf, -1 is returned. 532 */ 533static int 534mac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element) 535{ 536 int i, first; 537 538 switch (element->mbe_type) { 539 case MAC_BIBA_TYPE_HIGH: 540 return (sbuf_printf(sb, "high")); 541 542 case MAC_BIBA_TYPE_LOW: 543 return (sbuf_printf(sb, "low")); 544 545 case MAC_BIBA_TYPE_EQUAL: 546 return (sbuf_printf(sb, "equal")); 547 548 case MAC_BIBA_TYPE_GRADE: 549 if (sbuf_printf(sb, "%d", element->mbe_grade) == -1) 550 return (-1); 551 552 first = 1; 553 for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) { 554 if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) { 555 if (first) { 556 if (sbuf_putc(sb, ':') == -1) 557 return (-1); 558 if (sbuf_printf(sb, "%d", i) == -1) 559 return (-1); 560 first = 0; 561 } else { 562 if (sbuf_printf(sb, "+%d", i) == -1) 563 return (-1); 564 } 565 } 566 } 567 return (0); 568 569 default: 570 panic("mac_biba_element_to_string: invalid type (%d)", 571 element->mbe_type); 572 } 573} 574 575/* 576 * mac_biba_to_string() converts a Biba label to a string, and places 577 * the results in the passed sbuf. It returns 0 on success, or EINVAL 578 * if there isn't room in the sbuf. Note: the sbuf will be modified 579 * even in a failure case, so the caller may need to revert the sbuf 580 * by restoring the offset if that's undesired. 581 */ 582static int 583mac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba) 584{ 585 586 if (mac_biba->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 587 if (mac_biba_element_to_string(sb, &mac_biba->mb_effective) 588 == -1) 589 return (EINVAL); 590 } 591 592 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 593 if (sbuf_putc(sb, '(') == -1) 594 return (EINVAL); 595 596 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow) 597 == -1) 598 return (EINVAL); 599 600 if (sbuf_putc(sb, '-') == -1) 601 return (EINVAL); 602 603 if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh) 604 == -1) 605 return (EINVAL); 606 607 if (sbuf_putc(sb, ')') == -1) 608 return (EINVAL); 609 } 610 611 return (0); 612} 613 614static int 615mac_biba_externalize_label(struct label *label, char *element_name, 616 struct sbuf *sb, int *claimed) 617{ 618 struct mac_biba *mac_biba; 619 620 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 621 return (0); 622 623 (*claimed)++; 624 625 mac_biba = SLOT(label); 626 return (mac_biba_to_string(sb, mac_biba)); 627} 628 629static int 630mac_biba_parse_element(struct mac_biba_element *element, char *string) 631{ 632 char *compartment, *end, *grade; 633 int value; 634 635 if (strcmp(string, "high") == 0 || 636 strcmp(string, "hi") == 0) { 637 element->mbe_type = MAC_BIBA_TYPE_HIGH; 638 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 639 } else if (strcmp(string, "low") == 0 || 640 strcmp(string, "lo") == 0) { 641 element->mbe_type = MAC_BIBA_TYPE_LOW; 642 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 643 } else if (strcmp(string, "equal") == 0 || 644 strcmp(string, "eq") == 0) { 645 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 646 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 647 } else { 648 element->mbe_type = MAC_BIBA_TYPE_GRADE; 649 650 /* 651 * Numeric grade piece of the element. 652 */ 653 grade = strsep(&string, ":"); 654 value = strtol(grade, &end, 10); 655 if (end == grade || *end != '\0') 656 return (EINVAL); 657 if (value < 0 || value > 65535) 658 return (EINVAL); 659 element->mbe_grade = value; 660 661 /* 662 * Optional compartment piece of the element. If none 663 * are included, we assume that the label has no 664 * compartments. 665 */ 666 if (string == NULL) 667 return (0); 668 if (*string == '\0') 669 return (0); 670 671 while ((compartment = strsep(&string, "+")) != NULL) { 672 value = strtol(compartment, &end, 10); 673 if (compartment == end || *end != '\0') 674 return (EINVAL); 675 if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 676 return (EINVAL); 677 MAC_BIBA_BIT_SET(value, element->mbe_compartments); 678 } 679 } 680 681 return (0); 682} 683 684/* 685 * Note: destructively consumes the string, make a local copy before 686 * calling if that's a problem. 687 */ 688static int 689mac_biba_parse(struct mac_biba *mac_biba, char *string) 690{ 691 char *rangehigh, *rangelow, *effective; 692 int error; 693 694 effective = strsep(&string, "("); 695 if (*effective == '\0') 696 effective = NULL; 697 698 if (string != NULL) { 699 rangelow = strsep(&string, "-"); 700 if (string == NULL) 701 return (EINVAL); 702 rangehigh = strsep(&string, ")"); 703 if (string == NULL) 704 return (EINVAL); 705 if (*string != '\0') 706 return (EINVAL); 707 } else { 708 rangelow = NULL; 709 rangehigh = NULL; 710 } 711 712 KASSERT((rangelow != NULL && rangehigh != NULL) || 713 (rangelow == NULL && rangehigh == NULL), 714 ("mac_biba_parse: range mismatch")); 715 716 bzero(mac_biba, sizeof(*mac_biba)); 717 if (effective != NULL) { 718 error = mac_biba_parse_element(&mac_biba->mb_effective, effective); 719 if (error) 720 return (error); 721 mac_biba->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 722 } 723 724 if (rangelow != NULL) { 725 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 726 rangelow); 727 if (error) 728 return (error); 729 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 730 rangehigh); 731 if (error) 732 return (error); 733 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 734 } 735 736 error = mac_biba_valid(mac_biba); 737 if (error) 738 return (error); 739 740 return (0); 741} 742 743static int 744mac_biba_internalize_label(struct label *label, char *element_name, 745 char *element_data, int *claimed) 746{ 747 struct mac_biba *mac_biba, mac_biba_temp; 748 int error; 749 750 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 751 return (0); 752 753 (*claimed)++; 754 755 error = mac_biba_parse(&mac_biba_temp, element_data); 756 if (error) 757 return (error); 758 759 mac_biba = SLOT(label); 760 *mac_biba = mac_biba_temp; 761 762 return (0); 763} 764 765static void 766mac_biba_copy_label(struct label *src, struct label *dest) 767{ 768 769 *SLOT(dest) = *SLOT(src); 770} 771 772/* 773 * Labeling event operations: file system objects, and things that look 774 * a lot like file system objects. 775 */ 776static void 777mac_biba_create_devfs_device(struct mount *mp, struct cdev *dev, 778 struct devfs_dirent *devfs_dirent, struct label *label) 779{ 780 struct mac_biba *mac_biba; 781 int biba_type; 782 783 mac_biba = SLOT(label); 784 if (strcmp(dev->si_name, "null") == 0 || 785 strcmp(dev->si_name, "zero") == 0 || 786 strcmp(dev->si_name, "random") == 0 || 787 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 788 biba_type = MAC_BIBA_TYPE_EQUAL; 789 else if (ptys_equal && 790 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 791 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 792 biba_type = MAC_BIBA_TYPE_EQUAL; 793 else 794 biba_type = MAC_BIBA_TYPE_HIGH; 795 mac_biba_set_effective(mac_biba, biba_type, 0, NULL); 796} 797 798static void 799mac_biba_create_devfs_directory(struct mount *mp, char *dirname, 800 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 801{ 802 struct mac_biba *mac_biba; 803 804 mac_biba = SLOT(label); 805 mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 806} 807 808static void 809mac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp, 810 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 811 struct label *delabel) 812{ 813 struct mac_biba *source, *dest; 814 815 source = SLOT(cred->cr_label); 816 dest = SLOT(delabel); 817 818 mac_biba_copy_effective(source, dest); 819} 820 821static void 822mac_biba_create_mount(struct ucred *cred, struct mount *mp, 823 struct label *mntlabel, struct label *fslabel) 824{ 825 struct mac_biba *source, *dest; 826 827 source = SLOT(cred->cr_label); 828 dest = SLOT(mntlabel); 829 mac_biba_copy_effective(source, dest); 830 dest = SLOT(fslabel); 831 mac_biba_copy_effective(source, dest); 832} 833 834static void 835mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 836 struct label *mntlabel, struct label *fslabel) 837{ 838 struct mac_biba *mac_biba; 839 840 /* Always mount root as high integrity. */ 841 mac_biba = SLOT(fslabel); 842 mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 843 mac_biba = SLOT(mntlabel); 844 mac_biba_set_effective(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 845} 846 847static void 848mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 849 struct label *vnodelabel, struct label *label) 850{ 851 struct mac_biba *source, *dest; 852 853 source = SLOT(label); 854 dest = SLOT(vnodelabel); 855 856 mac_biba_copy(source, dest); 857} 858 859static void 860mac_biba_update_devfsdirent(struct mount *mp, 861 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 862 struct vnode *vp, struct label *vnodelabel) 863{ 864 struct mac_biba *source, *dest; 865 866 source = SLOT(vnodelabel); 867 dest = SLOT(direntlabel); 868 869 mac_biba_copy(source, dest); 870} 871 872static void 873mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 874 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 875 struct label *vlabel) 876{ 877 struct mac_biba *source, *dest; 878 879 source = SLOT(delabel); 880 dest = SLOT(vlabel); 881 882 mac_biba_copy_effective(source, dest); 883} 884 885static int 886mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 887 struct vnode *vp, struct label *vlabel) 888{ 889 struct mac_biba temp, *source, *dest; 890 int buflen, error; 891 892 source = SLOT(fslabel); 893 dest = SLOT(vlabel); 894 895 buflen = sizeof(temp); 896 bzero(&temp, buflen); 897 898 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 899 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 900 if (error == ENOATTR || error == EOPNOTSUPP) { 901 /* Fall back to the fslabel. */ 902 mac_biba_copy_effective(source, dest); 903 return (0); 904 } else if (error) 905 return (error); 906 907 if (buflen != sizeof(temp)) { 908 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 909 buflen); 910 return (EPERM); 911 } 912 if (mac_biba_valid(&temp) != 0) { 913 printf("mac_biba_associate_vnode_extattr: invalid\n"); 914 return (EPERM); 915 } 916 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_EFFECTIVE) { 917 printf("mac_biba_associate_vnode_extattr: not effective\n"); 918 return (EPERM); 919 } 920 921 mac_biba_copy_effective(&temp, dest); 922 return (0); 923} 924 925static void 926mac_biba_associate_vnode_singlelabel(struct mount *mp, 927 struct label *fslabel, struct vnode *vp, struct label *vlabel) 928{ 929 struct mac_biba *source, *dest; 930 931 source = SLOT(fslabel); 932 dest = SLOT(vlabel); 933 934 mac_biba_copy_effective(source, dest); 935} 936 937static int 938mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 939 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 940 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 941{ 942 struct mac_biba *source, *dest, temp; 943 size_t buflen; 944 int error; 945 946 buflen = sizeof(temp); 947 bzero(&temp, buflen); 948 949 source = SLOT(cred->cr_label); 950 dest = SLOT(vlabel); 951 mac_biba_copy_effective(source, &temp); 952 953 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 954 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 955 if (error == 0) 956 mac_biba_copy_effective(source, dest); 957 return (error); 958} 959 960static int 961mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 962 struct label *vlabel, struct label *intlabel) 963{ 964 struct mac_biba *source, temp; 965 size_t buflen; 966 int error; 967 968 buflen = sizeof(temp); 969 bzero(&temp, buflen); 970 971 source = SLOT(intlabel); 972 if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0) 973 return (0); 974 975 mac_biba_copy_effective(source, &temp); 976 977 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 978 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 979 return (error); 980} 981 982/* 983 * Labeling event operations: IPC object. 984 */ 985static void 986mac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel, 987 struct inpcb *inp, struct label *inplabel) 988{ 989 struct mac_biba *source, *dest; 990 991 source = SLOT(solabel); 992 dest = SLOT(inplabel); 993 994 mac_biba_copy_effective(source, dest); 995} 996 997static void 998mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 999 struct mbuf *m, struct label *mbuflabel) 1000{ 1001 struct mac_biba *source, *dest; 1002 1003 source = SLOT(socketlabel); 1004 dest = SLOT(mbuflabel); 1005 1006 mac_biba_copy_effective(source, dest); 1007} 1008 1009static void 1010mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1011 struct label *socketlabel) 1012{ 1013 struct mac_biba *source, *dest; 1014 1015 source = SLOT(cred->cr_label); 1016 dest = SLOT(socketlabel); 1017 1018 mac_biba_copy_effective(source, dest); 1019} 1020 1021static void 1022mac_biba_create_pipe(struct ucred *cred, struct pipepair *pp, 1023 struct label *pipelabel) 1024{ 1025 struct mac_biba *source, *dest; 1026 1027 source = SLOT(cred->cr_label); 1028 dest = SLOT(pipelabel); 1029 1030 mac_biba_copy_effective(source, dest); 1031} 1032 1033static void 1034mac_biba_create_socket_from_socket(struct socket *oldsocket, 1035 struct label *oldsocketlabel, struct socket *newsocket, 1036 struct label *newsocketlabel) 1037{ 1038 struct mac_biba *source, *dest; 1039 1040 source = SLOT(oldsocketlabel); 1041 dest = SLOT(newsocketlabel); 1042 1043 mac_biba_copy_effective(source, dest); 1044} 1045 1046static void 1047mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1048 struct label *socketlabel, struct label *newlabel) 1049{ 1050 struct mac_biba *source, *dest; 1051 1052 source = SLOT(newlabel); 1053 dest = SLOT(socketlabel); 1054 1055 mac_biba_copy(source, dest); 1056} 1057 1058static void 1059mac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1060 struct label *pipelabel, struct label *newlabel) 1061{ 1062 struct mac_biba *source, *dest; 1063 1064 source = SLOT(newlabel); 1065 dest = SLOT(pipelabel); 1066 1067 mac_biba_copy(source, dest); 1068} 1069 1070static void 1071mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1072 struct socket *socket, struct label *socketpeerlabel) 1073{ 1074 struct mac_biba *source, *dest; 1075 1076 source = SLOT(mbuflabel); 1077 dest = SLOT(socketpeerlabel); 1078 1079 mac_biba_copy_effective(source, dest); 1080} 1081 1082/* 1083 * Labeling event operations: network objects. 1084 */ 1085static void 1086mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1087 struct label *oldsocketlabel, struct socket *newsocket, 1088 struct label *newsocketpeerlabel) 1089{ 1090 struct mac_biba *source, *dest; 1091 1092 source = SLOT(oldsocketlabel); 1093 dest = SLOT(newsocketpeerlabel); 1094 1095 mac_biba_copy_effective(source, dest); 1096} 1097 1098static void 1099mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1100 struct label *bpflabel) 1101{ 1102 struct mac_biba *source, *dest; 1103 1104 source = SLOT(cred->cr_label); 1105 dest = SLOT(bpflabel); 1106 1107 mac_biba_copy_effective(source, dest); 1108} 1109 1110static void 1111mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1112{ 1113 char tifname[IFNAMSIZ], *p, *q; 1114 char tiflist[sizeof(trusted_interfaces)]; 1115 struct mac_biba *dest; 1116 int len, type; 1117 1118 dest = SLOT(ifnetlabel); 1119 1120 if (ifnet->if_type == IFT_LOOP) { 1121 type = MAC_BIBA_TYPE_EQUAL; 1122 goto set; 1123 } 1124 1125 if (trust_all_interfaces) { 1126 type = MAC_BIBA_TYPE_HIGH; 1127 goto set; 1128 } 1129 1130 type = MAC_BIBA_TYPE_LOW; 1131 1132 if (trusted_interfaces[0] == '\0' || 1133 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1134 goto set; 1135 1136 bzero(tiflist, sizeof(tiflist)); 1137 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1138 if(*p != ' ' && *p != '\t') 1139 *q = *p; 1140 1141 for (p = q = tiflist;; p++) { 1142 if (*p == ',' || *p == '\0') { 1143 len = p - q; 1144 if (len < IFNAMSIZ) { 1145 bzero(tifname, sizeof(tifname)); 1146 bcopy(q, tifname, len); 1147 if (strcmp(tifname, ifnet->if_xname) == 0) { 1148 type = MAC_BIBA_TYPE_HIGH; 1149 break; 1150 } 1151 } else { 1152 *p = '\0'; 1153 printf("mac_biba warning: interface name " 1154 "\"%s\" is too long (must be < %d)\n", 1155 q, IFNAMSIZ); 1156 } 1157 if (*p == '\0') 1158 break; 1159 q = p + 1; 1160 } 1161 } 1162set: 1163 mac_biba_set_effective(dest, type, 0, NULL); 1164 mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1165} 1166 1167static void 1168mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1169 struct ipq *ipq, struct label *ipqlabel) 1170{ 1171 struct mac_biba *source, *dest; 1172 1173 source = SLOT(fragmentlabel); 1174 dest = SLOT(ipqlabel); 1175 1176 mac_biba_copy_effective(source, dest); 1177} 1178 1179static void 1180mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1181 struct mbuf *datagram, struct label *datagramlabel) 1182{ 1183 struct mac_biba *source, *dest; 1184 1185 source = SLOT(ipqlabel); 1186 dest = SLOT(datagramlabel); 1187 1188 /* Just use the head, since we require them all to match. */ 1189 mac_biba_copy_effective(source, dest); 1190} 1191 1192static void 1193mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1194 struct mbuf *fragment, struct label *fragmentlabel) 1195{ 1196 struct mac_biba *source, *dest; 1197 1198 source = SLOT(datagramlabel); 1199 dest = SLOT(fragmentlabel); 1200 1201 mac_biba_copy_effective(source, dest); 1202} 1203 1204static void 1205mac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1206 struct mbuf *m, struct label *mlabel) 1207{ 1208 struct mac_biba *source, *dest; 1209 1210 source = SLOT(inplabel); 1211 dest = SLOT(mlabel); 1212 1213 mac_biba_copy_effective(source, dest); 1214} 1215 1216static void 1217mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1218 struct label *oldmbuflabel, struct mbuf *newmbuf, 1219 struct label *newmbuflabel) 1220{ 1221 struct mac_biba *source, *dest; 1222 1223 source = SLOT(oldmbuflabel); 1224 dest = SLOT(newmbuflabel); 1225 1226 /* 1227 * Because the source mbuf may not yet have been "created", 1228 * just initialized, we do a conditional copy. Since we don't 1229 * allow mbufs to have ranges, do a KASSERT to make sure that 1230 * doesn't happen. 1231 */ 1232 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1233 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1234 mac_biba_copy(source, dest); 1235} 1236 1237static void 1238mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1239 struct mbuf *mbuf, struct label *mbuflabel) 1240{ 1241 struct mac_biba *dest; 1242 1243 dest = SLOT(mbuflabel); 1244 1245 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1246} 1247 1248static void 1249mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1250 struct mbuf *mbuf, struct label *mbuflabel) 1251{ 1252 struct mac_biba *source, *dest; 1253 1254 source = SLOT(bpflabel); 1255 dest = SLOT(mbuflabel); 1256 1257 mac_biba_copy_effective(source, dest); 1258} 1259 1260static void 1261mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1262 struct mbuf *m, struct label *mbuflabel) 1263{ 1264 struct mac_biba *source, *dest; 1265 1266 source = SLOT(ifnetlabel); 1267 dest = SLOT(mbuflabel); 1268 1269 mac_biba_copy_effective(source, dest); 1270} 1271 1272static void 1273mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1274 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1275 struct mbuf *newmbuf, struct label *newmbuflabel) 1276{ 1277 struct mac_biba *source, *dest; 1278 1279 source = SLOT(oldmbuflabel); 1280 dest = SLOT(newmbuflabel); 1281 1282 mac_biba_copy_effective(source, dest); 1283} 1284 1285static void 1286mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1287 struct mbuf *newmbuf, struct label *newmbuflabel) 1288{ 1289 struct mac_biba *source, *dest; 1290 1291 source = SLOT(oldmbuflabel); 1292 dest = SLOT(newmbuflabel); 1293 1294 mac_biba_copy_effective(source, dest); 1295} 1296 1297static int 1298mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1299 struct ipq *ipq, struct label *ipqlabel) 1300{ 1301 struct mac_biba *a, *b; 1302 1303 a = SLOT(ipqlabel); 1304 b = SLOT(fragmentlabel); 1305 1306 return (mac_biba_equal_effective(a, b)); 1307} 1308 1309static void 1310mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1311 struct label *ifnetlabel, struct label *newlabel) 1312{ 1313 struct mac_biba *source, *dest; 1314 1315 source = SLOT(newlabel); 1316 dest = SLOT(ifnetlabel); 1317 1318 mac_biba_copy(source, dest); 1319} 1320 1321static void 1322mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1323 struct ipq *ipq, struct label *ipqlabel) 1324{ 1325 1326 /* NOOP: we only accept matching labels, so no need to update */ 1327} 1328 1329static void 1330mac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1331 struct inpcb *inp, struct label *inplabel) 1332{ 1333 struct mac_biba *source, *dest; 1334 1335 source = SLOT(solabel); 1336 dest = SLOT(inplabel); 1337 1338 mac_biba_copy(source, dest); 1339} 1340 1341/* 1342 * Labeling event operations: processes. 1343 */ 1344static void 1345mac_biba_create_proc0(struct ucred *cred) 1346{ 1347 struct mac_biba *dest; 1348 1349 dest = SLOT(cred->cr_label); 1350 1351 mac_biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1352 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1353 MAC_BIBA_TYPE_HIGH, 0, NULL); 1354} 1355 1356static void 1357mac_biba_create_proc1(struct ucred *cred) 1358{ 1359 struct mac_biba *dest; 1360 1361 dest = SLOT(cred->cr_label); 1362 1363 mac_biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1364 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1365 MAC_BIBA_TYPE_HIGH, 0, NULL); 1366} 1367 1368static void 1369mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1370{ 1371 struct mac_biba *source, *dest; 1372 1373 source = SLOT(newlabel); 1374 dest = SLOT(cred->cr_label); 1375 1376 mac_biba_copy(source, dest); 1377} 1378 1379/* 1380 * Access control checks. 1381 */ 1382static int 1383mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1384 struct ifnet *ifnet, struct label *ifnetlabel) 1385{ 1386 struct mac_biba *a, *b; 1387 1388 if (!mac_biba_enabled) 1389 return (0); 1390 1391 a = SLOT(bpflabel); 1392 b = SLOT(ifnetlabel); 1393 1394 if (mac_biba_equal_effective(a, b)) 1395 return (0); 1396 return (EACCES); 1397} 1398 1399static int 1400mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1401{ 1402 struct mac_biba *subj, *new; 1403 int error; 1404 1405 subj = SLOT(cred->cr_label); 1406 new = SLOT(newlabel); 1407 1408 /* 1409 * If there is a Biba label update for the credential, it may 1410 * be an update of the effective, range, or both. 1411 */ 1412 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1413 if (error) 1414 return (error); 1415 1416 /* 1417 * If the Biba label is to be changed, authorize as appropriate. 1418 */ 1419 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1420 /* 1421 * If the change request modifies both the Biba label 1422 * effective and range, check that the new effective will be 1423 * in the new range. 1424 */ 1425 if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1426 MAC_BIBA_FLAGS_BOTH && 1427 !mac_biba_effective_in_range(new, new)) 1428 return (EINVAL); 1429 1430 /* 1431 * To change the Biba effective label on a credential, the 1432 * new effective label must be in the current range. 1433 */ 1434 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE && 1435 !mac_biba_effective_in_range(new, subj)) 1436 return (EPERM); 1437 1438 /* 1439 * To change the Biba range on a credential, the new 1440 * range label must be in the current range. 1441 */ 1442 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1443 !mac_biba_range_in_range(new, subj)) 1444 return (EPERM); 1445 1446 /* 1447 * To have EQUAL in any component of the new credential 1448 * Biba label, the subject must already have EQUAL in 1449 * their label. 1450 */ 1451 if (mac_biba_contains_equal(new)) { 1452 error = mac_biba_subject_privileged(subj); 1453 if (error) 1454 return (error); 1455 } 1456 } 1457 1458 return (0); 1459} 1460 1461static int 1462mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1463{ 1464 struct mac_biba *subj, *obj; 1465 1466 if (!mac_biba_enabled) 1467 return (0); 1468 1469 subj = SLOT(u1->cr_label); 1470 obj = SLOT(u2->cr_label); 1471 1472 /* XXX: range */ 1473 if (!mac_biba_dominate_effective(obj, subj)) 1474 return (ESRCH); 1475 1476 return (0); 1477} 1478 1479static int 1480mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1481 struct label *ifnetlabel, struct label *newlabel) 1482{ 1483 struct mac_biba *subj, *new; 1484 int error; 1485 1486 subj = SLOT(cred->cr_label); 1487 new = SLOT(newlabel); 1488 1489 /* 1490 * If there is a Biba label update for the interface, it may 1491 * be an update of the effective, range, or both. 1492 */ 1493 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1494 if (error) 1495 return (error); 1496 1497 /* 1498 * Relabling network interfaces requires Biba privilege. 1499 */ 1500 error = mac_biba_subject_privileged(subj); 1501 if (error) 1502 return (error); 1503 1504 return (0); 1505} 1506 1507static int 1508mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1509 struct mbuf *m, struct label *mbuflabel) 1510{ 1511 struct mac_biba *p, *i; 1512 1513 if (!mac_biba_enabled) 1514 return (0); 1515 1516 p = SLOT(mbuflabel); 1517 i = SLOT(ifnetlabel); 1518 1519 return (mac_biba_effective_in_range(p, i) ? 0 : EACCES); 1520} 1521 1522static int 1523mac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1524 struct mbuf *m, struct label *mlabel) 1525{ 1526 struct mac_biba *p, *i; 1527 1528 if (!mac_biba_enabled) 1529 return (0); 1530 1531 p = SLOT(mlabel); 1532 i = SLOT(inplabel); 1533 1534 return (mac_biba_equal_effective(p, i) ? 0 : EACCES); 1535} 1536 1537static int 1538mac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1539 struct label *label) 1540{ 1541 struct mac_biba *subj, *obj; 1542 int error; 1543 1544 if (!mac_biba_enabled) 1545 return (0); 1546 1547 subj = SLOT(cred->cr_label); 1548 1549 error = mac_biba_subject_privileged(subj); 1550 if (error) 1551 return (error); 1552 1553 obj = SLOT(label); 1554 if (!mac_biba_high_effective(obj)) 1555 return (EACCES); 1556 1557 return (0); 1558} 1559 1560 1561static int 1562mac_biba_check_kld_unload(struct ucred *cred) 1563{ 1564 struct mac_biba *subj; 1565 1566 if (!mac_biba_enabled) 1567 return (0); 1568 1569 subj = SLOT(cred->cr_label); 1570 1571 return (mac_biba_subject_privileged(subj)); 1572} 1573 1574static int 1575mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1576 struct label *mntlabel) 1577{ 1578 struct mac_biba *subj, *obj; 1579 1580 if (!mac_biba_enabled) 1581 return (0); 1582 1583 subj = SLOT(cred->cr_label); 1584 obj = SLOT(mntlabel); 1585 1586 if (!mac_biba_dominate_effective(obj, subj)) 1587 return (EACCES); 1588 1589 return (0); 1590} 1591 1592static int 1593mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1594 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1595{ 1596 1597 if(!mac_biba_enabled) 1598 return (0); 1599 1600 /* XXX: This will be implemented soon... */ 1601 1602 return (0); 1603} 1604 1605static int 1606mac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp, 1607 struct label *pipelabel) 1608{ 1609 struct mac_biba *subj, *obj; 1610 1611 if (!mac_biba_enabled) 1612 return (0); 1613 1614 subj = SLOT(cred->cr_label); 1615 obj = SLOT((pipelabel)); 1616 1617 if (!mac_biba_dominate_effective(obj, subj)) 1618 return (EACCES); 1619 1620 return (0); 1621} 1622 1623static int 1624mac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1625 struct label *pipelabel) 1626{ 1627 struct mac_biba *subj, *obj; 1628 1629 if (!mac_biba_enabled) 1630 return (0); 1631 1632 subj = SLOT(cred->cr_label); 1633 obj = SLOT((pipelabel)); 1634 1635 if (!mac_biba_dominate_effective(obj, subj)) 1636 return (EACCES); 1637 1638 return (0); 1639} 1640 1641static int 1642mac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1643 struct label *pipelabel, struct label *newlabel) 1644{ 1645 struct mac_biba *subj, *obj, *new; 1646 int error; 1647 1648 new = SLOT(newlabel); 1649 subj = SLOT(cred->cr_label); 1650 obj = SLOT(pipelabel); 1651 1652 /* 1653 * If there is a Biba label update for a pipe, it must be a 1654 * effective update. 1655 */ 1656 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 1657 if (error) 1658 return (error); 1659 1660 /* 1661 * To perform a relabel of a pipe (Biba label or not), Biba must 1662 * authorize the relabel. 1663 */ 1664 if (!mac_biba_effective_in_range(obj, subj)) 1665 return (EPERM); 1666 1667 /* 1668 * If the Biba label is to be changed, authorize as appropriate. 1669 */ 1670 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 1671 /* 1672 * To change the Biba label on a pipe, the new pipe label 1673 * must be in the subject range. 1674 */ 1675 if (!mac_biba_effective_in_range(new, subj)) 1676 return (EPERM); 1677 1678 /* 1679 * To change the Biba label on a pipe to be EQUAL, the 1680 * subject must have appropriate privilege. 1681 */ 1682 if (mac_biba_contains_equal(new)) { 1683 error = mac_biba_subject_privileged(subj); 1684 if (error) 1685 return (error); 1686 } 1687 } 1688 1689 return (0); 1690} 1691 1692static int 1693mac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp, 1694 struct label *pipelabel) 1695{ 1696 struct mac_biba *subj, *obj; 1697 1698 if (!mac_biba_enabled) 1699 return (0); 1700 1701 subj = SLOT(cred->cr_label); 1702 obj = SLOT((pipelabel)); 1703 1704 if (!mac_biba_dominate_effective(obj, subj)) 1705 return (EACCES); 1706 1707 return (0); 1708} 1709 1710static int 1711mac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp, 1712 struct label *pipelabel) 1713{ 1714 struct mac_biba *subj, *obj; 1715 1716 if (!mac_biba_enabled) 1717 return (0); 1718 1719 subj = SLOT(cred->cr_label); 1720 obj = SLOT((pipelabel)); 1721 1722 if (!mac_biba_dominate_effective(subj, obj)) 1723 return (EACCES); 1724 1725 return (0); 1726} 1727 1728static int 1729mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1730{ 1731 struct mac_biba *subj, *obj; 1732 1733 if (!mac_biba_enabled) 1734 return (0); 1735 1736 subj = SLOT(cred->cr_label); 1737 obj = SLOT(proc->p_ucred->cr_label); 1738 1739 /* XXX: range checks */ 1740 if (!mac_biba_dominate_effective(obj, subj)) 1741 return (ESRCH); 1742 if (!mac_biba_dominate_effective(subj, obj)) 1743 return (EACCES); 1744 1745 return (0); 1746} 1747 1748static int 1749mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1750{ 1751 struct mac_biba *subj, *obj; 1752 1753 if (!mac_biba_enabled) 1754 return (0); 1755 1756 subj = SLOT(cred->cr_label); 1757 obj = SLOT(proc->p_ucred->cr_label); 1758 1759 /* XXX: range checks */ 1760 if (!mac_biba_dominate_effective(obj, subj)) 1761 return (ESRCH); 1762 if (!mac_biba_dominate_effective(subj, obj)) 1763 return (EACCES); 1764 1765 return (0); 1766} 1767 1768static int 1769mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1770{ 1771 struct mac_biba *subj, *obj; 1772 1773 if (!mac_biba_enabled) 1774 return (0); 1775 1776 subj = SLOT(cred->cr_label); 1777 obj = SLOT(proc->p_ucred->cr_label); 1778 1779 /* XXX: range checks */ 1780 if (!mac_biba_dominate_effective(obj, subj)) 1781 return (ESRCH); 1782 if (!mac_biba_dominate_effective(subj, obj)) 1783 return (EACCES); 1784 1785 return (0); 1786} 1787 1788static int 1789mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1790 struct mbuf *m, struct label *mbuflabel) 1791{ 1792 struct mac_biba *p, *s; 1793 1794 if (!mac_biba_enabled) 1795 return (0); 1796 1797 p = SLOT(mbuflabel); 1798 s = SLOT(socketlabel); 1799 1800 return (mac_biba_equal_effective(p, s) ? 0 : EACCES); 1801} 1802 1803static int 1804mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1805 struct label *socketlabel, struct label *newlabel) 1806{ 1807 struct mac_biba *subj, *obj, *new; 1808 int error; 1809 1810 new = SLOT(newlabel); 1811 subj = SLOT(cred->cr_label); 1812 obj = SLOT(socketlabel); 1813 1814 /* 1815 * If there is a Biba label update for the socket, it may be 1816 * an update of effective. 1817 */ 1818 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 1819 if (error) 1820 return (error); 1821 1822 /* 1823 * To relabel a socket, the old socket effective must be in the subject 1824 * range. 1825 */ 1826 if (!mac_biba_effective_in_range(obj, subj)) 1827 return (EPERM); 1828 1829 /* 1830 * If the Biba label is to be changed, authorize as appropriate. 1831 */ 1832 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 1833 /* 1834 * To relabel a socket, the new socket effective must be in 1835 * the subject range. 1836 */ 1837 if (!mac_biba_effective_in_range(new, subj)) 1838 return (EPERM); 1839 1840 /* 1841 * To change the Biba label on the socket to contain EQUAL, 1842 * the subject must have appropriate privilege. 1843 */ 1844 if (mac_biba_contains_equal(new)) { 1845 error = mac_biba_subject_privileged(subj); 1846 if (error) 1847 return (error); 1848 } 1849 } 1850 1851 return (0); 1852} 1853 1854static int 1855mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1856 struct label *socketlabel) 1857{ 1858 struct mac_biba *subj, *obj; 1859 1860 if (!mac_biba_enabled) 1861 return (0); 1862 1863 subj = SLOT(cred->cr_label); 1864 obj = SLOT(socketlabel); 1865 1866 if (!mac_biba_dominate_effective(obj, subj)) 1867 return (ENOENT); 1868 1869 return (0); 1870} 1871 1872static int 1873mac_biba_check_sysarch_ioperm(struct ucred *cred) 1874{ 1875 struct mac_biba *subj; 1876 int error; 1877 1878 if (!mac_biba_enabled) 1879 return (0); 1880 1881 subj = SLOT(cred->cr_label); 1882 1883 error = mac_biba_subject_privileged(subj); 1884 if (error) 1885 return (error); 1886 1887 return (0); 1888} 1889 1890static int 1891mac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1892 struct label *label) 1893{ 1894 struct mac_biba *subj, *obj; 1895 int error; 1896 1897 if (!mac_biba_enabled) 1898 return (0); 1899 1900 subj = SLOT(cred->cr_label); 1901 1902 error = mac_biba_subject_privileged(subj); 1903 if (error) 1904 return (error); 1905 1906 if (label == NULL) 1907 return (0); 1908 1909 obj = SLOT(label); 1910 if (!mac_biba_high_effective(obj)) 1911 return (EACCES); 1912 1913 return (0); 1914} 1915 1916static int 1917mac_biba_check_system_settime(struct ucred *cred) 1918{ 1919 struct mac_biba *subj; 1920 int error; 1921 1922 if (!mac_biba_enabled) 1923 return (0); 1924 1925 subj = SLOT(cred->cr_label); 1926 1927 error = mac_biba_subject_privileged(subj); 1928 if (error) 1929 return (error); 1930 1931 return (0); 1932} 1933 1934static int 1935mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1936 struct label *label) 1937{ 1938 struct mac_biba *subj, *obj; 1939 int error; 1940 1941 if (!mac_biba_enabled) 1942 return (0); 1943 1944 subj = SLOT(cred->cr_label); 1945 obj = SLOT(label); 1946 1947 error = mac_biba_subject_privileged(subj); 1948 if (error) 1949 return (error); 1950 1951 if (!mac_biba_high_effective(obj)) 1952 return (EACCES); 1953 1954 return (0); 1955} 1956 1957static int 1958mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 1959 struct label *label) 1960{ 1961 struct mac_biba *subj, *obj; 1962 int error; 1963 1964 if (!mac_biba_enabled) 1965 return (0); 1966 1967 subj = SLOT(cred->cr_label); 1968 obj = SLOT(label); 1969 1970 error = mac_biba_subject_privileged(subj); 1971 if (error) 1972 return (error); 1973 1974 return (0); 1975} 1976 1977static int 1978mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 1979 void *arg1, int arg2, struct sysctl_req *req) 1980{ 1981 struct mac_biba *subj; 1982 int error; 1983 1984 if (!mac_biba_enabled) 1985 return (0); 1986 1987 subj = SLOT(cred->cr_label); 1988 1989 /* 1990 * Treat sysctl variables without CTLFLAG_ANYBODY flag as 1991 * biba/high, but also require privilege to change them. 1992 */ 1993 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 1994 if (!mac_biba_subject_dominate_high(subj)) 1995 return (EACCES); 1996 1997 error = mac_biba_subject_privileged(subj); 1998 if (error) 1999 return (error); 2000 } 2001 2002 return (0); 2003} 2004 2005static int 2006mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2007 struct label *dlabel) 2008{ 2009 struct mac_biba *subj, *obj; 2010 2011 if (!mac_biba_enabled) 2012 return (0); 2013 2014 subj = SLOT(cred->cr_label); 2015 obj = SLOT(dlabel); 2016 2017 if (!mac_biba_dominate_effective(obj, subj)) 2018 return (EACCES); 2019 2020 return (0); 2021} 2022 2023static int 2024mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2025 struct label *dlabel) 2026{ 2027 struct mac_biba *subj, *obj; 2028 2029 if (!mac_biba_enabled) 2030 return (0); 2031 2032 subj = SLOT(cred->cr_label); 2033 obj = SLOT(dlabel); 2034 2035 if (!mac_biba_dominate_effective(obj, subj)) 2036 return (EACCES); 2037 2038 return (0); 2039} 2040 2041static int 2042mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2043 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2044{ 2045 struct mac_biba *subj, *obj; 2046 2047 if (!mac_biba_enabled) 2048 return (0); 2049 2050 subj = SLOT(cred->cr_label); 2051 obj = SLOT(dlabel); 2052 2053 if (!mac_biba_dominate_effective(subj, obj)) 2054 return (EACCES); 2055 2056 return (0); 2057} 2058 2059static int 2060mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2061 struct label *dlabel, struct vnode *vp, struct label *label, 2062 struct componentname *cnp) 2063{ 2064 struct mac_biba *subj, *obj; 2065 2066 if (!mac_biba_enabled) 2067 return (0); 2068 2069 subj = SLOT(cred->cr_label); 2070 obj = SLOT(dlabel); 2071 2072 if (!mac_biba_dominate_effective(subj, obj)) 2073 return (EACCES); 2074 2075 obj = SLOT(label); 2076 2077 if (!mac_biba_dominate_effective(subj, obj)) 2078 return (EACCES); 2079 2080 return (0); 2081} 2082 2083static int 2084mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2085 struct label *label, acl_type_t type) 2086{ 2087 struct mac_biba *subj, *obj; 2088 2089 if (!mac_biba_enabled) 2090 return (0); 2091 2092 subj = SLOT(cred->cr_label); 2093 obj = SLOT(label); 2094 2095 if (!mac_biba_dominate_effective(subj, obj)) 2096 return (EACCES); 2097 2098 return (0); 2099} 2100 2101static int 2102mac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2103 struct label *label, int attrnamespace, const char *name) 2104{ 2105 struct mac_biba *subj, *obj; 2106 2107 if (!mac_biba_enabled) 2108 return (0); 2109 2110 subj = SLOT(cred->cr_label); 2111 obj = SLOT(label); 2112 2113 if (!mac_biba_dominate_effective(subj, obj)) 2114 return (EACCES); 2115 2116 return (0); 2117} 2118 2119static int 2120mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2121 struct label *label, struct image_params *imgp, 2122 struct label *execlabel) 2123{ 2124 struct mac_biba *subj, *obj, *exec; 2125 int error; 2126 2127 if (execlabel != NULL) { 2128 /* 2129 * We currently don't permit labels to be changed at 2130 * exec-time as part of Biba, so disallow non-NULL 2131 * Biba label elements in the execlabel. 2132 */ 2133 exec = SLOT(execlabel); 2134 error = biba_atmostflags(exec, 0); 2135 if (error) 2136 return (error); 2137 } 2138 2139 if (!mac_biba_enabled) 2140 return (0); 2141 2142 subj = SLOT(cred->cr_label); 2143 obj = SLOT(label); 2144 2145 if (!mac_biba_dominate_effective(obj, subj)) 2146 return (EACCES); 2147 2148 return (0); 2149} 2150 2151static int 2152mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2153 struct label *label, acl_type_t type) 2154{ 2155 struct mac_biba *subj, *obj; 2156 2157 if (!mac_biba_enabled) 2158 return (0); 2159 2160 subj = SLOT(cred->cr_label); 2161 obj = SLOT(label); 2162 2163 if (!mac_biba_dominate_effective(obj, subj)) 2164 return (EACCES); 2165 2166 return (0); 2167} 2168 2169static int 2170mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2171 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2172{ 2173 struct mac_biba *subj, *obj; 2174 2175 if (!mac_biba_enabled) 2176 return (0); 2177 2178 subj = SLOT(cred->cr_label); 2179 obj = SLOT(label); 2180 2181 if (!mac_biba_dominate_effective(obj, subj)) 2182 return (EACCES); 2183 2184 return (0); 2185} 2186 2187static int 2188mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2189 struct label *dlabel, struct vnode *vp, struct label *label, 2190 struct componentname *cnp) 2191{ 2192 struct mac_biba *subj, *obj; 2193 2194 if (!mac_biba_enabled) 2195 return (0); 2196 2197 subj = SLOT(cred->cr_label); 2198 obj = SLOT(dlabel); 2199 2200 if (!mac_biba_dominate_effective(subj, obj)) 2201 return (EACCES); 2202 2203 obj = SLOT(label); 2204 2205 if (!mac_biba_dominate_effective(subj, obj)) 2206 return (EACCES); 2207 2208 return (0); 2209} 2210 2211static int 2212mac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2213 struct label *label, int attrnamespace) 2214{ 2215 struct mac_biba *subj, *obj; 2216 2217 if (!mac_biba_enabled) 2218 return (0); 2219 2220 subj = SLOT(cred->cr_label); 2221 obj = SLOT(label); 2222 2223 if (!mac_biba_dominate_effective(obj, subj)) 2224 return (EACCES); 2225 2226 return (0); 2227} 2228 2229static int 2230mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2231 struct label *dlabel, struct componentname *cnp) 2232{ 2233 struct mac_biba *subj, *obj; 2234 2235 if (!mac_biba_enabled) 2236 return (0); 2237 2238 subj = SLOT(cred->cr_label); 2239 obj = SLOT(dlabel); 2240 2241 if (!mac_biba_dominate_effective(obj, subj)) 2242 return (EACCES); 2243 2244 return (0); 2245} 2246 2247static int 2248mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2249 struct label *label, int prot) 2250{ 2251 struct mac_biba *subj, *obj; 2252 2253 /* 2254 * Rely on the use of open()-time protections to handle 2255 * non-revocation cases. 2256 */ 2257 if (!mac_biba_enabled || !revocation_enabled) 2258 return (0); 2259 2260 subj = SLOT(cred->cr_label); 2261 obj = SLOT(label); 2262 2263 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2264 if (!mac_biba_dominate_effective(obj, subj)) 2265 return (EACCES); 2266 } 2267 if (prot & VM_PROT_WRITE) { 2268 if (!mac_biba_dominate_effective(subj, obj)) 2269 return (EACCES); 2270 } 2271 2272 return (0); 2273} 2274 2275static int 2276mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2277 struct label *vnodelabel, int acc_mode) 2278{ 2279 struct mac_biba *subj, *obj; 2280 2281 if (!mac_biba_enabled) 2282 return (0); 2283 2284 subj = SLOT(cred->cr_label); 2285 obj = SLOT(vnodelabel); 2286 2287 /* XXX privilege override for admin? */ 2288 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2289 if (!mac_biba_dominate_effective(obj, subj)) 2290 return (EACCES); 2291 } 2292 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2293 if (!mac_biba_dominate_effective(subj, obj)) 2294 return (EACCES); 2295 } 2296 2297 return (0); 2298} 2299 2300static int 2301mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2302 struct vnode *vp, struct label *label) 2303{ 2304 struct mac_biba *subj, *obj; 2305 2306 if (!mac_biba_enabled || !revocation_enabled) 2307 return (0); 2308 2309 subj = SLOT(active_cred->cr_label); 2310 obj = SLOT(label); 2311 2312 if (!mac_biba_dominate_effective(obj, subj)) 2313 return (EACCES); 2314 2315 return (0); 2316} 2317 2318static int 2319mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2320 struct vnode *vp, struct label *label) 2321{ 2322 struct mac_biba *subj, *obj; 2323 2324 if (!mac_biba_enabled || !revocation_enabled) 2325 return (0); 2326 2327 subj = SLOT(active_cred->cr_label); 2328 obj = SLOT(label); 2329 2330 if (!mac_biba_dominate_effective(obj, subj)) 2331 return (EACCES); 2332 2333 return (0); 2334} 2335 2336static int 2337mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2338 struct label *dlabel) 2339{ 2340 struct mac_biba *subj, *obj; 2341 2342 if (!mac_biba_enabled) 2343 return (0); 2344 2345 subj = SLOT(cred->cr_label); 2346 obj = SLOT(dlabel); 2347 2348 if (!mac_biba_dominate_effective(obj, subj)) 2349 return (EACCES); 2350 2351 return (0); 2352} 2353 2354static int 2355mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2356 struct label *label) 2357{ 2358 struct mac_biba *subj, *obj; 2359 2360 if (!mac_biba_enabled) 2361 return (0); 2362 2363 subj = SLOT(cred->cr_label); 2364 obj = SLOT(label); 2365 2366 if (!mac_biba_dominate_effective(obj, subj)) 2367 return (EACCES); 2368 2369 return (0); 2370} 2371 2372static int 2373mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2374 struct label *vnodelabel, struct label *newlabel) 2375{ 2376 struct mac_biba *old, *new, *subj; 2377 int error; 2378 2379 old = SLOT(vnodelabel); 2380 new = SLOT(newlabel); 2381 subj = SLOT(cred->cr_label); 2382 2383 /* 2384 * If there is a Biba label update for the vnode, it must be a 2385 * effective label. 2386 */ 2387 error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2388 if (error) 2389 return (error); 2390 2391 /* 2392 * To perform a relabel of the vnode (Biba label or not), Biba must 2393 * authorize the relabel. 2394 */ 2395 if (!mac_biba_effective_in_range(old, subj)) 2396 return (EPERM); 2397 2398 /* 2399 * If the Biba label is to be changed, authorize as appropriate. 2400 */ 2401 if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2402 /* 2403 * To change the Biba label on a vnode, the new vnode label 2404 * must be in the subject range. 2405 */ 2406 if (!mac_biba_effective_in_range(new, subj)) 2407 return (EPERM); 2408 2409 /* 2410 * To change the Biba label on the vnode to be EQUAL, 2411 * the subject must have appropriate privilege. 2412 */ 2413 if (mac_biba_contains_equal(new)) { 2414 error = mac_biba_subject_privileged(subj); 2415 if (error) 2416 return (error); 2417 } 2418 } 2419 2420 return (0); 2421} 2422 2423static int 2424mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2425 struct label *dlabel, struct vnode *vp, struct label *label, 2426 struct componentname *cnp) 2427{ 2428 struct mac_biba *subj, *obj; 2429 2430 if (!mac_biba_enabled) 2431 return (0); 2432 2433 subj = SLOT(cred->cr_label); 2434 obj = SLOT(dlabel); 2435 2436 if (!mac_biba_dominate_effective(subj, obj)) 2437 return (EACCES); 2438 2439 obj = SLOT(label); 2440 2441 if (!mac_biba_dominate_effective(subj, obj)) 2442 return (EACCES); 2443 2444 return (0); 2445} 2446 2447static int 2448mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2449 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2450 struct componentname *cnp) 2451{ 2452 struct mac_biba *subj, *obj; 2453 2454 if (!mac_biba_enabled) 2455 return (0); 2456 2457 subj = SLOT(cred->cr_label); 2458 obj = SLOT(dlabel); 2459 2460 if (!mac_biba_dominate_effective(subj, obj)) 2461 return (EACCES); 2462 2463 if (vp != NULL) { 2464 obj = SLOT(label); 2465 2466 if (!mac_biba_dominate_effective(subj, obj)) 2467 return (EACCES); 2468 } 2469 2470 return (0); 2471} 2472 2473static int 2474mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2475 struct label *label) 2476{ 2477 struct mac_biba *subj, *obj; 2478 2479 if (!mac_biba_enabled) 2480 return (0); 2481 2482 subj = SLOT(cred->cr_label); 2483 obj = SLOT(label); 2484 2485 if (!mac_biba_dominate_effective(subj, obj)) 2486 return (EACCES); 2487 2488 return (0); 2489} 2490 2491static int 2492mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2493 struct label *label, acl_type_t type, struct acl *acl) 2494{ 2495 struct mac_biba *subj, *obj; 2496 2497 if (!mac_biba_enabled) 2498 return (0); 2499 2500 subj = SLOT(cred->cr_label); 2501 obj = SLOT(label); 2502 2503 if (!mac_biba_dominate_effective(subj, obj)) 2504 return (EACCES); 2505 2506 return (0); 2507} 2508 2509static int 2510mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2511 struct label *vnodelabel, int attrnamespace, const char *name, 2512 struct uio *uio) 2513{ 2514 struct mac_biba *subj, *obj; 2515 2516 if (!mac_biba_enabled) 2517 return (0); 2518 2519 subj = SLOT(cred->cr_label); 2520 obj = SLOT(vnodelabel); 2521 2522 if (!mac_biba_dominate_effective(subj, obj)) 2523 return (EACCES); 2524 2525 /* XXX: protect the MAC EA in a special way? */ 2526 2527 return (0); 2528} 2529 2530static int 2531mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2532 struct label *vnodelabel, u_long flags) 2533{ 2534 struct mac_biba *subj, *obj; 2535 2536 if (!mac_biba_enabled) 2537 return (0); 2538 2539 subj = SLOT(cred->cr_label); 2540 obj = SLOT(vnodelabel); 2541 2542 if (!mac_biba_dominate_effective(subj, obj)) 2543 return (EACCES); 2544 2545 return (0); 2546} 2547 2548static int 2549mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2550 struct label *vnodelabel, mode_t mode) 2551{ 2552 struct mac_biba *subj, *obj; 2553 2554 if (!mac_biba_enabled) 2555 return (0); 2556 2557 subj = SLOT(cred->cr_label); 2558 obj = SLOT(vnodelabel); 2559 2560 if (!mac_biba_dominate_effective(subj, obj)) 2561 return (EACCES); 2562 2563 return (0); 2564} 2565 2566static int 2567mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2568 struct label *vnodelabel, uid_t uid, gid_t gid) 2569{ 2570 struct mac_biba *subj, *obj; 2571 2572 if (!mac_biba_enabled) 2573 return (0); 2574 2575 subj = SLOT(cred->cr_label); 2576 obj = SLOT(vnodelabel); 2577 2578 if (!mac_biba_dominate_effective(subj, obj)) 2579 return (EACCES); 2580 2581 return (0); 2582} 2583 2584static int 2585mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2586 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2587{ 2588 struct mac_biba *subj, *obj; 2589 2590 if (!mac_biba_enabled) 2591 return (0); 2592 2593 subj = SLOT(cred->cr_label); 2594 obj = SLOT(vnodelabel); 2595 2596 if (!mac_biba_dominate_effective(subj, obj)) 2597 return (EACCES); 2598 2599 return (0); 2600} 2601 2602static int 2603mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2604 struct vnode *vp, struct label *vnodelabel) 2605{ 2606 struct mac_biba *subj, *obj; 2607 2608 if (!mac_biba_enabled) 2609 return (0); 2610 2611 subj = SLOT(active_cred->cr_label); 2612 obj = SLOT(vnodelabel); 2613 2614 if (!mac_biba_dominate_effective(obj, subj)) 2615 return (EACCES); 2616 2617 return (0); 2618} 2619 2620static int 2621mac_biba_check_vnode_write(struct ucred *active_cred, 2622 struct ucred *file_cred, struct vnode *vp, struct label *label) 2623{ 2624 struct mac_biba *subj, *obj; 2625 2626 if (!mac_biba_enabled || !revocation_enabled) 2627 return (0); 2628 2629 subj = SLOT(active_cred->cr_label); 2630 obj = SLOT(label); 2631 2632 if (!mac_biba_dominate_effective(subj, obj)) 2633 return (EACCES); 2634 2635 return (0); 2636} 2637 2638static struct mac_policy_ops mac_biba_ops = 2639{ 2640 .mpo_init = mac_biba_init, 2641 .mpo_init_bpfdesc_label = mac_biba_init_label, 2642 .mpo_init_cred_label = mac_biba_init_label, 2643 .mpo_init_devfsdirent_label = mac_biba_init_label, 2644 .mpo_init_ifnet_label = mac_biba_init_label, 2645 .mpo_init_inpcb_label = mac_biba_init_label_waitcheck, 2646 .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 2647 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2648 .mpo_init_mount_label = mac_biba_init_label, 2649 .mpo_init_mount_fs_label = mac_biba_init_label, 2650 .mpo_init_pipe_label = mac_biba_init_label, 2651 .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2652 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2653 .mpo_init_vnode_label = mac_biba_init_label, 2654 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2655 .mpo_destroy_cred_label = mac_biba_destroy_label, 2656 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2657 .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2658 .mpo_destroy_inpcb_label = mac_biba_destroy_label, 2659 .mpo_destroy_ipq_label = mac_biba_destroy_label, 2660 .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2661 .mpo_destroy_mount_label = mac_biba_destroy_label, 2662 .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2663 .mpo_destroy_pipe_label = mac_biba_destroy_label, 2664 .mpo_destroy_socket_label = mac_biba_destroy_label, 2665 .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2666 .mpo_destroy_vnode_label = mac_biba_destroy_label, 2667 .mpo_copy_cred_label = mac_biba_copy_label, 2668 .mpo_copy_ifnet_label = mac_biba_copy_label, 2669 .mpo_copy_mbuf_label = mac_biba_copy_label, 2670 .mpo_copy_pipe_label = mac_biba_copy_label, 2671 .mpo_copy_socket_label = mac_biba_copy_label, 2672 .mpo_copy_vnode_label = mac_biba_copy_label, 2673 .mpo_externalize_cred_label = mac_biba_externalize_label, 2674 .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2675 .mpo_externalize_pipe_label = mac_biba_externalize_label, 2676 .mpo_externalize_socket_label = mac_biba_externalize_label, 2677 .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2678 .mpo_externalize_vnode_label = mac_biba_externalize_label, 2679 .mpo_internalize_cred_label = mac_biba_internalize_label, 2680 .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2681 .mpo_internalize_pipe_label = mac_biba_internalize_label, 2682 .mpo_internalize_socket_label = mac_biba_internalize_label, 2683 .mpo_internalize_vnode_label = mac_biba_internalize_label, 2684 .mpo_create_devfs_device = mac_biba_create_devfs_device, 2685 .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2686 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2687 .mpo_create_mount = mac_biba_create_mount, 2688 .mpo_create_root_mount = mac_biba_create_root_mount, 2689 .mpo_relabel_vnode = mac_biba_relabel_vnode, 2690 .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2691 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2692 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2693 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2694 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2695 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2696 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2697 .mpo_create_pipe = mac_biba_create_pipe, 2698 .mpo_create_socket = mac_biba_create_socket, 2699 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2700 .mpo_relabel_pipe = mac_biba_relabel_pipe, 2701 .mpo_relabel_socket = mac_biba_relabel_socket, 2702 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2703 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2704 .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2705 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2706 .mpo_create_fragment = mac_biba_create_fragment, 2707 .mpo_create_ifnet = mac_biba_create_ifnet, 2708 .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket, 2709 .mpo_create_ipq = mac_biba_create_ipq, 2710 .mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb, 2711 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2712 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2713 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2714 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2715 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2716 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2717 .mpo_fragment_match = mac_biba_fragment_match, 2718 .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2719 .mpo_update_ipq = mac_biba_update_ipq, 2720 .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel, 2721 .mpo_create_proc0 = mac_biba_create_proc0, 2722 .mpo_create_proc1 = mac_biba_create_proc1, 2723 .mpo_relabel_cred = mac_biba_relabel_cred, 2724 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2725 .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2726 .mpo_check_cred_visible = mac_biba_check_cred_visible, 2727 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2728 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2729 .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver, 2730 .mpo_check_kld_load = mac_biba_check_kld_load, 2731 .mpo_check_kld_unload = mac_biba_check_kld_unload, 2732 .mpo_check_mount_stat = mac_biba_check_mount_stat, 2733 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2734 .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2735 .mpo_check_pipe_read = mac_biba_check_pipe_read, 2736 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2737 .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2738 .mpo_check_pipe_write = mac_biba_check_pipe_write, 2739 .mpo_check_proc_debug = mac_biba_check_proc_debug, 2740 .mpo_check_proc_sched = mac_biba_check_proc_sched, 2741 .mpo_check_proc_signal = mac_biba_check_proc_signal, 2742 .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2743 .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2744 .mpo_check_socket_visible = mac_biba_check_socket_visible, 2745 .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 2746 .mpo_check_system_acct = mac_biba_check_system_acct, 2747 .mpo_check_system_settime = mac_biba_check_system_settime, 2748 .mpo_check_system_swapon = mac_biba_check_system_swapon, 2749 .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 2750 .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2751 .mpo_check_vnode_access = mac_biba_check_vnode_open, 2752 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2753 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2754 .mpo_check_vnode_create = mac_biba_check_vnode_create, 2755 .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2756 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2757 .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr, 2758 .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2759 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2760 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2761 .mpo_check_vnode_link = mac_biba_check_vnode_link, 2762 .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr, 2763 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2764 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2765 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2766 .mpo_check_vnode_open = mac_biba_check_vnode_open, 2767 .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2768 .mpo_check_vnode_read = mac_biba_check_vnode_read, 2769 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2770 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2771 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2772 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2773 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2774 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2775 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2776 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2777 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2778 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2779 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2780 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2781 .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2782 .mpo_check_vnode_write = mac_biba_check_vnode_write, 2783}; 2784 2785MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 2786 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot); 2787