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