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