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