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 NAI Labs, 9 * the Security Research Division of Network Associates, Inc. under 10 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 11 * CHATS research program. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. The names of the authors may not be used to endorse or promote 22 * products derived from this software without specific prior written 23 * permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * $FreeBSD$ 38 */ 39 40 /* 41 * Developed by the TrustedBSD Project. 42 * Biba fixed label mandatory integrity policy. 43 */ 44 45 #include <sys/types.h> 46 #include <sys/param.h> 47 #include <sys/acl.h> 48 #include <sys/conf.h> 49 #include <sys/kernel.h> 50 #include <sys/mac.h> 51 #include <sys/malloc.h> 52 #include <sys/mount.h> 53 #include <sys/proc.h> 54 #include <sys/systm.h> 55 #include <sys/sysproto.h> 56 #include <sys/sysent.h> 57 #include <sys/systm.h> 58 #include <sys/vnode.h> 59 #include <sys/file.h> 60 #include <sys/socket.h> 61 #include <sys/socketvar.h> 62 #include <sys/pipe.h> 63 #include <sys/sysctl.h> 64 65 #include <fs/devfs/devfs.h> 66 67 #include <net/bpfdesc.h> 68 #include <net/if.h> 69 #include <net/if_types.h> 70 #include <net/if_var.h> 71 72 #include <netinet/in.h> 73 #include <netinet/ip_var.h> 74 75 #include <vm/vm.h> 76 77 #include <sys/mac_policy.h> 78 79 #include <security/mac_biba/mac_biba.h> 80 81 SYSCTL_DECL(_security_mac); 82 83 SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 84 "TrustedBSD mac_biba policy controls"); 85 86 static int mac_biba_enabled = 0; 87 SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 88 &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 89 TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 90 91 static int destroyed_not_inited; 92 SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 93 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 94 95 static int trust_all_interfaces = 0; 96 SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 97 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 98 TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 99 100 static char trusted_interfaces[128]; 101 SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 102 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 103 TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 104 sizeof(trusted_interfaces)); 105 106 static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 107 SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 108 &max_compartments, 0, "Maximum supported compartments"); 109 110 static int ptys_equal = 0; 111 SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 112 &ptys_equal, 0, "Label pty devices as biba/equal on create"); 113 TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 114 115 static int revocation_enabled = 0; 116 SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 117 &revocation_enabled, 0, "Revoke access to objects on relabel"); 118 TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 119 120 static int mac_biba_slot; 121 #define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 122 123 MALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels"); 124 125 static __inline int 126 biba_bit_set_empty(u_char *set) { 127 int i; 128 129 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 130 if (set[i] != 0) 131 return (0); 132 return (1); 133 } 134 135 static struct mac_biba * 136 biba_alloc(int flag) 137 { 138 struct mac_biba *mac_biba; 139 140 mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag); 141 142 return (mac_biba); 143 } 144 145 static void 146 biba_free(struct mac_biba *mac_biba) 147 { 148 149 if (mac_biba != NULL) 150 free(mac_biba, M_MACBIBA); 151 else 152 atomic_add_int(&destroyed_not_inited, 1); 153 } 154 155 static int 156 biba_atmostflags(struct mac_biba *mac_biba, int flags) 157 { 158 159 if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 160 return (EINVAL); 161 return (0); 162 } 163 164 static int 165 mac_biba_dominate_element(struct mac_biba_element *a, 166 struct mac_biba_element *b) 167 { 168 int bit; 169 170 switch (a->mbe_type) { 171 case MAC_BIBA_TYPE_EQUAL: 172 case MAC_BIBA_TYPE_HIGH: 173 return (1); 174 175 case MAC_BIBA_TYPE_LOW: 176 switch (b->mbe_type) { 177 case MAC_BIBA_TYPE_GRADE: 178 case MAC_BIBA_TYPE_HIGH: 179 return (0); 180 181 case MAC_BIBA_TYPE_EQUAL: 182 case MAC_BIBA_TYPE_LOW: 183 return (1); 184 185 default: 186 panic("mac_biba_dominate_element: b->mbe_type invalid"); 187 } 188 189 case MAC_BIBA_TYPE_GRADE: 190 switch (b->mbe_type) { 191 case MAC_BIBA_TYPE_EQUAL: 192 case MAC_BIBA_TYPE_LOW: 193 return (1); 194 195 case MAC_BIBA_TYPE_HIGH: 196 return (0); 197 198 case MAC_BIBA_TYPE_GRADE: 199 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 200 if (!MAC_BIBA_BIT_TEST(bit, 201 a->mbe_compartments) && 202 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 203 return (0); 204 return (a->mbe_grade >= b->mbe_grade); 205 206 default: 207 panic("mac_biba_dominate_element: b->mbe_type invalid"); 208 } 209 210 default: 211 panic("mac_biba_dominate_element: a->mbe_type invalid"); 212 } 213 214 return (0); 215 } 216 217 static int 218 mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 219 { 220 221 return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 222 &rangea->mb_rangehigh) && 223 mac_biba_dominate_element(&rangea->mb_rangelow, 224 &rangeb->mb_rangelow)); 225 } 226 227 static int 228 mac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range) 229 { 230 231 KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 232 ("mac_biba_single_in_range: a not single")); 233 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 234 ("mac_biba_single_in_range: b not range")); 235 236 return (mac_biba_dominate_element(&range->mb_rangehigh, 237 &single->mb_single) && 238 mac_biba_dominate_element(&single->mb_single, 239 &range->mb_rangelow)); 240 241 return (1); 242 } 243 244 static int 245 mac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b) 246 { 247 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 248 ("mac_biba_dominate_single: a not single")); 249 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 250 ("mac_biba_dominate_single: b not single")); 251 252 return (mac_biba_dominate_element(&a->mb_single, &b->mb_single)); 253 } 254 255 static int 256 mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 257 { 258 259 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 260 b->mbe_type == MAC_BIBA_TYPE_EQUAL) 261 return (1); 262 263 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 264 } 265 266 static int 267 mac_biba_equal_single(struct mac_biba *a, struct mac_biba *b) 268 { 269 270 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 271 ("mac_biba_equal_single: a not single")); 272 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 273 ("mac_biba_equal_single: b not single")); 274 275 return (mac_biba_equal_element(&a->mb_single, &b->mb_single)); 276 } 277 278 static int 279 mac_biba_contains_equal(struct mac_biba *mac_biba) 280 { 281 282 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) 283 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 284 return (1); 285 286 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 287 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 288 return (1); 289 if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 290 return (1); 291 } 292 293 return (0); 294 } 295 296 static int 297 mac_biba_subject_equal_ok(struct mac_biba *mac_biba) 298 { 299 300 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 301 MAC_BIBA_FLAGS_BOTH, 302 ("mac_biba_subject_equal_ok: subject doesn't have both labels")); 303 304 /* If the single is EQUAL, it's ok. */ 305 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 306 return (0); 307 308 /* If either range endpoint is EQUAL, it's ok. */ 309 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 310 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 311 return (0); 312 313 /* If the range is low-high, it's ok. */ 314 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 315 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 316 return (0); 317 318 /* It's not ok. */ 319 return (EPERM); 320 } 321 322 static int 323 mac_biba_valid(struct mac_biba *mac_biba) 324 { 325 326 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 327 switch (mac_biba->mb_single.mbe_type) { 328 case MAC_BIBA_TYPE_GRADE: 329 break; 330 331 case MAC_BIBA_TYPE_EQUAL: 332 case MAC_BIBA_TYPE_HIGH: 333 case MAC_BIBA_TYPE_LOW: 334 if (mac_biba->mb_single.mbe_grade != 0 || 335 !MAC_BIBA_BIT_SET_EMPTY( 336 mac_biba->mb_single.mbe_compartments)) 337 return (EINVAL); 338 break; 339 340 default: 341 return (EINVAL); 342 } 343 } else { 344 if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 345 return (EINVAL); 346 } 347 348 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 349 switch (mac_biba->mb_rangelow.mbe_type) { 350 case MAC_BIBA_TYPE_GRADE: 351 break; 352 353 case MAC_BIBA_TYPE_EQUAL: 354 case MAC_BIBA_TYPE_HIGH: 355 case MAC_BIBA_TYPE_LOW: 356 if (mac_biba->mb_rangelow.mbe_grade != 0 || 357 !MAC_BIBA_BIT_SET_EMPTY( 358 mac_biba->mb_rangelow.mbe_compartments)) 359 return (EINVAL); 360 break; 361 362 default: 363 return (EINVAL); 364 } 365 366 switch (mac_biba->mb_rangehigh.mbe_type) { 367 case MAC_BIBA_TYPE_GRADE: 368 break; 369 370 case MAC_BIBA_TYPE_EQUAL: 371 case MAC_BIBA_TYPE_HIGH: 372 case MAC_BIBA_TYPE_LOW: 373 if (mac_biba->mb_rangehigh.mbe_grade != 0 || 374 !MAC_BIBA_BIT_SET_EMPTY( 375 mac_biba->mb_rangehigh.mbe_compartments)) 376 return (EINVAL); 377 break; 378 379 default: 380 return (EINVAL); 381 } 382 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 383 &mac_biba->mb_rangelow)) 384 return (EINVAL); 385 } else { 386 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 387 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 388 return (EINVAL); 389 } 390 391 return (0); 392 } 393 394 static void 395 mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 396 u_short gradelow, u_char *compartmentslow, u_short typehigh, 397 u_short gradehigh, u_char *compartmentshigh) 398 { 399 400 mac_biba->mb_rangelow.mbe_type = typelow; 401 mac_biba->mb_rangelow.mbe_grade = gradelow; 402 if (compartmentslow != NULL) 403 memcpy(mac_biba->mb_rangelow.mbe_compartments, 404 compartmentslow, 405 sizeof(mac_biba->mb_rangelow.mbe_compartments)); 406 mac_biba->mb_rangehigh.mbe_type = typehigh; 407 mac_biba->mb_rangehigh.mbe_grade = gradehigh; 408 if (compartmentshigh != NULL) 409 memcpy(mac_biba->mb_rangehigh.mbe_compartments, 410 compartmentshigh, 411 sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 412 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 413 } 414 415 static void 416 mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 417 u_char *compartments) 418 { 419 420 mac_biba->mb_single.mbe_type = type; 421 mac_biba->mb_single.mbe_grade = grade; 422 if (compartments != NULL) 423 memcpy(mac_biba->mb_single.mbe_compartments, compartments, 424 sizeof(mac_biba->mb_single.mbe_compartments)); 425 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 426 } 427 428 static void 429 mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 430 { 431 432 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 433 ("mac_biba_copy_range: labelfrom not range")); 434 435 labelto->mb_rangelow = labelfrom->mb_rangelow; 436 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 437 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 438 } 439 440 static void 441 mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 442 { 443 444 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 445 ("mac_biba_copy_single: labelfrom not single")); 446 447 labelto->mb_single = labelfrom->mb_single; 448 labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 449 } 450 451 static void 452 mac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 453 { 454 455 if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 456 mac_biba_copy_single(source, dest); 457 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 458 mac_biba_copy_range(source, dest); 459 } 460 461 /* 462 * Policy module operations. 463 */ 464 static void 465 mac_biba_destroy(struct mac_policy_conf *conf) 466 { 467 468 } 469 470 static void 471 mac_biba_init(struct mac_policy_conf *conf) 472 { 473 474 } 475 476 /* 477 * Label operations. 478 */ 479 static void 480 mac_biba_init_label(struct label *label) 481 { 482 483 SLOT(label) = biba_alloc(M_WAITOK); 484 } 485 486 static int 487 mac_biba_init_label_waitcheck(struct label *label, int flag) 488 { 489 490 SLOT(label) = biba_alloc(flag); 491 if (SLOT(label) == NULL) 492 return (ENOMEM); 493 494 return (0); 495 } 496 497 static void 498 mac_biba_destroy_label(struct label *label) 499 { 500 501 biba_free(SLOT(label)); 502 SLOT(label) = NULL; 503 } 504 505 /* 506 * mac_biba_element_to_string() is basically an snprintf wrapper with 507 * the same properties as snprintf(). It returns the length it would 508 * have added to the string in the event the string is too short. 509 */ 510 static size_t 511 mac_biba_element_to_string(char *string, size_t size, 512 struct mac_biba_element *element) 513 { 514 int pos, bit = 1; 515 516 switch (element->mbe_type) { 517 case MAC_BIBA_TYPE_HIGH: 518 return (snprintf(string, size, "high")); 519 520 case MAC_BIBA_TYPE_LOW: 521 return (snprintf(string, size, "low")); 522 523 case MAC_BIBA_TYPE_EQUAL: 524 return (snprintf(string, size, "equal")); 525 526 case MAC_BIBA_TYPE_GRADE: 527 pos = snprintf(string, size, "%d:", element->mbe_grade); 528 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) { 529 if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments)) 530 pos += snprintf(string + pos, size - pos, 531 "%d+", bit); 532 } 533 if (string[pos - 1] == '+' || string[pos - 1] == ':') 534 string[--pos] = NULL; 535 return (pos); 536 537 default: 538 panic("mac_biba_element_to_string: invalid type (%d)", 539 element->mbe_type); 540 } 541 } 542 543 static int 544 mac_biba_to_string(char *string, size_t size, size_t *caller_len, 545 struct mac_biba *mac_biba) 546 { 547 size_t left, len; 548 char *curptr; 549 550 bzero(string, size); 551 curptr = string; 552 left = size; 553 554 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 555 len = mac_biba_element_to_string(curptr, left, 556 &mac_biba->mb_single); 557 if (len >= left) 558 return (EINVAL); 559 left -= len; 560 curptr += len; 561 } 562 563 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 564 len = snprintf(curptr, left, "("); 565 if (len >= left) 566 return (EINVAL); 567 left -= len; 568 curptr += len; 569 570 len = mac_biba_element_to_string(curptr, left, 571 &mac_biba->mb_rangelow); 572 if (len >= left) 573 return (EINVAL); 574 left -= len; 575 curptr += len; 576 577 len = snprintf(curptr, left, "-"); 578 if (len >= left) 579 return (EINVAL); 580 left -= len; 581 curptr += len; 582 583 len = mac_biba_element_to_string(curptr, left, 584 &mac_biba->mb_rangehigh); 585 if (len >= left) 586 return (EINVAL); 587 left -= len; 588 curptr += len; 589 590 len = snprintf(curptr, left, ")"); 591 if (len >= left) 592 return (EINVAL); 593 left -= len; 594 curptr += len; 595 } 596 597 *caller_len = strlen(string); 598 return (0); 599 } 600 601 static int 602 mac_biba_externalize_label(struct label *label, char *element_name, 603 char *element_data, size_t size, size_t *len, int *claimed) 604 { 605 struct mac_biba *mac_biba; 606 int error; 607 608 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 609 return (0); 610 611 (*claimed)++; 612 613 mac_biba = SLOT(label); 614 error = mac_biba_to_string(element_data, size, len, mac_biba); 615 if (error) 616 return (error); 617 618 *len = strlen(element_data); 619 return (0); 620 } 621 622 static int 623 mac_biba_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac) 624 { 625 struct mac_biba *mac_biba; 626 627 mac_biba = SLOT(label); 628 629 if (mac_biba == NULL) { 630 printf("mac_biba_externalize_vnode_oldmac: NULL pointer\n"); 631 return (0); 632 } 633 634 extmac->m_biba = *mac_biba; 635 636 return (0); 637 } 638 639 static int 640 mac_biba_parse_element(struct mac_biba_element *element, char *string) 641 { 642 643 if (strcmp(string, "high") == 0 || 644 strcmp(string, "hi") == 0) { 645 element->mbe_type = MAC_BIBA_TYPE_HIGH; 646 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 647 } else if (strcmp(string, "low") == 0 || 648 strcmp(string, "lo") == 0) { 649 element->mbe_type = MAC_BIBA_TYPE_LOW; 650 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 651 } else if (strcmp(string, "equal") == 0 || 652 strcmp(string, "eq") == 0) { 653 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 654 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 655 } else { 656 char *p0, *p1; 657 int d; 658 659 p0 = string; 660 d = strtol(p0, &p1, 10); 661 662 if (d < 0 || d > 65535) 663 return (EINVAL); 664 element->mbe_type = MAC_BIBA_TYPE_GRADE; 665 element->mbe_grade = d; 666 667 if (*p1 != ':') { 668 if (p1 == p0 || *p1 != '\0') 669 return (EINVAL); 670 else 671 return (0); 672 } 673 else 674 if (*(p1 + 1) == '\0') 675 return (0); 676 677 while ((p0 = ++p1)) { 678 d = strtol(p0, &p1, 10); 679 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS) 680 return (EINVAL); 681 682 MAC_BIBA_BIT_SET(d, element->mbe_compartments); 683 684 if (*p1 == '\0') 685 break; 686 if (p1 == p0 || *p1 != '+') 687 return (EINVAL); 688 } 689 } 690 691 return (0); 692 } 693 694 /* 695 * Note: destructively consumes the string, make a local copy before 696 * calling if that's a problem. 697 */ 698 static int 699 mac_biba_parse(struct mac_biba *mac_biba, char *string) 700 { 701 char *range, *rangeend, *rangehigh, *rangelow, *single; 702 int error; 703 704 /* Do we have a range? */ 705 single = string; 706 range = index(string, '('); 707 if (range == single) 708 single = NULL; 709 rangelow = rangehigh = NULL; 710 if (range != NULL) { 711 /* Nul terminate the end of the single string. */ 712 *range = '\0'; 713 range++; 714 rangelow = range; 715 rangehigh = index(rangelow, '-'); 716 if (rangehigh == NULL) 717 return (EINVAL); 718 rangehigh++; 719 if (*rangelow == '\0' || *rangehigh == '\0') 720 return (EINVAL); 721 rangeend = index(rangehigh, ')'); 722 if (rangeend == NULL) 723 return (EINVAL); 724 if (*(rangeend + 1) != '\0') 725 return (EINVAL); 726 /* Nul terminate the ends of the ranges. */ 727 *(rangehigh - 1) = '\0'; 728 *rangeend = '\0'; 729 } 730 KASSERT((rangelow != NULL && rangehigh != NULL) || 731 (rangelow == NULL && rangehigh == NULL), 732 ("mac_biba_internalize_label: range mismatch")); 733 734 bzero(mac_biba, sizeof(*mac_biba)); 735 if (single != NULL) { 736 error = mac_biba_parse_element(&mac_biba->mb_single, single); 737 if (error) 738 return (error); 739 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 740 } 741 742 if (rangelow != NULL) { 743 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 744 rangelow); 745 if (error) 746 return (error); 747 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 748 rangehigh); 749 if (error) 750 return (error); 751 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 752 } 753 754 error = mac_biba_valid(mac_biba); 755 if (error) 756 return (error); 757 758 return (0); 759 } 760 761 static int 762 mac_biba_internalize_label(struct label *label, char *element_name, 763 char *element_data, int *claimed) 764 { 765 struct mac_biba *mac_biba, mac_biba_temp; 766 int error; 767 768 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 769 return (0); 770 771 (*claimed)++; 772 773 error = mac_biba_parse(&mac_biba_temp, element_data); 774 if (error) 775 return (error); 776 777 mac_biba = SLOT(label); 778 *mac_biba = mac_biba_temp; 779 780 return (0); 781 } 782 783 static void 784 mac_biba_copy_label(struct label *src, struct label *dest) 785 { 786 787 *SLOT(dest) = *SLOT(src); 788 } 789 790 /* 791 * Labeling event operations: file system objects, and things that look 792 * a lot like file system objects. 793 */ 794 static void 795 mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 796 struct label *label) 797 { 798 struct mac_biba *mac_biba; 799 int biba_type; 800 801 mac_biba = SLOT(label); 802 if (strcmp(dev->si_name, "null") == 0 || 803 strcmp(dev->si_name, "zero") == 0 || 804 strcmp(dev->si_name, "random") == 0 || 805 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 806 biba_type = MAC_BIBA_TYPE_EQUAL; 807 else if (ptys_equal && 808 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 809 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 810 biba_type = MAC_BIBA_TYPE_EQUAL; 811 else 812 biba_type = MAC_BIBA_TYPE_HIGH; 813 mac_biba_set_single(mac_biba, biba_type, 0, NULL); 814 } 815 816 static void 817 mac_biba_create_devfs_directory(char *dirname, int dirnamelen, 818 struct devfs_dirent *devfs_dirent, struct label *label) 819 { 820 struct mac_biba *mac_biba; 821 822 mac_biba = SLOT(label); 823 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 824 } 825 826 static void 827 mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 828 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) 829 { 830 struct mac_biba *source, *dest; 831 832 source = SLOT(&cred->cr_label); 833 dest = SLOT(delabel); 834 835 mac_biba_copy_single(source, dest); 836 } 837 838 static void 839 mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 840 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 841 { 842 struct mac_biba *source, *dest; 843 844 source = SLOT(direntlabel); 845 dest = SLOT(vnodelabel); 846 mac_biba_copy_single(source, dest); 847 } 848 849 static void 850 mac_biba_create_vnode(struct ucred *cred, struct vnode *parent, 851 struct label *parentlabel, struct vnode *child, struct label *childlabel) 852 { 853 struct mac_biba *source, *dest; 854 855 source = SLOT(&cred->cr_label); 856 dest = SLOT(childlabel); 857 858 mac_biba_copy_single(source, dest); 859 } 860 861 static void 862 mac_biba_create_mount(struct ucred *cred, struct mount *mp, 863 struct label *mntlabel, struct label *fslabel) 864 { 865 struct mac_biba *source, *dest; 866 867 source = SLOT(&cred->cr_label); 868 dest = SLOT(mntlabel); 869 mac_biba_copy_single(source, dest); 870 dest = SLOT(fslabel); 871 mac_biba_copy_single(source, dest); 872 } 873 874 static void 875 mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 876 struct label *mntlabel, struct label *fslabel) 877 { 878 struct mac_biba *mac_biba; 879 880 /* Always mount root as high integrity. */ 881 mac_biba = SLOT(fslabel); 882 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 883 mac_biba = SLOT(mntlabel); 884 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 885 } 886 887 static void 888 mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 889 struct label *vnodelabel, struct label *label) 890 { 891 struct mac_biba *source, *dest; 892 893 source = SLOT(label); 894 dest = SLOT(vnodelabel); 895 896 mac_biba_copy(source, dest); 897 } 898 899 static void 900 mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent, 901 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 902 { 903 struct mac_biba *source, *dest; 904 905 source = SLOT(vnodelabel); 906 dest = SLOT(direntlabel); 907 908 mac_biba_copy(source, dest); 909 } 910 911 static void 912 mac_biba_update_procfsvnode(struct vnode *vp, struct label *vnodelabel, 913 struct ucred *cred) 914 { 915 struct mac_biba *source, *dest; 916 917 source = SLOT(&cred->cr_label); 918 dest = SLOT(vnodelabel); 919 920 /* 921 * Only copy the single, not the range, since vnodes only have 922 * a single. 923 */ 924 mac_biba_copy_single(source, dest); 925 } 926 927 static int 928 mac_biba_update_vnode_from_externalized(struct vnode *vp, 929 struct label *vnodelabel, struct oldmac *extmac) 930 { 931 struct mac_biba *source, *dest; 932 int error; 933 934 source = &extmac->m_biba; 935 dest = SLOT(vnodelabel); 936 937 error = mac_biba_valid(source); 938 if (error) 939 return (error); 940 941 if ((source->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) 942 return (EINVAL); 943 944 mac_biba_copy_single(source, dest); 945 946 return (0); 947 } 948 949 static void 950 mac_biba_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel, 951 struct mount *mp, struct label *fslabel) 952 { 953 struct mac_biba *source, *dest; 954 955 source = SLOT(fslabel); 956 dest = SLOT(vnodelabel); 957 958 mac_biba_copy_single(source, dest); 959 } 960 961 /* 962 * Labeling event operations: IPC object. 963 */ 964 static void 965 mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 966 struct mbuf *m, struct label *mbuflabel) 967 { 968 struct mac_biba *source, *dest; 969 970 source = SLOT(socketlabel); 971 dest = SLOT(mbuflabel); 972 973 mac_biba_copy_single(source, dest); 974 } 975 976 static void 977 mac_biba_create_socket(struct ucred *cred, struct socket *socket, 978 struct label *socketlabel) 979 { 980 struct mac_biba *source, *dest; 981 982 source = SLOT(&cred->cr_label); 983 dest = SLOT(socketlabel); 984 985 mac_biba_copy_single(source, dest); 986 } 987 988 static void 989 mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 990 struct label *pipelabel) 991 { 992 struct mac_biba *source, *dest; 993 994 source = SLOT(&cred->cr_label); 995 dest = SLOT(pipelabel); 996 997 mac_biba_copy_single(source, dest); 998 } 999 1000 static void 1001 mac_biba_create_socket_from_socket(struct socket *oldsocket, 1002 struct label *oldsocketlabel, struct socket *newsocket, 1003 struct label *newsocketlabel) 1004 { 1005 struct mac_biba *source, *dest; 1006 1007 source = SLOT(oldsocketlabel); 1008 dest = SLOT(newsocketlabel); 1009 1010 mac_biba_copy_single(source, dest); 1011 } 1012 1013 static void 1014 mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1015 struct label *socketlabel, struct label *newlabel) 1016 { 1017 struct mac_biba *source, *dest; 1018 1019 source = SLOT(newlabel); 1020 dest = SLOT(socketlabel); 1021 1022 mac_biba_copy(source, dest); 1023 } 1024 1025 static void 1026 mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1027 struct label *pipelabel, struct label *newlabel) 1028 { 1029 struct mac_biba *source, *dest; 1030 1031 source = SLOT(newlabel); 1032 dest = SLOT(pipelabel); 1033 1034 mac_biba_copy(source, dest); 1035 } 1036 1037 static void 1038 mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1039 struct socket *socket, struct label *socketpeerlabel) 1040 { 1041 struct mac_biba *source, *dest; 1042 1043 source = SLOT(mbuflabel); 1044 dest = SLOT(socketpeerlabel); 1045 1046 mac_biba_copy_single(source, dest); 1047 } 1048 1049 /* 1050 * Labeling event operations: network objects. 1051 */ 1052 static void 1053 mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1054 struct label *oldsocketlabel, struct socket *newsocket, 1055 struct label *newsocketpeerlabel) 1056 { 1057 struct mac_biba *source, *dest; 1058 1059 source = SLOT(oldsocketlabel); 1060 dest = SLOT(newsocketpeerlabel); 1061 1062 mac_biba_copy_single(source, dest); 1063 } 1064 1065 static void 1066 mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1067 struct label *bpflabel) 1068 { 1069 struct mac_biba *source, *dest; 1070 1071 source = SLOT(&cred->cr_label); 1072 dest = SLOT(bpflabel); 1073 1074 mac_biba_copy_single(source, dest); 1075 } 1076 1077 static void 1078 mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1079 { 1080 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1081 char tiflist[sizeof(trusted_interfaces)]; 1082 struct mac_biba *dest; 1083 int len, grade; 1084 1085 dest = SLOT(ifnetlabel); 1086 1087 if (ifnet->if_type == IFT_LOOP) { 1088 grade = MAC_BIBA_TYPE_EQUAL; 1089 goto set; 1090 } 1091 1092 if (trust_all_interfaces) { 1093 grade = MAC_BIBA_TYPE_HIGH; 1094 goto set; 1095 } 1096 1097 grade = MAC_BIBA_TYPE_LOW; 1098 1099 if (trusted_interfaces[0] == '\0' || 1100 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1101 goto set; 1102 1103 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1104 if(*p != ' ' && *p != '\t') 1105 *q = *p; 1106 1107 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1108 1109 for (p = q = tiflist;; p++) { 1110 if (*p == ',' || *p == '\0') { 1111 len = p - q; 1112 if (len < IFNAMSIZ) { 1113 bzero(tifname, sizeof(tifname)); 1114 bcopy(q, tifname, len); 1115 if (strcmp(tifname, ifname) == 0) { 1116 grade = MAC_BIBA_TYPE_HIGH; 1117 break; 1118 } 1119 } 1120 if (*p == '\0') 1121 break; 1122 q = p + 1; 1123 } 1124 } 1125 set: 1126 mac_biba_set_single(dest, grade, 0, NULL); 1127 mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL); 1128 } 1129 1130 static void 1131 mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1132 struct ipq *ipq, struct label *ipqlabel) 1133 { 1134 struct mac_biba *source, *dest; 1135 1136 source = SLOT(fragmentlabel); 1137 dest = SLOT(ipqlabel); 1138 1139 mac_biba_copy_single(source, dest); 1140 } 1141 1142 static void 1143 mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1144 struct mbuf *datagram, struct label *datagramlabel) 1145 { 1146 struct mac_biba *source, *dest; 1147 1148 source = SLOT(ipqlabel); 1149 dest = SLOT(datagramlabel); 1150 1151 /* Just use the head, since we require them all to match. */ 1152 mac_biba_copy_single(source, dest); 1153 } 1154 1155 static void 1156 mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1157 struct mbuf *fragment, struct label *fragmentlabel) 1158 { 1159 struct mac_biba *source, *dest; 1160 1161 source = SLOT(datagramlabel); 1162 dest = SLOT(fragmentlabel); 1163 1164 mac_biba_copy_single(source, dest); 1165 } 1166 1167 static void 1168 mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1169 struct label *oldmbuflabel, struct mbuf *newmbuf, 1170 struct label *newmbuflabel) 1171 { 1172 struct mac_biba *source, *dest; 1173 1174 source = SLOT(oldmbuflabel); 1175 dest = SLOT(newmbuflabel); 1176 1177 /* 1178 * Because the source mbuf may not yet have been "created", 1179 * just initialized, we do a conditional copy. Since we don't 1180 * allow mbufs to have ranges, do a KASSERT to make sure that 1181 * doesn't happen. 1182 */ 1183 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1184 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1185 mac_biba_copy(source, dest); 1186 } 1187 1188 static void 1189 mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1190 struct mbuf *mbuf, struct label *mbuflabel) 1191 { 1192 struct mac_biba *dest; 1193 1194 dest = SLOT(mbuflabel); 1195 1196 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1197 } 1198 1199 static void 1200 mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1201 struct mbuf *mbuf, struct label *mbuflabel) 1202 { 1203 struct mac_biba *source, *dest; 1204 1205 source = SLOT(bpflabel); 1206 dest = SLOT(mbuflabel); 1207 1208 mac_biba_copy_single(source, dest); 1209 } 1210 1211 static void 1212 mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1213 struct mbuf *m, struct label *mbuflabel) 1214 { 1215 struct mac_biba *source, *dest; 1216 1217 source = SLOT(ifnetlabel); 1218 dest = SLOT(mbuflabel); 1219 1220 mac_biba_copy_single(source, dest); 1221 } 1222 1223 static void 1224 mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1225 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1226 struct mbuf *newmbuf, struct label *newmbuflabel) 1227 { 1228 struct mac_biba *source, *dest; 1229 1230 source = SLOT(oldmbuflabel); 1231 dest = SLOT(newmbuflabel); 1232 1233 mac_biba_copy_single(source, dest); 1234 } 1235 1236 static void 1237 mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1238 struct mbuf *newmbuf, struct label *newmbuflabel) 1239 { 1240 struct mac_biba *source, *dest; 1241 1242 source = SLOT(oldmbuflabel); 1243 dest = SLOT(newmbuflabel); 1244 1245 mac_biba_copy_single(source, dest); 1246 } 1247 1248 static int 1249 mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1250 struct ipq *ipq, struct label *ipqlabel) 1251 { 1252 struct mac_biba *a, *b; 1253 1254 a = SLOT(ipqlabel); 1255 b = SLOT(fragmentlabel); 1256 1257 return (mac_biba_equal_single(a, b)); 1258 } 1259 1260 static void 1261 mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1262 struct label *ifnetlabel, struct label *newlabel) 1263 { 1264 struct mac_biba *source, *dest; 1265 1266 source = SLOT(newlabel); 1267 dest = SLOT(ifnetlabel); 1268 1269 mac_biba_copy(source, dest); 1270 } 1271 1272 static void 1273 mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1274 struct ipq *ipq, struct label *ipqlabel) 1275 { 1276 1277 /* NOOP: we only accept matching labels, so no need to update */ 1278 } 1279 1280 /* 1281 * Labeling event operations: processes. 1282 */ 1283 static void 1284 mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1285 { 1286 struct mac_biba *source, *dest; 1287 1288 source = SLOT(&cred_parent->cr_label); 1289 dest = SLOT(&cred_child->cr_label); 1290 1291 mac_biba_copy_single(source, dest); 1292 mac_biba_copy_range(source, dest); 1293 } 1294 1295 static void 1296 mac_biba_execve_transition(struct ucred *old, struct ucred *new, 1297 struct vnode *vp, struct mac *vnodelabel) 1298 { 1299 struct mac_biba *source, *dest; 1300 1301 source = SLOT(&old->cr_label); 1302 dest = SLOT(&new->cr_label); 1303 1304 mac_biba_copy_single(source, dest); 1305 mac_biba_copy_range(source, dest); 1306 } 1307 1308 static int 1309 mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp, 1310 struct mac *vnodelabel) 1311 { 1312 1313 return (0); 1314 } 1315 1316 static void 1317 mac_biba_create_proc0(struct ucred *cred) 1318 { 1319 struct mac_biba *dest; 1320 1321 dest = SLOT(&cred->cr_label); 1322 1323 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1324 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1325 MAC_BIBA_TYPE_HIGH, 0, NULL); 1326 } 1327 1328 static void 1329 mac_biba_create_proc1(struct ucred *cred) 1330 { 1331 struct mac_biba *dest; 1332 1333 dest = SLOT(&cred->cr_label); 1334 1335 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1336 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1337 MAC_BIBA_TYPE_HIGH, 0, NULL); 1338 } 1339 1340 static void 1341 mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1342 { 1343 struct mac_biba *source, *dest; 1344 1345 source = SLOT(newlabel); 1346 dest = SLOT(&cred->cr_label); 1347 1348 mac_biba_copy(source, dest); 1349 } 1350 1351 /* 1352 * Access control checks. 1353 */ 1354 static int 1355 mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1356 struct ifnet *ifnet, struct label *ifnetlabel) 1357 { 1358 struct mac_biba *a, *b; 1359 1360 if (!mac_biba_enabled) 1361 return (0); 1362 1363 a = SLOT(bpflabel); 1364 b = SLOT(ifnetlabel); 1365 1366 if (mac_biba_equal_single(a, b)) 1367 return (0); 1368 return (EACCES); 1369 } 1370 1371 static int 1372 mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1373 { 1374 struct mac_biba *subj, *new; 1375 int error; 1376 1377 subj = SLOT(&cred->cr_label); 1378 new = SLOT(newlabel); 1379 1380 /* 1381 * If there is a Biba label update for the credential, it may 1382 * be an update of the single, range, or both. 1383 */ 1384 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1385 if (error) 1386 return (error); 1387 1388 /* 1389 * If the Biba label is to be changed, authorize as appropriate. 1390 */ 1391 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1392 /* 1393 * To change the Biba single label on a credential, the 1394 * new single label must be in the current range. 1395 */ 1396 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1397 !mac_biba_single_in_range(new, subj)) 1398 return (EPERM); 1399 1400 /* 1401 * To change the Biba range on a credential, the new 1402 * range label must be in the current range. 1403 */ 1404 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1405 !mac_biba_range_in_range(new, subj)) 1406 return (EPERM); 1407 1408 /* 1409 * To have EQUAL in any component of the new credential 1410 * Biba label, the subject must already have EQUAL in 1411 * their label. 1412 */ 1413 if (mac_biba_contains_equal(new)) { 1414 error = mac_biba_subject_equal_ok(subj); 1415 if (error) 1416 return (error); 1417 } 1418 1419 /* 1420 * XXXMAC: Additional consistency tests regarding the 1421 * single and range of the new label might be performed 1422 * here. 1423 */ 1424 } 1425 1426 return (0); 1427 } 1428 1429 static int 1430 mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1431 { 1432 struct mac_biba *subj, *obj; 1433 1434 if (!mac_biba_enabled) 1435 return (0); 1436 1437 subj = SLOT(&u1->cr_label); 1438 obj = SLOT(&u2->cr_label); 1439 1440 /* XXX: range */ 1441 if (!mac_biba_dominate_single(obj, subj)) 1442 return (ESRCH); 1443 1444 return (0); 1445 } 1446 1447 static int 1448 mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1449 struct label *ifnetlabel, struct label *newlabel) 1450 { 1451 struct mac_biba *subj, *new; 1452 int error; 1453 1454 subj = SLOT(&cred->cr_label); 1455 new = SLOT(newlabel); 1456 1457 /* 1458 * If there is a Biba label update for the interface, it may 1459 * be an update of the single, range, or both. 1460 */ 1461 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1462 if (error) 1463 return (error); 1464 1465 /* 1466 * If the Biba label is to be changed, authorize as appropriate. 1467 */ 1468 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1469 /* 1470 * Rely on the traditional superuser status for the Biba 1471 * interface relabel requirements. XXXMAC: This will go 1472 * away. 1473 */ 1474 error = suser_cred(cred, 0); 1475 if (error) 1476 return (EPERM); 1477 1478 /* 1479 * XXXMAC: Additional consistency tests regarding the single 1480 * and the range of the new label might be performed here. 1481 */ 1482 } 1483 1484 return (0); 1485 } 1486 1487 static int 1488 mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1489 struct mbuf *m, struct label *mbuflabel) 1490 { 1491 struct mac_biba *p, *i; 1492 1493 if (!mac_biba_enabled) 1494 return (0); 1495 1496 p = SLOT(mbuflabel); 1497 i = SLOT(ifnetlabel); 1498 1499 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1500 } 1501 1502 static int 1503 mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1504 struct label *mntlabel) 1505 { 1506 struct mac_biba *subj, *obj; 1507 1508 if (!mac_biba_enabled) 1509 return (0); 1510 1511 subj = SLOT(&cred->cr_label); 1512 obj = SLOT(mntlabel); 1513 1514 if (!mac_biba_dominate_single(obj, subj)) 1515 return (EACCES); 1516 1517 return (0); 1518 } 1519 1520 static int 1521 mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1522 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1523 { 1524 1525 if(!mac_biba_enabled) 1526 return (0); 1527 1528 /* XXX: This will be implemented soon... */ 1529 1530 return (0); 1531 } 1532 1533 static int 1534 mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1535 struct label *pipelabel) 1536 { 1537 struct mac_biba *subj, *obj; 1538 1539 if (!mac_biba_enabled) 1540 return (0); 1541 1542 subj = SLOT(&cred->cr_label); 1543 obj = SLOT((pipelabel)); 1544 1545 if (!mac_biba_dominate_single(obj, subj)) 1546 return (EACCES); 1547 1548 return (0); 1549 } 1550 1551 static int 1552 mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1553 struct label *pipelabel) 1554 { 1555 struct mac_biba *subj, *obj; 1556 1557 if (!mac_biba_enabled) 1558 return (0); 1559 1560 subj = SLOT(&cred->cr_label); 1561 obj = SLOT((pipelabel)); 1562 1563 if (!mac_biba_dominate_single(obj, subj)) 1564 return (EACCES); 1565 1566 return (0); 1567 } 1568 1569 static int 1570 mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1571 struct label *pipelabel, struct label *newlabel) 1572 { 1573 struct mac_biba *subj, *obj, *new; 1574 int error; 1575 1576 new = SLOT(newlabel); 1577 subj = SLOT(&cred->cr_label); 1578 obj = SLOT(pipelabel); 1579 1580 /* 1581 * If there is a Biba label update for a pipe, it must be a 1582 * single update. 1583 */ 1584 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1585 if (error) 1586 return (error); 1587 1588 /* 1589 * To perform a relabel of a pipe (Biba label or not), Biba must 1590 * authorize the relabel. 1591 */ 1592 if (!mac_biba_single_in_range(obj, subj)) 1593 return (EPERM); 1594 1595 /* 1596 * If the Biba label is to be changed, authorize as appropriate. 1597 */ 1598 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1599 /* 1600 * To change the Biba label on a pipe, the new pipe label 1601 * must be in the subject range. 1602 */ 1603 if (!mac_biba_single_in_range(new, subj)) 1604 return (EPERM); 1605 1606 /* 1607 * To change the Biba label on a pipe to be EQUAL, the 1608 * subject must have appropriate privilege. 1609 */ 1610 if (mac_biba_contains_equal(new)) { 1611 error = mac_biba_subject_equal_ok(subj); 1612 if (error) 1613 return (error); 1614 } 1615 } 1616 1617 return (0); 1618 } 1619 1620 static int 1621 mac_biba_check_pipe_stat(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 1638 static int 1639 mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1640 struct label *pipelabel) 1641 { 1642 struct mac_biba *subj, *obj; 1643 1644 if (!mac_biba_enabled) 1645 return (0); 1646 1647 subj = SLOT(&cred->cr_label); 1648 obj = SLOT((pipelabel)); 1649 1650 if (!mac_biba_dominate_single(subj, obj)) 1651 return (EACCES); 1652 1653 return (0); 1654 } 1655 1656 static int 1657 mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1658 { 1659 struct mac_biba *subj, *obj; 1660 1661 if (!mac_biba_enabled) 1662 return (0); 1663 1664 subj = SLOT(&cred->cr_label); 1665 obj = SLOT(&proc->p_ucred->cr_label); 1666 1667 /* XXX: range checks */ 1668 if (!mac_biba_dominate_single(obj, subj)) 1669 return (ESRCH); 1670 if (!mac_biba_dominate_single(subj, obj)) 1671 return (EACCES); 1672 1673 return (0); 1674 } 1675 1676 static int 1677 mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1678 { 1679 struct mac_biba *subj, *obj; 1680 1681 if (!mac_biba_enabled) 1682 return (0); 1683 1684 subj = SLOT(&cred->cr_label); 1685 obj = SLOT(&proc->p_ucred->cr_label); 1686 1687 /* XXX: range checks */ 1688 if (!mac_biba_dominate_single(obj, subj)) 1689 return (ESRCH); 1690 if (!mac_biba_dominate_single(subj, obj)) 1691 return (EACCES); 1692 1693 return (0); 1694 } 1695 1696 static int 1697 mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1698 { 1699 struct mac_biba *subj, *obj; 1700 1701 if (!mac_biba_enabled) 1702 return (0); 1703 1704 subj = SLOT(&cred->cr_label); 1705 obj = SLOT(&proc->p_ucred->cr_label); 1706 1707 /* XXX: range checks */ 1708 if (!mac_biba_dominate_single(obj, subj)) 1709 return (ESRCH); 1710 if (!mac_biba_dominate_single(subj, obj)) 1711 return (EACCES); 1712 1713 return (0); 1714 } 1715 1716 static int 1717 mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1718 struct mbuf *m, struct label *mbuflabel) 1719 { 1720 struct mac_biba *p, *s; 1721 1722 if (!mac_biba_enabled) 1723 return (0); 1724 1725 p = SLOT(mbuflabel); 1726 s = SLOT(socketlabel); 1727 1728 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1729 } 1730 1731 static int 1732 mac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket, 1733 struct label *socketlabel, struct label *newlabel) 1734 { 1735 struct mac_biba *subj, *obj, *new; 1736 int error; 1737 1738 new = SLOT(newlabel); 1739 subj = SLOT(&cred->cr_label); 1740 obj = SLOT(socketlabel); 1741 1742 /* 1743 * If there is a Biba label update for the socket, it may be 1744 * an update of single. 1745 */ 1746 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1747 if (error) 1748 return (error); 1749 1750 /* 1751 * To relabel a socket, the old socket single must be in the subject 1752 * range. 1753 */ 1754 if (!mac_biba_single_in_range(obj, subj)) 1755 return (EPERM); 1756 1757 /* 1758 * If the Biba label is to be changed, authorize as appropriate. 1759 */ 1760 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1761 /* 1762 * To relabel a socket, the new socket single must be in 1763 * the subject range. 1764 */ 1765 if (!mac_biba_single_in_range(new, subj)) 1766 return (EPERM); 1767 1768 /* 1769 * To change the Biba label on the socket to contain EQUAL, 1770 * the subject must have appropriate privilege. 1771 */ 1772 if (mac_biba_contains_equal(new)) { 1773 error = mac_biba_subject_equal_ok(subj); 1774 if (error) 1775 return (error); 1776 } 1777 } 1778 1779 return (0); 1780 } 1781 1782 static int 1783 mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1784 struct label *socketlabel) 1785 { 1786 struct mac_biba *subj, *obj; 1787 1788 if (!mac_biba_enabled) 1789 return (0); 1790 1791 subj = SLOT(&cred->cr_label); 1792 obj = SLOT(socketlabel); 1793 1794 if (!mac_biba_dominate_single(obj, subj)) 1795 return (ENOENT); 1796 1797 return (0); 1798 } 1799 1800 static int 1801 mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1802 struct label *dlabel) 1803 { 1804 struct mac_biba *subj, *obj; 1805 1806 if (!mac_biba_enabled) 1807 return (0); 1808 1809 subj = SLOT(&cred->cr_label); 1810 obj = SLOT(dlabel); 1811 1812 if (!mac_biba_dominate_single(obj, subj)) 1813 return (EACCES); 1814 1815 return (0); 1816 } 1817 1818 static int 1819 mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1820 struct label *dlabel) 1821 { 1822 struct mac_biba *subj, *obj; 1823 1824 if (!mac_biba_enabled) 1825 return (0); 1826 1827 subj = SLOT(&cred->cr_label); 1828 obj = SLOT(dlabel); 1829 1830 if (!mac_biba_dominate_single(obj, subj)) 1831 return (EACCES); 1832 1833 return (0); 1834 } 1835 1836 static int 1837 mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1838 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1839 { 1840 struct mac_biba *subj, *obj; 1841 1842 if (!mac_biba_enabled) 1843 return (0); 1844 1845 subj = SLOT(&cred->cr_label); 1846 obj = SLOT(dlabel); 1847 1848 if (!mac_biba_dominate_single(subj, obj)) 1849 return (EACCES); 1850 1851 return (0); 1852 } 1853 1854 static int 1855 mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1856 struct label *dlabel, struct vnode *vp, struct label *label, 1857 struct componentname *cnp) 1858 { 1859 struct mac_biba *subj, *obj; 1860 1861 if (!mac_biba_enabled) 1862 return (0); 1863 1864 subj = SLOT(&cred->cr_label); 1865 obj = SLOT(dlabel); 1866 1867 if (!mac_biba_dominate_single(subj, obj)) 1868 return (EACCES); 1869 1870 obj = SLOT(label); 1871 1872 if (!mac_biba_dominate_single(subj, obj)) 1873 return (EACCES); 1874 1875 return (0); 1876 } 1877 1878 static int 1879 mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1880 struct label *label, acl_type_t type) 1881 { 1882 struct mac_biba *subj, *obj; 1883 1884 if (!mac_biba_enabled) 1885 return (0); 1886 1887 subj = SLOT(&cred->cr_label); 1888 obj = SLOT(label); 1889 1890 if (!mac_biba_dominate_single(subj, obj)) 1891 return (EACCES); 1892 1893 return (0); 1894 } 1895 1896 static int 1897 mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1898 struct label *label) 1899 { 1900 struct mac_biba *subj, *obj; 1901 1902 if (!mac_biba_enabled) 1903 return (0); 1904 1905 subj = SLOT(&cred->cr_label); 1906 obj = SLOT(label); 1907 1908 if (!mac_biba_dominate_single(obj, subj)) 1909 return (EACCES); 1910 1911 return (0); 1912 } 1913 1914 static int 1915 mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 1916 struct label *label, acl_type_t type) 1917 { 1918 struct mac_biba *subj, *obj; 1919 1920 if (!mac_biba_enabled) 1921 return (0); 1922 1923 subj = SLOT(&cred->cr_label); 1924 obj = SLOT(label); 1925 1926 if (!mac_biba_dominate_single(obj, subj)) 1927 return (EACCES); 1928 1929 return (0); 1930 } 1931 1932 static int 1933 mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1934 struct label *label, int attrnamespace, const char *name, struct uio *uio) 1935 { 1936 struct mac_biba *subj, *obj; 1937 1938 if (!mac_biba_enabled) 1939 return (0); 1940 1941 subj = SLOT(&cred->cr_label); 1942 obj = SLOT(label); 1943 1944 if (!mac_biba_dominate_single(obj, subj)) 1945 return (EACCES); 1946 1947 return (0); 1948 } 1949 1950 static int 1951 mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1952 struct label *dlabel, struct vnode *vp, struct label *label, 1953 struct componentname *cnp) 1954 { 1955 struct mac_biba *subj, *obj; 1956 1957 if (!mac_biba_enabled) 1958 return (0); 1959 1960 subj = SLOT(&cred->cr_label); 1961 obj = SLOT(dlabel); 1962 1963 if (!mac_biba_dominate_single(subj, obj)) 1964 return (EACCES); 1965 1966 obj = SLOT(label); 1967 1968 if (!mac_biba_dominate_single(subj, obj)) 1969 return (EACCES); 1970 1971 return (0); 1972 } 1973 1974 static int 1975 mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1976 struct label *dlabel, struct componentname *cnp) 1977 { 1978 struct mac_biba *subj, *obj; 1979 1980 if (!mac_biba_enabled) 1981 return (0); 1982 1983 subj = SLOT(&cred->cr_label); 1984 obj = SLOT(dlabel); 1985 1986 if (!mac_biba_dominate_single(obj, subj)) 1987 return (EACCES); 1988 1989 return (0); 1990 } 1991 1992 static int 1993 mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 1994 struct label *label, int prot) 1995 { 1996 struct mac_biba *subj, *obj; 1997 1998 /* 1999 * Rely on the use of open()-time protections to handle 2000 * non-revocation cases. 2001 */ 2002 if (!mac_biba_enabled || !revocation_enabled) 2003 return (0); 2004 2005 subj = SLOT(&cred->cr_label); 2006 obj = SLOT(label); 2007 2008 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2009 if (!mac_biba_dominate_single(obj, subj)) 2010 return (EACCES); 2011 } 2012 if (prot & VM_PROT_WRITE) { 2013 if (!mac_biba_dominate_single(subj, obj)) 2014 return (EACCES); 2015 } 2016 2017 return (0); 2018 } 2019 2020 static int 2021 mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2022 struct label *vnodelabel, mode_t acc_mode) 2023 { 2024 struct mac_biba *subj, *obj; 2025 2026 if (!mac_biba_enabled) 2027 return (0); 2028 2029 subj = SLOT(&cred->cr_label); 2030 obj = SLOT(vnodelabel); 2031 2032 /* XXX privilege override for admin? */ 2033 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2034 if (!mac_biba_dominate_single(obj, subj)) 2035 return (EACCES); 2036 } 2037 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2038 if (!mac_biba_dominate_single(subj, obj)) 2039 return (EACCES); 2040 } 2041 2042 return (0); 2043 } 2044 2045 static int 2046 mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2047 struct vnode *vp, struct label *label) 2048 { 2049 struct mac_biba *subj, *obj; 2050 2051 if (!mac_biba_enabled || !revocation_enabled) 2052 return (0); 2053 2054 subj = SLOT(&active_cred->cr_label); 2055 obj = SLOT(label); 2056 2057 if (!mac_biba_dominate_single(obj, subj)) 2058 return (EACCES); 2059 2060 return (0); 2061 } 2062 2063 static int 2064 mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2065 struct vnode *vp, struct label *label) 2066 { 2067 struct mac_biba *subj, *obj; 2068 2069 if (!mac_biba_enabled || !revocation_enabled) 2070 return (0); 2071 2072 subj = SLOT(&active_cred->cr_label); 2073 obj = SLOT(label); 2074 2075 if (!mac_biba_dominate_single(obj, subj)) 2076 return (EACCES); 2077 2078 return (0); 2079 } 2080 2081 static int 2082 mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2083 struct label *dlabel) 2084 { 2085 struct mac_biba *subj, *obj; 2086 2087 if (!mac_biba_enabled) 2088 return (0); 2089 2090 subj = SLOT(&cred->cr_label); 2091 obj = SLOT(dlabel); 2092 2093 if (!mac_biba_dominate_single(obj, subj)) 2094 return (EACCES); 2095 2096 return (0); 2097 } 2098 2099 static int 2100 mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2101 struct label *label) 2102 { 2103 struct mac_biba *subj, *obj; 2104 2105 if (!mac_biba_enabled) 2106 return (0); 2107 2108 subj = SLOT(&cred->cr_label); 2109 obj = SLOT(label); 2110 2111 if (!mac_biba_dominate_single(obj, subj)) 2112 return (EACCES); 2113 2114 return (0); 2115 } 2116 2117 static int 2118 mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2119 struct label *vnodelabel, struct label *newlabel) 2120 { 2121 struct mac_biba *old, *new, *subj; 2122 int error; 2123 2124 old = SLOT(vnodelabel); 2125 new = SLOT(newlabel); 2126 subj = SLOT(&cred->cr_label); 2127 2128 /* 2129 * If there is a Biba label update for the vnode, it must be a 2130 * single label. 2131 */ 2132 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2133 if (error) 2134 return (error); 2135 2136 /* 2137 * To perform a relabel of the vnode (Biba label or not), Biba must 2138 * authorize the relabel. 2139 */ 2140 if (!mac_biba_single_in_range(old, subj)) 2141 return (EPERM); 2142 2143 /* 2144 * If the Biba label is to be changed, authorize as appropriate. 2145 */ 2146 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2147 /* 2148 * To change the Biba label on a vnode, the new vnode label 2149 * must be in the subject range. 2150 */ 2151 if (!mac_biba_single_in_range(new, subj)) 2152 return (EPERM); 2153 2154 /* 2155 * To change the Biba label on the vnode to be EQUAL, 2156 * the subject must have appropriate privilege. 2157 */ 2158 if (mac_biba_contains_equal(new)) { 2159 error = mac_biba_subject_equal_ok(subj); 2160 if (error) 2161 return (error); 2162 } 2163 } 2164 2165 return (0); 2166 } 2167 2168 static int 2169 mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2170 struct label *dlabel, struct vnode *vp, struct label *label, 2171 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(subj, obj)) 2182 return (EACCES); 2183 2184 obj = SLOT(label); 2185 2186 if (!mac_biba_dominate_single(subj, obj)) 2187 return (EACCES); 2188 2189 return (0); 2190 } 2191 2192 static int 2193 mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2194 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2195 struct componentname *cnp) 2196 { 2197 struct mac_biba *subj, *obj; 2198 2199 if (!mac_biba_enabled) 2200 return (0); 2201 2202 subj = SLOT(&cred->cr_label); 2203 obj = SLOT(dlabel); 2204 2205 if (!mac_biba_dominate_single(subj, obj)) 2206 return (EACCES); 2207 2208 if (vp != NULL) { 2209 obj = SLOT(label); 2210 2211 if (!mac_biba_dominate_single(subj, obj)) 2212 return (EACCES); 2213 } 2214 2215 return (0); 2216 } 2217 2218 static int 2219 mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2220 struct label *label) 2221 { 2222 struct mac_biba *subj, *obj; 2223 2224 if (!mac_biba_enabled) 2225 return (0); 2226 2227 subj = SLOT(&cred->cr_label); 2228 obj = SLOT(label); 2229 2230 if (!mac_biba_dominate_single(subj, obj)) 2231 return (EACCES); 2232 2233 return (0); 2234 } 2235 2236 static int 2237 mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2238 struct label *label, acl_type_t type, struct acl *acl) 2239 { 2240 struct mac_biba *subj, *obj; 2241 2242 if (!mac_biba_enabled) 2243 return (0); 2244 2245 subj = SLOT(&cred->cr_label); 2246 obj = SLOT(label); 2247 2248 if (!mac_biba_dominate_single(subj, obj)) 2249 return (EACCES); 2250 2251 return (0); 2252 } 2253 2254 static int 2255 mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2256 struct label *vnodelabel, int attrnamespace, const char *name, 2257 struct uio *uio) 2258 { 2259 struct mac_biba *subj, *obj; 2260 2261 if (!mac_biba_enabled) 2262 return (0); 2263 2264 subj = SLOT(&cred->cr_label); 2265 obj = SLOT(vnodelabel); 2266 2267 if (!mac_biba_dominate_single(subj, obj)) 2268 return (EACCES); 2269 2270 /* XXX: protect the MAC EA in a special way? */ 2271 2272 return (0); 2273 } 2274 2275 static int 2276 mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2277 struct label *vnodelabel, u_long flags) 2278 { 2279 struct mac_biba *subj, *obj; 2280 2281 if (!mac_biba_enabled) 2282 return (0); 2283 2284 subj = SLOT(&cred->cr_label); 2285 obj = SLOT(vnodelabel); 2286 2287 if (!mac_biba_dominate_single(subj, obj)) 2288 return (EACCES); 2289 2290 return (0); 2291 } 2292 2293 static int 2294 mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2295 struct label *vnodelabel, mode_t mode) 2296 { 2297 struct mac_biba *subj, *obj; 2298 2299 if (!mac_biba_enabled) 2300 return (0); 2301 2302 subj = SLOT(&cred->cr_label); 2303 obj = SLOT(vnodelabel); 2304 2305 if (!mac_biba_dominate_single(subj, obj)) 2306 return (EACCES); 2307 2308 return (0); 2309 } 2310 2311 static int 2312 mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2313 struct label *vnodelabel, uid_t uid, gid_t gid) 2314 { 2315 struct mac_biba *subj, *obj; 2316 2317 if (!mac_biba_enabled) 2318 return (0); 2319 2320 subj = SLOT(&cred->cr_label); 2321 obj = SLOT(vnodelabel); 2322 2323 if (!mac_biba_dominate_single(subj, obj)) 2324 return (EACCES); 2325 2326 return (0); 2327 } 2328 2329 static int 2330 mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2331 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2332 { 2333 struct mac_biba *subj, *obj; 2334 2335 if (!mac_biba_enabled) 2336 return (0); 2337 2338 subj = SLOT(&cred->cr_label); 2339 obj = SLOT(vnodelabel); 2340 2341 if (!mac_biba_dominate_single(subj, obj)) 2342 return (EACCES); 2343 2344 return (0); 2345 } 2346 2347 static int 2348 mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2349 struct vnode *vp, struct label *vnodelabel) 2350 { 2351 struct mac_biba *subj, *obj; 2352 2353 if (!mac_biba_enabled) 2354 return (0); 2355 2356 subj = SLOT(&active_cred->cr_label); 2357 obj = SLOT(vnodelabel); 2358 2359 if (!mac_biba_dominate_single(obj, subj)) 2360 return (EACCES); 2361 2362 return (0); 2363 } 2364 2365 static int 2366 mac_biba_check_vnode_write(struct ucred *active_cred, 2367 struct ucred *file_cred, struct vnode *vp, struct label *label) 2368 { 2369 struct mac_biba *subj, *obj; 2370 2371 if (!mac_biba_enabled || !revocation_enabled) 2372 return (0); 2373 2374 subj = SLOT(&active_cred->cr_label); 2375 obj = SLOT(label); 2376 2377 if (!mac_biba_dominate_single(subj, obj)) 2378 return (EACCES); 2379 2380 return (0); 2381 } 2382 2383 static struct mac_policy_op_entry mac_biba_ops[] = 2384 { 2385 { MAC_DESTROY, 2386 (macop_t)mac_biba_destroy }, 2387 { MAC_INIT, 2388 (macop_t)mac_biba_init }, 2389 { MAC_INIT_BPFDESC_LABEL, 2390 (macop_t)mac_biba_init_label }, 2391 { MAC_INIT_CRED_LABEL, 2392 (macop_t)mac_biba_init_label }, 2393 { MAC_INIT_DEVFSDIRENT_LABEL, 2394 (macop_t)mac_biba_init_label }, 2395 { MAC_INIT_IFNET_LABEL, 2396 (macop_t)mac_biba_init_label }, 2397 { MAC_INIT_IPQ_LABEL, 2398 (macop_t)mac_biba_init_label }, 2399 { MAC_INIT_MBUF_LABEL, 2400 (macop_t)mac_biba_init_label_waitcheck }, 2401 { MAC_INIT_MOUNT_LABEL, 2402 (macop_t)mac_biba_init_label }, 2403 { MAC_INIT_MOUNT_FS_LABEL, 2404 (macop_t)mac_biba_init_label }, 2405 { MAC_INIT_PIPE_LABEL, 2406 (macop_t)mac_biba_init_label }, 2407 { MAC_INIT_SOCKET_LABEL, 2408 (macop_t)mac_biba_init_label_waitcheck }, 2409 { MAC_INIT_SOCKET_PEER_LABEL, 2410 (macop_t)mac_biba_init_label_waitcheck }, 2411 { MAC_INIT_VNODE_LABEL, 2412 (macop_t)mac_biba_init_label }, 2413 { MAC_DESTROY_BPFDESC_LABEL, 2414 (macop_t)mac_biba_destroy_label }, 2415 { MAC_DESTROY_CRED_LABEL, 2416 (macop_t)mac_biba_destroy_label }, 2417 { MAC_DESTROY_DEVFSDIRENT_LABEL, 2418 (macop_t)mac_biba_destroy_label }, 2419 { MAC_DESTROY_IFNET_LABEL, 2420 (macop_t)mac_biba_destroy_label }, 2421 { MAC_DESTROY_IPQ_LABEL, 2422 (macop_t)mac_biba_destroy_label }, 2423 { MAC_DESTROY_MBUF_LABEL, 2424 (macop_t)mac_biba_destroy_label }, 2425 { MAC_DESTROY_MOUNT_LABEL, 2426 (macop_t)mac_biba_destroy_label }, 2427 { MAC_DESTROY_MOUNT_FS_LABEL, 2428 (macop_t)mac_biba_destroy_label }, 2429 { MAC_DESTROY_PIPE_LABEL, 2430 (macop_t)mac_biba_destroy_label }, 2431 { MAC_DESTROY_SOCKET_LABEL, 2432 (macop_t)mac_biba_destroy_label }, 2433 { MAC_DESTROY_SOCKET_PEER_LABEL, 2434 (macop_t)mac_biba_destroy_label }, 2435 { MAC_DESTROY_VNODE_LABEL, 2436 (macop_t)mac_biba_destroy_label }, 2437 { MAC_COPY_PIPE_LABEL, 2438 (macop_t)mac_biba_copy_label }, 2439 { MAC_COPY_VNODE_LABEL, 2440 (macop_t)mac_biba_copy_label }, 2441 { MAC_EXTERNALIZE_CRED_LABEL, 2442 (macop_t)mac_biba_externalize_label }, 2443 { MAC_EXTERNALIZE_IFNET_LABEL, 2444 (macop_t)mac_biba_externalize_label }, 2445 { MAC_EXTERNALIZE_PIPE_LABEL, 2446 (macop_t)mac_biba_externalize_label }, 2447 { MAC_EXTERNALIZE_SOCKET_LABEL, 2448 (macop_t)mac_biba_externalize_label }, 2449 { MAC_EXTERNALIZE_SOCKET_PEER_LABEL, 2450 (macop_t)mac_biba_externalize_label }, 2451 { MAC_EXTERNALIZE_VNODE_LABEL, 2452 (macop_t)mac_biba_externalize_label }, 2453 { MAC_EXTERNALIZE_VNODE_OLDMAC, 2454 (macop_t)mac_biba_externalize_vnode_oldmac }, 2455 { MAC_INTERNALIZE_CRED_LABEL, 2456 (macop_t)mac_biba_internalize_label }, 2457 { MAC_INTERNALIZE_IFNET_LABEL, 2458 (macop_t)mac_biba_internalize_label }, 2459 { MAC_INTERNALIZE_PIPE_LABEL, 2460 (macop_t)mac_biba_internalize_label }, 2461 { MAC_INTERNALIZE_SOCKET_LABEL, 2462 (macop_t)mac_biba_internalize_label }, 2463 { MAC_INTERNALIZE_VNODE_LABEL, 2464 (macop_t)mac_biba_internalize_label }, 2465 { MAC_CREATE_DEVFS_DEVICE, 2466 (macop_t)mac_biba_create_devfs_device }, 2467 { MAC_CREATE_DEVFS_DIRECTORY, 2468 (macop_t)mac_biba_create_devfs_directory }, 2469 { MAC_CREATE_DEVFS_SYMLINK, 2470 (macop_t)mac_biba_create_devfs_symlink }, 2471 { MAC_CREATE_DEVFS_VNODE, 2472 (macop_t)mac_biba_create_devfs_vnode }, 2473 { MAC_CREATE_VNODE, 2474 (macop_t)mac_biba_create_vnode }, 2475 { MAC_CREATE_MOUNT, 2476 (macop_t)mac_biba_create_mount }, 2477 { MAC_CREATE_ROOT_MOUNT, 2478 (macop_t)mac_biba_create_root_mount }, 2479 { MAC_RELABEL_VNODE, 2480 (macop_t)mac_biba_relabel_vnode }, 2481 { MAC_UPDATE_DEVFSDIRENT, 2482 (macop_t)mac_biba_update_devfsdirent }, 2483 { MAC_UPDATE_PROCFSVNODE, 2484 (macop_t)mac_biba_update_procfsvnode }, 2485 { MAC_UPDATE_VNODE_FROM_EXTERNALIZED, 2486 (macop_t)mac_biba_update_vnode_from_externalized }, 2487 { MAC_UPDATE_VNODE_FROM_MOUNT, 2488 (macop_t)mac_biba_update_vnode_from_mount }, 2489 { MAC_CREATE_MBUF_FROM_SOCKET, 2490 (macop_t)mac_biba_create_mbuf_from_socket }, 2491 { MAC_CREATE_PIPE, 2492 (macop_t)mac_biba_create_pipe }, 2493 { MAC_CREATE_SOCKET, 2494 (macop_t)mac_biba_create_socket }, 2495 { MAC_CREATE_SOCKET_FROM_SOCKET, 2496 (macop_t)mac_biba_create_socket_from_socket }, 2497 { MAC_RELABEL_PIPE, 2498 (macop_t)mac_biba_relabel_pipe }, 2499 { MAC_RELABEL_SOCKET, 2500 (macop_t)mac_biba_relabel_socket }, 2501 { MAC_SET_SOCKET_PEER_FROM_MBUF, 2502 (macop_t)mac_biba_set_socket_peer_from_mbuf }, 2503 { MAC_SET_SOCKET_PEER_FROM_SOCKET, 2504 (macop_t)mac_biba_set_socket_peer_from_socket }, 2505 { MAC_CREATE_BPFDESC, 2506 (macop_t)mac_biba_create_bpfdesc }, 2507 { MAC_CREATE_DATAGRAM_FROM_IPQ, 2508 (macop_t)mac_biba_create_datagram_from_ipq }, 2509 { MAC_CREATE_FRAGMENT, 2510 (macop_t)mac_biba_create_fragment }, 2511 { MAC_CREATE_IFNET, 2512 (macop_t)mac_biba_create_ifnet }, 2513 { MAC_CREATE_IPQ, 2514 (macop_t)mac_biba_create_ipq }, 2515 { MAC_CREATE_MBUF_FROM_MBUF, 2516 (macop_t)mac_biba_create_mbuf_from_mbuf }, 2517 { MAC_CREATE_MBUF_LINKLAYER, 2518 (macop_t)mac_biba_create_mbuf_linklayer }, 2519 { MAC_CREATE_MBUF_FROM_BPFDESC, 2520 (macop_t)mac_biba_create_mbuf_from_bpfdesc }, 2521 { MAC_CREATE_MBUF_FROM_IFNET, 2522 (macop_t)mac_biba_create_mbuf_from_ifnet }, 2523 { MAC_CREATE_MBUF_MULTICAST_ENCAP, 2524 (macop_t)mac_biba_create_mbuf_multicast_encap }, 2525 { MAC_CREATE_MBUF_NETLAYER, 2526 (macop_t)mac_biba_create_mbuf_netlayer }, 2527 { MAC_FRAGMENT_MATCH, 2528 (macop_t)mac_biba_fragment_match }, 2529 { MAC_RELABEL_IFNET, 2530 (macop_t)mac_biba_relabel_ifnet }, 2531 { MAC_UPDATE_IPQ, 2532 (macop_t)mac_biba_update_ipq }, 2533 { MAC_CREATE_CRED, 2534 (macop_t)mac_biba_create_cred }, 2535 { MAC_EXECVE_TRANSITION, 2536 (macop_t)mac_biba_execve_transition }, 2537 { MAC_EXECVE_WILL_TRANSITION, 2538 (macop_t)mac_biba_execve_will_transition }, 2539 { MAC_CREATE_PROC0, 2540 (macop_t)mac_biba_create_proc0 }, 2541 { MAC_CREATE_PROC1, 2542 (macop_t)mac_biba_create_proc1 }, 2543 { MAC_RELABEL_CRED, 2544 (macop_t)mac_biba_relabel_cred }, 2545 { MAC_CHECK_BPFDESC_RECEIVE, 2546 (macop_t)mac_biba_check_bpfdesc_receive }, 2547 { MAC_CHECK_CRED_RELABEL, 2548 (macop_t)mac_biba_check_cred_relabel }, 2549 { MAC_CHECK_CRED_VISIBLE, 2550 (macop_t)mac_biba_check_cred_visible }, 2551 { MAC_CHECK_IFNET_RELABEL, 2552 (macop_t)mac_biba_check_ifnet_relabel }, 2553 { MAC_CHECK_IFNET_TRANSMIT, 2554 (macop_t)mac_biba_check_ifnet_transmit }, 2555 { MAC_CHECK_MOUNT_STAT, 2556 (macop_t)mac_biba_check_mount_stat }, 2557 { MAC_CHECK_PIPE_IOCTL, 2558 (macop_t)mac_biba_check_pipe_ioctl }, 2559 { MAC_CHECK_PIPE_POLL, 2560 (macop_t)mac_biba_check_pipe_poll }, 2561 { MAC_CHECK_PIPE_READ, 2562 (macop_t)mac_biba_check_pipe_read }, 2563 { MAC_CHECK_PIPE_RELABEL, 2564 (macop_t)mac_biba_check_pipe_relabel }, 2565 { MAC_CHECK_PIPE_STAT, 2566 (macop_t)mac_biba_check_pipe_stat }, 2567 { MAC_CHECK_PIPE_WRITE, 2568 (macop_t)mac_biba_check_pipe_write }, 2569 { MAC_CHECK_PROC_DEBUG, 2570 (macop_t)mac_biba_check_proc_debug }, 2571 { MAC_CHECK_PROC_SCHED, 2572 (macop_t)mac_biba_check_proc_sched }, 2573 { MAC_CHECK_PROC_SIGNAL, 2574 (macop_t)mac_biba_check_proc_signal }, 2575 { MAC_CHECK_SOCKET_DELIVER, 2576 (macop_t)mac_biba_check_socket_deliver }, 2577 { MAC_CHECK_SOCKET_RELABEL, 2578 (macop_t)mac_biba_check_socket_relabel }, 2579 { MAC_CHECK_SOCKET_VISIBLE, 2580 (macop_t)mac_biba_check_socket_visible }, 2581 { MAC_CHECK_VNODE_ACCESS, 2582 (macop_t)mac_biba_check_vnode_open }, 2583 { MAC_CHECK_VNODE_CHDIR, 2584 (macop_t)mac_biba_check_vnode_chdir }, 2585 { MAC_CHECK_VNODE_CHROOT, 2586 (macop_t)mac_biba_check_vnode_chroot }, 2587 { MAC_CHECK_VNODE_CREATE, 2588 (macop_t)mac_biba_check_vnode_create }, 2589 { MAC_CHECK_VNODE_DELETE, 2590 (macop_t)mac_biba_check_vnode_delete }, 2591 { MAC_CHECK_VNODE_DELETEACL, 2592 (macop_t)mac_biba_check_vnode_deleteacl }, 2593 { MAC_CHECK_VNODE_EXEC, 2594 (macop_t)mac_biba_check_vnode_exec }, 2595 { MAC_CHECK_VNODE_GETACL, 2596 (macop_t)mac_biba_check_vnode_getacl }, 2597 { MAC_CHECK_VNODE_GETEXTATTR, 2598 (macop_t)mac_biba_check_vnode_getextattr }, 2599 { MAC_CHECK_VNODE_LINK, 2600 (macop_t)mac_biba_check_vnode_link }, 2601 { MAC_CHECK_VNODE_LOOKUP, 2602 (macop_t)mac_biba_check_vnode_lookup }, 2603 { MAC_CHECK_VNODE_MMAP, 2604 (macop_t)mac_biba_check_vnode_mmap }, 2605 { MAC_CHECK_VNODE_MPROTECT, 2606 (macop_t)mac_biba_check_vnode_mmap }, 2607 { MAC_CHECK_VNODE_OPEN, 2608 (macop_t)mac_biba_check_vnode_open }, 2609 { MAC_CHECK_VNODE_POLL, 2610 (macop_t)mac_biba_check_vnode_poll }, 2611 { MAC_CHECK_VNODE_READ, 2612 (macop_t)mac_biba_check_vnode_read }, 2613 { MAC_CHECK_VNODE_READDIR, 2614 (macop_t)mac_biba_check_vnode_readdir }, 2615 { MAC_CHECK_VNODE_READLINK, 2616 (macop_t)mac_biba_check_vnode_readlink }, 2617 { MAC_CHECK_VNODE_RELABEL, 2618 (macop_t)mac_biba_check_vnode_relabel }, 2619 { MAC_CHECK_VNODE_RENAME_FROM, 2620 (macop_t)mac_biba_check_vnode_rename_from }, 2621 { MAC_CHECK_VNODE_RENAME_TO, 2622 (macop_t)mac_biba_check_vnode_rename_to }, 2623 { MAC_CHECK_VNODE_REVOKE, 2624 (macop_t)mac_biba_check_vnode_revoke }, 2625 { MAC_CHECK_VNODE_SETACL, 2626 (macop_t)mac_biba_check_vnode_setacl }, 2627 { MAC_CHECK_VNODE_SETEXTATTR, 2628 (macop_t)mac_biba_check_vnode_setextattr }, 2629 { MAC_CHECK_VNODE_SETFLAGS, 2630 (macop_t)mac_biba_check_vnode_setflags }, 2631 { MAC_CHECK_VNODE_SETMODE, 2632 (macop_t)mac_biba_check_vnode_setmode }, 2633 { MAC_CHECK_VNODE_SETOWNER, 2634 (macop_t)mac_biba_check_vnode_setowner }, 2635 { MAC_CHECK_VNODE_SETUTIMES, 2636 (macop_t)mac_biba_check_vnode_setutimes }, 2637 { MAC_CHECK_VNODE_STAT, 2638 (macop_t)mac_biba_check_vnode_stat }, 2639 { MAC_CHECK_VNODE_WRITE, 2640 (macop_t)mac_biba_check_vnode_write }, 2641 { MAC_OP_LAST, NULL } 2642 }; 2643 2644 MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2645 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot); 2646