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