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