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