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