1 /*- 2 * Copyright (c) 1999-2002, 2007 Robert N. M. Watson 3 * Copyright (c) 2001-2005 McAfee, Inc. 4 * Copyright (c) 2006 SPARTA, Inc. 5 * All rights reserved. 6 * 7 * This software was developed by Robert Watson for the TrustedBSD Project. 8 * 9 * This software was developed for the FreeBSD Project in part by McAfee 10 * Research, the Security Research Division of McAfee, Inc. under 11 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 12 * CHATS research program. 13 * 14 * This software was enhanced by SPARTA ISSO under SPAWAR contract 15 * N66001-04-C-6019 ("SEFOS"). 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * $FreeBSD$ 39 */ 40 41 /* 42 * Developed by the TrustedBSD Project. 43 * 44 * MLS fixed label mandatory confidentiality policy. 45 */ 46 47 #include <sys/types.h> 48 #include <sys/param.h> 49 #include <sys/acl.h> 50 #include <sys/conf.h> 51 #include <sys/extattr.h> 52 #include <sys/kernel.h> 53 #include <sys/ksem.h> 54 #include <sys/mman.h> 55 #include <sys/malloc.h> 56 #include <sys/mount.h> 57 #include <sys/proc.h> 58 #include <sys/sbuf.h> 59 #include <sys/systm.h> 60 #include <sys/sysproto.h> 61 #include <sys/sysent.h> 62 #include <sys/systm.h> 63 #include <sys/vnode.h> 64 #include <sys/file.h> 65 #include <sys/socket.h> 66 #include <sys/socketvar.h> 67 #include <sys/pipe.h> 68 #include <sys/sx.h> 69 #include <sys/sysctl.h> 70 #include <sys/msg.h> 71 #include <sys/sem.h> 72 #include <sys/shm.h> 73 74 #include <fs/devfs/devfs.h> 75 76 #include <net/bpfdesc.h> 77 #include <net/if.h> 78 #include <net/if_types.h> 79 #include <net/if_var.h> 80 81 #include <netinet/in.h> 82 #include <netinet/in_pcb.h> 83 #include <netinet/ip_var.h> 84 85 #include <vm/uma.h> 86 #include <vm/vm.h> 87 88 #include <security/mac/mac_policy.h> 89 #include <security/mac_mls/mac_mls.h> 90 91 SYSCTL_DECL(_security_mac); 92 93 SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0, 94 "TrustedBSD mac_mls policy controls"); 95 96 static int mls_label_size = sizeof(struct mac_mls); 97 SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD, 98 &mls_label_size, 0, "Size of struct mac_mls"); 99 100 static int mls_enabled = 1; 101 SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW, &mls_enabled, 0, 102 "Enforce MAC/MLS policy"); 103 TUNABLE_INT("security.mac.mls.enabled", &mls_enabled); 104 105 static int destroyed_not_inited; 106 SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 107 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 108 109 static int ptys_equal = 0; 110 SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW, 111 &ptys_equal, 0, "Label pty devices as mls/equal on create"); 112 TUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal); 113 114 static int revocation_enabled = 0; 115 SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, 116 &revocation_enabled, 0, "Revoke access to objects on relabel"); 117 TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled); 118 119 static int max_compartments = MAC_MLS_MAX_COMPARTMENTS; 120 SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD, 121 &max_compartments, 0, "Maximum compartments the policy supports"); 122 123 static int mls_slot; 124 #define SLOT(l) ((struct mac_mls *)mac_label_get((l), mls_slot)) 125 #define SLOT_SET(l, val) mac_label_set((l), mls_slot, (uintptr_t)(val)) 126 127 static uma_zone_t zone_mls; 128 129 static __inline int 130 mls_bit_set_empty(u_char *set) { 131 int i; 132 133 for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++) 134 if (set[i] != 0) 135 return (0); 136 return (1); 137 } 138 139 static struct mac_mls * 140 mls_alloc(int flag) 141 { 142 143 return (uma_zalloc(zone_mls, flag | M_ZERO)); 144 } 145 146 static void 147 mls_free(struct mac_mls *mm) 148 { 149 150 if (mm != NULL) 151 uma_zfree(zone_mls, mm); 152 else 153 atomic_add_int(&destroyed_not_inited, 1); 154 } 155 156 static int 157 mls_atmostflags(struct mac_mls *mm, int flags) 158 { 159 160 if ((mm->mm_flags & flags) != mm->mm_flags) 161 return (EINVAL); 162 return (0); 163 } 164 165 static int 166 mls_dominate_element(struct mac_mls_element *a, struct mac_mls_element *b) 167 { 168 int bit; 169 170 switch (a->mme_type) { 171 case MAC_MLS_TYPE_EQUAL: 172 case MAC_MLS_TYPE_HIGH: 173 return (1); 174 175 case MAC_MLS_TYPE_LOW: 176 switch (b->mme_type) { 177 case MAC_MLS_TYPE_LEVEL: 178 case MAC_MLS_TYPE_HIGH: 179 return (0); 180 181 case MAC_MLS_TYPE_EQUAL: 182 case MAC_MLS_TYPE_LOW: 183 return (1); 184 185 default: 186 panic("mls_dominate_element: b->mme_type invalid"); 187 } 188 189 case MAC_MLS_TYPE_LEVEL: 190 switch (b->mme_type) { 191 case MAC_MLS_TYPE_EQUAL: 192 case MAC_MLS_TYPE_LOW: 193 return (1); 194 195 case MAC_MLS_TYPE_HIGH: 196 return (0); 197 198 case MAC_MLS_TYPE_LEVEL: 199 for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) 200 if (!MAC_MLS_BIT_TEST(bit, 201 a->mme_compartments) && 202 MAC_MLS_BIT_TEST(bit, b->mme_compartments)) 203 return (0); 204 return (a->mme_level >= b->mme_level); 205 206 default: 207 panic("mls_dominate_element: b->mme_type invalid"); 208 } 209 210 default: 211 panic("mls_dominate_element: a->mme_type invalid"); 212 } 213 214 return (0); 215 } 216 217 static int 218 mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) 219 { 220 221 return (mls_dominate_element(&rangeb->mm_rangehigh, 222 &rangea->mm_rangehigh) && 223 mls_dominate_element(&rangea->mm_rangelow, 224 &rangeb->mm_rangelow)); 225 } 226 227 static int 228 mls_effective_in_range(struct mac_mls *effective, struct mac_mls *range) 229 { 230 231 KASSERT((effective->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 232 ("mls_effective_in_range: a not effective")); 233 KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 234 ("mls_effective_in_range: b not range")); 235 236 return (mls_dominate_element(&range->mm_rangehigh, 237 &effective->mm_effective) && 238 mls_dominate_element(&effective->mm_effective, 239 &range->mm_rangelow)); 240 241 return (1); 242 } 243 244 static int 245 mls_dominate_effective(struct mac_mls *a, struct mac_mls *b) 246 { 247 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 248 ("mls_dominate_effective: a not effective")); 249 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 250 ("mls_dominate_effective: b not effective")); 251 252 return (mls_dominate_element(&a->mm_effective, &b->mm_effective)); 253 } 254 255 static int 256 mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) 257 { 258 259 if (a->mme_type == MAC_MLS_TYPE_EQUAL || 260 b->mme_type == MAC_MLS_TYPE_EQUAL) 261 return (1); 262 263 return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); 264 } 265 266 static int 267 mls_equal_effective(struct mac_mls *a, struct mac_mls *b) 268 { 269 270 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 271 ("mls_equal_effective: a not effective")); 272 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 273 ("mls_equal_effective: b not effective")); 274 275 return (mls_equal_element(&a->mm_effective, &b->mm_effective)); 276 } 277 278 static int 279 mls_contains_equal(struct mac_mls *mm) 280 { 281 282 if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 283 if (mm->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 284 return (1); 285 286 if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 287 if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL) 288 return (1); 289 if (mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 290 return (1); 291 } 292 293 return (0); 294 } 295 296 static int 297 mls_subject_privileged(struct mac_mls *mm) 298 { 299 300 KASSERT((mm->mm_flags & MAC_MLS_FLAGS_BOTH) == MAC_MLS_FLAGS_BOTH, 301 ("mls_subject_privileged: subject doesn't have both labels")); 302 303 /* If the effective is EQUAL, it's ok. */ 304 if (mm->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 305 return (0); 306 307 /* If either range endpoint is EQUAL, it's ok. */ 308 if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL || 309 mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 310 return (0); 311 312 /* If the range is low-high, it's ok. */ 313 if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW && 314 mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH) 315 return (0); 316 317 /* It's not ok. */ 318 return (EPERM); 319 } 320 321 static int 322 mls_valid(struct mac_mls *mm) 323 { 324 325 if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 326 switch (mm->mm_effective.mme_type) { 327 case MAC_MLS_TYPE_LEVEL: 328 break; 329 330 case MAC_MLS_TYPE_EQUAL: 331 case MAC_MLS_TYPE_HIGH: 332 case MAC_MLS_TYPE_LOW: 333 if (mm->mm_effective.mme_level != 0 || 334 !MAC_MLS_BIT_SET_EMPTY( 335 mm->mm_effective.mme_compartments)) 336 return (EINVAL); 337 break; 338 339 default: 340 return (EINVAL); 341 } 342 } else { 343 if (mm->mm_effective.mme_type != MAC_MLS_TYPE_UNDEF) 344 return (EINVAL); 345 } 346 347 if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 348 switch (mm->mm_rangelow.mme_type) { 349 case MAC_MLS_TYPE_LEVEL: 350 break; 351 352 case MAC_MLS_TYPE_EQUAL: 353 case MAC_MLS_TYPE_HIGH: 354 case MAC_MLS_TYPE_LOW: 355 if (mm->mm_rangelow.mme_level != 0 || 356 !MAC_MLS_BIT_SET_EMPTY( 357 mm->mm_rangelow.mme_compartments)) 358 return (EINVAL); 359 break; 360 361 default: 362 return (EINVAL); 363 } 364 365 switch (mm->mm_rangehigh.mme_type) { 366 case MAC_MLS_TYPE_LEVEL: 367 break; 368 369 case MAC_MLS_TYPE_EQUAL: 370 case MAC_MLS_TYPE_HIGH: 371 case MAC_MLS_TYPE_LOW: 372 if (mm->mm_rangehigh.mme_level != 0 || 373 !MAC_MLS_BIT_SET_EMPTY( 374 mm->mm_rangehigh.mme_compartments)) 375 return (EINVAL); 376 break; 377 378 default: 379 return (EINVAL); 380 } 381 if (!mls_dominate_element(&mm->mm_rangehigh, 382 &mm->mm_rangelow)) 383 return (EINVAL); 384 } else { 385 if (mm->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || 386 mm->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) 387 return (EINVAL); 388 } 389 390 return (0); 391 } 392 393 static void 394 mls_set_range(struct mac_mls *mm, u_short typelow, u_short levellow, 395 u_char *compartmentslow, u_short typehigh, u_short levelhigh, 396 u_char *compartmentshigh) 397 { 398 399 mm->mm_rangelow.mme_type = typelow; 400 mm->mm_rangelow.mme_level = levellow; 401 if (compartmentslow != NULL) 402 memcpy(mm->mm_rangelow.mme_compartments, 403 compartmentslow, 404 sizeof(mm->mm_rangelow.mme_compartments)); 405 mm->mm_rangehigh.mme_type = typehigh; 406 mm->mm_rangehigh.mme_level = levelhigh; 407 if (compartmentshigh != NULL) 408 memcpy(mm->mm_rangehigh.mme_compartments, 409 compartmentshigh, 410 sizeof(mm->mm_rangehigh.mme_compartments)); 411 mm->mm_flags |= MAC_MLS_FLAG_RANGE; 412 } 413 414 static void 415 mls_set_effective(struct mac_mls *mm, u_short type, u_short level, 416 u_char *compartments) 417 { 418 419 mm->mm_effective.mme_type = type; 420 mm->mm_effective.mme_level = level; 421 if (compartments != NULL) 422 memcpy(mm->mm_effective.mme_compartments, compartments, 423 sizeof(mm->mm_effective.mme_compartments)); 424 mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 425 } 426 427 static void 428 mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 429 { 430 431 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 432 ("mls_copy_range: labelfrom not range")); 433 434 labelto->mm_rangelow = labelfrom->mm_rangelow; 435 labelto->mm_rangehigh = labelfrom->mm_rangehigh; 436 labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 437 } 438 439 static void 440 mls_copy_effective(struct mac_mls *labelfrom, struct mac_mls *labelto) 441 { 442 443 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 444 ("mls_copy_effective: labelfrom not effective")); 445 446 labelto->mm_effective = labelfrom->mm_effective; 447 labelto->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 448 } 449 450 static void 451 mls_copy(struct mac_mls *source, struct mac_mls *dest) 452 { 453 454 if (source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 455 mls_copy_effective(source, dest); 456 if (source->mm_flags & MAC_MLS_FLAG_RANGE) 457 mls_copy_range(source, dest); 458 } 459 460 /* 461 * Policy module operations. 462 */ 463 static void 464 mls_init(struct mac_policy_conf *conf) 465 { 466 467 zone_mls = uma_zcreate("mac_mls", sizeof(struct mac_mls), NULL, 468 NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 469 } 470 471 /* 472 * Label operations. 473 */ 474 static void 475 mls_init_label(struct label *label) 476 { 477 478 SLOT_SET(label, mls_alloc(M_WAITOK)); 479 } 480 481 static int 482 mls_init_label_waitcheck(struct label *label, int flag) 483 { 484 485 SLOT_SET(label, mls_alloc(flag)); 486 if (SLOT(label) == NULL) 487 return (ENOMEM); 488 489 return (0); 490 } 491 492 static void 493 mls_destroy_label(struct label *label) 494 { 495 496 mls_free(SLOT(label)); 497 SLOT_SET(label, NULL); 498 } 499 500 /* 501 * mls_element_to_string() accepts an sbuf and MLS element. It converts the 502 * MLS element to a string and stores the result in the sbuf; if there isn't 503 * space in the sbuf, -1 is returned. 504 */ 505 static int 506 mls_element_to_string(struct sbuf *sb, struct mac_mls_element *element) 507 { 508 int i, first; 509 510 switch (element->mme_type) { 511 case MAC_MLS_TYPE_HIGH: 512 return (sbuf_printf(sb, "high")); 513 514 case MAC_MLS_TYPE_LOW: 515 return (sbuf_printf(sb, "low")); 516 517 case MAC_MLS_TYPE_EQUAL: 518 return (sbuf_printf(sb, "equal")); 519 520 case MAC_MLS_TYPE_LEVEL: 521 if (sbuf_printf(sb, "%d", element->mme_level) == -1) 522 return (-1); 523 524 first = 1; 525 for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) { 526 if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) { 527 if (first) { 528 if (sbuf_putc(sb, ':') == -1) 529 return (-1); 530 if (sbuf_printf(sb, "%d", i) == -1) 531 return (-1); 532 first = 0; 533 } else { 534 if (sbuf_printf(sb, "+%d", i) == -1) 535 return (-1); 536 } 537 } 538 } 539 return (0); 540 541 default: 542 panic("mls_element_to_string: invalid type (%d)", 543 element->mme_type); 544 } 545 } 546 547 /* 548 * mls_to_string() converts an MLS label to a string, and places the results 549 * in the passed sbuf. It returns 0 on success, or EINVAL if there isn't 550 * room in the sbuf. Note: the sbuf will be modified even in a failure case, 551 * so the caller may need to revert the sbuf by restoring the offset if 552 * that's undesired. 553 */ 554 static int 555 mls_to_string(struct sbuf *sb, struct mac_mls *mm) 556 { 557 558 if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 559 if (mls_element_to_string(sb, &mm->mm_effective) == -1) 560 return (EINVAL); 561 } 562 563 if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 564 if (sbuf_putc(sb, '(') == -1) 565 return (EINVAL); 566 567 if (mls_element_to_string(sb, &mm->mm_rangelow) == -1) 568 return (EINVAL); 569 570 if (sbuf_putc(sb, '-') == -1) 571 return (EINVAL); 572 573 if (mls_element_to_string(sb, &mm->mm_rangehigh) == -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 mls_externalize_label(struct label *label, char *element_name, 585 struct sbuf *sb, int *claimed) 586 { 587 struct mac_mls *mm; 588 589 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 590 return (0); 591 592 (*claimed)++; 593 594 mm = SLOT(label); 595 596 return (mls_to_string(sb, mm)); 597 } 598 599 static int 600 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 || strcmp(string, "hi") == 0) { 606 element->mme_type = MAC_MLS_TYPE_HIGH; 607 element->mme_level = MAC_MLS_TYPE_UNDEF; 608 } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { 609 element->mme_type = MAC_MLS_TYPE_LOW; 610 element->mme_level = MAC_MLS_TYPE_UNDEF; 611 } else if (strcmp(string, "equal") == 0 || 612 strcmp(string, "eq") == 0) { 613 element->mme_type = MAC_MLS_TYPE_EQUAL; 614 element->mme_level = MAC_MLS_TYPE_UNDEF; 615 } else { 616 element->mme_type = MAC_MLS_TYPE_LEVEL; 617 618 /* 619 * Numeric level piece of the element. 620 */ 621 level = strsep(&string, ":"); 622 value = strtol(level, &end, 10); 623 if (end == level || *end != '\0') 624 return (EINVAL); 625 if (value < 0 || value > 65535) 626 return (EINVAL); 627 element->mme_level = value; 628 629 /* 630 * Optional compartment piece of the element. If none are 631 * included, we assume that the label has no compartments. 632 */ 633 if (string == NULL) 634 return (0); 635 if (*string == '\0') 636 return (0); 637 638 while ((compartment = strsep(&string, "+")) != NULL) { 639 value = strtol(compartment, &end, 10); 640 if (compartment == end || *end != '\0') 641 return (EINVAL); 642 if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS) 643 return (EINVAL); 644 MAC_MLS_BIT_SET(value, element->mme_compartments); 645 } 646 } 647 648 return (0); 649 } 650 651 /* 652 * Note: destructively consumes the string, make a local copy before calling 653 * if that's a problem. 654 */ 655 static int 656 mls_parse(struct mac_mls *mm, char *string) 657 { 658 char *rangehigh, *rangelow, *effective; 659 int error; 660 661 effective = strsep(&string, "("); 662 if (*effective == '\0') 663 effective = NULL; 664 665 if (string != NULL) { 666 rangelow = strsep(&string, "-"); 667 if (string == NULL) 668 return (EINVAL); 669 rangehigh = strsep(&string, ")"); 670 if (string == NULL) 671 return (EINVAL); 672 if (*string != '\0') 673 return (EINVAL); 674 } else { 675 rangelow = NULL; 676 rangehigh = NULL; 677 } 678 679 KASSERT((rangelow != NULL && rangehigh != NULL) || 680 (rangelow == NULL && rangehigh == NULL), 681 ("mls_parse: range mismatch")); 682 683 bzero(mm, sizeof(*mm)); 684 if (effective != NULL) { 685 error = mls_parse_element(&mm->mm_effective, effective); 686 if (error) 687 return (error); 688 mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 689 } 690 691 if (rangelow != NULL) { 692 error = mls_parse_element(&mm->mm_rangelow, 693 rangelow); 694 if (error) 695 return (error); 696 error = mls_parse_element(&mm->mm_rangehigh, 697 rangehigh); 698 if (error) 699 return (error); 700 mm->mm_flags |= MAC_MLS_FLAG_RANGE; 701 } 702 703 error = mls_valid(mm); 704 if (error) 705 return (error); 706 707 return (0); 708 } 709 710 static int 711 mls_internalize_label(struct label *label, char *element_name, 712 char *element_data, int *claimed) 713 { 714 struct mac_mls *mm, mm_temp; 715 int error; 716 717 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 718 return (0); 719 720 (*claimed)++; 721 722 error = mls_parse(&mm_temp, element_data); 723 if (error) 724 return (error); 725 726 mm = SLOT(label); 727 *mm = mm_temp; 728 729 return (0); 730 } 731 732 static void 733 mls_copy_label(struct label *src, struct label *dest) 734 { 735 736 *SLOT(dest) = *SLOT(src); 737 } 738 739 740 /* 741 * Object-specific entry point implementations are sorted alphabetically by 742 * object type name and then by operation. 743 */ 744 static int 745 mls_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 746 struct ifnet *ifp, struct label *ifplabel) 747 { 748 struct mac_mls *a, *b; 749 750 if (!mls_enabled) 751 return (0); 752 753 a = SLOT(dlabel); 754 b = SLOT(ifplabel); 755 756 if (mls_equal_effective(a, b)) 757 return (0); 758 return (EACCES); 759 } 760 761 static void 762 mls_bpfdesc_create(struct ucred *cred, struct bpf_d *d, struct label *dlabel) 763 { 764 struct mac_mls *source, *dest; 765 766 source = SLOT(cred->cr_label); 767 dest = SLOT(dlabel); 768 769 mls_copy_effective(source, dest); 770 } 771 772 static void 773 mls_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 774 struct mbuf *m, struct label *mlabel) 775 { 776 struct mac_mls *source, *dest; 777 778 source = SLOT(dlabel); 779 dest = SLOT(mlabel); 780 781 mls_copy_effective(source, dest); 782 } 783 784 static int 785 mls_cred_check_relabel(struct ucred *cred, struct label *newlabel) 786 { 787 struct mac_mls *subj, *new; 788 int error; 789 790 subj = SLOT(cred->cr_label); 791 new = SLOT(newlabel); 792 793 /* 794 * If there is an MLS label update for the credential, it may be an 795 * update of effective, range, or both. 796 */ 797 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 798 if (error) 799 return (error); 800 801 /* 802 * If the MLS label is to be changed, authorize as appropriate. 803 */ 804 if (new->mm_flags & MAC_MLS_FLAGS_BOTH) { 805 /* 806 * If the change request modifies both the MLS label 807 * effective and range, check that the new effective will be 808 * in the new range. 809 */ 810 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) == 811 MAC_MLS_FLAGS_BOTH && !mls_effective_in_range(new, new)) 812 return (EINVAL); 813 814 /* 815 * To change the MLS effective label on a credential, the new 816 * effective label must be in the current range. 817 */ 818 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE && 819 !mls_effective_in_range(new, subj)) 820 return (EPERM); 821 822 /* 823 * To change the MLS range label on a credential, the new 824 * range must be in the current range. 825 */ 826 if (new->mm_flags & MAC_MLS_FLAG_RANGE && 827 !mls_range_in_range(new, subj)) 828 return (EPERM); 829 830 /* 831 * To have EQUAL in any component of the new credential MLS 832 * label, the subject must already have EQUAL in their label. 833 */ 834 if (mls_contains_equal(new)) { 835 error = mls_subject_privileged(subj); 836 if (error) 837 return (error); 838 } 839 } 840 841 return (0); 842 } 843 844 static int 845 mls_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 846 { 847 struct mac_mls *subj, *obj; 848 849 if (!mls_enabled) 850 return (0); 851 852 subj = SLOT(cr1->cr_label); 853 obj = SLOT(cr2->cr_label); 854 855 /* XXX: range */ 856 if (!mls_dominate_effective(subj, obj)) 857 return (ESRCH); 858 859 return (0); 860 } 861 862 static void 863 mls_cred_relabel(struct ucred *cred, struct label *newlabel) 864 { 865 struct mac_mls *source, *dest; 866 867 source = SLOT(newlabel); 868 dest = SLOT(cred->cr_label); 869 870 mls_copy(source, dest); 871 } 872 873 static void 874 mls_devfs_create_device(struct ucred *cred, struct mount *mp, 875 struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 876 { 877 struct mac_mls *mm; 878 int mls_type; 879 880 mm = SLOT(delabel); 881 if (strcmp(dev->si_name, "null") == 0 || 882 strcmp(dev->si_name, "zero") == 0 || 883 strcmp(dev->si_name, "random") == 0 || 884 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 885 mls_type = MAC_MLS_TYPE_EQUAL; 886 else if (strcmp(dev->si_name, "kmem") == 0 || 887 strcmp(dev->si_name, "mem") == 0) 888 mls_type = MAC_MLS_TYPE_HIGH; 889 else if (ptys_equal && 890 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 891 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 892 mls_type = MAC_MLS_TYPE_EQUAL; 893 else 894 mls_type = MAC_MLS_TYPE_LOW; 895 mls_set_effective(mm, mls_type, 0, NULL); 896 } 897 898 static void 899 mls_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 900 struct devfs_dirent *de, struct label *delabel) 901 { 902 struct mac_mls *mm; 903 904 mm = SLOT(delabel); 905 mls_set_effective(mm, MAC_MLS_TYPE_LOW, 0, NULL); 906 } 907 908 static void 909 mls_devfs_create_symlink(struct ucred *cred, struct mount *mp, 910 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 911 struct label *delabel) 912 { 913 struct mac_mls *source, *dest; 914 915 source = SLOT(cred->cr_label); 916 dest = SLOT(delabel); 917 918 mls_copy_effective(source, dest); 919 } 920 921 static void 922 mls_devfs_update(struct mount *mp, struct devfs_dirent *de, 923 struct label *delabel, struct vnode *vp, struct label *vplabel) 924 { 925 struct mac_mls *source, *dest; 926 927 source = SLOT(vplabel); 928 dest = SLOT(delabel); 929 930 mls_copy_effective(source, dest); 931 } 932 933 static void 934 mls_devfs_vnode_associate(struct mount *mp, struct label *mplabel, 935 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 936 struct label *vplabel) 937 { 938 struct mac_mls *source, *dest; 939 940 source = SLOT(delabel); 941 dest = SLOT(vplabel); 942 943 mls_copy_effective(source, dest); 944 } 945 946 static int 947 mls_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 948 struct label *ifplabel, struct label *newlabel) 949 { 950 struct mac_mls *subj, *new; 951 int error; 952 953 subj = SLOT(cred->cr_label); 954 new = SLOT(newlabel); 955 956 /* 957 * If there is an MLS label update for the interface, it may be an 958 * update of effective, range, or both. 959 */ 960 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 961 if (error) 962 return (error); 963 964 /* 965 * Relabeling network interfaces requires MLS privilege. 966 */ 967 return (mls_subject_privileged(subj)); 968 } 969 970 static int 971 mls_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 972 struct mbuf *m, struct label *mlabel) 973 { 974 struct mac_mls *p, *i; 975 976 if (!mls_enabled) 977 return (0); 978 979 p = SLOT(mlabel); 980 i = SLOT(ifplabel); 981 982 return (mls_effective_in_range(p, i) ? 0 : EACCES); 983 } 984 985 static void 986 mls_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 987 { 988 struct mac_mls *dest; 989 int type; 990 991 dest = SLOT(ifplabel); 992 993 if (ifp->if_type == IFT_LOOP) 994 type = MAC_MLS_TYPE_EQUAL; 995 else 996 type = MAC_MLS_TYPE_LOW; 997 998 mls_set_effective(dest, type, 0, NULL); 999 mls_set_range(dest, type, 0, NULL, type, 0, NULL); 1000 } 1001 1002 static void 1003 mls_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1004 struct mbuf *m, struct label *mlabel) 1005 { 1006 struct mac_mls *source, *dest; 1007 1008 source = SLOT(ifplabel); 1009 dest = SLOT(mlabel); 1010 1011 mls_copy_effective(source, dest); 1012 } 1013 1014 static void 1015 mls_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1016 struct label *ifplabel, struct label *newlabel) 1017 { 1018 struct mac_mls *source, *dest; 1019 1020 source = SLOT(newlabel); 1021 dest = SLOT(ifplabel); 1022 1023 mls_copy(source, dest); 1024 } 1025 1026 static int 1027 mls_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1028 struct mbuf *m, struct label *mlabel) 1029 { 1030 struct mac_mls *p, *i; 1031 1032 if (!mls_enabled) 1033 return (0); 1034 1035 p = SLOT(mlabel); 1036 i = SLOT(inplabel); 1037 1038 return (mls_equal_effective(p, i) ? 0 : EACCES); 1039 } 1040 1041 static void 1042 mls_inpcb_create(struct socket *so, struct label *solabel, struct inpcb *inp, 1043 struct label *inplabel) 1044 { 1045 struct mac_mls *source, *dest; 1046 1047 source = SLOT(solabel); 1048 dest = SLOT(inplabel); 1049 1050 mls_copy_effective(source, dest); 1051 } 1052 1053 static void 1054 mls_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1055 struct mbuf *m, struct label *mlabel) 1056 { 1057 struct mac_mls *source, *dest; 1058 1059 source = SLOT(inplabel); 1060 dest = SLOT(mlabel); 1061 1062 mls_copy_effective(source, dest); 1063 } 1064 1065 static void 1066 mls_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1067 struct inpcb *inp, struct label *inplabel) 1068 { 1069 struct mac_mls *source, *dest; 1070 1071 source = SLOT(solabel); 1072 dest = SLOT(inplabel); 1073 1074 mls_copy(source, dest); 1075 } 1076 1077 static void 1078 mls_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 1079 struct label *ipqlabel) 1080 { 1081 struct mac_mls *source, *dest; 1082 1083 source = SLOT(mlabel); 1084 dest = SLOT(ipqlabel); 1085 1086 mls_copy_effective(source, dest); 1087 } 1088 1089 static int 1090 mls_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 1091 struct label *ipqlabel) 1092 { 1093 struct mac_mls *a, *b; 1094 1095 a = SLOT(ipqlabel); 1096 b = SLOT(mlabel); 1097 1098 return (mls_equal_effective(a, b)); 1099 } 1100 1101 static void 1102 mls_ipq_reassemble(struct ipq *ipq, struct label *ipqlabel, struct mbuf *m, 1103 struct label *mlabel) 1104 { 1105 struct mac_mls *source, *dest; 1106 1107 source = SLOT(ipqlabel); 1108 dest = SLOT(mlabel); 1109 1110 /* Just use the head, since we require them all to match. */ 1111 mls_copy_effective(source, dest); 1112 } 1113 1114 static void 1115 mls_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 1116 struct label *ipqlabel) 1117 { 1118 1119 /* NOOP: we only accept matching labels, so no need to update */ 1120 } 1121 1122 static int 1123 mls_mount_check_stat(struct ucred *cred, struct mount *mp, 1124 struct label *mntlabel) 1125 { 1126 struct mac_mls *subj, *obj; 1127 1128 if (!mls_enabled) 1129 return (0); 1130 1131 subj = SLOT(cred->cr_label); 1132 obj = SLOT(mntlabel); 1133 1134 if (!mls_dominate_effective(subj, obj)) 1135 return (EACCES); 1136 1137 return (0); 1138 } 1139 1140 static void 1141 mls_mount_create(struct ucred *cred, struct mount *mp, struct label *mplabel) 1142 { 1143 struct mac_mls *source, *dest; 1144 1145 source = SLOT(cred->cr_label); 1146 dest = SLOT(mplabel); 1147 1148 mls_copy_effective(source, dest); 1149 } 1150 1151 static void 1152 mls_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel, 1153 struct mbuf *m, struct label *mlabel) 1154 { 1155 struct mac_mls *dest; 1156 1157 dest = SLOT(mlabel); 1158 1159 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1160 } 1161 1162 static void 1163 mls_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1164 struct mbuf *m, struct label *mlabel) 1165 { 1166 struct mac_mls *dest; 1167 1168 dest = SLOT(mlabel); 1169 1170 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1171 } 1172 1173 static void 1174 mls_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1175 struct mbuf *msend, struct label *msendlabel) 1176 { 1177 struct mac_mls *source, *dest; 1178 1179 source = SLOT(mrecvlabel); 1180 dest = SLOT(msendlabel); 1181 1182 mls_copy_effective(source, dest); 1183 } 1184 1185 static void 1186 mls_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1187 { 1188 struct mac_mls *dest; 1189 1190 dest = SLOT(mlabel); 1191 1192 /* XXX: where is the label for the firewall really comming from? */ 1193 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1194 } 1195 1196 static void 1197 mls_netinet_fragment(struct mbuf *m, struct label *mlabel, struct mbuf *frag, 1198 struct label *fraglabel) 1199 { 1200 struct mac_mls *source, *dest; 1201 1202 source = SLOT(mlabel); 1203 dest = SLOT(fraglabel); 1204 1205 mls_copy_effective(source, dest); 1206 } 1207 1208 static void 1209 mls_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1210 struct mbuf *msend, struct label *msendlabel) 1211 { 1212 struct mac_mls *source, *dest; 1213 1214 source = SLOT(mrecvlabel); 1215 dest = SLOT(msendlabel); 1216 1217 mls_copy_effective(source, dest); 1218 } 1219 1220 static void 1221 mls_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1222 struct mbuf *m, struct label *mlabel) 1223 { 1224 struct mac_mls *dest; 1225 1226 dest = SLOT(mlabel); 1227 1228 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1229 } 1230 1231 static void 1232 mls_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1233 struct mbuf *m, struct label *mlabel) 1234 { 1235 struct mac_mls *dest; 1236 1237 dest = SLOT(mlabel); 1238 1239 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1240 } 1241 1242 static int 1243 mls_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1244 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1245 { 1246 1247 if (!mls_enabled) 1248 return (0); 1249 1250 /* XXX: This will be implemented soon... */ 1251 1252 return (0); 1253 } 1254 1255 static int 1256 mls_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1257 struct label *pplabel) 1258 { 1259 struct mac_mls *subj, *obj; 1260 1261 if (!mls_enabled) 1262 return (0); 1263 1264 subj = SLOT(cred->cr_label); 1265 obj = SLOT(pplabel); 1266 1267 if (!mls_dominate_effective(subj, obj)) 1268 return (EACCES); 1269 1270 return (0); 1271 } 1272 1273 static int 1274 mls_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1275 struct label *pplabel) 1276 { 1277 struct mac_mls *subj, *obj; 1278 1279 if (!mls_enabled) 1280 return (0); 1281 1282 subj = SLOT(cred->cr_label); 1283 obj = SLOT(pplabel); 1284 1285 if (!mls_dominate_effective(subj, obj)) 1286 return (EACCES); 1287 1288 return (0); 1289 } 1290 1291 static int 1292 mls_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1293 struct label *pplabel, struct label *newlabel) 1294 { 1295 struct mac_mls *subj, *obj, *new; 1296 int error; 1297 1298 new = SLOT(newlabel); 1299 subj = SLOT(cred->cr_label); 1300 obj = SLOT(pplabel); 1301 1302 /* 1303 * If there is an MLS label update for a pipe, it must be a effective 1304 * update. 1305 */ 1306 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1307 if (error) 1308 return (error); 1309 1310 /* 1311 * To perform a relabel of a pipe (MLS label or not), MLS must 1312 * authorize the relabel. 1313 */ 1314 if (!mls_effective_in_range(obj, subj)) 1315 return (EPERM); 1316 1317 /* 1318 * If the MLS label is to be changed, authorize as appropriate. 1319 */ 1320 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1321 /* 1322 * To change the MLS label on a pipe, the new pipe label must 1323 * be in the subject range. 1324 */ 1325 if (!mls_effective_in_range(new, subj)) 1326 return (EPERM); 1327 1328 /* 1329 * To change the MLS label on a pipe to be EQUAL, the subject 1330 * must have appropriate privilege. 1331 */ 1332 if (mls_contains_equal(new)) { 1333 error = mls_subject_privileged(subj); 1334 if (error) 1335 return (error); 1336 } 1337 } 1338 1339 return (0); 1340 } 1341 1342 static int 1343 mls_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 1344 struct label *pplabel) 1345 { 1346 struct mac_mls *subj, *obj; 1347 1348 if (!mls_enabled) 1349 return (0); 1350 1351 subj = SLOT(cred->cr_label); 1352 obj = SLOT(pplabel); 1353 1354 if (!mls_dominate_effective(subj, obj)) 1355 return (EACCES); 1356 1357 return (0); 1358 } 1359 1360 static int 1361 mls_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1362 struct label *pplabel) 1363 { 1364 struct mac_mls *subj, *obj; 1365 1366 if (!mls_enabled) 1367 return (0); 1368 1369 subj = SLOT(cred->cr_label); 1370 obj = SLOT(pplabel); 1371 1372 if (!mls_dominate_effective(obj, subj)) 1373 return (EACCES); 1374 1375 return (0); 1376 } 1377 1378 static void 1379 mls_pipe_create(struct ucred *cred, struct pipepair *pp, 1380 struct label *pplabel) 1381 { 1382 struct mac_mls *source, *dest; 1383 1384 source = SLOT(cred->cr_label); 1385 dest = SLOT(pplabel); 1386 1387 mls_copy_effective(source, dest); 1388 } 1389 1390 static void 1391 mls_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1392 struct label *pplabel, struct label *newlabel) 1393 { 1394 struct mac_mls *source, *dest; 1395 1396 source = SLOT(newlabel); 1397 dest = SLOT(pplabel); 1398 1399 mls_copy(source, dest); 1400 } 1401 1402 static int 1403 mls_posixsem_check_rdonly(struct ucred *cred, struct ksem *ks, 1404 struct label *kslabel) 1405 { 1406 struct mac_mls *subj, *obj; 1407 1408 if (!mls_enabled) 1409 return (0); 1410 1411 subj = SLOT(cred->cr_label); 1412 obj = SLOT(kslabel); 1413 1414 if (!mls_dominate_effective(subj, obj)) 1415 return (EACCES); 1416 1417 return (0); 1418 } 1419 1420 static int 1421 mls_posixsem_check_write(struct ucred *cred, struct ksem *ks, 1422 struct label *kslabel) 1423 { 1424 struct mac_mls *subj, *obj; 1425 1426 if (!mls_enabled) 1427 return (0); 1428 1429 subj = SLOT(cred->cr_label); 1430 obj = SLOT(kslabel); 1431 1432 if (!mls_dominate_effective(obj, subj)) 1433 return (EACCES); 1434 1435 return (0); 1436 } 1437 1438 static void 1439 mls_posixsem_create(struct ucred *cred, struct ksem *ks, 1440 struct label *kslabel) 1441 { 1442 struct mac_mls *source, *dest; 1443 1444 source = SLOT(cred->cr_label); 1445 dest = SLOT(kslabel); 1446 1447 mls_copy_effective(source, dest); 1448 } 1449 1450 static void 1451 mls_proc_associate_nfsd(struct ucred *cred) 1452 { 1453 struct mac_mls *label; 1454 1455 label = SLOT(cred->cr_label); 1456 mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL); 1457 mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1458 NULL); 1459 } 1460 1461 static int 1462 mls_proc_check_debug(struct ucred *cred, struct proc *p) 1463 { 1464 struct mac_mls *subj, *obj; 1465 1466 if (!mls_enabled) 1467 return (0); 1468 1469 subj = SLOT(cred->cr_label); 1470 obj = SLOT(p->p_ucred->cr_label); 1471 1472 /* XXX: range checks */ 1473 if (!mls_dominate_effective(subj, obj)) 1474 return (ESRCH); 1475 if (!mls_dominate_effective(obj, subj)) 1476 return (EACCES); 1477 1478 return (0); 1479 } 1480 1481 static int 1482 mls_proc_check_sched(struct ucred *cred, struct proc *p) 1483 { 1484 struct mac_mls *subj, *obj; 1485 1486 if (!mls_enabled) 1487 return (0); 1488 1489 subj = SLOT(cred->cr_label); 1490 obj = SLOT(p->p_ucred->cr_label); 1491 1492 /* XXX: range checks */ 1493 if (!mls_dominate_effective(subj, obj)) 1494 return (ESRCH); 1495 if (!mls_dominate_effective(obj, subj)) 1496 return (EACCES); 1497 1498 return (0); 1499 } 1500 1501 static int 1502 mls_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1503 { 1504 struct mac_mls *subj, *obj; 1505 1506 if (!mls_enabled) 1507 return (0); 1508 1509 subj = SLOT(cred->cr_label); 1510 obj = SLOT(p->p_ucred->cr_label); 1511 1512 /* XXX: range checks */ 1513 if (!mls_dominate_effective(subj, obj)) 1514 return (ESRCH); 1515 if (!mls_dominate_effective(obj, subj)) 1516 return (EACCES); 1517 1518 return (0); 1519 } 1520 1521 static void 1522 mls_proc_create_init(struct ucred *cred) 1523 { 1524 struct mac_mls *dest; 1525 1526 dest = SLOT(cred->cr_label); 1527 1528 mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL); 1529 mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1530 NULL); 1531 } 1532 1533 static void 1534 mls_proc_create_swapper(struct ucred *cred) 1535 { 1536 struct mac_mls *dest; 1537 1538 dest = SLOT(cred->cr_label); 1539 1540 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1541 mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1542 NULL); 1543 } 1544 1545 static int 1546 mls_socket_check_deliver(struct socket *so, struct label *solabel, 1547 struct mbuf *m, struct label *mlabel) 1548 { 1549 struct mac_mls *p, *s; 1550 1551 if (!mls_enabled) 1552 return (0); 1553 1554 p = SLOT(mlabel); 1555 s = SLOT(solabel); 1556 1557 return (mls_equal_effective(p, s) ? 0 : EACCES); 1558 } 1559 1560 static int 1561 mls_socket_check_relabel(struct ucred *cred, struct socket *so, 1562 struct label *solabel, struct label *newlabel) 1563 { 1564 struct mac_mls *subj, *obj, *new; 1565 int error; 1566 1567 new = SLOT(newlabel); 1568 subj = SLOT(cred->cr_label); 1569 obj = SLOT(solabel); 1570 1571 /* 1572 * If there is an MLS label update for the socket, it may be an 1573 * update of effective. 1574 */ 1575 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1576 if (error) 1577 return (error); 1578 1579 /* 1580 * To relabel a socket, the old socket effective must be in the 1581 * subject range. 1582 */ 1583 if (!mls_effective_in_range(obj, subj)) 1584 return (EPERM); 1585 1586 /* 1587 * If the MLS label is to be changed, authorize as appropriate. 1588 */ 1589 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1590 /* 1591 * To relabel a socket, the new socket effective must be in 1592 * the subject range. 1593 */ 1594 if (!mls_effective_in_range(new, subj)) 1595 return (EPERM); 1596 1597 /* 1598 * To change the MLS label on the socket to contain EQUAL, 1599 * the subject must have appropriate privilege. 1600 */ 1601 if (mls_contains_equal(new)) { 1602 error = mls_subject_privileged(subj); 1603 if (error) 1604 return (error); 1605 } 1606 } 1607 1608 return (0); 1609 } 1610 1611 static int 1612 mls_socket_check_visible(struct ucred *cred, struct socket *so, 1613 struct label *solabel) 1614 { 1615 struct mac_mls *subj, *obj; 1616 1617 if (!mls_enabled) 1618 return (0); 1619 1620 subj = SLOT(cred->cr_label); 1621 obj = SLOT(solabel); 1622 1623 if (!mls_dominate_effective(subj, obj)) 1624 return (ENOENT); 1625 1626 return (0); 1627 } 1628 1629 static void 1630 mls_socket_create(struct ucred *cred, struct socket *so, 1631 struct label *solabel) 1632 { 1633 struct mac_mls *source, *dest; 1634 1635 source = SLOT(cred->cr_label); 1636 dest = SLOT(solabel); 1637 1638 mls_copy_effective(source, dest); 1639 } 1640 1641 static void 1642 mls_socket_create_mbuf(struct socket *so, struct label *solabel, 1643 struct mbuf *m, struct label *mlabel) 1644 { 1645 struct mac_mls *source, *dest; 1646 1647 source = SLOT(solabel); 1648 dest = SLOT(mlabel); 1649 1650 mls_copy_effective(source, dest); 1651 } 1652 1653 static void 1654 mls_socket_newconn(struct socket *oldso, struct label *oldsolabel, 1655 struct socket *newso, struct label *newsolabel) 1656 { 1657 struct mac_mls *source, *dest; 1658 1659 source = SLOT(oldsolabel); 1660 dest = SLOT(newsolabel); 1661 1662 mls_copy_effective(source, dest); 1663 } 1664 1665 static void 1666 mls_socket_relabel(struct ucred *cred, struct socket *so, 1667 struct label *solabel, struct label *newlabel) 1668 { 1669 struct mac_mls *source, *dest; 1670 1671 source = SLOT(newlabel); 1672 dest = SLOT(solabel); 1673 1674 mls_copy(source, dest); 1675 } 1676 1677 static void 1678 mls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 1679 struct socket *so, struct label *sopeerlabel) 1680 { 1681 struct mac_mls *source, *dest; 1682 1683 source = SLOT(mlabel); 1684 dest = SLOT(sopeerlabel); 1685 1686 mls_copy_effective(source, dest); 1687 } 1688 1689 static void 1690 mls_socketpeer_set_from_socket(struct socket *oldso, 1691 struct label *oldsolabel, struct socket *newso, 1692 struct label *newsopeerlabel) 1693 { 1694 struct mac_mls *source, *dest; 1695 1696 source = SLOT(oldsolabel); 1697 dest = SLOT(newsopeerlabel); 1698 1699 mls_copy_effective(source, dest); 1700 } 1701 1702 static void 1703 mls_syncache_create(struct label *label, struct inpcb *inp) 1704 { 1705 struct mac_mls *source, *dest; 1706 1707 source = SLOT(inp->inp_label); 1708 dest = SLOT(label); 1709 1710 mls_copy_effective(source, dest); 1711 } 1712 1713 static void 1714 mls_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 1715 struct label *mlabel) 1716 { 1717 struct mac_mls *source, *dest; 1718 1719 source = SLOT(sc_label); 1720 dest = SLOT(mlabel); 1721 1722 mls_copy_effective(source, dest); 1723 } 1724 1725 static int 1726 mls_system_check_acct(struct ucred *cred, struct vnode *vp, 1727 struct label *vplabel) 1728 { 1729 struct mac_mls *subj, *obj; 1730 1731 if (!mls_enabled) 1732 return (0); 1733 1734 subj = SLOT(cred->cr_label); 1735 obj = SLOT(vplabel); 1736 1737 if (!mls_dominate_effective(obj, subj) || 1738 !mls_dominate_effective(subj, obj)) 1739 return (EACCES); 1740 1741 return (0); 1742 } 1743 1744 static int 1745 mls_system_check_auditctl(struct ucred *cred, struct vnode *vp, 1746 struct label *vplabel) 1747 { 1748 struct mac_mls *subj, *obj; 1749 1750 if (!mls_enabled) 1751 return (0); 1752 1753 subj = SLOT(cred->cr_label); 1754 obj = SLOT(vplabel); 1755 1756 if (!mls_dominate_effective(obj, subj) || 1757 !mls_dominate_effective(subj, obj)) 1758 return (EACCES); 1759 1760 return (0); 1761 } 1762 1763 static int 1764 mls_system_check_swapon(struct ucred *cred, struct vnode *vp, 1765 struct label *vplabel) 1766 { 1767 struct mac_mls *subj, *obj; 1768 1769 if (!mls_enabled) 1770 return (0); 1771 1772 subj = SLOT(cred->cr_label); 1773 obj = SLOT(vplabel); 1774 1775 if (!mls_dominate_effective(obj, subj) || 1776 !mls_dominate_effective(subj, obj)) 1777 return (EACCES); 1778 1779 return (0); 1780 } 1781 1782 static void 1783 mls_sysvmsg_cleanup(struct label *msglabel) 1784 { 1785 1786 bzero(SLOT(msglabel), sizeof(struct mac_mls)); 1787 } 1788 1789 static void 1790 mls_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1791 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1792 { 1793 struct mac_mls *source, *dest; 1794 1795 /* Ignore the msgq label. */ 1796 source = SLOT(cred->cr_label); 1797 dest = SLOT(msglabel); 1798 1799 mls_copy_effective(source, dest); 1800 } 1801 1802 static int 1803 mls_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 1804 struct label *msglabel) 1805 { 1806 struct mac_mls *subj, *obj; 1807 1808 if (!mls_enabled) 1809 return (0); 1810 1811 subj = SLOT(cred->cr_label); 1812 obj = SLOT(msglabel); 1813 1814 if (!mls_dominate_effective(subj, obj)) 1815 return (EACCES); 1816 1817 return (0); 1818 } 1819 1820 static int 1821 mls_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 1822 struct label *msglabel) 1823 { 1824 struct mac_mls *subj, *obj; 1825 1826 if (!mls_enabled) 1827 return (0); 1828 1829 subj = SLOT(cred->cr_label); 1830 obj = SLOT(msglabel); 1831 1832 if (!mls_dominate_effective(obj, subj)) 1833 return (EACCES); 1834 1835 return (0); 1836 } 1837 1838 static int 1839 mls_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1840 struct label *msqklabel) 1841 { 1842 struct mac_mls *subj, *obj; 1843 1844 if (!mls_enabled) 1845 return (0); 1846 1847 subj = SLOT(cred->cr_label); 1848 obj = SLOT(msqklabel); 1849 1850 if (!mls_dominate_effective(subj, obj)) 1851 return (EACCES); 1852 1853 return (0); 1854 } 1855 1856 static int 1857 mls_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1858 struct label *msqklabel) 1859 { 1860 struct mac_mls *subj, *obj; 1861 1862 if (!mls_enabled) 1863 return (0); 1864 1865 subj = SLOT(cred->cr_label); 1866 obj = SLOT(msqklabel); 1867 1868 if (!mls_dominate_effective(obj, subj)) 1869 return (EACCES); 1870 1871 return (0); 1872 } 1873 1874 static int 1875 mls_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1876 struct label *msqklabel) 1877 { 1878 struct mac_mls *subj, *obj; 1879 1880 if (!mls_enabled) 1881 return (0); 1882 1883 subj = SLOT(cred->cr_label); 1884 obj = SLOT(msqklabel); 1885 1886 if (!mls_dominate_effective(subj, obj)) 1887 return (EACCES); 1888 1889 return (0); 1890 } 1891 1892 static int 1893 mls_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1894 struct label *msqklabel, int cmd) 1895 { 1896 struct mac_mls *subj, *obj; 1897 1898 if (!mls_enabled) 1899 return (0); 1900 1901 subj = SLOT(cred->cr_label); 1902 obj = SLOT(msqklabel); 1903 1904 switch(cmd) { 1905 case IPC_RMID: 1906 case IPC_SET: 1907 if (!mls_dominate_effective(obj, subj)) 1908 return (EACCES); 1909 break; 1910 1911 case IPC_STAT: 1912 if (!mls_dominate_effective(subj, obj)) 1913 return (EACCES); 1914 break; 1915 1916 default: 1917 return (EACCES); 1918 } 1919 1920 return (0); 1921 } 1922 1923 static void 1924 mls_sysvmsq_cleanup(struct label *msqlabel) 1925 { 1926 1927 bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 1928 } 1929 1930 static void 1931 mls_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1932 struct label *msqlabel) 1933 { 1934 struct mac_mls *source, *dest; 1935 1936 source = SLOT(cred->cr_label); 1937 dest = SLOT(msqlabel); 1938 1939 mls_copy_effective(source, dest); 1940 } 1941 1942 static int 1943 mls_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1944 struct label *semaklabel, int cmd) 1945 { 1946 struct mac_mls *subj, *obj; 1947 1948 if (!mls_enabled) 1949 return (0); 1950 1951 subj = SLOT(cred->cr_label); 1952 obj = SLOT(semaklabel); 1953 1954 switch(cmd) { 1955 case IPC_RMID: 1956 case IPC_SET: 1957 case SETVAL: 1958 case SETALL: 1959 if (!mls_dominate_effective(obj, subj)) 1960 return (EACCES); 1961 break; 1962 1963 case IPC_STAT: 1964 case GETVAL: 1965 case GETPID: 1966 case GETNCNT: 1967 case GETZCNT: 1968 case GETALL: 1969 if (!mls_dominate_effective(subj, obj)) 1970 return (EACCES); 1971 break; 1972 1973 default: 1974 return (EACCES); 1975 } 1976 1977 return (0); 1978 } 1979 1980 static int 1981 mls_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 1982 struct label *semaklabel) 1983 { 1984 struct mac_mls *subj, *obj; 1985 1986 if (!mls_enabled) 1987 return (0); 1988 1989 subj = SLOT(cred->cr_label); 1990 obj = SLOT(semaklabel); 1991 1992 if (!mls_dominate_effective(subj, obj)) 1993 return (EACCES); 1994 1995 return (0); 1996 } 1997 1998 static int 1999 mls_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2000 struct label *semaklabel, size_t accesstype) 2001 { 2002 struct mac_mls *subj, *obj; 2003 2004 if (!mls_enabled) 2005 return (0); 2006 2007 subj = SLOT(cred->cr_label); 2008 obj = SLOT(semaklabel); 2009 2010 if( accesstype & SEM_R ) 2011 if (!mls_dominate_effective(subj, obj)) 2012 return (EACCES); 2013 2014 if( accesstype & SEM_A ) 2015 if (!mls_dominate_effective(obj, subj)) 2016 return (EACCES); 2017 2018 return (0); 2019 } 2020 2021 static void 2022 mls_sysvsem_cleanup(struct label *semalabel) 2023 { 2024 2025 bzero(SLOT(semalabel), sizeof(struct mac_mls)); 2026 } 2027 2028 static void 2029 mls_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2030 struct label *semalabel) 2031 { 2032 struct mac_mls *source, *dest; 2033 2034 source = SLOT(cred->cr_label); 2035 dest = SLOT(semalabel); 2036 2037 mls_copy_effective(source, dest); 2038 } 2039 2040 static int 2041 mls_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2042 struct label *shmseglabel, int shmflg) 2043 { 2044 struct mac_mls *subj, *obj; 2045 2046 if (!mls_enabled) 2047 return (0); 2048 2049 subj = SLOT(cred->cr_label); 2050 obj = SLOT(shmseglabel); 2051 2052 if (!mls_dominate_effective(subj, obj)) 2053 return (EACCES); 2054 if ((shmflg & SHM_RDONLY) == 0) { 2055 if (!mls_dominate_effective(obj, subj)) 2056 return (EACCES); 2057 } 2058 2059 return (0); 2060 } 2061 2062 static int 2063 mls_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2064 struct label *shmseglabel, int cmd) 2065 { 2066 struct mac_mls *subj, *obj; 2067 2068 if (!mls_enabled) 2069 return (0); 2070 2071 subj = SLOT(cred->cr_label); 2072 obj = SLOT(shmseglabel); 2073 2074 switch(cmd) { 2075 case IPC_RMID: 2076 case IPC_SET: 2077 if (!mls_dominate_effective(obj, subj)) 2078 return (EACCES); 2079 break; 2080 2081 case IPC_STAT: 2082 case SHM_STAT: 2083 if (!mls_dominate_effective(subj, obj)) 2084 return (EACCES); 2085 break; 2086 2087 default: 2088 return (EACCES); 2089 } 2090 2091 return (0); 2092 } 2093 2094 static int 2095 mls_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2096 struct label *shmseglabel, int shmflg) 2097 { 2098 struct mac_mls *subj, *obj; 2099 2100 if (!mls_enabled) 2101 return (0); 2102 2103 subj = SLOT(cred->cr_label); 2104 obj = SLOT(shmseglabel); 2105 2106 if (!mls_dominate_effective(obj, subj)) 2107 return (EACCES); 2108 2109 return (0); 2110 } 2111 2112 static void 2113 mls_sysvshm_cleanup(struct label *shmlabel) 2114 { 2115 2116 bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 2117 } 2118 2119 static void 2120 mls_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2121 struct label *shmlabel) 2122 { 2123 struct mac_mls *source, *dest; 2124 2125 source = SLOT(cred->cr_label); 2126 dest = SLOT(shmlabel); 2127 2128 mls_copy_effective(source, dest); 2129 } 2130 2131 static int 2132 mls_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2133 struct vnode *vp, struct label *vplabel) 2134 { 2135 struct mac_mls mm_temp, *source, *dest; 2136 int buflen, error; 2137 2138 source = SLOT(mplabel); 2139 dest = SLOT(vplabel); 2140 2141 buflen = sizeof(mm_temp); 2142 bzero(&mm_temp, buflen); 2143 2144 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2145 MAC_MLS_EXTATTR_NAME, &buflen, (char *) &mm_temp, curthread); 2146 if (error == ENOATTR || error == EOPNOTSUPP) { 2147 /* Fall back to the mntlabel. */ 2148 mls_copy_effective(source, dest); 2149 return (0); 2150 } else if (error) 2151 return (error); 2152 2153 if (buflen != sizeof(mm_temp)) { 2154 printf("mls_vnode_associate_extattr: bad size %d\n", buflen); 2155 return (EPERM); 2156 } 2157 if (mls_valid(&mm_temp) != 0) { 2158 printf("mls_vnode_associate_extattr: invalid\n"); 2159 return (EPERM); 2160 } 2161 if ((mm_temp.mm_flags & MAC_MLS_FLAGS_BOTH) != 2162 MAC_MLS_FLAG_EFFECTIVE) { 2163 printf("mls_associated_vnode_extattr: not effective\n"); 2164 return (EPERM); 2165 } 2166 2167 mls_copy_effective(&mm_temp, dest); 2168 return (0); 2169 } 2170 2171 static void 2172 mls_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2173 struct vnode *vp, struct label *vplabel) 2174 { 2175 struct mac_mls *source, *dest; 2176 2177 source = SLOT(mplabel); 2178 dest = SLOT(vplabel); 2179 2180 mls_copy_effective(source, dest); 2181 } 2182 2183 static int 2184 mls_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2185 struct label *dvplabel) 2186 { 2187 struct mac_mls *subj, *obj; 2188 2189 if (!mls_enabled) 2190 return (0); 2191 2192 subj = SLOT(cred->cr_label); 2193 obj = SLOT(dvplabel); 2194 2195 if (!mls_dominate_effective(subj, obj)) 2196 return (EACCES); 2197 2198 return (0); 2199 } 2200 2201 static int 2202 mls_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2203 struct label *dvplabel) 2204 { 2205 struct mac_mls *subj, *obj; 2206 2207 if (!mls_enabled) 2208 return (0); 2209 2210 subj = SLOT(cred->cr_label); 2211 obj = SLOT(dvplabel); 2212 2213 if (!mls_dominate_effective(subj, obj)) 2214 return (EACCES); 2215 2216 return (0); 2217 } 2218 2219 static int 2220 mls_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2221 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2222 { 2223 struct mac_mls *subj, *obj; 2224 2225 if (!mls_enabled) 2226 return (0); 2227 2228 subj = SLOT(cred->cr_label); 2229 obj = SLOT(dvplabel); 2230 2231 if (!mls_dominate_effective(obj, subj)) 2232 return (EACCES); 2233 2234 return (0); 2235 } 2236 2237 static int 2238 mls_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2239 struct label *vplabel, acl_type_t type) 2240 { 2241 struct mac_mls *subj, *obj; 2242 2243 if (!mls_enabled) 2244 return (0); 2245 2246 subj = SLOT(cred->cr_label); 2247 obj = SLOT(vplabel); 2248 2249 if (!mls_dominate_effective(obj, subj)) 2250 return (EACCES); 2251 2252 return (0); 2253 } 2254 2255 static int 2256 mls_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2257 struct label *vplabel, int attrnamespace, const char *name) 2258 { 2259 struct mac_mls *subj, *obj; 2260 2261 if (!mls_enabled) 2262 return (0); 2263 2264 subj = SLOT(cred->cr_label); 2265 obj = SLOT(vplabel); 2266 2267 if (!mls_dominate_effective(obj, subj)) 2268 return (EACCES); 2269 2270 return (0); 2271 } 2272 2273 static int 2274 mls_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2275 struct label *vplabel, struct image_params *imgp, 2276 struct label *execlabel) 2277 { 2278 struct mac_mls *subj, *obj, *exec; 2279 int error; 2280 2281 if (execlabel != NULL) { 2282 /* 2283 * We currently don't permit labels to be changed at 2284 * exec-time as part of MLS, so disallow non-NULL MLS label 2285 * elements in the execlabel. 2286 */ 2287 exec = SLOT(execlabel); 2288 error = mls_atmostflags(exec, 0); 2289 if (error) 2290 return (error); 2291 } 2292 2293 if (!mls_enabled) 2294 return (0); 2295 2296 subj = SLOT(cred->cr_label); 2297 obj = SLOT(vplabel); 2298 2299 if (!mls_dominate_effective(subj, obj)) 2300 return (EACCES); 2301 2302 return (0); 2303 } 2304 2305 static int 2306 mls_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2307 struct label *vplabel, acl_type_t type) 2308 { 2309 struct mac_mls *subj, *obj; 2310 2311 if (!mls_enabled) 2312 return (0); 2313 2314 subj = SLOT(cred->cr_label); 2315 obj = SLOT(vplabel); 2316 2317 if (!mls_dominate_effective(subj, obj)) 2318 return (EACCES); 2319 2320 return (0); 2321 } 2322 2323 static int 2324 mls_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 2325 struct label *vplabel, int attrnamespace, const char *name, 2326 struct uio *uio) 2327 { 2328 struct mac_mls *subj, *obj; 2329 2330 if (!mls_enabled) 2331 return (0); 2332 2333 subj = SLOT(cred->cr_label); 2334 obj = SLOT(vplabel); 2335 2336 if (!mls_dominate_effective(subj, obj)) 2337 return (EACCES); 2338 2339 return (0); 2340 } 2341 2342 static int 2343 mls_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2344 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2345 struct componentname *cnp) 2346 { 2347 struct mac_mls *subj, *obj; 2348 2349 if (!mls_enabled) 2350 return (0); 2351 2352 subj = SLOT(cred->cr_label); 2353 obj = SLOT(dvplabel); 2354 2355 if (!mls_dominate_effective(obj, subj)) 2356 return (EACCES); 2357 2358 obj = SLOT(vplabel); 2359 if (!mls_dominate_effective(obj, subj)) 2360 return (EACCES); 2361 2362 return (0); 2363 } 2364 2365 static int 2366 mls_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 2367 struct label *vplabel, int attrnamespace) 2368 { 2369 2370 struct mac_mls *subj, *obj; 2371 2372 if (!mls_enabled) 2373 return (0); 2374 2375 subj = SLOT(cred->cr_label); 2376 obj = SLOT(vplabel); 2377 2378 if (!mls_dominate_effective(subj, obj)) 2379 return (EACCES); 2380 2381 return (0); 2382 } 2383 2384 static int 2385 mls_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 2386 struct label *dvplabel, struct componentname *cnp) 2387 { 2388 struct mac_mls *subj, *obj; 2389 2390 if (!mls_enabled) 2391 return (0); 2392 2393 subj = SLOT(cred->cr_label); 2394 obj = SLOT(dvplabel); 2395 2396 if (!mls_dominate_effective(subj, obj)) 2397 return (EACCES); 2398 2399 return (0); 2400 } 2401 2402 static int 2403 mls_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2404 struct label *vplabel, int prot, int flags) 2405 { 2406 struct mac_mls *subj, *obj; 2407 2408 /* 2409 * Rely on the use of open()-time protections to handle 2410 * non-revocation cases. 2411 */ 2412 if (!mls_enabled || !revocation_enabled) 2413 return (0); 2414 2415 subj = SLOT(cred->cr_label); 2416 obj = SLOT(vplabel); 2417 2418 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2419 if (!mls_dominate_effective(subj, obj)) 2420 return (EACCES); 2421 } 2422 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2423 if (!mls_dominate_effective(obj, subj)) 2424 return (EACCES); 2425 } 2426 2427 return (0); 2428 } 2429 2430 static int 2431 mls_vnode_check_open(struct ucred *cred, struct vnode *vp, 2432 struct label *vplabel, int acc_mode) 2433 { 2434 struct mac_mls *subj, *obj; 2435 2436 if (!mls_enabled) 2437 return (0); 2438 2439 subj = SLOT(cred->cr_label); 2440 obj = SLOT(vplabel); 2441 2442 /* XXX privilege override for admin? */ 2443 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2444 if (!mls_dominate_effective(subj, obj)) 2445 return (EACCES); 2446 } 2447 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2448 if (!mls_dominate_effective(obj, subj)) 2449 return (EACCES); 2450 } 2451 2452 return (0); 2453 } 2454 2455 static int 2456 mls_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 2457 struct vnode *vp, struct label *vplabel) 2458 { 2459 struct mac_mls *subj, *obj; 2460 2461 if (!mls_enabled || !revocation_enabled) 2462 return (0); 2463 2464 subj = SLOT(active_cred->cr_label); 2465 obj = SLOT(vplabel); 2466 2467 if (!mls_dominate_effective(subj, obj)) 2468 return (EACCES); 2469 2470 return (0); 2471 } 2472 2473 static int 2474 mls_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2475 struct vnode *vp, struct label *vplabel) 2476 { 2477 struct mac_mls *subj, *obj; 2478 2479 if (!mls_enabled || !revocation_enabled) 2480 return (0); 2481 2482 subj = SLOT(active_cred->cr_label); 2483 obj = SLOT(vplabel); 2484 2485 if (!mls_dominate_effective(subj, obj)) 2486 return (EACCES); 2487 2488 return (0); 2489 } 2490 2491 static int 2492 mls_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 2493 struct label *dvplabel) 2494 { 2495 struct mac_mls *subj, *obj; 2496 2497 if (!mls_enabled) 2498 return (0); 2499 2500 subj = SLOT(cred->cr_label); 2501 obj = SLOT(dvplabel); 2502 2503 if (!mls_dominate_effective(subj, obj)) 2504 return (EACCES); 2505 2506 return (0); 2507 } 2508 2509 static int 2510 mls_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 2511 struct label *vplabel) 2512 { 2513 struct mac_mls *subj, *obj; 2514 2515 if (!mls_enabled) 2516 return (0); 2517 2518 subj = SLOT(cred->cr_label); 2519 obj = SLOT(vplabel); 2520 2521 if (!mls_dominate_effective(subj, obj)) 2522 return (EACCES); 2523 2524 return (0); 2525 } 2526 2527 static int 2528 mls_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2529 struct label *vplabel, struct label *newlabel) 2530 { 2531 struct mac_mls *old, *new, *subj; 2532 int error; 2533 2534 old = SLOT(vplabel); 2535 new = SLOT(newlabel); 2536 subj = SLOT(cred->cr_label); 2537 2538 /* 2539 * If there is an MLS label update for the vnode, it must be a 2540 * effective label. 2541 */ 2542 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2543 if (error) 2544 return (error); 2545 2546 /* 2547 * To perform a relabel of the vnode (MLS label or not), MLS must 2548 * authorize the relabel. 2549 */ 2550 if (!mls_effective_in_range(old, subj)) 2551 return (EPERM); 2552 2553 /* 2554 * If the MLS label is to be changed, authorize as appropriate. 2555 */ 2556 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2557 /* 2558 * To change the MLS label on a vnode, the new vnode label 2559 * must be in the subject range. 2560 */ 2561 if (!mls_effective_in_range(new, subj)) 2562 return (EPERM); 2563 2564 /* 2565 * To change the MLS label on the vnode to be EQUAL, the 2566 * subject must have appropriate privilege. 2567 */ 2568 if (mls_contains_equal(new)) { 2569 error = mls_subject_privileged(subj); 2570 if (error) 2571 return (error); 2572 } 2573 } 2574 2575 return (0); 2576 } 2577 2578 static int 2579 mls_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2580 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2581 struct componentname *cnp) 2582 { 2583 struct mac_mls *subj, *obj; 2584 2585 if (!mls_enabled) 2586 return (0); 2587 2588 subj = SLOT(cred->cr_label); 2589 obj = SLOT(dvplabel); 2590 2591 if (!mls_dominate_effective(obj, subj)) 2592 return (EACCES); 2593 2594 obj = SLOT(vplabel); 2595 2596 if (!mls_dominate_effective(obj, subj)) 2597 return (EACCES); 2598 2599 return (0); 2600 } 2601 2602 static int 2603 mls_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2604 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2605 int samedir, struct componentname *cnp) 2606 { 2607 struct mac_mls *subj, *obj; 2608 2609 if (!mls_enabled) 2610 return (0); 2611 2612 subj = SLOT(cred->cr_label); 2613 obj = SLOT(dvplabel); 2614 2615 if (!mls_dominate_effective(obj, subj)) 2616 return (EACCES); 2617 2618 if (vp != NULL) { 2619 obj = SLOT(vplabel); 2620 2621 if (!mls_dominate_effective(obj, subj)) 2622 return (EACCES); 2623 } 2624 2625 return (0); 2626 } 2627 2628 static int 2629 mls_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2630 struct label *vplabel) 2631 { 2632 struct mac_mls *subj, *obj; 2633 2634 if (!mls_enabled) 2635 return (0); 2636 2637 subj = SLOT(cred->cr_label); 2638 obj = SLOT(vplabel); 2639 2640 if (!mls_dominate_effective(obj, subj)) 2641 return (EACCES); 2642 2643 return (0); 2644 } 2645 2646 static int 2647 mls_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2648 struct label *vplabel, acl_type_t type, struct acl *acl) 2649 { 2650 struct mac_mls *subj, *obj; 2651 2652 if (!mls_enabled) 2653 return (0); 2654 2655 subj = SLOT(cred->cr_label); 2656 obj = SLOT(vplabel); 2657 2658 if (!mls_dominate_effective(obj, subj)) 2659 return (EACCES); 2660 2661 return (0); 2662 } 2663 2664 static int 2665 mls_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2666 struct label *vplabel, int attrnamespace, const char *name, 2667 struct uio *uio) 2668 { 2669 struct mac_mls *subj, *obj; 2670 2671 if (!mls_enabled) 2672 return (0); 2673 2674 subj = SLOT(cred->cr_label); 2675 obj = SLOT(vplabel); 2676 2677 if (!mls_dominate_effective(obj, subj)) 2678 return (EACCES); 2679 2680 /* XXX: protect the MAC EA in a special way? */ 2681 2682 return (0); 2683 } 2684 2685 static int 2686 mls_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2687 struct label *vplabel, u_long flags) 2688 { 2689 struct mac_mls *subj, *obj; 2690 2691 if (!mls_enabled) 2692 return (0); 2693 2694 subj = SLOT(cred->cr_label); 2695 obj = SLOT(vplabel); 2696 2697 if (!mls_dominate_effective(obj, subj)) 2698 return (EACCES); 2699 2700 return (0); 2701 } 2702 2703 static int 2704 mls_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 2705 struct label *vplabel, mode_t mode) 2706 { 2707 struct mac_mls *subj, *obj; 2708 2709 if (!mls_enabled) 2710 return (0); 2711 2712 subj = SLOT(cred->cr_label); 2713 obj = SLOT(vplabel); 2714 2715 if (!mls_dominate_effective(obj, subj)) 2716 return (EACCES); 2717 2718 return (0); 2719 } 2720 2721 static int 2722 mls_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 2723 struct label *vplabel, uid_t uid, gid_t gid) 2724 { 2725 struct mac_mls *subj, *obj; 2726 2727 if (!mls_enabled) 2728 return (0); 2729 2730 subj = SLOT(cred->cr_label); 2731 obj = SLOT(vplabel); 2732 2733 if (!mls_dominate_effective(obj, subj)) 2734 return (EACCES); 2735 2736 return (0); 2737 } 2738 2739 static int 2740 mls_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 2741 struct label *vplabel, struct timespec atime, struct timespec mtime) 2742 { 2743 struct mac_mls *subj, *obj; 2744 2745 if (!mls_enabled) 2746 return (0); 2747 2748 subj = SLOT(cred->cr_label); 2749 obj = SLOT(vplabel); 2750 2751 if (!mls_dominate_effective(obj, subj)) 2752 return (EACCES); 2753 2754 return (0); 2755 } 2756 2757 static int 2758 mls_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 2759 struct vnode *vp, struct label *vplabel) 2760 { 2761 struct mac_mls *subj, *obj; 2762 2763 if (!mls_enabled) 2764 return (0); 2765 2766 subj = SLOT(active_cred->cr_label); 2767 obj = SLOT(vplabel); 2768 2769 if (!mls_dominate_effective(subj, obj)) 2770 return (EACCES); 2771 2772 return (0); 2773 } 2774 2775 static int 2776 mls_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 2777 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2778 struct componentname *cnp) 2779 { 2780 struct mac_mls *subj, *obj; 2781 2782 if (!mls_enabled) 2783 return (0); 2784 2785 subj = SLOT(cred->cr_label); 2786 obj = SLOT(dvplabel); 2787 2788 if (!mls_dominate_effective(obj, subj)) 2789 return (EACCES); 2790 2791 obj = SLOT(vplabel); 2792 2793 if (!mls_dominate_effective(obj, subj)) 2794 return (EACCES); 2795 2796 return (0); 2797 } 2798 2799 static int 2800 mls_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred, 2801 struct vnode *vp, struct label *vplabel) 2802 { 2803 struct mac_mls *subj, *obj; 2804 2805 if (!mls_enabled || !revocation_enabled) 2806 return (0); 2807 2808 subj = SLOT(active_cred->cr_label); 2809 obj = SLOT(vplabel); 2810 2811 if (!mls_dominate_effective(obj, subj)) 2812 return (EACCES); 2813 2814 return (0); 2815 } 2816 2817 static int 2818 mls_vnode_create_extattr(struct ucred *cred, struct mount *mp, 2819 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 2820 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 2821 { 2822 struct mac_mls *source, *dest, mm_temp; 2823 size_t buflen; 2824 int error; 2825 2826 buflen = sizeof(mm_temp); 2827 bzero(&mm_temp, buflen); 2828 2829 source = SLOT(cred->cr_label); 2830 dest = SLOT(vplabel); 2831 mls_copy_effective(source, &mm_temp); 2832 2833 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2834 MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 2835 if (error == 0) 2836 mls_copy_effective(source, dest); 2837 return (error); 2838 } 2839 2840 static void 2841 mls_vnode_relabel(struct ucred *cred, struct vnode *vp, 2842 struct label *vplabel, struct label *label) 2843 { 2844 struct mac_mls *source, *dest; 2845 2846 source = SLOT(label); 2847 dest = SLOT(vplabel); 2848 2849 mls_copy(source, dest); 2850 } 2851 2852 static int 2853 mls_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 2854 struct label *vplabel, struct label *intlabel) 2855 { 2856 struct mac_mls *source, mm_temp; 2857 size_t buflen; 2858 int error; 2859 2860 buflen = sizeof(mm_temp); 2861 bzero(&mm_temp, buflen); 2862 2863 source = SLOT(intlabel); 2864 if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 2865 return (0); 2866 2867 mls_copy_effective(source, &mm_temp); 2868 2869 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2870 MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 2871 return (error); 2872 } 2873 2874 static struct mac_policy_ops mls_ops = 2875 { 2876 .mpo_init = mls_init, 2877 2878 .mpo_bpfdesc_check_receive = mls_bpfdesc_check_receive, 2879 .mpo_bpfdesc_create = mls_bpfdesc_create, 2880 .mpo_bpfdesc_create_mbuf = mls_bpfdesc_create_mbuf, 2881 .mpo_bpfdesc_destroy_label = mls_destroy_label, 2882 .mpo_bpfdesc_init_label = mls_init_label, 2883 2884 .mpo_cred_check_relabel = mls_cred_check_relabel, 2885 .mpo_cred_check_visible = mls_cred_check_visible, 2886 .mpo_cred_copy_label = mls_copy_label, 2887 .mpo_cred_destroy_label = mls_destroy_label, 2888 .mpo_cred_externalize_label = mls_externalize_label, 2889 .mpo_cred_init_label = mls_init_label, 2890 .mpo_cred_internalize_label = mls_internalize_label, 2891 .mpo_cred_relabel = mls_cred_relabel, 2892 2893 .mpo_devfs_create_device = mls_devfs_create_device, 2894 .mpo_devfs_create_directory = mls_devfs_create_directory, 2895 .mpo_devfs_create_symlink = mls_devfs_create_symlink, 2896 .mpo_devfs_destroy_label = mls_destroy_label, 2897 .mpo_devfs_init_label = mls_init_label, 2898 .mpo_devfs_update = mls_devfs_update, 2899 .mpo_devfs_vnode_associate = mls_devfs_vnode_associate, 2900 2901 .mpo_ifnet_check_relabel = mls_ifnet_check_relabel, 2902 .mpo_ifnet_check_transmit = mls_ifnet_check_transmit, 2903 .mpo_ifnet_copy_label = mls_copy_label, 2904 .mpo_ifnet_create = mls_ifnet_create, 2905 .mpo_ifnet_create_mbuf = mls_ifnet_create_mbuf, 2906 .mpo_ifnet_destroy_label = mls_destroy_label, 2907 .mpo_ifnet_externalize_label = mls_externalize_label, 2908 .mpo_ifnet_init_label = mls_init_label, 2909 .mpo_ifnet_internalize_label = mls_internalize_label, 2910 .mpo_ifnet_relabel = mls_ifnet_relabel, 2911 2912 .mpo_inpcb_check_deliver = mls_inpcb_check_deliver, 2913 .mpo_inpcb_create = mls_inpcb_create, 2914 .mpo_inpcb_create_mbuf = mls_inpcb_create_mbuf, 2915 .mpo_inpcb_destroy_label = mls_destroy_label, 2916 .mpo_inpcb_init_label = mls_init_label_waitcheck, 2917 .mpo_inpcb_sosetlabel = mls_inpcb_sosetlabel, 2918 2919 .mpo_ipq_create = mls_ipq_create, 2920 .mpo_ipq_destroy_label = mls_destroy_label, 2921 .mpo_ipq_init_label = mls_init_label_waitcheck, 2922 .mpo_ipq_match = mls_ipq_match, 2923 .mpo_ipq_reassemble = mls_ipq_reassemble, 2924 .mpo_ipq_update = mls_ipq_update, 2925 2926 .mpo_mbuf_copy_label = mls_copy_label, 2927 .mpo_mbuf_destroy_label = mls_destroy_label, 2928 .mpo_mbuf_init_label = mls_init_label_waitcheck, 2929 2930 .mpo_mount_check_stat = mls_mount_check_stat, 2931 .mpo_mount_create = mls_mount_create, 2932 .mpo_mount_destroy_label = mls_destroy_label, 2933 .mpo_mount_init_label = mls_init_label, 2934 2935 .mpo_netatalk_aarp_send = mls_netatalk_aarp_send, 2936 2937 .mpo_netinet_arp_send = mls_netinet_arp_send, 2938 .mpo_netinet_firewall_reply = mls_netinet_firewall_reply, 2939 .mpo_netinet_firewall_send = mls_netinet_firewall_send, 2940 .mpo_netinet_fragment = mls_netinet_fragment, 2941 .mpo_netinet_icmp_reply = mls_netinet_icmp_reply, 2942 .mpo_netinet_igmp_send = mls_netinet_igmp_send, 2943 2944 .mpo_netinet6_nd6_send = mls_netinet6_nd6_send, 2945 2946 .mpo_pipe_check_ioctl = mls_pipe_check_ioctl, 2947 .mpo_pipe_check_poll = mls_pipe_check_poll, 2948 .mpo_pipe_check_read = mls_pipe_check_read, 2949 .mpo_pipe_check_relabel = mls_pipe_check_relabel, 2950 .mpo_pipe_check_stat = mls_pipe_check_stat, 2951 .mpo_pipe_check_write = mls_pipe_check_write, 2952 .mpo_pipe_copy_label = mls_copy_label, 2953 .mpo_pipe_create = mls_pipe_create, 2954 .mpo_pipe_destroy_label = mls_destroy_label, 2955 .mpo_pipe_externalize_label = mls_externalize_label, 2956 .mpo_pipe_init_label = mls_init_label, 2957 .mpo_pipe_internalize_label = mls_internalize_label, 2958 .mpo_pipe_relabel = mls_pipe_relabel, 2959 2960 .mpo_posixsem_check_destroy = mls_posixsem_check_write, 2961 .mpo_posixsem_check_getvalue = mls_posixsem_check_rdonly, 2962 .mpo_posixsem_check_open = mls_posixsem_check_write, 2963 .mpo_posixsem_check_post = mls_posixsem_check_write, 2964 .mpo_posixsem_check_unlink = mls_posixsem_check_write, 2965 .mpo_posixsem_check_wait = mls_posixsem_check_write, 2966 .mpo_posixsem_create = mls_posixsem_create, 2967 .mpo_posixsem_destroy_label = mls_destroy_label, 2968 .mpo_posixsem_init_label = mls_init_label, 2969 2970 .mpo_proc_associate_nfsd = mls_proc_associate_nfsd, 2971 .mpo_proc_check_debug = mls_proc_check_debug, 2972 .mpo_proc_check_sched = mls_proc_check_sched, 2973 .mpo_proc_check_signal = mls_proc_check_signal, 2974 .mpo_proc_create_init = mls_proc_create_init, 2975 .mpo_proc_create_swapper = mls_proc_create_swapper, 2976 2977 .mpo_socket_check_deliver = mls_socket_check_deliver, 2978 .mpo_socket_check_relabel = mls_socket_check_relabel, 2979 .mpo_socket_check_visible = mls_socket_check_visible, 2980 .mpo_socket_copy_label = mls_copy_label, 2981 .mpo_socket_create = mls_socket_create, 2982 .mpo_socket_create_mbuf = mls_socket_create_mbuf, 2983 .mpo_socket_destroy_label = mls_destroy_label, 2984 .mpo_socket_externalize_label = mls_externalize_label, 2985 .mpo_socket_init_label = mls_init_label_waitcheck, 2986 .mpo_socket_internalize_label = mls_internalize_label, 2987 .mpo_socket_newconn = mls_socket_newconn, 2988 .mpo_socket_relabel = mls_socket_relabel, 2989 2990 .mpo_socketpeer_destroy_label = mls_destroy_label, 2991 .mpo_socketpeer_externalize_label = mls_externalize_label, 2992 .mpo_socketpeer_init_label = mls_init_label_waitcheck, 2993 .mpo_socketpeer_set_from_mbuf = mls_socketpeer_set_from_mbuf, 2994 .mpo_socketpeer_set_from_socket = mls_socketpeer_set_from_socket, 2995 2996 .mpo_syncache_create = mls_syncache_create, 2997 .mpo_syncache_create_mbuf = mls_syncache_create_mbuf, 2998 .mpo_syncache_destroy_label = mls_destroy_label, 2999 .mpo_syncache_init_label = mls_init_label_waitcheck, 3000 3001 .mpo_sysvmsg_cleanup = mls_sysvmsg_cleanup, 3002 .mpo_sysvmsg_create = mls_sysvmsg_create, 3003 .mpo_sysvmsg_destroy_label = mls_destroy_label, 3004 .mpo_sysvmsg_init_label = mls_init_label, 3005 3006 .mpo_sysvmsq_check_msgrcv = mls_sysvmsq_check_msgrcv, 3007 .mpo_sysvmsq_check_msgrmid = mls_sysvmsq_check_msgrmid, 3008 .mpo_sysvmsq_check_msqget = mls_sysvmsq_check_msqget, 3009 .mpo_sysvmsq_check_msqsnd = mls_sysvmsq_check_msqsnd, 3010 .mpo_sysvmsq_check_msqrcv = mls_sysvmsq_check_msqrcv, 3011 .mpo_sysvmsq_check_msqctl = mls_sysvmsq_check_msqctl, 3012 .mpo_sysvmsq_cleanup = mls_sysvmsq_cleanup, 3013 .mpo_sysvmsq_destroy_label = mls_destroy_label, 3014 .mpo_sysvmsq_init_label = mls_init_label, 3015 .mpo_sysvmsq_create = mls_sysvmsq_create, 3016 3017 .mpo_sysvsem_check_semctl = mls_sysvsem_check_semctl, 3018 .mpo_sysvsem_check_semget = mls_sysvsem_check_semget, 3019 .mpo_sysvsem_check_semop = mls_sysvsem_check_semop, 3020 .mpo_sysvsem_cleanup = mls_sysvsem_cleanup, 3021 .mpo_sysvsem_create = mls_sysvsem_create, 3022 .mpo_sysvsem_destroy_label = mls_destroy_label, 3023 .mpo_sysvsem_init_label = mls_init_label, 3024 3025 .mpo_sysvshm_check_shmat = mls_sysvshm_check_shmat, 3026 .mpo_sysvshm_check_shmctl = mls_sysvshm_check_shmctl, 3027 .mpo_sysvshm_check_shmget = mls_sysvshm_check_shmget, 3028 .mpo_sysvshm_cleanup = mls_sysvshm_cleanup, 3029 .mpo_sysvshm_create = mls_sysvshm_create, 3030 .mpo_sysvshm_destroy_label = mls_destroy_label, 3031 .mpo_sysvshm_init_label = mls_init_label, 3032 3033 3034 .mpo_system_check_acct = mls_system_check_acct, 3035 .mpo_system_check_auditctl = mls_system_check_auditctl, 3036 .mpo_system_check_swapon = mls_system_check_swapon, 3037 3038 .mpo_vnode_associate_extattr = mls_vnode_associate_extattr, 3039 .mpo_vnode_associate_singlelabel = mls_vnode_associate_singlelabel, 3040 .mpo_vnode_check_access = mls_vnode_check_open, 3041 .mpo_vnode_check_chdir = mls_vnode_check_chdir, 3042 .mpo_vnode_check_chroot = mls_vnode_check_chroot, 3043 .mpo_vnode_check_create = mls_vnode_check_create, 3044 .mpo_vnode_check_deleteacl = mls_vnode_check_deleteacl, 3045 .mpo_vnode_check_deleteextattr = mls_vnode_check_deleteextattr, 3046 .mpo_vnode_check_exec = mls_vnode_check_exec, 3047 .mpo_vnode_check_getacl = mls_vnode_check_getacl, 3048 .mpo_vnode_check_getextattr = mls_vnode_check_getextattr, 3049 .mpo_vnode_check_link = mls_vnode_check_link, 3050 .mpo_vnode_check_listextattr = mls_vnode_check_listextattr, 3051 .mpo_vnode_check_lookup = mls_vnode_check_lookup, 3052 .mpo_vnode_check_mmap = mls_vnode_check_mmap, 3053 .mpo_vnode_check_open = mls_vnode_check_open, 3054 .mpo_vnode_check_poll = mls_vnode_check_poll, 3055 .mpo_vnode_check_read = mls_vnode_check_read, 3056 .mpo_vnode_check_readdir = mls_vnode_check_readdir, 3057 .mpo_vnode_check_readlink = mls_vnode_check_readlink, 3058 .mpo_vnode_check_relabel = mls_vnode_check_relabel, 3059 .mpo_vnode_check_rename_from = mls_vnode_check_rename_from, 3060 .mpo_vnode_check_rename_to = mls_vnode_check_rename_to, 3061 .mpo_vnode_check_revoke = mls_vnode_check_revoke, 3062 .mpo_vnode_check_setacl = mls_vnode_check_setacl, 3063 .mpo_vnode_check_setextattr = mls_vnode_check_setextattr, 3064 .mpo_vnode_check_setflags = mls_vnode_check_setflags, 3065 .mpo_vnode_check_setmode = mls_vnode_check_setmode, 3066 .mpo_vnode_check_setowner = mls_vnode_check_setowner, 3067 .mpo_vnode_check_setutimes = mls_vnode_check_setutimes, 3068 .mpo_vnode_check_stat = mls_vnode_check_stat, 3069 .mpo_vnode_check_unlink = mls_vnode_check_unlink, 3070 .mpo_vnode_check_write = mls_vnode_check_write, 3071 .mpo_vnode_copy_label = mls_copy_label, 3072 .mpo_vnode_create_extattr = mls_vnode_create_extattr, 3073 .mpo_vnode_destroy_label = mls_destroy_label, 3074 .mpo_vnode_externalize_label = mls_externalize_label, 3075 .mpo_vnode_init_label = mls_init_label, 3076 .mpo_vnode_internalize_label = mls_internalize_label, 3077 .mpo_vnode_relabel = mls_vnode_relabel, 3078 .mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr, 3079 }; 3080 3081 MAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS", 3082 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mls_slot); 3083