mac_biba.c revision 106416
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 106416 2002-11-04 17:36: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/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 = 0; 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 651 if (strcmp(string, "high") == 0 || 652 strcmp(string, "hi") == 0) { 653 element->mbe_type = MAC_BIBA_TYPE_HIGH; 654 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 655 } else if (strcmp(string, "low") == 0 || 656 strcmp(string, "lo") == 0) { 657 element->mbe_type = MAC_BIBA_TYPE_LOW; 658 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 659 } else if (strcmp(string, "equal") == 0 || 660 strcmp(string, "eq") == 0) { 661 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 662 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 663 } else { 664 char *p0, *p1; 665 int d; 666 667 p0 = string; 668 d = strtol(p0, &p1, 10); 669 670 if (d < 0 || d > 65535) 671 return (EINVAL); 672 element->mbe_type = MAC_BIBA_TYPE_GRADE; 673 element->mbe_grade = d; 674 675 if (*p1 != ':') { 676 if (p1 == p0 || *p1 != '\0') 677 return (EINVAL); 678 else 679 return (0); 680 } 681 else 682 if (*(p1 + 1) == '\0') 683 return (0); 684 685 while ((p0 = ++p1)) { 686 d = strtol(p0, &p1, 10); 687 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS) 688 return (EINVAL); 689 690 MAC_BIBA_BIT_SET(d, element->mbe_compartments); 691 692 if (*p1 == '\0') 693 break; 694 if (p1 == p0 || *p1 != '+') 695 return (EINVAL); 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 *range, *rangeend, *rangehigh, *rangelow, *single; 710 int error; 711 712 /* Do we have a range? */ 713 single = string; 714 range = index(string, '('); 715 if (range == single) 716 single = NULL; 717 rangelow = rangehigh = NULL; 718 if (range != NULL) { 719 /* Nul terminate the end of the single string. */ 720 *range = '\0'; 721 range++; 722 rangelow = range; 723 rangehigh = index(rangelow, '-'); 724 if (rangehigh == NULL) 725 return (EINVAL); 726 rangehigh++; 727 if (*rangelow == '\0' || *rangehigh == '\0') 728 return (EINVAL); 729 rangeend = index(rangehigh, ')'); 730 if (rangeend == NULL) 731 return (EINVAL); 732 if (*(rangeend + 1) != '\0') 733 return (EINVAL); 734 /* Nul terminate the ends of the ranges. */ 735 *(rangehigh - 1) = '\0'; 736 *rangeend = '\0'; 737 } 738 KASSERT((rangelow != NULL && rangehigh != NULL) || 739 (rangelow == NULL && rangehigh == NULL), 740 ("mac_biba_internalize_label: range mismatch")); 741 742 bzero(mac_biba, sizeof(*mac_biba)); 743 if (single != NULL) { 744 error = mac_biba_parse_element(&mac_biba->mb_single, single); 745 if (error) 746 return (error); 747 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 748 } 749 750 if (rangelow != NULL) { 751 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 752 rangelow); 753 if (error) 754 return (error); 755 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 756 rangehigh); 757 if (error) 758 return (error); 759 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 760 } 761 762 error = mac_biba_valid(mac_biba); 763 if (error) 764 return (error); 765 766 return (0); 767} 768 769static int 770mac_biba_internalize_label(struct label *label, char *element_name, 771 char *element_data, int *claimed) 772{ 773 struct mac_biba *mac_biba, mac_biba_temp; 774 int error; 775 776 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 777 return (0); 778 779 (*claimed)++; 780 781 error = mac_biba_parse(&mac_biba_temp, element_data); 782 if (error) 783 return (error); 784 785 mac_biba = SLOT(label); 786 *mac_biba = mac_biba_temp; 787 788 return (0); 789} 790 791static void 792mac_biba_copy_label(struct label *src, struct label *dest) 793{ 794 795 *SLOT(dest) = *SLOT(src); 796} 797 798/* 799 * Labeling event operations: file system objects, and things that look 800 * a lot like file system objects. 801 */ 802static void 803mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 804 struct label *label) 805{ 806 struct mac_biba *mac_biba; 807 int biba_type; 808 809 mac_biba = SLOT(label); 810 if (strcmp(dev->si_name, "null") == 0 || 811 strcmp(dev->si_name, "zero") == 0 || 812 strcmp(dev->si_name, "random") == 0 || 813 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 814 biba_type = MAC_BIBA_TYPE_EQUAL; 815 else if (ptys_equal && 816 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 817 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 818 biba_type = MAC_BIBA_TYPE_EQUAL; 819 else 820 biba_type = MAC_BIBA_TYPE_HIGH; 821 mac_biba_set_single(mac_biba, biba_type, 0, NULL); 822} 823 824static void 825mac_biba_create_devfs_directory(char *dirname, int dirnamelen, 826 struct devfs_dirent *devfs_dirent, struct label *label) 827{ 828 struct mac_biba *mac_biba; 829 830 mac_biba = SLOT(label); 831 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 832} 833 834static void 835mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 836 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) 837{ 838 struct mac_biba *source, *dest; 839 840 source = SLOT(&cred->cr_label); 841 dest = SLOT(delabel); 842 843 mac_biba_copy_single(source, dest); 844} 845 846static void 847mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 848 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 849{ 850 struct mac_biba *source, *dest; 851 852 source = SLOT(direntlabel); 853 dest = SLOT(vnodelabel); 854 mac_biba_copy_single(source, dest); 855} 856 857static void 858mac_biba_create_mount(struct ucred *cred, struct mount *mp, 859 struct label *mntlabel, struct label *fslabel) 860{ 861 struct mac_biba *source, *dest; 862 863 source = SLOT(&cred->cr_label); 864 dest = SLOT(mntlabel); 865 mac_biba_copy_single(source, dest); 866 dest = SLOT(fslabel); 867 mac_biba_copy_single(source, dest); 868} 869 870static void 871mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 872 struct label *mntlabel, struct label *fslabel) 873{ 874 struct mac_biba *mac_biba; 875 876 /* Always mount root as high integrity. */ 877 mac_biba = SLOT(fslabel); 878 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 879 mac_biba = SLOT(mntlabel); 880 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 881} 882 883static void 884mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 885 struct label *vnodelabel, struct label *label) 886{ 887 struct mac_biba *source, *dest; 888 889 source = SLOT(label); 890 dest = SLOT(vnodelabel); 891 892 mac_biba_copy(source, dest); 893} 894 895static void 896mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent, 897 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 898{ 899 struct mac_biba *source, *dest; 900 901 source = SLOT(vnodelabel); 902 dest = SLOT(direntlabel); 903 904 mac_biba_copy(source, dest); 905} 906 907static void 908mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 909 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 910 struct label *vlabel) 911{ 912 struct mac_biba *source, *dest; 913 914 source = SLOT(delabel); 915 dest = SLOT(vlabel); 916 917 mac_biba_copy_single(source, dest); 918} 919 920static int 921mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 922 struct vnode *vp, struct label *vlabel) 923{ 924 struct mac_biba temp, *source, *dest; 925 int buflen, error; 926 927 source = SLOT(fslabel); 928 dest = SLOT(vlabel); 929 930 buflen = sizeof(temp); 931 bzero(&temp, buflen); 932 933 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 934 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 935 if (error == ENOATTR || error == EOPNOTSUPP) { 936 /* Fall back to the fslabel. */ 937 mac_biba_copy_single(source, dest); 938 return (0); 939 } else if (error) 940 return (error); 941 942 if (buflen != sizeof(temp)) { 943 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 944 buflen); 945 return (EPERM); 946 } 947 if (mac_biba_valid(&temp) != 0) { 948 printf("mac_biba_associate_vnode_extattr: invalid\n"); 949 return (EPERM); 950 } 951 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 952 printf("mac_biba_associate_vnode_extattr: not single\n"); 953 return (EPERM); 954 } 955 956 mac_biba_copy_single(&temp, dest); 957 return (0); 958} 959 960static void 961mac_biba_associate_vnode_singlelabel(struct mount *mp, 962 struct label *fslabel, struct vnode *vp, struct label *vlabel) 963{ 964 struct mac_biba *source, *dest; 965 966 source = SLOT(fslabel); 967 dest = SLOT(vlabel); 968 969 mac_biba_copy_single(source, dest); 970} 971 972static int 973mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 974 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 975 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 976{ 977 struct mac_biba *source, *dest, temp; 978 size_t buflen; 979 int error; 980 981 buflen = sizeof(temp); 982 bzero(&temp, buflen); 983 984 source = SLOT(&cred->cr_label); 985 dest = SLOT(vlabel); 986 mac_biba_copy_single(source, &temp); 987 988 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 989 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 990 if (error == 0) 991 mac_biba_copy_single(source, dest); 992 return (error); 993} 994 995static int 996mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 997 struct label *vlabel, struct label *intlabel) 998{ 999 struct mac_biba *source, temp; 1000 size_t buflen; 1001 int error; 1002 1003 buflen = sizeof(temp); 1004 bzero(&temp, buflen); 1005 1006 source = SLOT(intlabel); 1007 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 1008 return (0); 1009 1010 mac_biba_copy_single(source, &temp); 1011 1012 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 1013 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 1014 return (error); 1015} 1016 1017/* 1018 * Labeling event operations: IPC object. 1019 */ 1020static void 1021mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1022 struct mbuf *m, struct label *mbuflabel) 1023{ 1024 struct mac_biba *source, *dest; 1025 1026 source = SLOT(socketlabel); 1027 dest = SLOT(mbuflabel); 1028 1029 mac_biba_copy_single(source, dest); 1030} 1031 1032static void 1033mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1034 struct label *socketlabel) 1035{ 1036 struct mac_biba *source, *dest; 1037 1038 source = SLOT(&cred->cr_label); 1039 dest = SLOT(socketlabel); 1040 1041 mac_biba_copy_single(source, dest); 1042} 1043 1044static void 1045mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1046 struct label *pipelabel) 1047{ 1048 struct mac_biba *source, *dest; 1049 1050 source = SLOT(&cred->cr_label); 1051 dest = SLOT(pipelabel); 1052 1053 mac_biba_copy_single(source, dest); 1054} 1055 1056static void 1057mac_biba_create_socket_from_socket(struct socket *oldsocket, 1058 struct label *oldsocketlabel, struct socket *newsocket, 1059 struct label *newsocketlabel) 1060{ 1061 struct mac_biba *source, *dest; 1062 1063 source = SLOT(oldsocketlabel); 1064 dest = SLOT(newsocketlabel); 1065 1066 mac_biba_copy_single(source, dest); 1067} 1068 1069static void 1070mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1071 struct label *socketlabel, struct label *newlabel) 1072{ 1073 struct mac_biba *source, *dest; 1074 1075 source = SLOT(newlabel); 1076 dest = SLOT(socketlabel); 1077 1078 mac_biba_copy(source, dest); 1079} 1080 1081static void 1082mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1083 struct label *pipelabel, struct label *newlabel) 1084{ 1085 struct mac_biba *source, *dest; 1086 1087 source = SLOT(newlabel); 1088 dest = SLOT(pipelabel); 1089 1090 mac_biba_copy(source, dest); 1091} 1092 1093static void 1094mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1095 struct socket *socket, struct label *socketpeerlabel) 1096{ 1097 struct mac_biba *source, *dest; 1098 1099 source = SLOT(mbuflabel); 1100 dest = SLOT(socketpeerlabel); 1101 1102 mac_biba_copy_single(source, dest); 1103} 1104 1105/* 1106 * Labeling event operations: network objects. 1107 */ 1108static void 1109mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1110 struct label *oldsocketlabel, struct socket *newsocket, 1111 struct label *newsocketpeerlabel) 1112{ 1113 struct mac_biba *source, *dest; 1114 1115 source = SLOT(oldsocketlabel); 1116 dest = SLOT(newsocketpeerlabel); 1117 1118 mac_biba_copy_single(source, dest); 1119} 1120 1121static void 1122mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1123 struct label *bpflabel) 1124{ 1125 struct mac_biba *source, *dest; 1126 1127 source = SLOT(&cred->cr_label); 1128 dest = SLOT(bpflabel); 1129 1130 mac_biba_copy_single(source, dest); 1131} 1132 1133static void 1134mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1135{ 1136 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1137 char tiflist[sizeof(trusted_interfaces)]; 1138 struct mac_biba *dest; 1139 int len, grade; 1140 1141 dest = SLOT(ifnetlabel); 1142 1143 if (ifnet->if_type == IFT_LOOP) { 1144 grade = MAC_BIBA_TYPE_EQUAL; 1145 goto set; 1146 } 1147 1148 if (trust_all_interfaces) { 1149 grade = MAC_BIBA_TYPE_HIGH; 1150 goto set; 1151 } 1152 1153 grade = MAC_BIBA_TYPE_LOW; 1154 1155 if (trusted_interfaces[0] == '\0' || 1156 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1157 goto set; 1158 1159 bzero(tiflist, sizeof(tiflist)); 1160 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1161 if(*p != ' ' && *p != '\t') 1162 *q = *p; 1163 1164 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1165 1166 for (p = q = tiflist;; p++) { 1167 if (*p == ',' || *p == '\0') { 1168 len = p - q; 1169 if (len < IFNAMSIZ) { 1170 bzero(tifname, sizeof(tifname)); 1171 bcopy(q, tifname, len); 1172 if (strcmp(tifname, ifname) == 0) { 1173 grade = MAC_BIBA_TYPE_HIGH; 1174 break; 1175 } 1176 } else { 1177 *p = '\0'; 1178 printf("mac_biba warning: interface name " 1179 "\"%s\" is too long (must be < %d)\n", 1180 q, IFNAMSIZ); 1181 } 1182 if (*p == '\0') 1183 break; 1184 q = p + 1; 1185 } 1186 } 1187set: 1188 mac_biba_set_single(dest, grade, 0, NULL); 1189 mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL); 1190} 1191 1192static void 1193mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1194 struct ipq *ipq, struct label *ipqlabel) 1195{ 1196 struct mac_biba *source, *dest; 1197 1198 source = SLOT(fragmentlabel); 1199 dest = SLOT(ipqlabel); 1200 1201 mac_biba_copy_single(source, dest); 1202} 1203 1204static void 1205mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1206 struct mbuf *datagram, struct label *datagramlabel) 1207{ 1208 struct mac_biba *source, *dest; 1209 1210 source = SLOT(ipqlabel); 1211 dest = SLOT(datagramlabel); 1212 1213 /* Just use the head, since we require them all to match. */ 1214 mac_biba_copy_single(source, dest); 1215} 1216 1217static void 1218mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1219 struct mbuf *fragment, struct label *fragmentlabel) 1220{ 1221 struct mac_biba *source, *dest; 1222 1223 source = SLOT(datagramlabel); 1224 dest = SLOT(fragmentlabel); 1225 1226 mac_biba_copy_single(source, dest); 1227} 1228 1229static void 1230mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1231 struct label *oldmbuflabel, struct mbuf *newmbuf, 1232 struct label *newmbuflabel) 1233{ 1234 struct mac_biba *source, *dest; 1235 1236 source = SLOT(oldmbuflabel); 1237 dest = SLOT(newmbuflabel); 1238 1239 /* 1240 * Because the source mbuf may not yet have been "created", 1241 * just initialized, we do a conditional copy. Since we don't 1242 * allow mbufs to have ranges, do a KASSERT to make sure that 1243 * doesn't happen. 1244 */ 1245 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1246 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1247 mac_biba_copy(source, dest); 1248} 1249 1250static void 1251mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1252 struct mbuf *mbuf, struct label *mbuflabel) 1253{ 1254 struct mac_biba *dest; 1255 1256 dest = SLOT(mbuflabel); 1257 1258 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1259} 1260 1261static void 1262mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1263 struct mbuf *mbuf, struct label *mbuflabel) 1264{ 1265 struct mac_biba *source, *dest; 1266 1267 source = SLOT(bpflabel); 1268 dest = SLOT(mbuflabel); 1269 1270 mac_biba_copy_single(source, dest); 1271} 1272 1273static void 1274mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1275 struct mbuf *m, struct label *mbuflabel) 1276{ 1277 struct mac_biba *source, *dest; 1278 1279 source = SLOT(ifnetlabel); 1280 dest = SLOT(mbuflabel); 1281 1282 mac_biba_copy_single(source, dest); 1283} 1284 1285static void 1286mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1287 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1288 struct mbuf *newmbuf, struct label *newmbuflabel) 1289{ 1290 struct mac_biba *source, *dest; 1291 1292 source = SLOT(oldmbuflabel); 1293 dest = SLOT(newmbuflabel); 1294 1295 mac_biba_copy_single(source, dest); 1296} 1297 1298static void 1299mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1300 struct mbuf *newmbuf, struct label *newmbuflabel) 1301{ 1302 struct mac_biba *source, *dest; 1303 1304 source = SLOT(oldmbuflabel); 1305 dest = SLOT(newmbuflabel); 1306 1307 mac_biba_copy_single(source, dest); 1308} 1309 1310static int 1311mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1312 struct ipq *ipq, struct label *ipqlabel) 1313{ 1314 struct mac_biba *a, *b; 1315 1316 a = SLOT(ipqlabel); 1317 b = SLOT(fragmentlabel); 1318 1319 return (mac_biba_equal_single(a, b)); 1320} 1321 1322static void 1323mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1324 struct label *ifnetlabel, struct label *newlabel) 1325{ 1326 struct mac_biba *source, *dest; 1327 1328 source = SLOT(newlabel); 1329 dest = SLOT(ifnetlabel); 1330 1331 mac_biba_copy(source, dest); 1332} 1333 1334static void 1335mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1336 struct ipq *ipq, struct label *ipqlabel) 1337{ 1338 1339 /* NOOP: we only accept matching labels, so no need to update */ 1340} 1341 1342/* 1343 * Labeling event operations: processes. 1344 */ 1345static void 1346mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1347{ 1348 struct mac_biba *source, *dest; 1349 1350 source = SLOT(&cred_parent->cr_label); 1351 dest = SLOT(&cred_child->cr_label); 1352 1353 mac_biba_copy_single(source, dest); 1354 mac_biba_copy_range(source, dest); 1355} 1356 1357static void 1358mac_biba_execve_transition(struct ucred *old, struct ucred *new, 1359 struct vnode *vp, struct label *vnodelabel) 1360{ 1361 struct mac_biba *source, *dest; 1362 1363 source = SLOT(&old->cr_label); 1364 dest = SLOT(&new->cr_label); 1365 1366 mac_biba_copy_single(source, dest); 1367 mac_biba_copy_range(source, dest); 1368} 1369 1370static int 1371mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp, 1372 struct label *vnodelabel) 1373{ 1374 1375 return (0); 1376} 1377 1378static void 1379mac_biba_create_proc0(struct ucred *cred) 1380{ 1381 struct mac_biba *dest; 1382 1383 dest = SLOT(&cred->cr_label); 1384 1385 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1386 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1387 MAC_BIBA_TYPE_HIGH, 0, NULL); 1388} 1389 1390static void 1391mac_biba_create_proc1(struct ucred *cred) 1392{ 1393 struct mac_biba *dest; 1394 1395 dest = SLOT(&cred->cr_label); 1396 1397 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1398 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1399 MAC_BIBA_TYPE_HIGH, 0, NULL); 1400} 1401 1402static void 1403mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1404{ 1405 struct mac_biba *source, *dest; 1406 1407 source = SLOT(newlabel); 1408 dest = SLOT(&cred->cr_label); 1409 1410 mac_biba_copy(source, dest); 1411} 1412 1413/* 1414 * Access control checks. 1415 */ 1416static int 1417mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1418 struct ifnet *ifnet, struct label *ifnetlabel) 1419{ 1420 struct mac_biba *a, *b; 1421 1422 if (!mac_biba_enabled) 1423 return (0); 1424 1425 a = SLOT(bpflabel); 1426 b = SLOT(ifnetlabel); 1427 1428 if (mac_biba_equal_single(a, b)) 1429 return (0); 1430 return (EACCES); 1431} 1432 1433static int 1434mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1435{ 1436 struct mac_biba *subj, *new; 1437 int error; 1438 1439 subj = SLOT(&cred->cr_label); 1440 new = SLOT(newlabel); 1441 1442 /* 1443 * If there is a Biba label update for the credential, it may 1444 * be an update of the single, range, or both. 1445 */ 1446 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1447 if (error) 1448 return (error); 1449 1450 /* 1451 * If the Biba label is to be changed, authorize as appropriate. 1452 */ 1453 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1454 /* 1455 * To change the Biba single label on a credential, the 1456 * new single label must be in the current range. 1457 */ 1458 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1459 !mac_biba_single_in_range(new, subj)) 1460 return (EPERM); 1461 1462 /* 1463 * To change the Biba range on a credential, the new 1464 * range label must be in the current range. 1465 */ 1466 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1467 !mac_biba_range_in_range(new, subj)) 1468 return (EPERM); 1469 1470 /* 1471 * To have EQUAL in any component of the new credential 1472 * Biba label, the subject must already have EQUAL in 1473 * their label. 1474 */ 1475 if (mac_biba_contains_equal(new)) { 1476 error = mac_biba_subject_privileged(subj); 1477 if (error) 1478 return (error); 1479 } 1480 1481 /* 1482 * XXXMAC: Additional consistency tests regarding the 1483 * single and range of the new label might be performed 1484 * here. 1485 */ 1486 } 1487 1488 return (0); 1489} 1490 1491static int 1492mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1493{ 1494 struct mac_biba *subj, *obj; 1495 1496 if (!mac_biba_enabled) 1497 return (0); 1498 1499 subj = SLOT(&u1->cr_label); 1500 obj = SLOT(&u2->cr_label); 1501 1502 /* XXX: range */ 1503 if (!mac_biba_dominate_single(obj, subj)) 1504 return (ESRCH); 1505 1506 return (0); 1507} 1508 1509static int 1510mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1511 struct label *ifnetlabel, struct label *newlabel) 1512{ 1513 struct mac_biba *subj, *new; 1514 int error; 1515 1516 subj = SLOT(&cred->cr_label); 1517 new = SLOT(newlabel); 1518 1519 /* 1520 * If there is a Biba label update for the interface, it may 1521 * be an update of the single, range, or both. 1522 */ 1523 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1524 if (error) 1525 return (error); 1526 1527 /* 1528 * Relabling network interfaces requires Biba privilege. 1529 */ 1530 error = mac_biba_subject_privileged(subj); 1531 if (error) 1532 return (error); 1533 1534 /* 1535 * If the Biba label is to be changed, authorize as appropriate. 1536 */ 1537 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1538 /* 1539 * Rely on the traditional superuser status for the Biba 1540 * interface relabel requirements. XXXMAC: This will go 1541 * away. 1542 */ 1543 error = suser_cred(cred, 0); 1544 if (error) 1545 return (EPERM); 1546 1547 /* 1548 * XXXMAC: Additional consistency tests regarding the single 1549 * and the range of the new label might be performed here. 1550 */ 1551 } 1552 1553 return (0); 1554} 1555 1556static int 1557mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1558 struct mbuf *m, struct label *mbuflabel) 1559{ 1560 struct mac_biba *p, *i; 1561 1562 if (!mac_biba_enabled) 1563 return (0); 1564 1565 p = SLOT(mbuflabel); 1566 i = SLOT(ifnetlabel); 1567 1568 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1569} 1570 1571static int 1572mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1573 struct label *mntlabel) 1574{ 1575 struct mac_biba *subj, *obj; 1576 1577 if (!mac_biba_enabled) 1578 return (0); 1579 1580 subj = SLOT(&cred->cr_label); 1581 obj = SLOT(mntlabel); 1582 1583 if (!mac_biba_dominate_single(obj, subj)) 1584 return (EACCES); 1585 1586 return (0); 1587} 1588 1589static int 1590mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1591 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1592{ 1593 1594 if(!mac_biba_enabled) 1595 return (0); 1596 1597 /* XXX: This will be implemented soon... */ 1598 1599 return (0); 1600} 1601 1602static int 1603mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1604 struct label *pipelabel) 1605{ 1606 struct mac_biba *subj, *obj; 1607 1608 if (!mac_biba_enabled) 1609 return (0); 1610 1611 subj = SLOT(&cred->cr_label); 1612 obj = SLOT((pipelabel)); 1613 1614 if (!mac_biba_dominate_single(obj, subj)) 1615 return (EACCES); 1616 1617 return (0); 1618} 1619 1620static int 1621mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1622 struct label *pipelabel) 1623{ 1624 struct mac_biba *subj, *obj; 1625 1626 if (!mac_biba_enabled) 1627 return (0); 1628 1629 subj = SLOT(&cred->cr_label); 1630 obj = SLOT((pipelabel)); 1631 1632 if (!mac_biba_dominate_single(obj, subj)) 1633 return (EACCES); 1634 1635 return (0); 1636} 1637 1638static int 1639mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1640 struct label *pipelabel, struct label *newlabel) 1641{ 1642 struct mac_biba *subj, *obj, *new; 1643 int error; 1644 1645 new = SLOT(newlabel); 1646 subj = SLOT(&cred->cr_label); 1647 obj = SLOT(pipelabel); 1648 1649 /* 1650 * If there is a Biba label update for a pipe, it must be a 1651 * single update. 1652 */ 1653 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1654 if (error) 1655 return (error); 1656 1657 /* 1658 * To perform a relabel of a pipe (Biba label or not), Biba must 1659 * authorize the relabel. 1660 */ 1661 if (!mac_biba_single_in_range(obj, subj)) 1662 return (EPERM); 1663 1664 /* 1665 * If the Biba label is to be changed, authorize as appropriate. 1666 */ 1667 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1668 /* 1669 * To change the Biba label on a pipe, the new pipe label 1670 * must be in the subject range. 1671 */ 1672 if (!mac_biba_single_in_range(new, subj)) 1673 return (EPERM); 1674 1675 /* 1676 * To change the Biba label on a pipe to be EQUAL, the 1677 * subject must have appropriate privilege. 1678 */ 1679 if (mac_biba_contains_equal(new)) { 1680 error = mac_biba_subject_privileged(subj); 1681 if (error) 1682 return (error); 1683 } 1684 } 1685 1686 return (0); 1687} 1688 1689static int 1690mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1691 struct label *pipelabel) 1692{ 1693 struct mac_biba *subj, *obj; 1694 1695 if (!mac_biba_enabled) 1696 return (0); 1697 1698 subj = SLOT(&cred->cr_label); 1699 obj = SLOT((pipelabel)); 1700 1701 if (!mac_biba_dominate_single(obj, subj)) 1702 return (EACCES); 1703 1704 return (0); 1705} 1706 1707static int 1708mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1709 struct label *pipelabel) 1710{ 1711 struct mac_biba *subj, *obj; 1712 1713 if (!mac_biba_enabled) 1714 return (0); 1715 1716 subj = SLOT(&cred->cr_label); 1717 obj = SLOT((pipelabel)); 1718 1719 if (!mac_biba_dominate_single(subj, obj)) 1720 return (EACCES); 1721 1722 return (0); 1723} 1724 1725static int 1726mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1727{ 1728 struct mac_biba *subj, *obj; 1729 1730 if (!mac_biba_enabled) 1731 return (0); 1732 1733 subj = SLOT(&cred->cr_label); 1734 obj = SLOT(&proc->p_ucred->cr_label); 1735 1736 /* XXX: range checks */ 1737 if (!mac_biba_dominate_single(obj, subj)) 1738 return (ESRCH); 1739 if (!mac_biba_dominate_single(subj, obj)) 1740 return (EACCES); 1741 1742 return (0); 1743} 1744 1745static int 1746mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1747{ 1748 struct mac_biba *subj, *obj; 1749 1750 if (!mac_biba_enabled) 1751 return (0); 1752 1753 subj = SLOT(&cred->cr_label); 1754 obj = SLOT(&proc->p_ucred->cr_label); 1755 1756 /* XXX: range checks */ 1757 if (!mac_biba_dominate_single(obj, subj)) 1758 return (ESRCH); 1759 if (!mac_biba_dominate_single(subj, obj)) 1760 return (EACCES); 1761 1762 return (0); 1763} 1764 1765static int 1766mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1767{ 1768 struct mac_biba *subj, *obj; 1769 1770 if (!mac_biba_enabled) 1771 return (0); 1772 1773 subj = SLOT(&cred->cr_label); 1774 obj = SLOT(&proc->p_ucred->cr_label); 1775 1776 /* XXX: range checks */ 1777 if (!mac_biba_dominate_single(obj, subj)) 1778 return (ESRCH); 1779 if (!mac_biba_dominate_single(subj, obj)) 1780 return (EACCES); 1781 1782 return (0); 1783} 1784 1785static int 1786mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1787 struct mbuf *m, struct label *mbuflabel) 1788{ 1789 struct mac_biba *p, *s; 1790 1791 if (!mac_biba_enabled) 1792 return (0); 1793 1794 p = SLOT(mbuflabel); 1795 s = SLOT(socketlabel); 1796 1797 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1798} 1799 1800static int 1801mac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1802 struct label *socketlabel, struct label *newlabel) 1803{ 1804 struct mac_biba *subj, *obj, *new; 1805 int error; 1806 1807 new = SLOT(newlabel); 1808 subj = SLOT(&cred->cr_label); 1809 obj = SLOT(socketlabel); 1810 1811 /* 1812 * If there is a Biba label update for the socket, it may be 1813 * an update of single. 1814 */ 1815 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1816 if (error) 1817 return (error); 1818 1819 /* 1820 * To relabel a socket, the old socket single must be in the subject 1821 * range. 1822 */ 1823 if (!mac_biba_single_in_range(obj, subj)) 1824 return (EPERM); 1825 1826 /* 1827 * If the Biba label is to be changed, authorize as appropriate. 1828 */ 1829 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1830 /* 1831 * To relabel a socket, the new socket single must be in 1832 * the subject range. 1833 */ 1834 if (!mac_biba_single_in_range(new, subj)) 1835 return (EPERM); 1836 1837 /* 1838 * To change the Biba label on the socket to contain EQUAL, 1839 * the subject must have appropriate privilege. 1840 */ 1841 if (mac_biba_contains_equal(new)) { 1842 error = mac_biba_subject_privileged(subj); 1843 if (error) 1844 return (error); 1845 } 1846 } 1847 1848 return (0); 1849} 1850 1851static int 1852mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1853 struct label *socketlabel) 1854{ 1855 struct mac_biba *subj, *obj; 1856 1857 if (!mac_biba_enabled) 1858 return (0); 1859 1860 subj = SLOT(&cred->cr_label); 1861 obj = SLOT(socketlabel); 1862 1863 if (!mac_biba_dominate_single(obj, subj)) 1864 return (ENOENT); 1865 1866 return (0); 1867} 1868 1869static int 1870mac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1871 struct label *label) 1872{ 1873 struct mac_biba *subj, *obj; 1874 int error; 1875 1876 if (!mac_biba_enabled) 1877 return (0); 1878 1879 subj = SLOT(&cred->cr_label); 1880 obj = SLOT(label); 1881 1882 error = mac_biba_subject_privileged(subj); 1883 if (error) 1884 return (error); 1885 1886 if (!mac_biba_high_single(obj)) 1887 return (EACCES); 1888 1889 return (0); 1890} 1891 1892static int 1893mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1894 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1895{ 1896 struct mac_biba *subj; 1897 int error; 1898 1899 if (!mac_biba_enabled) 1900 return (0); 1901 1902 subj = SLOT(&cred->cr_label); 1903 1904 /* 1905 * In general, treat sysctl variables as biba/high, but also 1906 * require privilege to change them, since they are a 1907 * communications channel between grades. Exempt MIB 1908 * queries from this due to undocmented sysctl magic. 1909 * XXXMAC: This probably requires some more review. 1910 */ 1911 if (new != NULL) { 1912 if (namelen > 0 && name[0] == 0) 1913 return (0); 1914 1915 if (!mac_biba_subject_dominate_high(subj)) 1916 return (EACCES); 1917 1918 error = mac_biba_subject_privileged(subj); 1919 if (error) 1920 return (error); 1921 } 1922 1923 return (0); 1924} 1925 1926static int 1927mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1928 struct label *dlabel) 1929{ 1930 struct mac_biba *subj, *obj; 1931 1932 if (!mac_biba_enabled) 1933 return (0); 1934 1935 subj = SLOT(&cred->cr_label); 1936 obj = SLOT(dlabel); 1937 1938 if (!mac_biba_dominate_single(obj, subj)) 1939 return (EACCES); 1940 1941 return (0); 1942} 1943 1944static int 1945mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1946 struct label *dlabel) 1947{ 1948 struct mac_biba *subj, *obj; 1949 1950 if (!mac_biba_enabled) 1951 return (0); 1952 1953 subj = SLOT(&cred->cr_label); 1954 obj = SLOT(dlabel); 1955 1956 if (!mac_biba_dominate_single(obj, subj)) 1957 return (EACCES); 1958 1959 return (0); 1960} 1961 1962static int 1963mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1964 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1965{ 1966 struct mac_biba *subj, *obj; 1967 1968 if (!mac_biba_enabled) 1969 return (0); 1970 1971 subj = SLOT(&cred->cr_label); 1972 obj = SLOT(dlabel); 1973 1974 if (!mac_biba_dominate_single(subj, obj)) 1975 return (EACCES); 1976 1977 return (0); 1978} 1979 1980static int 1981mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1982 struct label *dlabel, struct vnode *vp, struct label *label, 1983 struct componentname *cnp) 1984{ 1985 struct mac_biba *subj, *obj; 1986 1987 if (!mac_biba_enabled) 1988 return (0); 1989 1990 subj = SLOT(&cred->cr_label); 1991 obj = SLOT(dlabel); 1992 1993 if (!mac_biba_dominate_single(subj, obj)) 1994 return (EACCES); 1995 1996 obj = SLOT(label); 1997 1998 if (!mac_biba_dominate_single(subj, obj)) 1999 return (EACCES); 2000 2001 return (0); 2002} 2003 2004static int 2005mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2006 struct label *label, acl_type_t type) 2007{ 2008 struct mac_biba *subj, *obj; 2009 2010 if (!mac_biba_enabled) 2011 return (0); 2012 2013 subj = SLOT(&cred->cr_label); 2014 obj = SLOT(label); 2015 2016 if (!mac_biba_dominate_single(subj, obj)) 2017 return (EACCES); 2018 2019 return (0); 2020} 2021 2022static int 2023mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2024 struct label *label) 2025{ 2026 struct mac_biba *subj, *obj; 2027 2028 if (!mac_biba_enabled) 2029 return (0); 2030 2031 subj = SLOT(&cred->cr_label); 2032 obj = SLOT(label); 2033 2034 if (!mac_biba_dominate_single(obj, subj)) 2035 return (EACCES); 2036 2037 return (0); 2038} 2039 2040static int 2041mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2042 struct label *label, acl_type_t type) 2043{ 2044 struct mac_biba *subj, *obj; 2045 2046 if (!mac_biba_enabled) 2047 return (0); 2048 2049 subj = SLOT(&cred->cr_label); 2050 obj = SLOT(label); 2051 2052 if (!mac_biba_dominate_single(obj, subj)) 2053 return (EACCES); 2054 2055 return (0); 2056} 2057 2058static int 2059mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2060 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2061{ 2062 struct mac_biba *subj, *obj; 2063 2064 if (!mac_biba_enabled) 2065 return (0); 2066 2067 subj = SLOT(&cred->cr_label); 2068 obj = SLOT(label); 2069 2070 if (!mac_biba_dominate_single(obj, subj)) 2071 return (EACCES); 2072 2073 return (0); 2074} 2075 2076static int 2077mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2078 struct label *dlabel, struct vnode *vp, struct label *label, 2079 struct componentname *cnp) 2080{ 2081 struct mac_biba *subj, *obj; 2082 2083 if (!mac_biba_enabled) 2084 return (0); 2085 2086 subj = SLOT(&cred->cr_label); 2087 obj = SLOT(dlabel); 2088 2089 if (!mac_biba_dominate_single(subj, obj)) 2090 return (EACCES); 2091 2092 obj = SLOT(label); 2093 2094 if (!mac_biba_dominate_single(subj, obj)) 2095 return (EACCES); 2096 2097 return (0); 2098} 2099 2100static int 2101mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2102 struct label *dlabel, struct componentname *cnp) 2103{ 2104 struct mac_biba *subj, *obj; 2105 2106 if (!mac_biba_enabled) 2107 return (0); 2108 2109 subj = SLOT(&cred->cr_label); 2110 obj = SLOT(dlabel); 2111 2112 if (!mac_biba_dominate_single(obj, subj)) 2113 return (EACCES); 2114 2115 return (0); 2116} 2117 2118static int 2119mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2120 struct label *label, int prot) 2121{ 2122 struct mac_biba *subj, *obj; 2123 2124 /* 2125 * Rely on the use of open()-time protections to handle 2126 * non-revocation cases. 2127 */ 2128 if (!mac_biba_enabled || !revocation_enabled) 2129 return (0); 2130 2131 subj = SLOT(&cred->cr_label); 2132 obj = SLOT(label); 2133 2134 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2135 if (!mac_biba_dominate_single(obj, subj)) 2136 return (EACCES); 2137 } 2138 if (prot & VM_PROT_WRITE) { 2139 if (!mac_biba_dominate_single(subj, obj)) 2140 return (EACCES); 2141 } 2142 2143 return (0); 2144} 2145 2146static int 2147mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2148 struct label *vnodelabel, int acc_mode) 2149{ 2150 struct mac_biba *subj, *obj; 2151 2152 if (!mac_biba_enabled) 2153 return (0); 2154 2155 subj = SLOT(&cred->cr_label); 2156 obj = SLOT(vnodelabel); 2157 2158 /* XXX privilege override for admin? */ 2159 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2160 if (!mac_biba_dominate_single(obj, subj)) 2161 return (EACCES); 2162 } 2163 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2164 if (!mac_biba_dominate_single(subj, obj)) 2165 return (EACCES); 2166 } 2167 2168 return (0); 2169} 2170 2171static int 2172mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2173 struct vnode *vp, struct label *label) 2174{ 2175 struct mac_biba *subj, *obj; 2176 2177 if (!mac_biba_enabled || !revocation_enabled) 2178 return (0); 2179 2180 subj = SLOT(&active_cred->cr_label); 2181 obj = SLOT(label); 2182 2183 if (!mac_biba_dominate_single(obj, subj)) 2184 return (EACCES); 2185 2186 return (0); 2187} 2188 2189static int 2190mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2191 struct vnode *vp, struct label *label) 2192{ 2193 struct mac_biba *subj, *obj; 2194 2195 if (!mac_biba_enabled || !revocation_enabled) 2196 return (0); 2197 2198 subj = SLOT(&active_cred->cr_label); 2199 obj = SLOT(label); 2200 2201 if (!mac_biba_dominate_single(obj, subj)) 2202 return (EACCES); 2203 2204 return (0); 2205} 2206 2207static int 2208mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2209 struct label *dlabel) 2210{ 2211 struct mac_biba *subj, *obj; 2212 2213 if (!mac_biba_enabled) 2214 return (0); 2215 2216 subj = SLOT(&cred->cr_label); 2217 obj = SLOT(dlabel); 2218 2219 if (!mac_biba_dominate_single(obj, subj)) 2220 return (EACCES); 2221 2222 return (0); 2223} 2224 2225static int 2226mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2227 struct label *label) 2228{ 2229 struct mac_biba *subj, *obj; 2230 2231 if (!mac_biba_enabled) 2232 return (0); 2233 2234 subj = SLOT(&cred->cr_label); 2235 obj = SLOT(label); 2236 2237 if (!mac_biba_dominate_single(obj, subj)) 2238 return (EACCES); 2239 2240 return (0); 2241} 2242 2243static int 2244mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2245 struct label *vnodelabel, struct label *newlabel) 2246{ 2247 struct mac_biba *old, *new, *subj; 2248 int error; 2249 2250 old = SLOT(vnodelabel); 2251 new = SLOT(newlabel); 2252 subj = SLOT(&cred->cr_label); 2253 2254 /* 2255 * If there is a Biba label update for the vnode, it must be a 2256 * single label. 2257 */ 2258 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2259 if (error) 2260 return (error); 2261 2262 /* 2263 * To perform a relabel of the vnode (Biba label or not), Biba must 2264 * authorize the relabel. 2265 */ 2266 if (!mac_biba_single_in_range(old, subj)) 2267 return (EPERM); 2268 2269 /* 2270 * If the Biba label is to be changed, authorize as appropriate. 2271 */ 2272 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2273 /* 2274 * To change the Biba label on a vnode, the new vnode label 2275 * must be in the subject range. 2276 */ 2277 if (!mac_biba_single_in_range(new, subj)) 2278 return (EPERM); 2279 2280 /* 2281 * To change the Biba label on the vnode to be EQUAL, 2282 * the subject must have appropriate privilege. 2283 */ 2284 if (mac_biba_contains_equal(new)) { 2285 error = mac_biba_subject_privileged(subj); 2286 if (error) 2287 return (error); 2288 } 2289 } 2290 2291 return (0); 2292} 2293 2294static int 2295mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2296 struct label *dlabel, struct vnode *vp, struct label *label, 2297 struct componentname *cnp) 2298{ 2299 struct mac_biba *subj, *obj; 2300 2301 if (!mac_biba_enabled) 2302 return (0); 2303 2304 subj = SLOT(&cred->cr_label); 2305 obj = SLOT(dlabel); 2306 2307 if (!mac_biba_dominate_single(subj, obj)) 2308 return (EACCES); 2309 2310 obj = SLOT(label); 2311 2312 if (!mac_biba_dominate_single(subj, obj)) 2313 return (EACCES); 2314 2315 return (0); 2316} 2317 2318static int 2319mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2320 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2321 struct componentname *cnp) 2322{ 2323 struct mac_biba *subj, *obj; 2324 2325 if (!mac_biba_enabled) 2326 return (0); 2327 2328 subj = SLOT(&cred->cr_label); 2329 obj = SLOT(dlabel); 2330 2331 if (!mac_biba_dominate_single(subj, obj)) 2332 return (EACCES); 2333 2334 if (vp != NULL) { 2335 obj = SLOT(label); 2336 2337 if (!mac_biba_dominate_single(subj, obj)) 2338 return (EACCES); 2339 } 2340 2341 return (0); 2342} 2343 2344static int 2345mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2346 struct label *label) 2347{ 2348 struct mac_biba *subj, *obj; 2349 2350 if (!mac_biba_enabled) 2351 return (0); 2352 2353 subj = SLOT(&cred->cr_label); 2354 obj = SLOT(label); 2355 2356 if (!mac_biba_dominate_single(subj, obj)) 2357 return (EACCES); 2358 2359 return (0); 2360} 2361 2362static int 2363mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2364 struct label *label, acl_type_t type, struct acl *acl) 2365{ 2366 struct mac_biba *subj, *obj; 2367 2368 if (!mac_biba_enabled) 2369 return (0); 2370 2371 subj = SLOT(&cred->cr_label); 2372 obj = SLOT(label); 2373 2374 if (!mac_biba_dominate_single(subj, obj)) 2375 return (EACCES); 2376 2377 return (0); 2378} 2379 2380static int 2381mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2382 struct label *vnodelabel, int attrnamespace, const char *name, 2383 struct uio *uio) 2384{ 2385 struct mac_biba *subj, *obj; 2386 2387 if (!mac_biba_enabled) 2388 return (0); 2389 2390 subj = SLOT(&cred->cr_label); 2391 obj = SLOT(vnodelabel); 2392 2393 if (!mac_biba_dominate_single(subj, obj)) 2394 return (EACCES); 2395 2396 /* XXX: protect the MAC EA in a special way? */ 2397 2398 return (0); 2399} 2400 2401static int 2402mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2403 struct label *vnodelabel, u_long flags) 2404{ 2405 struct mac_biba *subj, *obj; 2406 2407 if (!mac_biba_enabled) 2408 return (0); 2409 2410 subj = SLOT(&cred->cr_label); 2411 obj = SLOT(vnodelabel); 2412 2413 if (!mac_biba_dominate_single(subj, obj)) 2414 return (EACCES); 2415 2416 return (0); 2417} 2418 2419static int 2420mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2421 struct label *vnodelabel, mode_t mode) 2422{ 2423 struct mac_biba *subj, *obj; 2424 2425 if (!mac_biba_enabled) 2426 return (0); 2427 2428 subj = SLOT(&cred->cr_label); 2429 obj = SLOT(vnodelabel); 2430 2431 if (!mac_biba_dominate_single(subj, obj)) 2432 return (EACCES); 2433 2434 return (0); 2435} 2436 2437static int 2438mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2439 struct label *vnodelabel, uid_t uid, gid_t gid) 2440{ 2441 struct mac_biba *subj, *obj; 2442 2443 if (!mac_biba_enabled) 2444 return (0); 2445 2446 subj = SLOT(&cred->cr_label); 2447 obj = SLOT(vnodelabel); 2448 2449 if (!mac_biba_dominate_single(subj, obj)) 2450 return (EACCES); 2451 2452 return (0); 2453} 2454 2455static int 2456mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2457 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2458{ 2459 struct mac_biba *subj, *obj; 2460 2461 if (!mac_biba_enabled) 2462 return (0); 2463 2464 subj = SLOT(&cred->cr_label); 2465 obj = SLOT(vnodelabel); 2466 2467 if (!mac_biba_dominate_single(subj, obj)) 2468 return (EACCES); 2469 2470 return (0); 2471} 2472 2473static int 2474mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2475 struct vnode *vp, struct label *vnodelabel) 2476{ 2477 struct mac_biba *subj, *obj; 2478 2479 if (!mac_biba_enabled) 2480 return (0); 2481 2482 subj = SLOT(&active_cred->cr_label); 2483 obj = SLOT(vnodelabel); 2484 2485 if (!mac_biba_dominate_single(obj, subj)) 2486 return (EACCES); 2487 2488 return (0); 2489} 2490 2491static int 2492mac_biba_check_vnode_write(struct ucred *active_cred, 2493 struct ucred *file_cred, struct vnode *vp, struct label *label) 2494{ 2495 struct mac_biba *subj, *obj; 2496 2497 if (!mac_biba_enabled || !revocation_enabled) 2498 return (0); 2499 2500 subj = SLOT(&active_cred->cr_label); 2501 obj = SLOT(label); 2502 2503 if (!mac_biba_dominate_single(subj, obj)) 2504 return (EACCES); 2505 2506 return (0); 2507} 2508 2509static struct mac_policy_ops mac_biba_ops = 2510{ 2511 .mpo_destroy = mac_biba_destroy, 2512 .mpo_init = mac_biba_init, 2513 .mpo_init_bpfdesc_label = mac_biba_init_label, 2514 .mpo_init_cred_label = mac_biba_init_label, 2515 .mpo_init_devfsdirent_label = mac_biba_init_label, 2516 .mpo_init_ifnet_label = mac_biba_init_label, 2517 .mpo_init_ipq_label = mac_biba_init_label, 2518 .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2519 .mpo_init_mount_label = mac_biba_init_label, 2520 .mpo_init_mount_fs_label = mac_biba_init_label, 2521 .mpo_init_pipe_label = mac_biba_init_label, 2522 .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2523 .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2524 .mpo_init_vnode_label = mac_biba_init_label, 2525 .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2526 .mpo_destroy_cred_label = mac_biba_destroy_label, 2527 .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2528 .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2529 .mpo_destroy_ipq_label = mac_biba_destroy_label, 2530 .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2531 .mpo_destroy_mount_label = mac_biba_destroy_label, 2532 .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2533 .mpo_destroy_pipe_label = mac_biba_destroy_label, 2534 .mpo_destroy_socket_label = mac_biba_destroy_label, 2535 .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2536 .mpo_destroy_vnode_label = mac_biba_destroy_label, 2537 .mpo_copy_pipe_label = mac_biba_copy_label, 2538 .mpo_copy_vnode_label = mac_biba_copy_label, 2539 .mpo_externalize_cred_label = mac_biba_externalize_label, 2540 .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2541 .mpo_externalize_pipe_label = mac_biba_externalize_label, 2542 .mpo_externalize_socket_label = mac_biba_externalize_label, 2543 .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2544 .mpo_externalize_vnode_label = mac_biba_externalize_label, 2545 .mpo_internalize_cred_label = mac_biba_internalize_label, 2546 .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2547 .mpo_internalize_pipe_label = mac_biba_internalize_label, 2548 .mpo_internalize_socket_label = mac_biba_internalize_label, 2549 .mpo_internalize_vnode_label = mac_biba_internalize_label, 2550 .mpo_create_devfs_device = mac_biba_create_devfs_device, 2551 .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2552 .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2553 .mpo_create_devfs_vnode = mac_biba_create_devfs_vnode, 2554 .mpo_create_mount = mac_biba_create_mount, 2555 .mpo_create_root_mount = mac_biba_create_root_mount, 2556 .mpo_relabel_vnode = mac_biba_relabel_vnode, 2557 .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2558 .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2559 .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2560 .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2561 .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2562 .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2563 .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2564 .mpo_create_pipe = mac_biba_create_pipe, 2565 .mpo_create_socket = mac_biba_create_socket, 2566 .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2567 .mpo_relabel_pipe = mac_biba_relabel_pipe, 2568 .mpo_relabel_socket = mac_biba_relabel_socket, 2569 .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2570 .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2571 .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2572 .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2573 .mpo_create_fragment = mac_biba_create_fragment, 2574 .mpo_create_ifnet = mac_biba_create_ifnet, 2575 .mpo_create_ipq = mac_biba_create_ipq, 2576 .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2577 .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2578 .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2579 .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2580 .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2581 .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2582 .mpo_fragment_match = mac_biba_fragment_match, 2583 .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2584 .mpo_update_ipq = mac_biba_update_ipq, 2585 .mpo_create_cred = mac_biba_create_cred, 2586 .mpo_execve_transition = mac_biba_execve_transition, 2587 .mpo_execve_will_transition = mac_biba_execve_will_transition, 2588 .mpo_create_proc0 = mac_biba_create_proc0, 2589 .mpo_create_proc1 = mac_biba_create_proc1, 2590 .mpo_relabel_cred = mac_biba_relabel_cred, 2591 .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2592 .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2593 .mpo_check_cred_visible = mac_biba_check_cred_visible, 2594 .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2595 .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2596 .mpo_check_mount_stat = mac_biba_check_mount_stat, 2597 .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2598 .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2599 .mpo_check_pipe_read = mac_biba_check_pipe_read, 2600 .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2601 .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2602 .mpo_check_pipe_write = mac_biba_check_pipe_write, 2603 .mpo_check_proc_debug = mac_biba_check_proc_debug, 2604 .mpo_check_proc_sched = mac_biba_check_proc_sched, 2605 .mpo_check_proc_signal = mac_biba_check_proc_signal, 2606 .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2607 .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2608 .mpo_check_socket_visible = mac_biba_check_socket_visible, 2609 .mpo_check_system_swapon = mac_biba_check_system_swapon, 2610 .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2611 .mpo_check_vnode_access = mac_biba_check_vnode_open, 2612 .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2613 .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2614 .mpo_check_vnode_create = mac_biba_check_vnode_create, 2615 .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2616 .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2617 .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2618 .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2619 .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2620 .mpo_check_vnode_link = mac_biba_check_vnode_link, 2621 .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2622 .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2623 .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2624 .mpo_check_vnode_open = mac_biba_check_vnode_open, 2625 .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2626 .mpo_check_vnode_read = mac_biba_check_vnode_read, 2627 .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2628 .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2629 .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2630 .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2631 .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2632 .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2633 .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2634 .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2635 .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2636 .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2637 .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2638 .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2639 .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2640 .mpo_check_vnode_write = mac_biba_check_vnode_write, 2641}; 2642 2643MAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2644 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot); 2645