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