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