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