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