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