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