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