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