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 error = mls_subject_privileged(subj); 968 969 return (0); 970 } 971 972 static int 973 mls_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 974 struct mbuf *m, struct label *mlabel) 975 { 976 struct mac_mls *p, *i; 977 978 if (!mls_enabled) 979 return (0); 980 981 p = SLOT(mlabel); 982 i = SLOT(ifplabel); 983 984 return (mls_effective_in_range(p, i) ? 0 : EACCES); 985 } 986 987 static void 988 mls_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 989 { 990 struct mac_mls *dest; 991 int type; 992 993 dest = SLOT(ifplabel); 994 995 if (ifp->if_type == IFT_LOOP) 996 type = MAC_MLS_TYPE_EQUAL; 997 else 998 type = MAC_MLS_TYPE_LOW; 999 1000 mls_set_effective(dest, type, 0, NULL); 1001 mls_set_range(dest, type, 0, NULL, type, 0, NULL); 1002 } 1003 1004 static void 1005 mls_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1006 struct mbuf *m, struct label *mlabel) 1007 { 1008 struct mac_mls *source, *dest; 1009 1010 source = SLOT(ifplabel); 1011 dest = SLOT(mlabel); 1012 1013 mls_copy_effective(source, dest); 1014 } 1015 1016 static void 1017 mls_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1018 struct label *ifplabel, struct label *newlabel) 1019 { 1020 struct mac_mls *source, *dest; 1021 1022 source = SLOT(newlabel); 1023 dest = SLOT(ifplabel); 1024 1025 mls_copy(source, dest); 1026 } 1027 1028 static int 1029 mls_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1030 struct mbuf *m, struct label *mlabel) 1031 { 1032 struct mac_mls *p, *i; 1033 1034 if (!mls_enabled) 1035 return (0); 1036 1037 p = SLOT(mlabel); 1038 i = SLOT(inplabel); 1039 1040 return (mls_equal_effective(p, i) ? 0 : EACCES); 1041 } 1042 1043 static void 1044 mls_inpcb_create(struct socket *so, struct label *solabel, struct inpcb *inp, 1045 struct label *inplabel) 1046 { 1047 struct mac_mls *source, *dest; 1048 1049 source = SLOT(solabel); 1050 dest = SLOT(inplabel); 1051 1052 mls_copy_effective(source, dest); 1053 } 1054 1055 static void 1056 mls_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1057 struct mbuf *m, struct label *mlabel) 1058 { 1059 struct mac_mls *source, *dest; 1060 1061 source = SLOT(inplabel); 1062 dest = SLOT(mlabel); 1063 1064 mls_copy_effective(source, dest); 1065 } 1066 1067 static void 1068 mls_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1069 struct inpcb *inp, struct label *inplabel) 1070 { 1071 struct mac_mls *source, *dest; 1072 1073 source = SLOT(solabel); 1074 dest = SLOT(inplabel); 1075 1076 mls_copy(source, dest); 1077 } 1078 1079 static void 1080 mls_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 1081 struct label *ipqlabel) 1082 { 1083 struct mac_mls *source, *dest; 1084 1085 source = SLOT(mlabel); 1086 dest = SLOT(ipqlabel); 1087 1088 mls_copy_effective(source, dest); 1089 } 1090 1091 static int 1092 mls_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 1093 struct label *ipqlabel) 1094 { 1095 struct mac_mls *a, *b; 1096 1097 a = SLOT(ipqlabel); 1098 b = SLOT(mlabel); 1099 1100 return (mls_equal_effective(a, b)); 1101 } 1102 1103 static void 1104 mls_ipq_reassemble(struct ipq *ipq, struct label *ipqlabel, struct mbuf *m, 1105 struct label *mlabel) 1106 { 1107 struct mac_mls *source, *dest; 1108 1109 source = SLOT(ipqlabel); 1110 dest = SLOT(mlabel); 1111 1112 /* Just use the head, since we require them all to match. */ 1113 mls_copy_effective(source, dest); 1114 } 1115 1116 static void 1117 mls_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 1118 struct label *ipqlabel) 1119 { 1120 1121 /* NOOP: we only accept matching labels, so no need to update */ 1122 } 1123 1124 static int 1125 mls_mount_check_stat(struct ucred *cred, struct mount *mp, 1126 struct label *mntlabel) 1127 { 1128 struct mac_mls *subj, *obj; 1129 1130 if (!mls_enabled) 1131 return (0); 1132 1133 subj = SLOT(cred->cr_label); 1134 obj = SLOT(mntlabel); 1135 1136 if (!mls_dominate_effective(subj, obj)) 1137 return (EACCES); 1138 1139 return (0); 1140 } 1141 1142 static void 1143 mls_mount_create(struct ucred *cred, struct mount *mp, struct label *mplabel) 1144 { 1145 struct mac_mls *source, *dest; 1146 1147 source = SLOT(cred->cr_label); 1148 dest = SLOT(mplabel); 1149 1150 mls_copy_effective(source, dest); 1151 } 1152 1153 static void 1154 mls_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel, 1155 struct mbuf *m, struct label *mlabel) 1156 { 1157 struct mac_mls *dest; 1158 1159 dest = SLOT(mlabel); 1160 1161 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1162 } 1163 1164 static void 1165 mls_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1166 struct mbuf *m, struct label *mlabel) 1167 { 1168 struct mac_mls *dest; 1169 1170 dest = SLOT(mlabel); 1171 1172 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1173 } 1174 1175 static void 1176 mls_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1177 struct mbuf *msend, struct label *msendlabel) 1178 { 1179 struct mac_mls *source, *dest; 1180 1181 source = SLOT(mrecvlabel); 1182 dest = SLOT(msendlabel); 1183 1184 mls_copy_effective(source, dest); 1185 } 1186 1187 static void 1188 mls_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1189 { 1190 struct mac_mls *dest; 1191 1192 dest = SLOT(mlabel); 1193 1194 /* XXX: where is the label for the firewall really comming from? */ 1195 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1196 } 1197 1198 static void 1199 mls_netinet_fragment(struct mbuf *m, struct label *mlabel, struct mbuf *frag, 1200 struct label *fraglabel) 1201 { 1202 struct mac_mls *source, *dest; 1203 1204 source = SLOT(mlabel); 1205 dest = SLOT(fraglabel); 1206 1207 mls_copy_effective(source, dest); 1208 } 1209 1210 static void 1211 mls_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1212 struct mbuf *msend, struct label *msendlabel) 1213 { 1214 struct mac_mls *source, *dest; 1215 1216 source = SLOT(mrecvlabel); 1217 dest = SLOT(msendlabel); 1218 1219 mls_copy_effective(source, dest); 1220 } 1221 1222 static void 1223 mls_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1224 struct mbuf *m, struct label *mlabel) 1225 { 1226 struct mac_mls *dest; 1227 1228 dest = SLOT(mlabel); 1229 1230 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1231 } 1232 1233 static void 1234 mls_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1235 struct mbuf *m, struct label *mlabel) 1236 { 1237 struct mac_mls *dest; 1238 1239 dest = SLOT(mlabel); 1240 1241 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1242 } 1243 1244 static int 1245 mls_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1246 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1247 { 1248 1249 if (!mls_enabled) 1250 return (0); 1251 1252 /* XXX: This will be implemented soon... */ 1253 1254 return (0); 1255 } 1256 1257 static int 1258 mls_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1259 struct label *pplabel) 1260 { 1261 struct mac_mls *subj, *obj; 1262 1263 if (!mls_enabled) 1264 return (0); 1265 1266 subj = SLOT(cred->cr_label); 1267 obj = SLOT(pplabel); 1268 1269 if (!mls_dominate_effective(subj, obj)) 1270 return (EACCES); 1271 1272 return (0); 1273 } 1274 1275 static int 1276 mls_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1277 struct label *pplabel) 1278 { 1279 struct mac_mls *subj, *obj; 1280 1281 if (!mls_enabled) 1282 return (0); 1283 1284 subj = SLOT(cred->cr_label); 1285 obj = SLOT(pplabel); 1286 1287 if (!mls_dominate_effective(subj, obj)) 1288 return (EACCES); 1289 1290 return (0); 1291 } 1292 1293 static int 1294 mls_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1295 struct label *pplabel, struct label *newlabel) 1296 { 1297 struct mac_mls *subj, *obj, *new; 1298 int error; 1299 1300 new = SLOT(newlabel); 1301 subj = SLOT(cred->cr_label); 1302 obj = SLOT(pplabel); 1303 1304 /* 1305 * If there is an MLS label update for a pipe, it must be a effective 1306 * update. 1307 */ 1308 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1309 if (error) 1310 return (error); 1311 1312 /* 1313 * To perform a relabel of a pipe (MLS label or not), MLS must 1314 * authorize the relabel. 1315 */ 1316 if (!mls_effective_in_range(obj, subj)) 1317 return (EPERM); 1318 1319 /* 1320 * If the MLS label is to be changed, authorize as appropriate. 1321 */ 1322 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1323 /* 1324 * To change the MLS label on a pipe, the new pipe label must 1325 * be in the subject range. 1326 */ 1327 if (!mls_effective_in_range(new, subj)) 1328 return (EPERM); 1329 1330 /* 1331 * To change the MLS label on a pipe to be EQUAL, the subject 1332 * must have appropriate privilege. 1333 */ 1334 if (mls_contains_equal(new)) { 1335 error = mls_subject_privileged(subj); 1336 if (error) 1337 return (error); 1338 } 1339 } 1340 1341 return (0); 1342 } 1343 1344 static int 1345 mls_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 1346 struct label *pplabel) 1347 { 1348 struct mac_mls *subj, *obj; 1349 1350 if (!mls_enabled) 1351 return (0); 1352 1353 subj = SLOT(cred->cr_label); 1354 obj = SLOT(pplabel); 1355 1356 if (!mls_dominate_effective(subj, obj)) 1357 return (EACCES); 1358 1359 return (0); 1360 } 1361 1362 static int 1363 mls_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1364 struct label *pplabel) 1365 { 1366 struct mac_mls *subj, *obj; 1367 1368 if (!mls_enabled) 1369 return (0); 1370 1371 subj = SLOT(cred->cr_label); 1372 obj = SLOT(pplabel); 1373 1374 if (!mls_dominate_effective(obj, subj)) 1375 return (EACCES); 1376 1377 return (0); 1378 } 1379 1380 static void 1381 mls_pipe_create(struct ucred *cred, struct pipepair *pp, 1382 struct label *pplabel) 1383 { 1384 struct mac_mls *source, *dest; 1385 1386 source = SLOT(cred->cr_label); 1387 dest = SLOT(pplabel); 1388 1389 mls_copy_effective(source, dest); 1390 } 1391 1392 static void 1393 mls_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1394 struct label *pplabel, struct label *newlabel) 1395 { 1396 struct mac_mls *source, *dest; 1397 1398 source = SLOT(newlabel); 1399 dest = SLOT(pplabel); 1400 1401 mls_copy(source, dest); 1402 } 1403 1404 static int 1405 mls_posixsem_check_rdonly(struct ucred *cred, struct ksem *ks, 1406 struct label *kslabel) 1407 { 1408 struct mac_mls *subj, *obj; 1409 1410 if (!mls_enabled) 1411 return (0); 1412 1413 subj = SLOT(cred->cr_label); 1414 obj = SLOT(kslabel); 1415 1416 if (!mls_dominate_effective(subj, obj)) 1417 return (EACCES); 1418 1419 return (0); 1420 } 1421 1422 static int 1423 mls_posixsem_check_write(struct ucred *cred, struct ksem *ks, 1424 struct label *kslabel) 1425 { 1426 struct mac_mls *subj, *obj; 1427 1428 if (!mls_enabled) 1429 return (0); 1430 1431 subj = SLOT(cred->cr_label); 1432 obj = SLOT(kslabel); 1433 1434 if (!mls_dominate_effective(obj, subj)) 1435 return (EACCES); 1436 1437 return (0); 1438 } 1439 1440 static void 1441 mls_posixsem_create(struct ucred *cred, struct ksem *ks, 1442 struct label *kslabel) 1443 { 1444 struct mac_mls *source, *dest; 1445 1446 source = SLOT(cred->cr_label); 1447 dest = SLOT(kslabel); 1448 1449 mls_copy_effective(source, dest); 1450 } 1451 1452 static void 1453 mls_proc_associate_nfsd(struct ucred *cred) 1454 { 1455 struct mac_mls *label; 1456 1457 label = SLOT(cred->cr_label); 1458 mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL); 1459 mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1460 NULL); 1461 } 1462 1463 static int 1464 mls_proc_check_debug(struct ucred *cred, struct proc *p) 1465 { 1466 struct mac_mls *subj, *obj; 1467 1468 if (!mls_enabled) 1469 return (0); 1470 1471 subj = SLOT(cred->cr_label); 1472 obj = SLOT(p->p_ucred->cr_label); 1473 1474 /* XXX: range checks */ 1475 if (!mls_dominate_effective(subj, obj)) 1476 return (ESRCH); 1477 if (!mls_dominate_effective(obj, subj)) 1478 return (EACCES); 1479 1480 return (0); 1481 } 1482 1483 static int 1484 mls_proc_check_sched(struct ucred *cred, struct proc *p) 1485 { 1486 struct mac_mls *subj, *obj; 1487 1488 if (!mls_enabled) 1489 return (0); 1490 1491 subj = SLOT(cred->cr_label); 1492 obj = SLOT(p->p_ucred->cr_label); 1493 1494 /* XXX: range checks */ 1495 if (!mls_dominate_effective(subj, obj)) 1496 return (ESRCH); 1497 if (!mls_dominate_effective(obj, subj)) 1498 return (EACCES); 1499 1500 return (0); 1501 } 1502 1503 static int 1504 mls_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1505 { 1506 struct mac_mls *subj, *obj; 1507 1508 if (!mls_enabled) 1509 return (0); 1510 1511 subj = SLOT(cred->cr_label); 1512 obj = SLOT(p->p_ucred->cr_label); 1513 1514 /* XXX: range checks */ 1515 if (!mls_dominate_effective(subj, obj)) 1516 return (ESRCH); 1517 if (!mls_dominate_effective(obj, subj)) 1518 return (EACCES); 1519 1520 return (0); 1521 } 1522 1523 static void 1524 mls_proc_create_init(struct ucred *cred) 1525 { 1526 struct mac_mls *dest; 1527 1528 dest = SLOT(cred->cr_label); 1529 1530 mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL); 1531 mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1532 NULL); 1533 } 1534 1535 static void 1536 mls_proc_create_swapper(struct ucred *cred) 1537 { 1538 struct mac_mls *dest; 1539 1540 dest = SLOT(cred->cr_label); 1541 1542 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1543 mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1544 NULL); 1545 } 1546 1547 static int 1548 mls_socket_check_deliver(struct socket *so, struct label *solabel, 1549 struct mbuf *m, struct label *mlabel) 1550 { 1551 struct mac_mls *p, *s; 1552 1553 if (!mls_enabled) 1554 return (0); 1555 1556 p = SLOT(mlabel); 1557 s = SLOT(solabel); 1558 1559 return (mls_equal_effective(p, s) ? 0 : EACCES); 1560 } 1561 1562 static int 1563 mls_socket_check_relabel(struct ucred *cred, struct socket *so, 1564 struct label *solabel, struct label *newlabel) 1565 { 1566 struct mac_mls *subj, *obj, *new; 1567 int error; 1568 1569 new = SLOT(newlabel); 1570 subj = SLOT(cred->cr_label); 1571 obj = SLOT(solabel); 1572 1573 /* 1574 * If there is an MLS label update for the socket, it may be an 1575 * update of effective. 1576 */ 1577 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1578 if (error) 1579 return (error); 1580 1581 /* 1582 * To relabel a socket, the old socket effective must be in the 1583 * subject range. 1584 */ 1585 if (!mls_effective_in_range(obj, subj)) 1586 return (EPERM); 1587 1588 /* 1589 * If the MLS label is to be changed, authorize as appropriate. 1590 */ 1591 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1592 /* 1593 * To relabel a socket, the new socket effective must be in 1594 * the subject range. 1595 */ 1596 if (!mls_effective_in_range(new, subj)) 1597 return (EPERM); 1598 1599 /* 1600 * To change the MLS label on the socket to contain EQUAL, 1601 * the subject must have appropriate privilege. 1602 */ 1603 if (mls_contains_equal(new)) { 1604 error = mls_subject_privileged(subj); 1605 if (error) 1606 return (error); 1607 } 1608 } 1609 1610 return (0); 1611 } 1612 1613 static int 1614 mls_socket_check_visible(struct ucred *cred, struct socket *so, 1615 struct label *solabel) 1616 { 1617 struct mac_mls *subj, *obj; 1618 1619 if (!mls_enabled) 1620 return (0); 1621 1622 subj = SLOT(cred->cr_label); 1623 obj = SLOT(solabel); 1624 1625 if (!mls_dominate_effective(subj, obj)) 1626 return (ENOENT); 1627 1628 return (0); 1629 } 1630 1631 static void 1632 mls_socket_create(struct ucred *cred, struct socket *so, 1633 struct label *solabel) 1634 { 1635 struct mac_mls *source, *dest; 1636 1637 source = SLOT(cred->cr_label); 1638 dest = SLOT(solabel); 1639 1640 mls_copy_effective(source, dest); 1641 } 1642 1643 static void 1644 mls_socket_create_mbuf(struct socket *so, struct label *solabel, 1645 struct mbuf *m, struct label *mlabel) 1646 { 1647 struct mac_mls *source, *dest; 1648 1649 source = SLOT(solabel); 1650 dest = SLOT(mlabel); 1651 1652 mls_copy_effective(source, dest); 1653 } 1654 1655 static void 1656 mls_socket_newconn(struct socket *oldso, struct label *oldsolabel, 1657 struct socket *newso, struct label *newsolabel) 1658 { 1659 struct mac_mls *source, *dest; 1660 1661 source = SLOT(oldsolabel); 1662 dest = SLOT(newsolabel); 1663 1664 mls_copy_effective(source, dest); 1665 } 1666 1667 static void 1668 mls_socket_relabel(struct ucred *cred, struct socket *so, 1669 struct label *solabel, struct label *newlabel) 1670 { 1671 struct mac_mls *source, *dest; 1672 1673 source = SLOT(newlabel); 1674 dest = SLOT(solabel); 1675 1676 mls_copy(source, dest); 1677 } 1678 1679 static void 1680 mls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 1681 struct socket *so, struct label *sopeerlabel) 1682 { 1683 struct mac_mls *source, *dest; 1684 1685 source = SLOT(mlabel); 1686 dest = SLOT(sopeerlabel); 1687 1688 mls_copy_effective(source, dest); 1689 } 1690 1691 static void 1692 mls_socketpeer_set_from_socket(struct socket *oldso, 1693 struct label *oldsolabel, struct socket *newso, 1694 struct label *newsopeerlabel) 1695 { 1696 struct mac_mls *source, *dest; 1697 1698 source = SLOT(oldsolabel); 1699 dest = SLOT(newsopeerlabel); 1700 1701 mls_copy_effective(source, dest); 1702 } 1703 1704 static void 1705 mls_syncache_create(struct label *label, struct inpcb *inp) 1706 { 1707 struct mac_mls *source, *dest; 1708 1709 source = SLOT(inp->inp_label); 1710 dest = SLOT(label); 1711 1712 mls_copy_effective(source, dest); 1713 } 1714 1715 static void 1716 mls_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 1717 struct label *mlabel) 1718 { 1719 struct mac_mls *source, *dest; 1720 1721 source = SLOT(sc_label); 1722 dest = SLOT(mlabel); 1723 1724 mls_copy_effective(source, dest); 1725 } 1726 1727 static int 1728 mls_system_check_acct(struct ucred *cred, struct vnode *vp, 1729 struct label *vplabel) 1730 { 1731 struct mac_mls *subj, *obj; 1732 1733 if (!mls_enabled) 1734 return (0); 1735 1736 subj = SLOT(cred->cr_label); 1737 obj = SLOT(vplabel); 1738 1739 if (!mls_dominate_effective(obj, subj) || 1740 !mls_dominate_effective(subj, obj)) 1741 return (EACCES); 1742 1743 return (0); 1744 } 1745 1746 static int 1747 mls_system_check_auditctl(struct ucred *cred, struct vnode *vp, 1748 struct label *vplabel) 1749 { 1750 struct mac_mls *subj, *obj; 1751 1752 if (!mls_enabled) 1753 return (0); 1754 1755 subj = SLOT(cred->cr_label); 1756 obj = SLOT(vplabel); 1757 1758 if (!mls_dominate_effective(obj, subj) || 1759 !mls_dominate_effective(subj, obj)) 1760 return (EACCES); 1761 1762 return (0); 1763 } 1764 1765 static int 1766 mls_system_check_swapon(struct ucred *cred, struct vnode *vp, 1767 struct label *vplabel) 1768 { 1769 struct mac_mls *subj, *obj; 1770 1771 if (!mls_enabled) 1772 return (0); 1773 1774 subj = SLOT(cred->cr_label); 1775 obj = SLOT(vplabel); 1776 1777 if (!mls_dominate_effective(obj, subj) || 1778 !mls_dominate_effective(subj, obj)) 1779 return (EACCES); 1780 1781 return (0); 1782 } 1783 1784 static void 1785 mls_sysvmsg_cleanup(struct label *msglabel) 1786 { 1787 1788 bzero(SLOT(msglabel), sizeof(struct mac_mls)); 1789 } 1790 1791 static void 1792 mls_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1793 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1794 { 1795 struct mac_mls *source, *dest; 1796 1797 /* Ignore the msgq label. */ 1798 source = SLOT(cred->cr_label); 1799 dest = SLOT(msglabel); 1800 1801 mls_copy_effective(source, dest); 1802 } 1803 1804 static int 1805 mls_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 1806 struct label *msglabel) 1807 { 1808 struct mac_mls *subj, *obj; 1809 1810 if (!mls_enabled) 1811 return (0); 1812 1813 subj = SLOT(cred->cr_label); 1814 obj = SLOT(msglabel); 1815 1816 if (!mls_dominate_effective(subj, obj)) 1817 return (EACCES); 1818 1819 return (0); 1820 } 1821 1822 static int 1823 mls_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 1824 struct label *msglabel) 1825 { 1826 struct mac_mls *subj, *obj; 1827 1828 if (!mls_enabled) 1829 return (0); 1830 1831 subj = SLOT(cred->cr_label); 1832 obj = SLOT(msglabel); 1833 1834 if (!mls_dominate_effective(obj, subj)) 1835 return (EACCES); 1836 1837 return (0); 1838 } 1839 1840 static int 1841 mls_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1842 struct label *msqklabel) 1843 { 1844 struct mac_mls *subj, *obj; 1845 1846 if (!mls_enabled) 1847 return (0); 1848 1849 subj = SLOT(cred->cr_label); 1850 obj = SLOT(msqklabel); 1851 1852 if (!mls_dominate_effective(subj, obj)) 1853 return (EACCES); 1854 1855 return (0); 1856 } 1857 1858 static int 1859 mls_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1860 struct label *msqklabel) 1861 { 1862 struct mac_mls *subj, *obj; 1863 1864 if (!mls_enabled) 1865 return (0); 1866 1867 subj = SLOT(cred->cr_label); 1868 obj = SLOT(msqklabel); 1869 1870 if (!mls_dominate_effective(obj, subj)) 1871 return (EACCES); 1872 1873 return (0); 1874 } 1875 1876 static int 1877 mls_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1878 struct label *msqklabel) 1879 { 1880 struct mac_mls *subj, *obj; 1881 1882 if (!mls_enabled) 1883 return (0); 1884 1885 subj = SLOT(cred->cr_label); 1886 obj = SLOT(msqklabel); 1887 1888 if (!mls_dominate_effective(subj, obj)) 1889 return (EACCES); 1890 1891 return (0); 1892 } 1893 1894 static int 1895 mls_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1896 struct label *msqklabel, int cmd) 1897 { 1898 struct mac_mls *subj, *obj; 1899 1900 if (!mls_enabled) 1901 return (0); 1902 1903 subj = SLOT(cred->cr_label); 1904 obj = SLOT(msqklabel); 1905 1906 switch(cmd) { 1907 case IPC_RMID: 1908 case IPC_SET: 1909 if (!mls_dominate_effective(obj, subj)) 1910 return (EACCES); 1911 break; 1912 1913 case IPC_STAT: 1914 if (!mls_dominate_effective(subj, obj)) 1915 return (EACCES); 1916 break; 1917 1918 default: 1919 return (EACCES); 1920 } 1921 1922 return (0); 1923 } 1924 1925 static void 1926 mls_sysvmsq_cleanup(struct label *msqlabel) 1927 { 1928 1929 bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 1930 } 1931 1932 static void 1933 mls_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1934 struct label *msqlabel) 1935 { 1936 struct mac_mls *source, *dest; 1937 1938 source = SLOT(cred->cr_label); 1939 dest = SLOT(msqlabel); 1940 1941 mls_copy_effective(source, dest); 1942 } 1943 1944 static int 1945 mls_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1946 struct label *semaklabel, int cmd) 1947 { 1948 struct mac_mls *subj, *obj; 1949 1950 if (!mls_enabled) 1951 return (0); 1952 1953 subj = SLOT(cred->cr_label); 1954 obj = SLOT(semaklabel); 1955 1956 switch(cmd) { 1957 case IPC_RMID: 1958 case IPC_SET: 1959 case SETVAL: 1960 case SETALL: 1961 if (!mls_dominate_effective(obj, subj)) 1962 return (EACCES); 1963 break; 1964 1965 case IPC_STAT: 1966 case GETVAL: 1967 case GETPID: 1968 case GETNCNT: 1969 case GETZCNT: 1970 case GETALL: 1971 if (!mls_dominate_effective(subj, obj)) 1972 return (EACCES); 1973 break; 1974 1975 default: 1976 return (EACCES); 1977 } 1978 1979 return (0); 1980 } 1981 1982 static int 1983 mls_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 1984 struct label *semaklabel) 1985 { 1986 struct mac_mls *subj, *obj; 1987 1988 if (!mls_enabled) 1989 return (0); 1990 1991 subj = SLOT(cred->cr_label); 1992 obj = SLOT(semaklabel); 1993 1994 if (!mls_dominate_effective(subj, obj)) 1995 return (EACCES); 1996 1997 return (0); 1998 } 1999 2000 static int 2001 mls_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2002 struct label *semaklabel, size_t accesstype) 2003 { 2004 struct mac_mls *subj, *obj; 2005 2006 if (!mls_enabled) 2007 return (0); 2008 2009 subj = SLOT(cred->cr_label); 2010 obj = SLOT(semaklabel); 2011 2012 if( accesstype & SEM_R ) 2013 if (!mls_dominate_effective(subj, obj)) 2014 return (EACCES); 2015 2016 if( accesstype & SEM_A ) 2017 if (!mls_dominate_effective(obj, subj)) 2018 return (EACCES); 2019 2020 return (0); 2021 } 2022 2023 static void 2024 mls_sysvsem_cleanup(struct label *semalabel) 2025 { 2026 2027 bzero(SLOT(semalabel), sizeof(struct mac_mls)); 2028 } 2029 2030 static void 2031 mls_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2032 struct label *semalabel) 2033 { 2034 struct mac_mls *source, *dest; 2035 2036 source = SLOT(cred->cr_label); 2037 dest = SLOT(semalabel); 2038 2039 mls_copy_effective(source, dest); 2040 } 2041 2042 static int 2043 mls_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2044 struct label *shmseglabel, int shmflg) 2045 { 2046 struct mac_mls *subj, *obj; 2047 2048 if (!mls_enabled) 2049 return (0); 2050 2051 subj = SLOT(cred->cr_label); 2052 obj = SLOT(shmseglabel); 2053 2054 if (!mls_dominate_effective(subj, obj)) 2055 return (EACCES); 2056 if ((shmflg & SHM_RDONLY) == 0) { 2057 if (!mls_dominate_effective(obj, subj)) 2058 return (EACCES); 2059 } 2060 2061 return (0); 2062 } 2063 2064 static int 2065 mls_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2066 struct label *shmseglabel, int cmd) 2067 { 2068 struct mac_mls *subj, *obj; 2069 2070 if (!mls_enabled) 2071 return (0); 2072 2073 subj = SLOT(cred->cr_label); 2074 obj = SLOT(shmseglabel); 2075 2076 switch(cmd) { 2077 case IPC_RMID: 2078 case IPC_SET: 2079 if (!mls_dominate_effective(obj, subj)) 2080 return (EACCES); 2081 break; 2082 2083 case IPC_STAT: 2084 case SHM_STAT: 2085 if (!mls_dominate_effective(subj, obj)) 2086 return (EACCES); 2087 break; 2088 2089 default: 2090 return (EACCES); 2091 } 2092 2093 return (0); 2094 } 2095 2096 static int 2097 mls_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2098 struct label *shmseglabel, int shmflg) 2099 { 2100 struct mac_mls *subj, *obj; 2101 2102 if (!mls_enabled) 2103 return (0); 2104 2105 subj = SLOT(cred->cr_label); 2106 obj = SLOT(shmseglabel); 2107 2108 if (!mls_dominate_effective(obj, subj)) 2109 return (EACCES); 2110 2111 return (0); 2112 } 2113 2114 static void 2115 mls_sysvshm_cleanup(struct label *shmlabel) 2116 { 2117 2118 bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 2119 } 2120 2121 static void 2122 mls_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2123 struct label *shmlabel) 2124 { 2125 struct mac_mls *source, *dest; 2126 2127 source = SLOT(cred->cr_label); 2128 dest = SLOT(shmlabel); 2129 2130 mls_copy_effective(source, dest); 2131 } 2132 2133 static int 2134 mls_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2135 struct vnode *vp, struct label *vplabel) 2136 { 2137 struct mac_mls mm_temp, *source, *dest; 2138 int buflen, error; 2139 2140 source = SLOT(mplabel); 2141 dest = SLOT(vplabel); 2142 2143 buflen = sizeof(mm_temp); 2144 bzero(&mm_temp, buflen); 2145 2146 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2147 MAC_MLS_EXTATTR_NAME, &buflen, (char *) &mm_temp, curthread); 2148 if (error == ENOATTR || error == EOPNOTSUPP) { 2149 /* Fall back to the mntlabel. */ 2150 mls_copy_effective(source, dest); 2151 return (0); 2152 } else if (error) 2153 return (error); 2154 2155 if (buflen != sizeof(mm_temp)) { 2156 printf("mls_vnode_associate_extattr: bad size %d\n", buflen); 2157 return (EPERM); 2158 } 2159 if (mls_valid(&mm_temp) != 0) { 2160 printf("mls_vnode_associate_extattr: invalid\n"); 2161 return (EPERM); 2162 } 2163 if ((mm_temp.mm_flags & MAC_MLS_FLAGS_BOTH) != 2164 MAC_MLS_FLAG_EFFECTIVE) { 2165 printf("mls_associated_vnode_extattr: not effective\n"); 2166 return (EPERM); 2167 } 2168 2169 mls_copy_effective(&mm_temp, dest); 2170 return (0); 2171 } 2172 2173 static void 2174 mls_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2175 struct vnode *vp, struct label *vplabel) 2176 { 2177 struct mac_mls *source, *dest; 2178 2179 source = SLOT(mplabel); 2180 dest = SLOT(vplabel); 2181 2182 mls_copy_effective(source, dest); 2183 } 2184 2185 static int 2186 mls_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2187 struct label *dvplabel) 2188 { 2189 struct mac_mls *subj, *obj; 2190 2191 if (!mls_enabled) 2192 return (0); 2193 2194 subj = SLOT(cred->cr_label); 2195 obj = SLOT(dvplabel); 2196 2197 if (!mls_dominate_effective(subj, obj)) 2198 return (EACCES); 2199 2200 return (0); 2201 } 2202 2203 static int 2204 mls_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2205 struct label *dvplabel) 2206 { 2207 struct mac_mls *subj, *obj; 2208 2209 if (!mls_enabled) 2210 return (0); 2211 2212 subj = SLOT(cred->cr_label); 2213 obj = SLOT(dvplabel); 2214 2215 if (!mls_dominate_effective(subj, obj)) 2216 return (EACCES); 2217 2218 return (0); 2219 } 2220 2221 static int 2222 mls_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2223 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2224 { 2225 struct mac_mls *subj, *obj; 2226 2227 if (!mls_enabled) 2228 return (0); 2229 2230 subj = SLOT(cred->cr_label); 2231 obj = SLOT(dvplabel); 2232 2233 if (!mls_dominate_effective(obj, subj)) 2234 return (EACCES); 2235 2236 return (0); 2237 } 2238 2239 static int 2240 mls_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2241 struct label *vplabel, acl_type_t type) 2242 { 2243 struct mac_mls *subj, *obj; 2244 2245 if (!mls_enabled) 2246 return (0); 2247 2248 subj = SLOT(cred->cr_label); 2249 obj = SLOT(vplabel); 2250 2251 if (!mls_dominate_effective(obj, subj)) 2252 return (EACCES); 2253 2254 return (0); 2255 } 2256 2257 static int 2258 mls_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2259 struct label *vplabel, int attrnamespace, const char *name) 2260 { 2261 struct mac_mls *subj, *obj; 2262 2263 if (!mls_enabled) 2264 return (0); 2265 2266 subj = SLOT(cred->cr_label); 2267 obj = SLOT(vplabel); 2268 2269 if (!mls_dominate_effective(obj, subj)) 2270 return (EACCES); 2271 2272 return (0); 2273 } 2274 2275 static int 2276 mls_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2277 struct label *vplabel, struct image_params *imgp, 2278 struct label *execlabel) 2279 { 2280 struct mac_mls *subj, *obj, *exec; 2281 int error; 2282 2283 if (execlabel != NULL) { 2284 /* 2285 * We currently don't permit labels to be changed at 2286 * exec-time as part of MLS, so disallow non-NULL MLS label 2287 * elements in the execlabel. 2288 */ 2289 exec = SLOT(execlabel); 2290 error = mls_atmostflags(exec, 0); 2291 if (error) 2292 return (error); 2293 } 2294 2295 if (!mls_enabled) 2296 return (0); 2297 2298 subj = SLOT(cred->cr_label); 2299 obj = SLOT(vplabel); 2300 2301 if (!mls_dominate_effective(subj, obj)) 2302 return (EACCES); 2303 2304 return (0); 2305 } 2306 2307 static int 2308 mls_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2309 struct label *vplabel, acl_type_t type) 2310 { 2311 struct mac_mls *subj, *obj; 2312 2313 if (!mls_enabled) 2314 return (0); 2315 2316 subj = SLOT(cred->cr_label); 2317 obj = SLOT(vplabel); 2318 2319 if (!mls_dominate_effective(subj, obj)) 2320 return (EACCES); 2321 2322 return (0); 2323 } 2324 2325 static int 2326 mls_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 2327 struct label *vplabel, int attrnamespace, const char *name, 2328 struct uio *uio) 2329 { 2330 struct mac_mls *subj, *obj; 2331 2332 if (!mls_enabled) 2333 return (0); 2334 2335 subj = SLOT(cred->cr_label); 2336 obj = SLOT(vplabel); 2337 2338 if (!mls_dominate_effective(subj, obj)) 2339 return (EACCES); 2340 2341 return (0); 2342 } 2343 2344 static int 2345 mls_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2346 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2347 struct componentname *cnp) 2348 { 2349 struct mac_mls *subj, *obj; 2350 2351 if (!mls_enabled) 2352 return (0); 2353 2354 subj = SLOT(cred->cr_label); 2355 obj = SLOT(dvplabel); 2356 2357 if (!mls_dominate_effective(obj, subj)) 2358 return (EACCES); 2359 2360 obj = SLOT(vplabel); 2361 if (!mls_dominate_effective(obj, subj)) 2362 return (EACCES); 2363 2364 return (0); 2365 } 2366 2367 static int 2368 mls_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 2369 struct label *vplabel, int attrnamespace) 2370 { 2371 2372 struct mac_mls *subj, *obj; 2373 2374 if (!mls_enabled) 2375 return (0); 2376 2377 subj = SLOT(cred->cr_label); 2378 obj = SLOT(vplabel); 2379 2380 if (!mls_dominate_effective(subj, obj)) 2381 return (EACCES); 2382 2383 return (0); 2384 } 2385 2386 static int 2387 mls_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 2388 struct label *dvplabel, struct componentname *cnp) 2389 { 2390 struct mac_mls *subj, *obj; 2391 2392 if (!mls_enabled) 2393 return (0); 2394 2395 subj = SLOT(cred->cr_label); 2396 obj = SLOT(dvplabel); 2397 2398 if (!mls_dominate_effective(subj, obj)) 2399 return (EACCES); 2400 2401 return (0); 2402 } 2403 2404 static int 2405 mls_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2406 struct label *vplabel, int prot, int flags) 2407 { 2408 struct mac_mls *subj, *obj; 2409 2410 /* 2411 * Rely on the use of open()-time protections to handle 2412 * non-revocation cases. 2413 */ 2414 if (!mls_enabled || !revocation_enabled) 2415 return (0); 2416 2417 subj = SLOT(cred->cr_label); 2418 obj = SLOT(vplabel); 2419 2420 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2421 if (!mls_dominate_effective(subj, obj)) 2422 return (EACCES); 2423 } 2424 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2425 if (!mls_dominate_effective(obj, subj)) 2426 return (EACCES); 2427 } 2428 2429 return (0); 2430 } 2431 2432 static int 2433 mls_vnode_check_open(struct ucred *cred, struct vnode *vp, 2434 struct label *vplabel, int acc_mode) 2435 { 2436 struct mac_mls *subj, *obj; 2437 2438 if (!mls_enabled) 2439 return (0); 2440 2441 subj = SLOT(cred->cr_label); 2442 obj = SLOT(vplabel); 2443 2444 /* XXX privilege override for admin? */ 2445 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2446 if (!mls_dominate_effective(subj, obj)) 2447 return (EACCES); 2448 } 2449 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2450 if (!mls_dominate_effective(obj, subj)) 2451 return (EACCES); 2452 } 2453 2454 return (0); 2455 } 2456 2457 static int 2458 mls_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 2459 struct vnode *vp, struct label *vplabel) 2460 { 2461 struct mac_mls *subj, *obj; 2462 2463 if (!mls_enabled || !revocation_enabled) 2464 return (0); 2465 2466 subj = SLOT(active_cred->cr_label); 2467 obj = SLOT(vplabel); 2468 2469 if (!mls_dominate_effective(subj, obj)) 2470 return (EACCES); 2471 2472 return (0); 2473 } 2474 2475 static int 2476 mls_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2477 struct vnode *vp, struct label *vplabel) 2478 { 2479 struct mac_mls *subj, *obj; 2480 2481 if (!mls_enabled || !revocation_enabled) 2482 return (0); 2483 2484 subj = SLOT(active_cred->cr_label); 2485 obj = SLOT(vplabel); 2486 2487 if (!mls_dominate_effective(subj, obj)) 2488 return (EACCES); 2489 2490 return (0); 2491 } 2492 2493 static int 2494 mls_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 2495 struct label *dvplabel) 2496 { 2497 struct mac_mls *subj, *obj; 2498 2499 if (!mls_enabled) 2500 return (0); 2501 2502 subj = SLOT(cred->cr_label); 2503 obj = SLOT(dvplabel); 2504 2505 if (!mls_dominate_effective(subj, obj)) 2506 return (EACCES); 2507 2508 return (0); 2509 } 2510 2511 static int 2512 mls_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 2513 struct label *vplabel) 2514 { 2515 struct mac_mls *subj, *obj; 2516 2517 if (!mls_enabled) 2518 return (0); 2519 2520 subj = SLOT(cred->cr_label); 2521 obj = SLOT(vplabel); 2522 2523 if (!mls_dominate_effective(subj, obj)) 2524 return (EACCES); 2525 2526 return (0); 2527 } 2528 2529 static int 2530 mls_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2531 struct label *vplabel, struct label *newlabel) 2532 { 2533 struct mac_mls *old, *new, *subj; 2534 int error; 2535 2536 old = SLOT(vplabel); 2537 new = SLOT(newlabel); 2538 subj = SLOT(cred->cr_label); 2539 2540 /* 2541 * If there is an MLS label update for the vnode, it must be a 2542 * effective label. 2543 */ 2544 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2545 if (error) 2546 return (error); 2547 2548 /* 2549 * To perform a relabel of the vnode (MLS label or not), MLS must 2550 * authorize the relabel. 2551 */ 2552 if (!mls_effective_in_range(old, subj)) 2553 return (EPERM); 2554 2555 /* 2556 * If the MLS label is to be changed, authorize as appropriate. 2557 */ 2558 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2559 /* 2560 * To change the MLS label on a vnode, the new vnode label 2561 * must be in the subject range. 2562 */ 2563 if (!mls_effective_in_range(new, subj)) 2564 return (EPERM); 2565 2566 /* 2567 * To change the MLS label on the vnode to be EQUAL, the 2568 * subject must have appropriate privilege. 2569 */ 2570 if (mls_contains_equal(new)) { 2571 error = mls_subject_privileged(subj); 2572 if (error) 2573 return (error); 2574 } 2575 } 2576 2577 return (0); 2578 } 2579 2580 static int 2581 mls_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2582 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2583 struct componentname *cnp) 2584 { 2585 struct mac_mls *subj, *obj; 2586 2587 if (!mls_enabled) 2588 return (0); 2589 2590 subj = SLOT(cred->cr_label); 2591 obj = SLOT(dvplabel); 2592 2593 if (!mls_dominate_effective(obj, subj)) 2594 return (EACCES); 2595 2596 obj = SLOT(vplabel); 2597 2598 if (!mls_dominate_effective(obj, subj)) 2599 return (EACCES); 2600 2601 return (0); 2602 } 2603 2604 static int 2605 mls_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2606 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2607 int samedir, struct componentname *cnp) 2608 { 2609 struct mac_mls *subj, *obj; 2610 2611 if (!mls_enabled) 2612 return (0); 2613 2614 subj = SLOT(cred->cr_label); 2615 obj = SLOT(dvplabel); 2616 2617 if (!mls_dominate_effective(obj, subj)) 2618 return (EACCES); 2619 2620 if (vp != NULL) { 2621 obj = SLOT(vplabel); 2622 2623 if (!mls_dominate_effective(obj, subj)) 2624 return (EACCES); 2625 } 2626 2627 return (0); 2628 } 2629 2630 static int 2631 mls_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2632 struct label *vplabel) 2633 { 2634 struct mac_mls *subj, *obj; 2635 2636 if (!mls_enabled) 2637 return (0); 2638 2639 subj = SLOT(cred->cr_label); 2640 obj = SLOT(vplabel); 2641 2642 if (!mls_dominate_effective(obj, subj)) 2643 return (EACCES); 2644 2645 return (0); 2646 } 2647 2648 static int 2649 mls_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2650 struct label *vplabel, acl_type_t type, struct acl *acl) 2651 { 2652 struct mac_mls *subj, *obj; 2653 2654 if (!mls_enabled) 2655 return (0); 2656 2657 subj = SLOT(cred->cr_label); 2658 obj = SLOT(vplabel); 2659 2660 if (!mls_dominate_effective(obj, subj)) 2661 return (EACCES); 2662 2663 return (0); 2664 } 2665 2666 static int 2667 mls_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2668 struct label *vplabel, int attrnamespace, const char *name, 2669 struct uio *uio) 2670 { 2671 struct mac_mls *subj, *obj; 2672 2673 if (!mls_enabled) 2674 return (0); 2675 2676 subj = SLOT(cred->cr_label); 2677 obj = SLOT(vplabel); 2678 2679 if (!mls_dominate_effective(obj, subj)) 2680 return (EACCES); 2681 2682 /* XXX: protect the MAC EA in a special way? */ 2683 2684 return (0); 2685 } 2686 2687 static int 2688 mls_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2689 struct label *vplabel, u_long flags) 2690 { 2691 struct mac_mls *subj, *obj; 2692 2693 if (!mls_enabled) 2694 return (0); 2695 2696 subj = SLOT(cred->cr_label); 2697 obj = SLOT(vplabel); 2698 2699 if (!mls_dominate_effective(obj, subj)) 2700 return (EACCES); 2701 2702 return (0); 2703 } 2704 2705 static int 2706 mls_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 2707 struct label *vplabel, mode_t mode) 2708 { 2709 struct mac_mls *subj, *obj; 2710 2711 if (!mls_enabled) 2712 return (0); 2713 2714 subj = SLOT(cred->cr_label); 2715 obj = SLOT(vplabel); 2716 2717 if (!mls_dominate_effective(obj, subj)) 2718 return (EACCES); 2719 2720 return (0); 2721 } 2722 2723 static int 2724 mls_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 2725 struct label *vplabel, uid_t uid, gid_t gid) 2726 { 2727 struct mac_mls *subj, *obj; 2728 2729 if (!mls_enabled) 2730 return (0); 2731 2732 subj = SLOT(cred->cr_label); 2733 obj = SLOT(vplabel); 2734 2735 if (!mls_dominate_effective(obj, subj)) 2736 return (EACCES); 2737 2738 return (0); 2739 } 2740 2741 static int 2742 mls_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 2743 struct label *vplabel, struct timespec atime, struct timespec mtime) 2744 { 2745 struct mac_mls *subj, *obj; 2746 2747 if (!mls_enabled) 2748 return (0); 2749 2750 subj = SLOT(cred->cr_label); 2751 obj = SLOT(vplabel); 2752 2753 if (!mls_dominate_effective(obj, subj)) 2754 return (EACCES); 2755 2756 return (0); 2757 } 2758 2759 static int 2760 mls_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 2761 struct vnode *vp, struct label *vplabel) 2762 { 2763 struct mac_mls *subj, *obj; 2764 2765 if (!mls_enabled) 2766 return (0); 2767 2768 subj = SLOT(active_cred->cr_label); 2769 obj = SLOT(vplabel); 2770 2771 if (!mls_dominate_effective(subj, obj)) 2772 return (EACCES); 2773 2774 return (0); 2775 } 2776 2777 static int 2778 mls_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 2779 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2780 struct componentname *cnp) 2781 { 2782 struct mac_mls *subj, *obj; 2783 2784 if (!mls_enabled) 2785 return (0); 2786 2787 subj = SLOT(cred->cr_label); 2788 obj = SLOT(dvplabel); 2789 2790 if (!mls_dominate_effective(obj, subj)) 2791 return (EACCES); 2792 2793 obj = SLOT(vplabel); 2794 2795 if (!mls_dominate_effective(obj, subj)) 2796 return (EACCES); 2797 2798 return (0); 2799 } 2800 2801 static int 2802 mls_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred, 2803 struct vnode *vp, struct label *vplabel) 2804 { 2805 struct mac_mls *subj, *obj; 2806 2807 if (!mls_enabled || !revocation_enabled) 2808 return (0); 2809 2810 subj = SLOT(active_cred->cr_label); 2811 obj = SLOT(vplabel); 2812 2813 if (!mls_dominate_effective(obj, subj)) 2814 return (EACCES); 2815 2816 return (0); 2817 } 2818 2819 static int 2820 mls_vnode_create_extattr(struct ucred *cred, struct mount *mp, 2821 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 2822 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 2823 { 2824 struct mac_mls *source, *dest, mm_temp; 2825 size_t buflen; 2826 int error; 2827 2828 buflen = sizeof(mm_temp); 2829 bzero(&mm_temp, buflen); 2830 2831 source = SLOT(cred->cr_label); 2832 dest = SLOT(vplabel); 2833 mls_copy_effective(source, &mm_temp); 2834 2835 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2836 MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 2837 if (error == 0) 2838 mls_copy_effective(source, dest); 2839 return (error); 2840 } 2841 2842 static void 2843 mls_vnode_relabel(struct ucred *cred, struct vnode *vp, 2844 struct label *vplabel, struct label *label) 2845 { 2846 struct mac_mls *source, *dest; 2847 2848 source = SLOT(label); 2849 dest = SLOT(vplabel); 2850 2851 mls_copy(source, dest); 2852 } 2853 2854 static int 2855 mls_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 2856 struct label *vplabel, struct label *intlabel) 2857 { 2858 struct mac_mls *source, mm_temp; 2859 size_t buflen; 2860 int error; 2861 2862 buflen = sizeof(mm_temp); 2863 bzero(&mm_temp, buflen); 2864 2865 source = SLOT(intlabel); 2866 if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 2867 return (0); 2868 2869 mls_copy_effective(source, &mm_temp); 2870 2871 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2872 MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 2873 return (error); 2874 } 2875 2876 static struct mac_policy_ops mls_ops = 2877 { 2878 .mpo_init = mls_init, 2879 2880 .mpo_bpfdesc_check_receive = mls_bpfdesc_check_receive, 2881 .mpo_bpfdesc_create = mls_bpfdesc_create, 2882 .mpo_bpfdesc_create_mbuf = mls_bpfdesc_create_mbuf, 2883 .mpo_bpfdesc_destroy_label = mls_destroy_label, 2884 .mpo_bpfdesc_init_label = mls_init_label, 2885 2886 .mpo_cred_check_relabel = mls_cred_check_relabel, 2887 .mpo_cred_check_visible = mls_cred_check_visible, 2888 .mpo_cred_copy_label = mls_copy_label, 2889 .mpo_cred_destroy_label = mls_destroy_label, 2890 .mpo_cred_externalize_label = mls_externalize_label, 2891 .mpo_cred_init_label = mls_init_label, 2892 .mpo_cred_internalize_label = mls_internalize_label, 2893 .mpo_cred_relabel = mls_cred_relabel, 2894 2895 .mpo_devfs_create_device = mls_devfs_create_device, 2896 .mpo_devfs_create_directory = mls_devfs_create_directory, 2897 .mpo_devfs_create_symlink = mls_devfs_create_symlink, 2898 .mpo_devfs_destroy_label = mls_destroy_label, 2899 .mpo_devfs_init_label = mls_init_label, 2900 .mpo_devfs_update = mls_devfs_update, 2901 .mpo_devfs_vnode_associate = mls_devfs_vnode_associate, 2902 2903 .mpo_ifnet_check_relabel = mls_ifnet_check_relabel, 2904 .mpo_ifnet_check_transmit = mls_ifnet_check_transmit, 2905 .mpo_ifnet_copy_label = mls_copy_label, 2906 .mpo_ifnet_create = mls_ifnet_create, 2907 .mpo_ifnet_create_mbuf = mls_ifnet_create_mbuf, 2908 .mpo_ifnet_destroy_label = mls_destroy_label, 2909 .mpo_ifnet_externalize_label = mls_externalize_label, 2910 .mpo_ifnet_init_label = mls_init_label, 2911 .mpo_ifnet_internalize_label = mls_internalize_label, 2912 .mpo_ifnet_relabel = mls_ifnet_relabel, 2913 2914 .mpo_inpcb_check_deliver = mls_inpcb_check_deliver, 2915 .mpo_inpcb_create = mls_inpcb_create, 2916 .mpo_inpcb_create_mbuf = mls_inpcb_create_mbuf, 2917 .mpo_inpcb_destroy_label = mls_destroy_label, 2918 .mpo_inpcb_init_label = mls_init_label_waitcheck, 2919 .mpo_inpcb_sosetlabel = mls_inpcb_sosetlabel, 2920 2921 .mpo_ipq_create = mls_ipq_create, 2922 .mpo_ipq_destroy_label = mls_destroy_label, 2923 .mpo_ipq_init_label = mls_init_label_waitcheck, 2924 .mpo_ipq_match = mls_ipq_match, 2925 .mpo_ipq_reassemble = mls_ipq_reassemble, 2926 .mpo_ipq_update = mls_ipq_update, 2927 2928 .mpo_mbuf_copy_label = mls_copy_label, 2929 .mpo_mbuf_destroy_label = mls_destroy_label, 2930 .mpo_mbuf_init_label = mls_init_label_waitcheck, 2931 2932 .mpo_mount_check_stat = mls_mount_check_stat, 2933 .mpo_mount_create = mls_mount_create, 2934 .mpo_mount_destroy_label = mls_destroy_label, 2935 .mpo_mount_init_label = mls_init_label, 2936 2937 .mpo_netatalk_aarp_send = mls_netatalk_aarp_send, 2938 2939 .mpo_netinet_arp_send = mls_netinet_arp_send, 2940 .mpo_netinet_firewall_reply = mls_netinet_firewall_reply, 2941 .mpo_netinet_firewall_send = mls_netinet_firewall_send, 2942 .mpo_netinet_fragment = mls_netinet_fragment, 2943 .mpo_netinet_icmp_reply = mls_netinet_icmp_reply, 2944 .mpo_netinet_igmp_send = mls_netinet_igmp_send, 2945 2946 .mpo_netinet6_nd6_send = mls_netinet6_nd6_send, 2947 2948 .mpo_pipe_check_ioctl = mls_pipe_check_ioctl, 2949 .mpo_pipe_check_poll = mls_pipe_check_poll, 2950 .mpo_pipe_check_read = mls_pipe_check_read, 2951 .mpo_pipe_check_relabel = mls_pipe_check_relabel, 2952 .mpo_pipe_check_stat = mls_pipe_check_stat, 2953 .mpo_pipe_check_write = mls_pipe_check_write, 2954 .mpo_pipe_copy_label = mls_copy_label, 2955 .mpo_pipe_create = mls_pipe_create, 2956 .mpo_pipe_destroy_label = mls_destroy_label, 2957 .mpo_pipe_externalize_label = mls_externalize_label, 2958 .mpo_pipe_init_label = mls_init_label, 2959 .mpo_pipe_internalize_label = mls_internalize_label, 2960 .mpo_pipe_relabel = mls_pipe_relabel, 2961 2962 .mpo_posixsem_check_destroy = mls_posixsem_check_write, 2963 .mpo_posixsem_check_getvalue = mls_posixsem_check_rdonly, 2964 .mpo_posixsem_check_open = mls_posixsem_check_write, 2965 .mpo_posixsem_check_post = mls_posixsem_check_write, 2966 .mpo_posixsem_check_unlink = mls_posixsem_check_write, 2967 .mpo_posixsem_check_wait = mls_posixsem_check_write, 2968 .mpo_posixsem_create = mls_posixsem_create, 2969 .mpo_posixsem_destroy_label = mls_destroy_label, 2970 .mpo_posixsem_init_label = mls_init_label, 2971 2972 .mpo_proc_associate_nfsd = mls_proc_associate_nfsd, 2973 .mpo_proc_check_debug = mls_proc_check_debug, 2974 .mpo_proc_check_sched = mls_proc_check_sched, 2975 .mpo_proc_check_signal = mls_proc_check_signal, 2976 .mpo_proc_create_init = mls_proc_create_init, 2977 .mpo_proc_create_swapper = mls_proc_create_swapper, 2978 2979 .mpo_socket_check_deliver = mls_socket_check_deliver, 2980 .mpo_socket_check_relabel = mls_socket_check_relabel, 2981 .mpo_socket_check_visible = mls_socket_check_visible, 2982 .mpo_socket_copy_label = mls_copy_label, 2983 .mpo_socket_create = mls_socket_create, 2984 .mpo_socket_create_mbuf = mls_socket_create_mbuf, 2985 .mpo_socket_destroy_label = mls_destroy_label, 2986 .mpo_socket_externalize_label = mls_externalize_label, 2987 .mpo_socket_init_label = mls_init_label_waitcheck, 2988 .mpo_socket_internalize_label = mls_internalize_label, 2989 .mpo_socket_newconn = mls_socket_newconn, 2990 .mpo_socket_relabel = mls_socket_relabel, 2991 2992 .mpo_socketpeer_destroy_label = mls_destroy_label, 2993 .mpo_socketpeer_externalize_label = mls_externalize_label, 2994 .mpo_socketpeer_init_label = mls_init_label_waitcheck, 2995 .mpo_socketpeer_set_from_mbuf = mls_socketpeer_set_from_mbuf, 2996 .mpo_socketpeer_set_from_socket = mls_socketpeer_set_from_socket, 2997 2998 .mpo_syncache_create = mls_syncache_create, 2999 .mpo_syncache_create_mbuf = mls_syncache_create_mbuf, 3000 .mpo_syncache_destroy_label = mls_destroy_label, 3001 .mpo_syncache_init_label = mls_init_label_waitcheck, 3002 3003 .mpo_sysvmsg_cleanup = mls_sysvmsg_cleanup, 3004 .mpo_sysvmsg_create = mls_sysvmsg_create, 3005 .mpo_sysvmsg_destroy_label = mls_destroy_label, 3006 .mpo_sysvmsg_init_label = mls_init_label, 3007 3008 .mpo_sysvmsq_check_msgrcv = mls_sysvmsq_check_msgrcv, 3009 .mpo_sysvmsq_check_msgrmid = mls_sysvmsq_check_msgrmid, 3010 .mpo_sysvmsq_check_msqget = mls_sysvmsq_check_msqget, 3011 .mpo_sysvmsq_check_msqsnd = mls_sysvmsq_check_msqsnd, 3012 .mpo_sysvmsq_check_msqrcv = mls_sysvmsq_check_msqrcv, 3013 .mpo_sysvmsq_check_msqctl = mls_sysvmsq_check_msqctl, 3014 .mpo_sysvmsq_cleanup = mls_sysvmsq_cleanup, 3015 .mpo_sysvmsq_destroy_label = mls_destroy_label, 3016 .mpo_sysvmsq_init_label = mls_init_label, 3017 .mpo_sysvmsq_create = mls_sysvmsq_create, 3018 3019 .mpo_sysvsem_check_semctl = mls_sysvsem_check_semctl, 3020 .mpo_sysvsem_check_semget = mls_sysvsem_check_semget, 3021 .mpo_sysvsem_check_semop = mls_sysvsem_check_semop, 3022 .mpo_sysvsem_cleanup = mls_sysvsem_cleanup, 3023 .mpo_sysvsem_create = mls_sysvsem_create, 3024 .mpo_sysvsem_destroy_label = mls_destroy_label, 3025 .mpo_sysvsem_init_label = mls_init_label, 3026 3027 .mpo_sysvshm_check_shmat = mls_sysvshm_check_shmat, 3028 .mpo_sysvshm_check_shmctl = mls_sysvshm_check_shmctl, 3029 .mpo_sysvshm_check_shmget = mls_sysvshm_check_shmget, 3030 .mpo_sysvshm_cleanup = mls_sysvshm_cleanup, 3031 .mpo_sysvshm_create = mls_sysvshm_create, 3032 .mpo_sysvshm_destroy_label = mls_destroy_label, 3033 .mpo_sysvshm_init_label = mls_init_label, 3034 3035 3036 .mpo_system_check_acct = mls_system_check_acct, 3037 .mpo_system_check_auditctl = mls_system_check_auditctl, 3038 .mpo_system_check_swapon = mls_system_check_swapon, 3039 3040 .mpo_vnode_associate_extattr = mls_vnode_associate_extattr, 3041 .mpo_vnode_associate_singlelabel = mls_vnode_associate_singlelabel, 3042 .mpo_vnode_check_access = mls_vnode_check_open, 3043 .mpo_vnode_check_chdir = mls_vnode_check_chdir, 3044 .mpo_vnode_check_chroot = mls_vnode_check_chroot, 3045 .mpo_vnode_check_create = mls_vnode_check_create, 3046 .mpo_vnode_check_deleteacl = mls_vnode_check_deleteacl, 3047 .mpo_vnode_check_deleteextattr = mls_vnode_check_deleteextattr, 3048 .mpo_vnode_check_exec = mls_vnode_check_exec, 3049 .mpo_vnode_check_getacl = mls_vnode_check_getacl, 3050 .mpo_vnode_check_getextattr = mls_vnode_check_getextattr, 3051 .mpo_vnode_check_link = mls_vnode_check_link, 3052 .mpo_vnode_check_listextattr = mls_vnode_check_listextattr, 3053 .mpo_vnode_check_lookup = mls_vnode_check_lookup, 3054 .mpo_vnode_check_mmap = mls_vnode_check_mmap, 3055 .mpo_vnode_check_open = mls_vnode_check_open, 3056 .mpo_vnode_check_poll = mls_vnode_check_poll, 3057 .mpo_vnode_check_read = mls_vnode_check_read, 3058 .mpo_vnode_check_readdir = mls_vnode_check_readdir, 3059 .mpo_vnode_check_readlink = mls_vnode_check_readlink, 3060 .mpo_vnode_check_relabel = mls_vnode_check_relabel, 3061 .mpo_vnode_check_rename_from = mls_vnode_check_rename_from, 3062 .mpo_vnode_check_rename_to = mls_vnode_check_rename_to, 3063 .mpo_vnode_check_revoke = mls_vnode_check_revoke, 3064 .mpo_vnode_check_setacl = mls_vnode_check_setacl, 3065 .mpo_vnode_check_setextattr = mls_vnode_check_setextattr, 3066 .mpo_vnode_check_setflags = mls_vnode_check_setflags, 3067 .mpo_vnode_check_setmode = mls_vnode_check_setmode, 3068 .mpo_vnode_check_setowner = mls_vnode_check_setowner, 3069 .mpo_vnode_check_setutimes = mls_vnode_check_setutimes, 3070 .mpo_vnode_check_stat = mls_vnode_check_stat, 3071 .mpo_vnode_check_unlink = mls_vnode_check_unlink, 3072 .mpo_vnode_check_write = mls_vnode_check_write, 3073 .mpo_vnode_copy_label = mls_copy_label, 3074 .mpo_vnode_create_extattr = mls_vnode_create_extattr, 3075 .mpo_vnode_destroy_label = mls_destroy_label, 3076 .mpo_vnode_externalize_label = mls_externalize_label, 3077 .mpo_vnode_init_label = mls_init_label, 3078 .mpo_vnode_internalize_label = mls_internalize_label, 3079 .mpo_vnode_relabel = mls_vnode_relabel, 3080 .mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr, 3081 }; 3082 3083 MAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS", 3084 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mls_slot); 3085