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