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 *q, 1079 struct label *qlabel) 1080 { 1081 struct mac_mls *source, *dest; 1082 1083 source = SLOT(mlabel); 1084 dest = SLOT(qlabel); 1085 1086 mls_copy_effective(source, dest); 1087 } 1088 1089 static int 1090 mls_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1091 struct label *qlabel) 1092 { 1093 struct mac_mls *a, *b; 1094 1095 a = SLOT(qlabel); 1096 b = SLOT(mlabel); 1097 1098 return (mls_equal_effective(a, b)); 1099 } 1100 1101 static void 1102 mls_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1103 struct label *mlabel) 1104 { 1105 struct mac_mls *source, *dest; 1106 1107 source = SLOT(qlabel); 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 *q, 1116 struct label *qlabel) 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_openunlink(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(obj, subj)) 1415 return (EACCES); 1416 1417 return (0); 1418 } 1419 1420 static int 1421 mls_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred, 1422 struct ksem *ks, struct label *kslabel) 1423 { 1424 struct mac_mls *subj, *obj; 1425 1426 if (!mls_enabled) 1427 return (0); 1428 1429 subj = SLOT(active_cred->cr_label); 1430 obj = SLOT(kslabel); 1431 1432 if (!mls_dominate_effective(subj, obj)) 1433 return (EACCES); 1434 1435 return (0); 1436 } 1437 1438 static int 1439 mls_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred, 1440 struct ksem *ks, struct label *kslabel) 1441 { 1442 struct mac_mls *subj, *obj; 1443 1444 if (!mls_enabled) 1445 return (0); 1446 1447 subj = SLOT(active_cred->cr_label); 1448 obj = SLOT(kslabel); 1449 1450 if (!mls_dominate_effective(obj, subj)) 1451 return (EACCES); 1452 1453 return (0); 1454 } 1455 1456 static void 1457 mls_posixsem_create(struct ucred *cred, struct ksem *ks, 1458 struct label *kslabel) 1459 { 1460 struct mac_mls *source, *dest; 1461 1462 source = SLOT(cred->cr_label); 1463 dest = SLOT(kslabel); 1464 1465 mls_copy_effective(source, dest); 1466 } 1467 1468 static void 1469 mls_proc_associate_nfsd(struct ucred *cred) 1470 { 1471 struct mac_mls *label; 1472 1473 label = SLOT(cred->cr_label); 1474 mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL); 1475 mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1476 NULL); 1477 } 1478 1479 static int 1480 mls_proc_check_debug(struct ucred *cred, struct proc *p) 1481 { 1482 struct mac_mls *subj, *obj; 1483 1484 if (!mls_enabled) 1485 return (0); 1486 1487 subj = SLOT(cred->cr_label); 1488 obj = SLOT(p->p_ucred->cr_label); 1489 1490 /* XXX: range checks */ 1491 if (!mls_dominate_effective(subj, obj)) 1492 return (ESRCH); 1493 if (!mls_dominate_effective(obj, subj)) 1494 return (EACCES); 1495 1496 return (0); 1497 } 1498 1499 static int 1500 mls_proc_check_sched(struct ucred *cred, struct proc *p) 1501 { 1502 struct mac_mls *subj, *obj; 1503 1504 if (!mls_enabled) 1505 return (0); 1506 1507 subj = SLOT(cred->cr_label); 1508 obj = SLOT(p->p_ucred->cr_label); 1509 1510 /* XXX: range checks */ 1511 if (!mls_dominate_effective(subj, obj)) 1512 return (ESRCH); 1513 if (!mls_dominate_effective(obj, subj)) 1514 return (EACCES); 1515 1516 return (0); 1517 } 1518 1519 static int 1520 mls_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1521 { 1522 struct mac_mls *subj, *obj; 1523 1524 if (!mls_enabled) 1525 return (0); 1526 1527 subj = SLOT(cred->cr_label); 1528 obj = SLOT(p->p_ucred->cr_label); 1529 1530 /* XXX: range checks */ 1531 if (!mls_dominate_effective(subj, obj)) 1532 return (ESRCH); 1533 if (!mls_dominate_effective(obj, subj)) 1534 return (EACCES); 1535 1536 return (0); 1537 } 1538 1539 static void 1540 mls_proc_create_init(struct ucred *cred) 1541 { 1542 struct mac_mls *dest; 1543 1544 dest = SLOT(cred->cr_label); 1545 1546 mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL); 1547 mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1548 NULL); 1549 } 1550 1551 static void 1552 mls_proc_create_swapper(struct ucred *cred) 1553 { 1554 struct mac_mls *dest; 1555 1556 dest = SLOT(cred->cr_label); 1557 1558 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1559 mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1560 NULL); 1561 } 1562 1563 static int 1564 mls_socket_check_deliver(struct socket *so, struct label *solabel, 1565 struct mbuf *m, struct label *mlabel) 1566 { 1567 struct mac_mls *p, *s; 1568 1569 if (!mls_enabled) 1570 return (0); 1571 1572 p = SLOT(mlabel); 1573 s = SLOT(solabel); 1574 1575 return (mls_equal_effective(p, s) ? 0 : EACCES); 1576 } 1577 1578 static int 1579 mls_socket_check_relabel(struct ucred *cred, struct socket *so, 1580 struct label *solabel, struct label *newlabel) 1581 { 1582 struct mac_mls *subj, *obj, *new; 1583 int error; 1584 1585 new = SLOT(newlabel); 1586 subj = SLOT(cred->cr_label); 1587 obj = SLOT(solabel); 1588 1589 /* 1590 * If there is an MLS label update for the socket, it may be an 1591 * update of effective. 1592 */ 1593 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1594 if (error) 1595 return (error); 1596 1597 /* 1598 * To relabel a socket, the old socket effective must be in the 1599 * subject range. 1600 */ 1601 if (!mls_effective_in_range(obj, subj)) 1602 return (EPERM); 1603 1604 /* 1605 * If the MLS label is to be changed, authorize as appropriate. 1606 */ 1607 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1608 /* 1609 * To relabel a socket, the new socket effective must be in 1610 * the subject range. 1611 */ 1612 if (!mls_effective_in_range(new, subj)) 1613 return (EPERM); 1614 1615 /* 1616 * To change the MLS label on the socket to contain EQUAL, 1617 * the subject must have appropriate privilege. 1618 */ 1619 if (mls_contains_equal(new)) { 1620 error = mls_subject_privileged(subj); 1621 if (error) 1622 return (error); 1623 } 1624 } 1625 1626 return (0); 1627 } 1628 1629 static int 1630 mls_socket_check_visible(struct ucred *cred, struct socket *so, 1631 struct label *solabel) 1632 { 1633 struct mac_mls *subj, *obj; 1634 1635 if (!mls_enabled) 1636 return (0); 1637 1638 subj = SLOT(cred->cr_label); 1639 obj = SLOT(solabel); 1640 1641 if (!mls_dominate_effective(subj, obj)) 1642 return (ENOENT); 1643 1644 return (0); 1645 } 1646 1647 static void 1648 mls_socket_create(struct ucred *cred, struct socket *so, 1649 struct label *solabel) 1650 { 1651 struct mac_mls *source, *dest; 1652 1653 source = SLOT(cred->cr_label); 1654 dest = SLOT(solabel); 1655 1656 mls_copy_effective(source, dest); 1657 } 1658 1659 static void 1660 mls_socket_create_mbuf(struct socket *so, struct label *solabel, 1661 struct mbuf *m, struct label *mlabel) 1662 { 1663 struct mac_mls *source, *dest; 1664 1665 source = SLOT(solabel); 1666 dest = SLOT(mlabel); 1667 1668 mls_copy_effective(source, dest); 1669 } 1670 1671 static void 1672 mls_socket_newconn(struct socket *oldso, struct label *oldsolabel, 1673 struct socket *newso, struct label *newsolabel) 1674 { 1675 struct mac_mls *source, *dest; 1676 1677 source = SLOT(oldsolabel); 1678 dest = SLOT(newsolabel); 1679 1680 mls_copy_effective(source, dest); 1681 } 1682 1683 static void 1684 mls_socket_relabel(struct ucred *cred, struct socket *so, 1685 struct label *solabel, struct label *newlabel) 1686 { 1687 struct mac_mls *source, *dest; 1688 1689 source = SLOT(newlabel); 1690 dest = SLOT(solabel); 1691 1692 mls_copy(source, dest); 1693 } 1694 1695 static void 1696 mls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 1697 struct socket *so, struct label *sopeerlabel) 1698 { 1699 struct mac_mls *source, *dest; 1700 1701 source = SLOT(mlabel); 1702 dest = SLOT(sopeerlabel); 1703 1704 mls_copy_effective(source, dest); 1705 } 1706 1707 static void 1708 mls_socketpeer_set_from_socket(struct socket *oldso, 1709 struct label *oldsolabel, struct socket *newso, 1710 struct label *newsopeerlabel) 1711 { 1712 struct mac_mls *source, *dest; 1713 1714 source = SLOT(oldsolabel); 1715 dest = SLOT(newsopeerlabel); 1716 1717 mls_copy_effective(source, dest); 1718 } 1719 1720 static void 1721 mls_syncache_create(struct label *label, struct inpcb *inp) 1722 { 1723 struct mac_mls *source, *dest; 1724 1725 source = SLOT(inp->inp_label); 1726 dest = SLOT(label); 1727 1728 mls_copy_effective(source, dest); 1729 } 1730 1731 static void 1732 mls_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 1733 struct label *mlabel) 1734 { 1735 struct mac_mls *source, *dest; 1736 1737 source = SLOT(sc_label); 1738 dest = SLOT(mlabel); 1739 1740 mls_copy_effective(source, dest); 1741 } 1742 1743 static int 1744 mls_system_check_acct(struct ucred *cred, struct vnode *vp, 1745 struct label *vplabel) 1746 { 1747 struct mac_mls *subj, *obj; 1748 1749 if (!mls_enabled) 1750 return (0); 1751 1752 subj = SLOT(cred->cr_label); 1753 obj = SLOT(vplabel); 1754 1755 if (!mls_dominate_effective(obj, subj) || 1756 !mls_dominate_effective(subj, obj)) 1757 return (EACCES); 1758 1759 return (0); 1760 } 1761 1762 static int 1763 mls_system_check_auditctl(struct ucred *cred, struct vnode *vp, 1764 struct label *vplabel) 1765 { 1766 struct mac_mls *subj, *obj; 1767 1768 if (!mls_enabled) 1769 return (0); 1770 1771 subj = SLOT(cred->cr_label); 1772 obj = SLOT(vplabel); 1773 1774 if (!mls_dominate_effective(obj, subj) || 1775 !mls_dominate_effective(subj, obj)) 1776 return (EACCES); 1777 1778 return (0); 1779 } 1780 1781 static int 1782 mls_system_check_swapon(struct ucred *cred, struct vnode *vp, 1783 struct label *vplabel) 1784 { 1785 struct mac_mls *subj, *obj; 1786 1787 if (!mls_enabled) 1788 return (0); 1789 1790 subj = SLOT(cred->cr_label); 1791 obj = SLOT(vplabel); 1792 1793 if (!mls_dominate_effective(obj, subj) || 1794 !mls_dominate_effective(subj, obj)) 1795 return (EACCES); 1796 1797 return (0); 1798 } 1799 1800 static void 1801 mls_sysvmsg_cleanup(struct label *msglabel) 1802 { 1803 1804 bzero(SLOT(msglabel), sizeof(struct mac_mls)); 1805 } 1806 1807 static void 1808 mls_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1809 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1810 { 1811 struct mac_mls *source, *dest; 1812 1813 /* Ignore the msgq label. */ 1814 source = SLOT(cred->cr_label); 1815 dest = SLOT(msglabel); 1816 1817 mls_copy_effective(source, dest); 1818 } 1819 1820 static int 1821 mls_sysvmsq_check_msgrcv(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(subj, obj)) 1833 return (EACCES); 1834 1835 return (0); 1836 } 1837 1838 static int 1839 mls_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 1840 struct label *msglabel) 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(msglabel); 1849 1850 if (!mls_dominate_effective(obj, subj)) 1851 return (EACCES); 1852 1853 return (0); 1854 } 1855 1856 static int 1857 mls_sysvmsq_check_msqget(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(subj, obj)) 1869 return (EACCES); 1870 1871 return (0); 1872 } 1873 1874 static int 1875 mls_sysvmsq_check_msqsnd(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(obj, subj)) 1887 return (EACCES); 1888 1889 return (0); 1890 } 1891 1892 static int 1893 mls_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1894 struct label *msqklabel) 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 if (!mls_dominate_effective(subj, obj)) 1905 return (EACCES); 1906 1907 return (0); 1908 } 1909 1910 static int 1911 mls_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1912 struct label *msqklabel, int cmd) 1913 { 1914 struct mac_mls *subj, *obj; 1915 1916 if (!mls_enabled) 1917 return (0); 1918 1919 subj = SLOT(cred->cr_label); 1920 obj = SLOT(msqklabel); 1921 1922 switch(cmd) { 1923 case IPC_RMID: 1924 case IPC_SET: 1925 if (!mls_dominate_effective(obj, subj)) 1926 return (EACCES); 1927 break; 1928 1929 case IPC_STAT: 1930 if (!mls_dominate_effective(subj, obj)) 1931 return (EACCES); 1932 break; 1933 1934 default: 1935 return (EACCES); 1936 } 1937 1938 return (0); 1939 } 1940 1941 static void 1942 mls_sysvmsq_cleanup(struct label *msqlabel) 1943 { 1944 1945 bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 1946 } 1947 1948 static void 1949 mls_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1950 struct label *msqlabel) 1951 { 1952 struct mac_mls *source, *dest; 1953 1954 source = SLOT(cred->cr_label); 1955 dest = SLOT(msqlabel); 1956 1957 mls_copy_effective(source, dest); 1958 } 1959 1960 static int 1961 mls_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1962 struct label *semaklabel, int cmd) 1963 { 1964 struct mac_mls *subj, *obj; 1965 1966 if (!mls_enabled) 1967 return (0); 1968 1969 subj = SLOT(cred->cr_label); 1970 obj = SLOT(semaklabel); 1971 1972 switch(cmd) { 1973 case IPC_RMID: 1974 case IPC_SET: 1975 case SETVAL: 1976 case SETALL: 1977 if (!mls_dominate_effective(obj, subj)) 1978 return (EACCES); 1979 break; 1980 1981 case IPC_STAT: 1982 case GETVAL: 1983 case GETPID: 1984 case GETNCNT: 1985 case GETZCNT: 1986 case GETALL: 1987 if (!mls_dominate_effective(subj, obj)) 1988 return (EACCES); 1989 break; 1990 1991 default: 1992 return (EACCES); 1993 } 1994 1995 return (0); 1996 } 1997 1998 static int 1999 mls_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 2000 struct label *semaklabel) 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 (!mls_dominate_effective(subj, obj)) 2011 return (EACCES); 2012 2013 return (0); 2014 } 2015 2016 static int 2017 mls_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2018 struct label *semaklabel, size_t accesstype) 2019 { 2020 struct mac_mls *subj, *obj; 2021 2022 if (!mls_enabled) 2023 return (0); 2024 2025 subj = SLOT(cred->cr_label); 2026 obj = SLOT(semaklabel); 2027 2028 if( accesstype & SEM_R ) 2029 if (!mls_dominate_effective(subj, obj)) 2030 return (EACCES); 2031 2032 if( accesstype & SEM_A ) 2033 if (!mls_dominate_effective(obj, subj)) 2034 return (EACCES); 2035 2036 return (0); 2037 } 2038 2039 static void 2040 mls_sysvsem_cleanup(struct label *semalabel) 2041 { 2042 2043 bzero(SLOT(semalabel), sizeof(struct mac_mls)); 2044 } 2045 2046 static void 2047 mls_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2048 struct label *semalabel) 2049 { 2050 struct mac_mls *source, *dest; 2051 2052 source = SLOT(cred->cr_label); 2053 dest = SLOT(semalabel); 2054 2055 mls_copy_effective(source, dest); 2056 } 2057 2058 static int 2059 mls_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2060 struct label *shmseglabel, int shmflg) 2061 { 2062 struct mac_mls *subj, *obj; 2063 2064 if (!mls_enabled) 2065 return (0); 2066 2067 subj = SLOT(cred->cr_label); 2068 obj = SLOT(shmseglabel); 2069 2070 if (!mls_dominate_effective(subj, obj)) 2071 return (EACCES); 2072 if ((shmflg & SHM_RDONLY) == 0) { 2073 if (!mls_dominate_effective(obj, subj)) 2074 return (EACCES); 2075 } 2076 2077 return (0); 2078 } 2079 2080 static int 2081 mls_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2082 struct label *shmseglabel, int cmd) 2083 { 2084 struct mac_mls *subj, *obj; 2085 2086 if (!mls_enabled) 2087 return (0); 2088 2089 subj = SLOT(cred->cr_label); 2090 obj = SLOT(shmseglabel); 2091 2092 switch(cmd) { 2093 case IPC_RMID: 2094 case IPC_SET: 2095 if (!mls_dominate_effective(obj, subj)) 2096 return (EACCES); 2097 break; 2098 2099 case IPC_STAT: 2100 case SHM_STAT: 2101 if (!mls_dominate_effective(subj, obj)) 2102 return (EACCES); 2103 break; 2104 2105 default: 2106 return (EACCES); 2107 } 2108 2109 return (0); 2110 } 2111 2112 static int 2113 mls_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2114 struct label *shmseglabel, int shmflg) 2115 { 2116 struct mac_mls *subj, *obj; 2117 2118 if (!mls_enabled) 2119 return (0); 2120 2121 subj = SLOT(cred->cr_label); 2122 obj = SLOT(shmseglabel); 2123 2124 if (!mls_dominate_effective(obj, subj)) 2125 return (EACCES); 2126 2127 return (0); 2128 } 2129 2130 static void 2131 mls_sysvshm_cleanup(struct label *shmlabel) 2132 { 2133 2134 bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 2135 } 2136 2137 static void 2138 mls_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2139 struct label *shmlabel) 2140 { 2141 struct mac_mls *source, *dest; 2142 2143 source = SLOT(cred->cr_label); 2144 dest = SLOT(shmlabel); 2145 2146 mls_copy_effective(source, dest); 2147 } 2148 2149 static int 2150 mls_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2151 struct vnode *vp, struct label *vplabel) 2152 { 2153 struct mac_mls mm_temp, *source, *dest; 2154 int buflen, error; 2155 2156 source = SLOT(mplabel); 2157 dest = SLOT(vplabel); 2158 2159 buflen = sizeof(mm_temp); 2160 bzero(&mm_temp, buflen); 2161 2162 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2163 MAC_MLS_EXTATTR_NAME, &buflen, (char *) &mm_temp, curthread); 2164 if (error == ENOATTR || error == EOPNOTSUPP) { 2165 /* Fall back to the mntlabel. */ 2166 mls_copy_effective(source, dest); 2167 return (0); 2168 } else if (error) 2169 return (error); 2170 2171 if (buflen != sizeof(mm_temp)) { 2172 printf("mls_vnode_associate_extattr: bad size %d\n", buflen); 2173 return (EPERM); 2174 } 2175 if (mls_valid(&mm_temp) != 0) { 2176 printf("mls_vnode_associate_extattr: invalid\n"); 2177 return (EPERM); 2178 } 2179 if ((mm_temp.mm_flags & MAC_MLS_FLAGS_BOTH) != 2180 MAC_MLS_FLAG_EFFECTIVE) { 2181 printf("mls_associated_vnode_extattr: not effective\n"); 2182 return (EPERM); 2183 } 2184 2185 mls_copy_effective(&mm_temp, dest); 2186 return (0); 2187 } 2188 2189 static void 2190 mls_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2191 struct vnode *vp, struct label *vplabel) 2192 { 2193 struct mac_mls *source, *dest; 2194 2195 source = SLOT(mplabel); 2196 dest = SLOT(vplabel); 2197 2198 mls_copy_effective(source, dest); 2199 } 2200 2201 static int 2202 mls_vnode_check_chdir(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_chroot(struct ucred *cred, struct vnode *dvp, 2221 struct label *dvplabel) 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(subj, obj)) 2232 return (EACCES); 2233 2234 return (0); 2235 } 2236 2237 static int 2238 mls_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2239 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 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(dvplabel); 2248 2249 if (!mls_dominate_effective(obj, subj)) 2250 return (EACCES); 2251 2252 return (0); 2253 } 2254 2255 static int 2256 mls_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2257 struct label *vplabel, acl_type_t type) 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_deleteextattr(struct ucred *cred, struct vnode *vp, 2275 struct label *vplabel, int attrnamespace, const char *name) 2276 { 2277 struct mac_mls *subj, *obj; 2278 2279 if (!mls_enabled) 2280 return (0); 2281 2282 subj = SLOT(cred->cr_label); 2283 obj = SLOT(vplabel); 2284 2285 if (!mls_dominate_effective(obj, subj)) 2286 return (EACCES); 2287 2288 return (0); 2289 } 2290 2291 static int 2292 mls_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2293 struct label *vplabel, struct image_params *imgp, 2294 struct label *execlabel) 2295 { 2296 struct mac_mls *subj, *obj, *exec; 2297 int error; 2298 2299 if (execlabel != NULL) { 2300 /* 2301 * We currently don't permit labels to be changed at 2302 * exec-time as part of MLS, so disallow non-NULL MLS label 2303 * elements in the execlabel. 2304 */ 2305 exec = SLOT(execlabel); 2306 error = mls_atmostflags(exec, 0); 2307 if (error) 2308 return (error); 2309 } 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_getacl(struct ucred *cred, struct vnode *vp, 2325 struct label *vplabel, acl_type_t type) 2326 { 2327 struct mac_mls *subj, *obj; 2328 2329 if (!mls_enabled) 2330 return (0); 2331 2332 subj = SLOT(cred->cr_label); 2333 obj = SLOT(vplabel); 2334 2335 if (!mls_dominate_effective(subj, obj)) 2336 return (EACCES); 2337 2338 return (0); 2339 } 2340 2341 static int 2342 mls_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 2343 struct label *vplabel, int attrnamespace, const char *name, 2344 struct uio *uio) 2345 { 2346 struct mac_mls *subj, *obj; 2347 2348 if (!mls_enabled) 2349 return (0); 2350 2351 subj = SLOT(cred->cr_label); 2352 obj = SLOT(vplabel); 2353 2354 if (!mls_dominate_effective(subj, obj)) 2355 return (EACCES); 2356 2357 return (0); 2358 } 2359 2360 static int 2361 mls_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2362 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2363 struct componentname *cnp) 2364 { 2365 struct mac_mls *subj, *obj; 2366 2367 if (!mls_enabled) 2368 return (0); 2369 2370 subj = SLOT(cred->cr_label); 2371 obj = SLOT(dvplabel); 2372 2373 if (!mls_dominate_effective(obj, subj)) 2374 return (EACCES); 2375 2376 obj = SLOT(vplabel); 2377 if (!mls_dominate_effective(obj, subj)) 2378 return (EACCES); 2379 2380 return (0); 2381 } 2382 2383 static int 2384 mls_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 2385 struct label *vplabel, int attrnamespace) 2386 { 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(vplabel); 2395 2396 if (!mls_dominate_effective(subj, obj)) 2397 return (EACCES); 2398 2399 return (0); 2400 } 2401 2402 static int 2403 mls_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 2404 struct label *dvplabel, struct componentname *cnp) 2405 { 2406 struct mac_mls *subj, *obj; 2407 2408 if (!mls_enabled) 2409 return (0); 2410 2411 subj = SLOT(cred->cr_label); 2412 obj = SLOT(dvplabel); 2413 2414 if (!mls_dominate_effective(subj, obj)) 2415 return (EACCES); 2416 2417 return (0); 2418 } 2419 2420 static int 2421 mls_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2422 struct label *vplabel, int prot, int flags) 2423 { 2424 struct mac_mls *subj, *obj; 2425 2426 /* 2427 * Rely on the use of open()-time protections to handle 2428 * non-revocation cases. 2429 */ 2430 if (!mls_enabled || !revocation_enabled) 2431 return (0); 2432 2433 subj = SLOT(cred->cr_label); 2434 obj = SLOT(vplabel); 2435 2436 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2437 if (!mls_dominate_effective(subj, obj)) 2438 return (EACCES); 2439 } 2440 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2441 if (!mls_dominate_effective(obj, subj)) 2442 return (EACCES); 2443 } 2444 2445 return (0); 2446 } 2447 2448 static int 2449 mls_vnode_check_open(struct ucred *cred, struct vnode *vp, 2450 struct label *vplabel, int acc_mode) 2451 { 2452 struct mac_mls *subj, *obj; 2453 2454 if (!mls_enabled) 2455 return (0); 2456 2457 subj = SLOT(cred->cr_label); 2458 obj = SLOT(vplabel); 2459 2460 /* XXX privilege override for admin? */ 2461 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2462 if (!mls_dominate_effective(subj, obj)) 2463 return (EACCES); 2464 } 2465 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2466 if (!mls_dominate_effective(obj, subj)) 2467 return (EACCES); 2468 } 2469 2470 return (0); 2471 } 2472 2473 static int 2474 mls_vnode_check_poll(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_read(struct ucred *active_cred, struct ucred *file_cred, 2493 struct vnode *vp, struct label *vplabel) 2494 { 2495 struct mac_mls *subj, *obj; 2496 2497 if (!mls_enabled || !revocation_enabled) 2498 return (0); 2499 2500 subj = SLOT(active_cred->cr_label); 2501 obj = SLOT(vplabel); 2502 2503 if (!mls_dominate_effective(subj, obj)) 2504 return (EACCES); 2505 2506 return (0); 2507 } 2508 2509 static int 2510 mls_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 2511 struct label *dvplabel) 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(dvplabel); 2520 2521 if (!mls_dominate_effective(subj, obj)) 2522 return (EACCES); 2523 2524 return (0); 2525 } 2526 2527 static int 2528 mls_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 2529 struct label *vplabel) 2530 { 2531 struct mac_mls *subj, *obj; 2532 2533 if (!mls_enabled) 2534 return (0); 2535 2536 subj = SLOT(cred->cr_label); 2537 obj = SLOT(vplabel); 2538 2539 if (!mls_dominate_effective(subj, obj)) 2540 return (EACCES); 2541 2542 return (0); 2543 } 2544 2545 static int 2546 mls_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2547 struct label *vplabel, struct label *newlabel) 2548 { 2549 struct mac_mls *old, *new, *subj; 2550 int error; 2551 2552 old = SLOT(vplabel); 2553 new = SLOT(newlabel); 2554 subj = SLOT(cred->cr_label); 2555 2556 /* 2557 * If there is an MLS label update for the vnode, it must be a 2558 * effective label. 2559 */ 2560 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2561 if (error) 2562 return (error); 2563 2564 /* 2565 * To perform a relabel of the vnode (MLS label or not), MLS must 2566 * authorize the relabel. 2567 */ 2568 if (!mls_effective_in_range(old, subj)) 2569 return (EPERM); 2570 2571 /* 2572 * If the MLS label is to be changed, authorize as appropriate. 2573 */ 2574 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2575 /* 2576 * To change the MLS label on a vnode, the new vnode label 2577 * must be in the subject range. 2578 */ 2579 if (!mls_effective_in_range(new, subj)) 2580 return (EPERM); 2581 2582 /* 2583 * To change the MLS label on the vnode to be EQUAL, the 2584 * subject must have appropriate privilege. 2585 */ 2586 if (mls_contains_equal(new)) { 2587 error = mls_subject_privileged(subj); 2588 if (error) 2589 return (error); 2590 } 2591 } 2592 2593 return (0); 2594 } 2595 2596 static int 2597 mls_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2598 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2599 struct componentname *cnp) 2600 { 2601 struct mac_mls *subj, *obj; 2602 2603 if (!mls_enabled) 2604 return (0); 2605 2606 subj = SLOT(cred->cr_label); 2607 obj = SLOT(dvplabel); 2608 2609 if (!mls_dominate_effective(obj, subj)) 2610 return (EACCES); 2611 2612 obj = SLOT(vplabel); 2613 2614 if (!mls_dominate_effective(obj, subj)) 2615 return (EACCES); 2616 2617 return (0); 2618 } 2619 2620 static int 2621 mls_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2622 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2623 int samedir, struct componentname *cnp) 2624 { 2625 struct mac_mls *subj, *obj; 2626 2627 if (!mls_enabled) 2628 return (0); 2629 2630 subj = SLOT(cred->cr_label); 2631 obj = SLOT(dvplabel); 2632 2633 if (!mls_dominate_effective(obj, subj)) 2634 return (EACCES); 2635 2636 if (vp != NULL) { 2637 obj = SLOT(vplabel); 2638 2639 if (!mls_dominate_effective(obj, subj)) 2640 return (EACCES); 2641 } 2642 2643 return (0); 2644 } 2645 2646 static int 2647 mls_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2648 struct label *vplabel) 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_setacl(struct ucred *cred, struct vnode *vp, 2666 struct label *vplabel, acl_type_t type, struct acl *acl) 2667 { 2668 struct mac_mls *subj, *obj; 2669 2670 if (!mls_enabled) 2671 return (0); 2672 2673 subj = SLOT(cred->cr_label); 2674 obj = SLOT(vplabel); 2675 2676 if (!mls_dominate_effective(obj, subj)) 2677 return (EACCES); 2678 2679 return (0); 2680 } 2681 2682 static int 2683 mls_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2684 struct label *vplabel, int attrnamespace, const char *name, 2685 struct uio *uio) 2686 { 2687 struct mac_mls *subj, *obj; 2688 2689 if (!mls_enabled) 2690 return (0); 2691 2692 subj = SLOT(cred->cr_label); 2693 obj = SLOT(vplabel); 2694 2695 if (!mls_dominate_effective(obj, subj)) 2696 return (EACCES); 2697 2698 /* XXX: protect the MAC EA in a special way? */ 2699 2700 return (0); 2701 } 2702 2703 static int 2704 mls_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2705 struct label *vplabel, u_long flags) 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_setmode(struct ucred *cred, struct vnode *vp, 2723 struct label *vplabel, mode_t mode) 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_setowner(struct ucred *cred, struct vnode *vp, 2741 struct label *vplabel, uid_t uid, gid_t gid) 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_setutimes(struct ucred *cred, struct vnode *vp, 2759 struct label *vplabel, struct timespec atime, struct timespec mtime) 2760 { 2761 struct mac_mls *subj, *obj; 2762 2763 if (!mls_enabled) 2764 return (0); 2765 2766 subj = SLOT(cred->cr_label); 2767 obj = SLOT(vplabel); 2768 2769 if (!mls_dominate_effective(obj, subj)) 2770 return (EACCES); 2771 2772 return (0); 2773 } 2774 2775 static int 2776 mls_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 2777 struct vnode *vp, struct label *vplabel) 2778 { 2779 struct mac_mls *subj, *obj; 2780 2781 if (!mls_enabled) 2782 return (0); 2783 2784 subj = SLOT(active_cred->cr_label); 2785 obj = SLOT(vplabel); 2786 2787 if (!mls_dominate_effective(subj, obj)) 2788 return (EACCES); 2789 2790 return (0); 2791 } 2792 2793 static int 2794 mls_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 2795 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2796 struct componentname *cnp) 2797 { 2798 struct mac_mls *subj, *obj; 2799 2800 if (!mls_enabled) 2801 return (0); 2802 2803 subj = SLOT(cred->cr_label); 2804 obj = SLOT(dvplabel); 2805 2806 if (!mls_dominate_effective(obj, subj)) 2807 return (EACCES); 2808 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_check_write(struct ucred *active_cred, struct ucred *file_cred, 2819 struct vnode *vp, struct label *vplabel) 2820 { 2821 struct mac_mls *subj, *obj; 2822 2823 if (!mls_enabled || !revocation_enabled) 2824 return (0); 2825 2826 subj = SLOT(active_cred->cr_label); 2827 obj = SLOT(vplabel); 2828 2829 if (!mls_dominate_effective(obj, subj)) 2830 return (EACCES); 2831 2832 return (0); 2833 } 2834 2835 static int 2836 mls_vnode_create_extattr(struct ucred *cred, struct mount *mp, 2837 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 2838 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 2839 { 2840 struct mac_mls *source, *dest, mm_temp; 2841 size_t buflen; 2842 int error; 2843 2844 buflen = sizeof(mm_temp); 2845 bzero(&mm_temp, buflen); 2846 2847 source = SLOT(cred->cr_label); 2848 dest = SLOT(vplabel); 2849 mls_copy_effective(source, &mm_temp); 2850 2851 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2852 MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 2853 if (error == 0) 2854 mls_copy_effective(source, dest); 2855 return (error); 2856 } 2857 2858 static void 2859 mls_vnode_relabel(struct ucred *cred, struct vnode *vp, 2860 struct label *vplabel, struct label *label) 2861 { 2862 struct mac_mls *source, *dest; 2863 2864 source = SLOT(label); 2865 dest = SLOT(vplabel); 2866 2867 mls_copy(source, dest); 2868 } 2869 2870 static int 2871 mls_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 2872 struct label *vplabel, struct label *intlabel) 2873 { 2874 struct mac_mls *source, mm_temp; 2875 size_t buflen; 2876 int error; 2877 2878 buflen = sizeof(mm_temp); 2879 bzero(&mm_temp, buflen); 2880 2881 source = SLOT(intlabel); 2882 if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 2883 return (0); 2884 2885 mls_copy_effective(source, &mm_temp); 2886 2887 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2888 MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 2889 return (error); 2890 } 2891 2892 static struct mac_policy_ops mls_ops = 2893 { 2894 .mpo_init = mls_init, 2895 2896 .mpo_bpfdesc_check_receive = mls_bpfdesc_check_receive, 2897 .mpo_bpfdesc_create = mls_bpfdesc_create, 2898 .mpo_bpfdesc_create_mbuf = mls_bpfdesc_create_mbuf, 2899 .mpo_bpfdesc_destroy_label = mls_destroy_label, 2900 .mpo_bpfdesc_init_label = mls_init_label, 2901 2902 .mpo_cred_check_relabel = mls_cred_check_relabel, 2903 .mpo_cred_check_visible = mls_cred_check_visible, 2904 .mpo_cred_copy_label = mls_copy_label, 2905 .mpo_cred_destroy_label = mls_destroy_label, 2906 .mpo_cred_externalize_label = mls_externalize_label, 2907 .mpo_cred_init_label = mls_init_label, 2908 .mpo_cred_internalize_label = mls_internalize_label, 2909 .mpo_cred_relabel = mls_cred_relabel, 2910 2911 .mpo_devfs_create_device = mls_devfs_create_device, 2912 .mpo_devfs_create_directory = mls_devfs_create_directory, 2913 .mpo_devfs_create_symlink = mls_devfs_create_symlink, 2914 .mpo_devfs_destroy_label = mls_destroy_label, 2915 .mpo_devfs_init_label = mls_init_label, 2916 .mpo_devfs_update = mls_devfs_update, 2917 .mpo_devfs_vnode_associate = mls_devfs_vnode_associate, 2918 2919 .mpo_ifnet_check_relabel = mls_ifnet_check_relabel, 2920 .mpo_ifnet_check_transmit = mls_ifnet_check_transmit, 2921 .mpo_ifnet_copy_label = mls_copy_label, 2922 .mpo_ifnet_create = mls_ifnet_create, 2923 .mpo_ifnet_create_mbuf = mls_ifnet_create_mbuf, 2924 .mpo_ifnet_destroy_label = mls_destroy_label, 2925 .mpo_ifnet_externalize_label = mls_externalize_label, 2926 .mpo_ifnet_init_label = mls_init_label, 2927 .mpo_ifnet_internalize_label = mls_internalize_label, 2928 .mpo_ifnet_relabel = mls_ifnet_relabel, 2929 2930 .mpo_inpcb_check_deliver = mls_inpcb_check_deliver, 2931 .mpo_inpcb_create = mls_inpcb_create, 2932 .mpo_inpcb_create_mbuf = mls_inpcb_create_mbuf, 2933 .mpo_inpcb_destroy_label = mls_destroy_label, 2934 .mpo_inpcb_init_label = mls_init_label_waitcheck, 2935 .mpo_inpcb_sosetlabel = mls_inpcb_sosetlabel, 2936 2937 .mpo_ipq_create = mls_ipq_create, 2938 .mpo_ipq_destroy_label = mls_destroy_label, 2939 .mpo_ipq_init_label = mls_init_label_waitcheck, 2940 .mpo_ipq_match = mls_ipq_match, 2941 .mpo_ipq_reassemble = mls_ipq_reassemble, 2942 .mpo_ipq_update = mls_ipq_update, 2943 2944 .mpo_mbuf_copy_label = mls_copy_label, 2945 .mpo_mbuf_destroy_label = mls_destroy_label, 2946 .mpo_mbuf_init_label = mls_init_label_waitcheck, 2947 2948 .mpo_mount_check_stat = mls_mount_check_stat, 2949 .mpo_mount_create = mls_mount_create, 2950 .mpo_mount_destroy_label = mls_destroy_label, 2951 .mpo_mount_init_label = mls_init_label, 2952 2953 .mpo_netatalk_aarp_send = mls_netatalk_aarp_send, 2954 2955 .mpo_netinet_arp_send = mls_netinet_arp_send, 2956 .mpo_netinet_firewall_reply = mls_netinet_firewall_reply, 2957 .mpo_netinet_firewall_send = mls_netinet_firewall_send, 2958 .mpo_netinet_fragment = mls_netinet_fragment, 2959 .mpo_netinet_icmp_reply = mls_netinet_icmp_reply, 2960 .mpo_netinet_igmp_send = mls_netinet_igmp_send, 2961 2962 .mpo_netinet6_nd6_send = mls_netinet6_nd6_send, 2963 2964 .mpo_pipe_check_ioctl = mls_pipe_check_ioctl, 2965 .mpo_pipe_check_poll = mls_pipe_check_poll, 2966 .mpo_pipe_check_read = mls_pipe_check_read, 2967 .mpo_pipe_check_relabel = mls_pipe_check_relabel, 2968 .mpo_pipe_check_stat = mls_pipe_check_stat, 2969 .mpo_pipe_check_write = mls_pipe_check_write, 2970 .mpo_pipe_copy_label = mls_copy_label, 2971 .mpo_pipe_create = mls_pipe_create, 2972 .mpo_pipe_destroy_label = mls_destroy_label, 2973 .mpo_pipe_externalize_label = mls_externalize_label, 2974 .mpo_pipe_init_label = mls_init_label, 2975 .mpo_pipe_internalize_label = mls_internalize_label, 2976 .mpo_pipe_relabel = mls_pipe_relabel, 2977 2978 .mpo_posixsem_check_getvalue = mls_posixsem_check_rdonly, 2979 .mpo_posixsem_check_open = mls_posixsem_check_openunlink, 2980 .mpo_posixsem_check_post = mls_posixsem_check_write, 2981 .mpo_posixsem_check_stat = mls_posixsem_check_rdonly, 2982 .mpo_posixsem_check_unlink = mls_posixsem_check_openunlink, 2983 .mpo_posixsem_check_wait = mls_posixsem_check_write, 2984 .mpo_posixsem_create = mls_posixsem_create, 2985 .mpo_posixsem_destroy_label = mls_destroy_label, 2986 .mpo_posixsem_init_label = mls_init_label, 2987 2988 .mpo_proc_associate_nfsd = mls_proc_associate_nfsd, 2989 .mpo_proc_check_debug = mls_proc_check_debug, 2990 .mpo_proc_check_sched = mls_proc_check_sched, 2991 .mpo_proc_check_signal = mls_proc_check_signal, 2992 .mpo_proc_create_init = mls_proc_create_init, 2993 .mpo_proc_create_swapper = mls_proc_create_swapper, 2994 2995 .mpo_socket_check_deliver = mls_socket_check_deliver, 2996 .mpo_socket_check_relabel = mls_socket_check_relabel, 2997 .mpo_socket_check_visible = mls_socket_check_visible, 2998 .mpo_socket_copy_label = mls_copy_label, 2999 .mpo_socket_create = mls_socket_create, 3000 .mpo_socket_create_mbuf = mls_socket_create_mbuf, 3001 .mpo_socket_destroy_label = mls_destroy_label, 3002 .mpo_socket_externalize_label = mls_externalize_label, 3003 .mpo_socket_init_label = mls_init_label_waitcheck, 3004 .mpo_socket_internalize_label = mls_internalize_label, 3005 .mpo_socket_newconn = mls_socket_newconn, 3006 .mpo_socket_relabel = mls_socket_relabel, 3007 3008 .mpo_socketpeer_destroy_label = mls_destroy_label, 3009 .mpo_socketpeer_externalize_label = mls_externalize_label, 3010 .mpo_socketpeer_init_label = mls_init_label_waitcheck, 3011 .mpo_socketpeer_set_from_mbuf = mls_socketpeer_set_from_mbuf, 3012 .mpo_socketpeer_set_from_socket = mls_socketpeer_set_from_socket, 3013 3014 .mpo_syncache_create = mls_syncache_create, 3015 .mpo_syncache_create_mbuf = mls_syncache_create_mbuf, 3016 .mpo_syncache_destroy_label = mls_destroy_label, 3017 .mpo_syncache_init_label = mls_init_label_waitcheck, 3018 3019 .mpo_sysvmsg_cleanup = mls_sysvmsg_cleanup, 3020 .mpo_sysvmsg_create = mls_sysvmsg_create, 3021 .mpo_sysvmsg_destroy_label = mls_destroy_label, 3022 .mpo_sysvmsg_init_label = mls_init_label, 3023 3024 .mpo_sysvmsq_check_msgrcv = mls_sysvmsq_check_msgrcv, 3025 .mpo_sysvmsq_check_msgrmid = mls_sysvmsq_check_msgrmid, 3026 .mpo_sysvmsq_check_msqget = mls_sysvmsq_check_msqget, 3027 .mpo_sysvmsq_check_msqsnd = mls_sysvmsq_check_msqsnd, 3028 .mpo_sysvmsq_check_msqrcv = mls_sysvmsq_check_msqrcv, 3029 .mpo_sysvmsq_check_msqctl = mls_sysvmsq_check_msqctl, 3030 .mpo_sysvmsq_cleanup = mls_sysvmsq_cleanup, 3031 .mpo_sysvmsq_destroy_label = mls_destroy_label, 3032 .mpo_sysvmsq_init_label = mls_init_label, 3033 .mpo_sysvmsq_create = mls_sysvmsq_create, 3034 3035 .mpo_sysvsem_check_semctl = mls_sysvsem_check_semctl, 3036 .mpo_sysvsem_check_semget = mls_sysvsem_check_semget, 3037 .mpo_sysvsem_check_semop = mls_sysvsem_check_semop, 3038 .mpo_sysvsem_cleanup = mls_sysvsem_cleanup, 3039 .mpo_sysvsem_create = mls_sysvsem_create, 3040 .mpo_sysvsem_destroy_label = mls_destroy_label, 3041 .mpo_sysvsem_init_label = mls_init_label, 3042 3043 .mpo_sysvshm_check_shmat = mls_sysvshm_check_shmat, 3044 .mpo_sysvshm_check_shmctl = mls_sysvshm_check_shmctl, 3045 .mpo_sysvshm_check_shmget = mls_sysvshm_check_shmget, 3046 .mpo_sysvshm_cleanup = mls_sysvshm_cleanup, 3047 .mpo_sysvshm_create = mls_sysvshm_create, 3048 .mpo_sysvshm_destroy_label = mls_destroy_label, 3049 .mpo_sysvshm_init_label = mls_init_label, 3050 3051 3052 .mpo_system_check_acct = mls_system_check_acct, 3053 .mpo_system_check_auditctl = mls_system_check_auditctl, 3054 .mpo_system_check_swapon = mls_system_check_swapon, 3055 3056 .mpo_vnode_associate_extattr = mls_vnode_associate_extattr, 3057 .mpo_vnode_associate_singlelabel = mls_vnode_associate_singlelabel, 3058 .mpo_vnode_check_access = mls_vnode_check_open, 3059 .mpo_vnode_check_chdir = mls_vnode_check_chdir, 3060 .mpo_vnode_check_chroot = mls_vnode_check_chroot, 3061 .mpo_vnode_check_create = mls_vnode_check_create, 3062 .mpo_vnode_check_deleteacl = mls_vnode_check_deleteacl, 3063 .mpo_vnode_check_deleteextattr = mls_vnode_check_deleteextattr, 3064 .mpo_vnode_check_exec = mls_vnode_check_exec, 3065 .mpo_vnode_check_getacl = mls_vnode_check_getacl, 3066 .mpo_vnode_check_getextattr = mls_vnode_check_getextattr, 3067 .mpo_vnode_check_link = mls_vnode_check_link, 3068 .mpo_vnode_check_listextattr = mls_vnode_check_listextattr, 3069 .mpo_vnode_check_lookup = mls_vnode_check_lookup, 3070 .mpo_vnode_check_mmap = mls_vnode_check_mmap, 3071 .mpo_vnode_check_open = mls_vnode_check_open, 3072 .mpo_vnode_check_poll = mls_vnode_check_poll, 3073 .mpo_vnode_check_read = mls_vnode_check_read, 3074 .mpo_vnode_check_readdir = mls_vnode_check_readdir, 3075 .mpo_vnode_check_readlink = mls_vnode_check_readlink, 3076 .mpo_vnode_check_relabel = mls_vnode_check_relabel, 3077 .mpo_vnode_check_rename_from = mls_vnode_check_rename_from, 3078 .mpo_vnode_check_rename_to = mls_vnode_check_rename_to, 3079 .mpo_vnode_check_revoke = mls_vnode_check_revoke, 3080 .mpo_vnode_check_setacl = mls_vnode_check_setacl, 3081 .mpo_vnode_check_setextattr = mls_vnode_check_setextattr, 3082 .mpo_vnode_check_setflags = mls_vnode_check_setflags, 3083 .mpo_vnode_check_setmode = mls_vnode_check_setmode, 3084 .mpo_vnode_check_setowner = mls_vnode_check_setowner, 3085 .mpo_vnode_check_setutimes = mls_vnode_check_setutimes, 3086 .mpo_vnode_check_stat = mls_vnode_check_stat, 3087 .mpo_vnode_check_unlink = mls_vnode_check_unlink, 3088 .mpo_vnode_check_write = mls_vnode_check_write, 3089 .mpo_vnode_copy_label = mls_copy_label, 3090 .mpo_vnode_create_extattr = mls_vnode_create_extattr, 3091 .mpo_vnode_destroy_label = mls_destroy_label, 3092 .mpo_vnode_externalize_label = mls_externalize_label, 3093 .mpo_vnode_init_label = mls_init_label, 3094 .mpo_vnode_internalize_label = mls_internalize_label, 3095 .mpo_vnode_relabel = mls_vnode_relabel, 3096 .mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr, 3097 }; 3098 3099 MAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS", 3100 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mls_slot); 3101