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