1 /*- 2 * Copyright (c) 1999-2002 Robert N. M. Watson 3 * Copyright (c) 2001-2005 McAfee, Inc. 4 * All rights reserved. 5 * 6 * This software was developed by Robert Watson for the TrustedBSD Project. 7 * 8 * This software was developed for the FreeBSD Project in part by McAfee 9 * Research, the Security Research Division of McAfee, Inc. under 10 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 11 * CHATS research program. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $FreeBSD$ 35 */ 36 37 /* 38 * Developed by the TrustedBSD Project. 39 * MLS fixed label mandatory confidentiality policy. 40 */ 41 42 #include <sys/types.h> 43 #include <sys/param.h> 44 #include <sys/acl.h> 45 #include <sys/conf.h> 46 #include <sys/extattr.h> 47 #include <sys/kernel.h> 48 #include <sys/mac.h> 49 #include <sys/malloc.h> 50 #include <sys/mount.h> 51 #include <sys/proc.h> 52 #include <sys/sbuf.h> 53 #include <sys/systm.h> 54 #include <sys/sysproto.h> 55 #include <sys/sysent.h> 56 #include <sys/systm.h> 57 #include <sys/vnode.h> 58 #include <sys/file.h> 59 #include <sys/socket.h> 60 #include <sys/socketvar.h> 61 #include <sys/pipe.h> 62 #include <sys/sysctl.h> 63 #include <sys/msg.h> 64 #include <sys/sem.h> 65 #include <sys/shm.h> 66 67 #include <fs/devfs/devfs.h> 68 69 #include <net/bpfdesc.h> 70 #include <net/if.h> 71 #include <net/if_types.h> 72 #include <net/if_var.h> 73 74 #include <netinet/in.h> 75 #include <netinet/in_pcb.h> 76 #include <netinet/ip_var.h> 77 78 #include <vm/uma.h> 79 #include <vm/vm.h> 80 81 #include <sys/mac_policy.h> 82 83 #include <security/mac_mls/mac_mls.h> 84 85 SYSCTL_DECL(_security_mac); 86 87 SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0, 88 "TrustedBSD mac_mls policy controls"); 89 90 static int mac_mls_label_size = sizeof(struct mac_mls); 91 SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD, 92 &mac_mls_label_size, 0, "Size of struct mac_mls"); 93 94 static int mac_mls_enabled = 1; 95 SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW, 96 &mac_mls_enabled, 0, "Enforce MAC/MLS policy"); 97 TUNABLE_INT("security.mac.mls.enabled", &mac_mls_enabled); 98 99 static int destroyed_not_inited; 100 SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 101 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 102 103 static int ptys_equal = 0; 104 SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW, 105 &ptys_equal, 0, "Label pty devices as mls/equal on create"); 106 TUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal); 107 108 static int revocation_enabled = 0; 109 SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, 110 &revocation_enabled, 0, "Revoke access to objects on relabel"); 111 TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled); 112 113 static int max_compartments = MAC_MLS_MAX_COMPARTMENTS; 114 SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD, 115 &max_compartments, 0, "Maximum compartments the policy supports"); 116 117 static int mac_mls_slot; 118 #define SLOT(l) ((struct mac_mls *)LABEL_TO_SLOT((l), mac_mls_slot).l_ptr) 119 #define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_mls_slot).l_ptr = (val)) 120 121 static uma_zone_t zone_mls; 122 123 static __inline int 124 mls_bit_set_empty(u_char *set) { 125 int i; 126 127 for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++) 128 if (set[i] != 0) 129 return (0); 130 return (1); 131 } 132 133 static struct mac_mls * 134 mls_alloc(int flag) 135 { 136 137 return (uma_zalloc(zone_mls, flag | M_ZERO)); 138 } 139 140 static void 141 mls_free(struct mac_mls *mac_mls) 142 { 143 144 if (mac_mls != NULL) 145 uma_zfree(zone_mls, mac_mls); 146 else 147 atomic_add_int(&destroyed_not_inited, 1); 148 } 149 150 static int 151 mls_atmostflags(struct mac_mls *mac_mls, int flags) 152 { 153 154 if ((mac_mls->mm_flags & flags) != mac_mls->mm_flags) 155 return (EINVAL); 156 return (0); 157 } 158 159 static int 160 mac_mls_dominate_element(struct mac_mls_element *a, 161 struct mac_mls_element *b) 162 { 163 int bit; 164 165 switch (a->mme_type) { 166 case MAC_MLS_TYPE_EQUAL: 167 case MAC_MLS_TYPE_HIGH: 168 return (1); 169 170 case MAC_MLS_TYPE_LOW: 171 switch (b->mme_type) { 172 case MAC_MLS_TYPE_LEVEL: 173 case MAC_MLS_TYPE_HIGH: 174 return (0); 175 176 case MAC_MLS_TYPE_EQUAL: 177 case MAC_MLS_TYPE_LOW: 178 return (1); 179 180 default: 181 panic("mac_mls_dominate_element: b->mme_type invalid"); 182 } 183 184 case MAC_MLS_TYPE_LEVEL: 185 switch (b->mme_type) { 186 case MAC_MLS_TYPE_EQUAL: 187 case MAC_MLS_TYPE_LOW: 188 return (1); 189 190 case MAC_MLS_TYPE_HIGH: 191 return (0); 192 193 case MAC_MLS_TYPE_LEVEL: 194 for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) 195 if (!MAC_MLS_BIT_TEST(bit, 196 a->mme_compartments) && 197 MAC_MLS_BIT_TEST(bit, b->mme_compartments)) 198 return (0); 199 return (a->mme_level >= b->mme_level); 200 201 default: 202 panic("mac_mls_dominate_element: b->mme_type invalid"); 203 } 204 205 default: 206 panic("mac_mls_dominate_element: a->mme_type invalid"); 207 } 208 209 return (0); 210 } 211 212 static int 213 mac_mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) 214 { 215 216 return (mac_mls_dominate_element(&rangeb->mm_rangehigh, 217 &rangea->mm_rangehigh) && 218 mac_mls_dominate_element(&rangea->mm_rangelow, 219 &rangeb->mm_rangelow)); 220 } 221 222 static int 223 mac_mls_effective_in_range(struct mac_mls *effective, struct mac_mls *range) 224 { 225 226 KASSERT((effective->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 227 ("mac_mls_effective_in_range: a not effective")); 228 KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 229 ("mac_mls_effective_in_range: b not range")); 230 231 return (mac_mls_dominate_element(&range->mm_rangehigh, 232 &effective->mm_effective) && 233 mac_mls_dominate_element(&effective->mm_effective, 234 &range->mm_rangelow)); 235 236 return (1); 237 } 238 239 static int 240 mac_mls_dominate_effective(struct mac_mls *a, struct mac_mls *b) 241 { 242 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 243 ("mac_mls_dominate_effective: a not effective")); 244 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 245 ("mac_mls_dominate_effective: b not effective")); 246 247 return (mac_mls_dominate_element(&a->mm_effective, &b->mm_effective)); 248 } 249 250 static int 251 mac_mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) 252 { 253 254 if (a->mme_type == MAC_MLS_TYPE_EQUAL || 255 b->mme_type == MAC_MLS_TYPE_EQUAL) 256 return (1); 257 258 return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); 259 } 260 261 static int 262 mac_mls_equal_effective(struct mac_mls *a, struct mac_mls *b) 263 { 264 265 KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 266 ("mac_mls_equal_effective: a not effective")); 267 KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 268 ("mac_mls_equal_effective: b not effective")); 269 270 return (mac_mls_equal_element(&a->mm_effective, &b->mm_effective)); 271 } 272 273 static int 274 mac_mls_contains_equal(struct mac_mls *mac_mls) 275 { 276 277 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 278 if (mac_mls->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 279 return (1); 280 281 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 282 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL) 283 return (1); 284 if (mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 285 return (1); 286 } 287 288 return (0); 289 } 290 291 static int 292 mac_mls_subject_privileged(struct mac_mls *mac_mls) 293 { 294 295 KASSERT((mac_mls->mm_flags & MAC_MLS_FLAGS_BOTH) == 296 MAC_MLS_FLAGS_BOTH, 297 ("mac_mls_subject_privileged: subject doesn't have both labels")); 298 299 /* If the effective is EQUAL, it's ok. */ 300 if (mac_mls->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 301 return (0); 302 303 /* If either range endpoint is EQUAL, it's ok. */ 304 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL || 305 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 306 return (0); 307 308 /* If the range is low-high, it's ok. */ 309 if (mac_mls->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW && 310 mac_mls->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH) 311 return (0); 312 313 /* It's not ok. */ 314 return (EPERM); 315 } 316 317 static int 318 mac_mls_valid(struct mac_mls *mac_mls) 319 { 320 321 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 322 switch (mac_mls->mm_effective.mme_type) { 323 case MAC_MLS_TYPE_LEVEL: 324 break; 325 326 case MAC_MLS_TYPE_EQUAL: 327 case MAC_MLS_TYPE_HIGH: 328 case MAC_MLS_TYPE_LOW: 329 if (mac_mls->mm_effective.mme_level != 0 || 330 !MAC_MLS_BIT_SET_EMPTY( 331 mac_mls->mm_effective.mme_compartments)) 332 return (EINVAL); 333 break; 334 335 default: 336 return (EINVAL); 337 } 338 } else { 339 if (mac_mls->mm_effective.mme_type != MAC_MLS_TYPE_UNDEF) 340 return (EINVAL); 341 } 342 343 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 344 switch (mac_mls->mm_rangelow.mme_type) { 345 case MAC_MLS_TYPE_LEVEL: 346 break; 347 348 case MAC_MLS_TYPE_EQUAL: 349 case MAC_MLS_TYPE_HIGH: 350 case MAC_MLS_TYPE_LOW: 351 if (mac_mls->mm_rangelow.mme_level != 0 || 352 !MAC_MLS_BIT_SET_EMPTY( 353 mac_mls->mm_rangelow.mme_compartments)) 354 return (EINVAL); 355 break; 356 357 default: 358 return (EINVAL); 359 } 360 361 switch (mac_mls->mm_rangehigh.mme_type) { 362 case MAC_MLS_TYPE_LEVEL: 363 break; 364 365 case MAC_MLS_TYPE_EQUAL: 366 case MAC_MLS_TYPE_HIGH: 367 case MAC_MLS_TYPE_LOW: 368 if (mac_mls->mm_rangehigh.mme_level != 0 || 369 !MAC_MLS_BIT_SET_EMPTY( 370 mac_mls->mm_rangehigh.mme_compartments)) 371 return (EINVAL); 372 break; 373 374 default: 375 return (EINVAL); 376 } 377 if (!mac_mls_dominate_element(&mac_mls->mm_rangehigh, 378 &mac_mls->mm_rangelow)) 379 return (EINVAL); 380 } else { 381 if (mac_mls->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || 382 mac_mls->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) 383 return (EINVAL); 384 } 385 386 return (0); 387 } 388 389 static void 390 mac_mls_set_range(struct mac_mls *mac_mls, u_short typelow, 391 u_short levellow, u_char *compartmentslow, u_short typehigh, 392 u_short levelhigh, u_char *compartmentshigh) 393 { 394 395 mac_mls->mm_rangelow.mme_type = typelow; 396 mac_mls->mm_rangelow.mme_level = levellow; 397 if (compartmentslow != NULL) 398 memcpy(mac_mls->mm_rangelow.mme_compartments, 399 compartmentslow, 400 sizeof(mac_mls->mm_rangelow.mme_compartments)); 401 mac_mls->mm_rangehigh.mme_type = typehigh; 402 mac_mls->mm_rangehigh.mme_level = levelhigh; 403 if (compartmentshigh != NULL) 404 memcpy(mac_mls->mm_rangehigh.mme_compartments, 405 compartmentshigh, 406 sizeof(mac_mls->mm_rangehigh.mme_compartments)); 407 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 408 } 409 410 static void 411 mac_mls_set_effective(struct mac_mls *mac_mls, u_short type, u_short level, 412 u_char *compartments) 413 { 414 415 mac_mls->mm_effective.mme_type = type; 416 mac_mls->mm_effective.mme_level = level; 417 if (compartments != NULL) 418 memcpy(mac_mls->mm_effective.mme_compartments, compartments, 419 sizeof(mac_mls->mm_effective.mme_compartments)); 420 mac_mls->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 421 } 422 423 static void 424 mac_mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 425 { 426 427 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 428 ("mac_mls_copy_range: labelfrom not range")); 429 430 labelto->mm_rangelow = labelfrom->mm_rangelow; 431 labelto->mm_rangehigh = labelfrom->mm_rangehigh; 432 labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 433 } 434 435 static void 436 mac_mls_copy_effective(struct mac_mls *labelfrom, struct mac_mls *labelto) 437 { 438 439 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 440 ("mac_mls_copy_effective: labelfrom not effective")); 441 442 labelto->mm_effective = labelfrom->mm_effective; 443 labelto->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 444 } 445 446 static void 447 mac_mls_copy(struct mac_mls *source, struct mac_mls *dest) 448 { 449 450 if (source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 451 mac_mls_copy_effective(source, dest); 452 if (source->mm_flags & MAC_MLS_FLAG_RANGE) 453 mac_mls_copy_range(source, dest); 454 } 455 456 /* 457 * Policy module operations. 458 */ 459 static void 460 mac_mls_init(struct mac_policy_conf *conf) 461 { 462 463 zone_mls = uma_zcreate("mac_mls", sizeof(struct mac_mls), NULL, 464 NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 465 } 466 467 /* 468 * Label operations. 469 */ 470 static void 471 mac_mls_init_label(struct label *label) 472 { 473 474 SLOT_SET(label, mls_alloc(M_WAITOK)); 475 } 476 477 static int 478 mac_mls_init_label_waitcheck(struct label *label, int flag) 479 { 480 481 SLOT_SET(label, mls_alloc(flag)); 482 if (SLOT(label) == NULL) 483 return (ENOMEM); 484 485 return (0); 486 } 487 488 static void 489 mac_mls_destroy_label(struct label *label) 490 { 491 492 mls_free(SLOT(label)); 493 SLOT_SET(label, NULL); 494 } 495 496 /* 497 * mac_mls_element_to_string() accepts an sbuf and MLS element. It 498 * converts the MLS element to a string and stores the result in the 499 * sbuf; if there isn't space in the sbuf, -1 is returned. 500 */ 501 static int 502 mac_mls_element_to_string(struct sbuf *sb, struct mac_mls_element *element) 503 { 504 int i, first; 505 506 switch (element->mme_type) { 507 case MAC_MLS_TYPE_HIGH: 508 return (sbuf_printf(sb, "high")); 509 510 case MAC_MLS_TYPE_LOW: 511 return (sbuf_printf(sb, "low")); 512 513 case MAC_MLS_TYPE_EQUAL: 514 return (sbuf_printf(sb, "equal")); 515 516 case MAC_MLS_TYPE_LEVEL: 517 if (sbuf_printf(sb, "%d", element->mme_level) == -1) 518 return (-1); 519 520 first = 1; 521 for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) { 522 if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) { 523 if (first) { 524 if (sbuf_putc(sb, ':') == -1) 525 return (-1); 526 if (sbuf_printf(sb, "%d", i) == -1) 527 return (-1); 528 first = 0; 529 } else { 530 if (sbuf_printf(sb, "+%d", i) == -1) 531 return (-1); 532 } 533 } 534 } 535 return (0); 536 537 default: 538 panic("mac_mls_element_to_string: invalid type (%d)", 539 element->mme_type); 540 } 541 } 542 543 /* 544 * mac_mls_to_string() converts an MLS label to a string, and places 545 * the results in the passed sbuf. It returns 0 on success, or EINVAL 546 * if there isn't room in the sbuf. Note: the sbuf will be modified 547 * even in a failure case, so the caller may need to revert the sbuf 548 * by restoring the offset if that's undesired. 549 */ 550 static int 551 mac_mls_to_string(struct sbuf *sb, struct mac_mls *mac_mls) 552 { 553 554 if (mac_mls->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 555 if (mac_mls_element_to_string(sb, &mac_mls->mm_effective) 556 == -1) 557 return (EINVAL); 558 } 559 560 if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) { 561 if (sbuf_putc(sb, '(') == -1) 562 return (EINVAL); 563 564 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangelow) 565 == -1) 566 return (EINVAL); 567 568 if (sbuf_putc(sb, '-') == -1) 569 return (EINVAL); 570 571 if (mac_mls_element_to_string(sb, &mac_mls->mm_rangehigh) 572 == -1) 573 return (EINVAL); 574 575 if (sbuf_putc(sb, ')') == -1) 576 return (EINVAL); 577 } 578 579 return (0); 580 } 581 582 static int 583 mac_mls_externalize_label(struct label *label, char *element_name, 584 struct sbuf *sb, int *claimed) 585 { 586 struct mac_mls *mac_mls; 587 588 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 589 return (0); 590 591 (*claimed)++; 592 593 mac_mls = SLOT(label); 594 595 return (mac_mls_to_string(sb, mac_mls)); 596 } 597 598 static int 599 mac_mls_parse_element(struct mac_mls_element *element, char *string) 600 { 601 char *compartment, *end, *level; 602 int value; 603 604 if (strcmp(string, "high") == 0 || 605 strcmp(string, "hi") == 0) { 606 element->mme_type = MAC_MLS_TYPE_HIGH; 607 element->mme_level = MAC_MLS_TYPE_UNDEF; 608 } else if (strcmp(string, "low") == 0 || 609 strcmp(string, "lo") == 0) { 610 element->mme_type = MAC_MLS_TYPE_LOW; 611 element->mme_level = MAC_MLS_TYPE_UNDEF; 612 } else if (strcmp(string, "equal") == 0 || 613 strcmp(string, "eq") == 0) { 614 element->mme_type = MAC_MLS_TYPE_EQUAL; 615 element->mme_level = MAC_MLS_TYPE_UNDEF; 616 } else { 617 element->mme_type = MAC_MLS_TYPE_LEVEL; 618 619 /* 620 * Numeric level piece of the element. 621 */ 622 level = strsep(&string, ":"); 623 value = strtol(level, &end, 10); 624 if (end == level || *end != '\0') 625 return (EINVAL); 626 if (value < 0 || value > 65535) 627 return (EINVAL); 628 element->mme_level = value; 629 630 /* 631 * Optional compartment piece of the element. If none 632 * are included, we assume that the label has no 633 * compartments. 634 */ 635 if (string == NULL) 636 return (0); 637 if (*string == '\0') 638 return (0); 639 640 while ((compartment = strsep(&string, "+")) != NULL) { 641 value = strtol(compartment, &end, 10); 642 if (compartment == end || *end != '\0') 643 return (EINVAL); 644 if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS) 645 return (EINVAL); 646 MAC_MLS_BIT_SET(value, element->mme_compartments); 647 } 648 } 649 650 return (0); 651 } 652 653 /* 654 * Note: destructively consumes the string, make a local copy before 655 * calling if that's a problem. 656 */ 657 static int 658 mac_mls_parse(struct mac_mls *mac_mls, char *string) 659 { 660 char *rangehigh, *rangelow, *effective; 661 int error; 662 663 effective = strsep(&string, "("); 664 if (*effective == '\0') 665 effective = NULL; 666 667 if (string != NULL) { 668 rangelow = strsep(&string, "-"); 669 if (string == NULL) 670 return (EINVAL); 671 rangehigh = strsep(&string, ")"); 672 if (string == NULL) 673 return (EINVAL); 674 if (*string != '\0') 675 return (EINVAL); 676 } else { 677 rangelow = NULL; 678 rangehigh = NULL; 679 } 680 681 KASSERT((rangelow != NULL && rangehigh != NULL) || 682 (rangelow == NULL && rangehigh == NULL), 683 ("mac_mls_parse: range mismatch")); 684 685 bzero(mac_mls, sizeof(*mac_mls)); 686 if (effective != NULL) { 687 error = mac_mls_parse_element(&mac_mls->mm_effective, effective); 688 if (error) 689 return (error); 690 mac_mls->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 691 } 692 693 if (rangelow != NULL) { 694 error = mac_mls_parse_element(&mac_mls->mm_rangelow, 695 rangelow); 696 if (error) 697 return (error); 698 error = mac_mls_parse_element(&mac_mls->mm_rangehigh, 699 rangehigh); 700 if (error) 701 return (error); 702 mac_mls->mm_flags |= MAC_MLS_FLAG_RANGE; 703 } 704 705 error = mac_mls_valid(mac_mls); 706 if (error) 707 return (error); 708 709 return (0); 710 } 711 712 static int 713 mac_mls_internalize_label(struct label *label, char *element_name, 714 char *element_data, int *claimed) 715 { 716 struct mac_mls *mac_mls, mac_mls_temp; 717 int error; 718 719 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 720 return (0); 721 722 (*claimed)++; 723 724 error = mac_mls_parse(&mac_mls_temp, element_data); 725 if (error) 726 return (error); 727 728 mac_mls = SLOT(label); 729 *mac_mls = mac_mls_temp; 730 731 return (0); 732 } 733 734 static void 735 mac_mls_copy_label(struct label *src, struct label *dest) 736 { 737 738 *SLOT(dest) = *SLOT(src); 739 } 740 741 /* 742 * Labeling event operations: file system objects, and things that look 743 * a lot like file system objects. 744 */ 745 static void 746 mac_mls_create_devfs_device(struct mount *mp, struct cdev *dev, 747 struct devfs_dirent *devfs_dirent, struct label *label) 748 { 749 struct mac_mls *mac_mls; 750 int mls_type; 751 752 mac_mls = SLOT(label); 753 if (strcmp(dev->si_name, "null") == 0 || 754 strcmp(dev->si_name, "zero") == 0 || 755 strcmp(dev->si_name, "random") == 0 || 756 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 757 mls_type = MAC_MLS_TYPE_EQUAL; 758 else if (strcmp(dev->si_name, "kmem") == 0 || 759 strcmp(dev->si_name, "mem") == 0) 760 mls_type = MAC_MLS_TYPE_HIGH; 761 else if (ptys_equal && 762 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 763 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 764 mls_type = MAC_MLS_TYPE_EQUAL; 765 else 766 mls_type = MAC_MLS_TYPE_LOW; 767 mac_mls_set_effective(mac_mls, mls_type, 0, NULL); 768 } 769 770 static void 771 mac_mls_create_devfs_directory(struct mount *mp, char *dirname, 772 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 773 { 774 struct mac_mls *mac_mls; 775 776 mac_mls = SLOT(label); 777 mac_mls_set_effective(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL); 778 } 779 780 static void 781 mac_mls_create_devfs_symlink(struct ucred *cred, struct mount *mp, 782 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 783 struct label *delabel) 784 { 785 struct mac_mls *source, *dest; 786 787 source = SLOT(cred->cr_label); 788 dest = SLOT(delabel); 789 790 mac_mls_copy_effective(source, dest); 791 } 792 793 static void 794 mac_mls_create_mount(struct ucred *cred, struct mount *mp, 795 struct label *mntlabel, struct label *fslabel) 796 { 797 struct mac_mls *source, *dest; 798 799 source = SLOT(cred->cr_label); 800 dest = SLOT(mntlabel); 801 mac_mls_copy_effective(source, dest); 802 dest = SLOT(fslabel); 803 mac_mls_copy_effective(source, dest); 804 } 805 806 static void 807 mac_mls_create_root_mount(struct ucred *cred, struct mount *mp, 808 struct label *mntlabel, struct label *fslabel) 809 { 810 struct mac_mls *mac_mls; 811 812 /* Always mount root as high integrity. */ 813 mac_mls = SLOT(fslabel); 814 mac_mls_set_effective(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL); 815 mac_mls = SLOT(mntlabel); 816 mac_mls_set_effective(mac_mls, MAC_MLS_TYPE_LOW, 0, NULL); 817 } 818 819 static void 820 mac_mls_relabel_vnode(struct ucred *cred, struct vnode *vp, 821 struct label *vnodelabel, struct label *label) 822 { 823 struct mac_mls *source, *dest; 824 825 source = SLOT(label); 826 dest = SLOT(vnodelabel); 827 828 mac_mls_copy(source, dest); 829 } 830 831 static void 832 mac_mls_update_devfsdirent(struct mount *mp, 833 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 834 struct vnode *vp, struct label *vnodelabel) 835 { 836 struct mac_mls *source, *dest; 837 838 source = SLOT(vnodelabel); 839 dest = SLOT(direntlabel); 840 841 mac_mls_copy_effective(source, dest); 842 } 843 844 static void 845 mac_mls_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 846 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 847 struct label *vlabel) 848 { 849 struct mac_mls *source, *dest; 850 851 source = SLOT(delabel); 852 dest = SLOT(vlabel); 853 854 mac_mls_copy_effective(source, dest); 855 } 856 857 static int 858 mac_mls_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 859 struct vnode *vp, struct label *vlabel) 860 { 861 struct mac_mls temp, *source, *dest; 862 int buflen, error; 863 864 source = SLOT(fslabel); 865 dest = SLOT(vlabel); 866 867 buflen = sizeof(temp); 868 bzero(&temp, buflen); 869 870 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 871 MAC_MLS_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 872 if (error == ENOATTR || error == EOPNOTSUPP) { 873 /* Fall back to the fslabel. */ 874 mac_mls_copy_effective(source, dest); 875 return (0); 876 } else if (error) 877 return (error); 878 879 if (buflen != sizeof(temp)) { 880 printf("mac_mls_associate_vnode_extattr: bad size %d\n", 881 buflen); 882 return (EPERM); 883 } 884 if (mac_mls_valid(&temp) != 0) { 885 printf("mac_mls_associate_vnode_extattr: invalid\n"); 886 return (EPERM); 887 } 888 if ((temp.mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_EFFECTIVE) { 889 printf("mac_mls_associated_vnode_extattr: not effective\n"); 890 return (EPERM); 891 } 892 893 mac_mls_copy_effective(&temp, dest); 894 return (0); 895 } 896 897 static void 898 mac_mls_associate_vnode_singlelabel(struct mount *mp, 899 struct label *fslabel, struct vnode *vp, struct label *vlabel) 900 { 901 struct mac_mls *source, *dest; 902 903 source = SLOT(fslabel); 904 dest = SLOT(vlabel); 905 906 mac_mls_copy_effective(source, dest); 907 } 908 909 static int 910 mac_mls_create_vnode_extattr(struct ucred *cred, struct mount *mp, 911 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 912 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 913 { 914 struct mac_mls *source, *dest, temp; 915 size_t buflen; 916 int error; 917 918 buflen = sizeof(temp); 919 bzero(&temp, buflen); 920 921 source = SLOT(cred->cr_label); 922 dest = SLOT(vlabel); 923 mac_mls_copy_effective(source, &temp); 924 925 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 926 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread); 927 if (error == 0) 928 mac_mls_copy_effective(source, dest); 929 return (error); 930 } 931 932 static int 933 mac_mls_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 934 struct label *vlabel, struct label *intlabel) 935 { 936 struct mac_mls *source, temp; 937 size_t buflen; 938 int error; 939 940 buflen = sizeof(temp); 941 bzero(&temp, buflen); 942 943 source = SLOT(intlabel); 944 if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 945 return (0); 946 947 mac_mls_copy_effective(source, &temp); 948 949 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 950 MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread); 951 return (error); 952 } 953 954 /* 955 * Labeling event operations: IPC object. 956 */ 957 static void 958 mac_mls_create_inpcb_from_socket(struct socket *so, struct label *solabel, 959 struct inpcb *inp, struct label *inplabel) 960 { 961 struct mac_mls *source, *dest; 962 963 source = SLOT(solabel); 964 dest = SLOT(inplabel); 965 966 mac_mls_copy_effective(source, dest); 967 } 968 969 static void 970 mac_mls_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 971 struct mbuf *m, struct label *mbuflabel) 972 { 973 struct mac_mls *source, *dest; 974 975 source = SLOT(socketlabel); 976 dest = SLOT(mbuflabel); 977 978 mac_mls_copy_effective(source, dest); 979 } 980 981 static void 982 mac_mls_create_socket(struct ucred *cred, struct socket *socket, 983 struct label *socketlabel) 984 { 985 struct mac_mls *source, *dest; 986 987 source = SLOT(cred->cr_label); 988 dest = SLOT(socketlabel); 989 990 mac_mls_copy_effective(source, dest); 991 } 992 993 static void 994 mac_mls_create_pipe(struct ucred *cred, struct pipepair *pp, 995 struct label *pipelabel) 996 { 997 struct mac_mls *source, *dest; 998 999 source = SLOT(cred->cr_label); 1000 dest = SLOT(pipelabel); 1001 1002 mac_mls_copy_effective(source, dest); 1003 } 1004 1005 static void 1006 mac_mls_create_socket_from_socket(struct socket *oldsocket, 1007 struct label *oldsocketlabel, struct socket *newsocket, 1008 struct label *newsocketlabel) 1009 { 1010 struct mac_mls *source, *dest; 1011 1012 source = SLOT(oldsocketlabel); 1013 dest = SLOT(newsocketlabel); 1014 1015 mac_mls_copy_effective(source, dest); 1016 } 1017 1018 static void 1019 mac_mls_relabel_socket(struct ucred *cred, struct socket *socket, 1020 struct label *socketlabel, struct label *newlabel) 1021 { 1022 struct mac_mls *source, *dest; 1023 1024 source = SLOT(newlabel); 1025 dest = SLOT(socketlabel); 1026 1027 mac_mls_copy(source, dest); 1028 } 1029 1030 static void 1031 mac_mls_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1032 struct label *pipelabel, struct label *newlabel) 1033 { 1034 struct mac_mls *source, *dest; 1035 1036 source = SLOT(newlabel); 1037 dest = SLOT(pipelabel); 1038 1039 mac_mls_copy(source, dest); 1040 } 1041 1042 static void 1043 mac_mls_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1044 struct socket *socket, struct label *socketpeerlabel) 1045 { 1046 struct mac_mls *source, *dest; 1047 1048 source = SLOT(mbuflabel); 1049 dest = SLOT(socketpeerlabel); 1050 1051 mac_mls_copy_effective(source, dest); 1052 } 1053 1054 /* 1055 * Labeling event operations: System V IPC objects. 1056 */ 1057 1058 static void 1059 mac_mls_create_sysv_msgmsg(struct ucred *cred, struct msqid_kernel *msqkptr, 1060 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1061 { 1062 struct mac_mls *source, *dest; 1063 1064 /* Ignore the msgq label */ 1065 source = SLOT(cred->cr_label); 1066 dest = SLOT(msglabel); 1067 1068 mac_mls_copy_effective(source, dest); 1069 } 1070 1071 static void 1072 mac_mls_create_sysv_msgqueue(struct ucred *cred, struct msqid_kernel *msqkptr, 1073 struct label *msqlabel) 1074 { 1075 struct mac_mls *source, *dest; 1076 1077 source = SLOT(cred->cr_label); 1078 dest = SLOT(msqlabel); 1079 1080 mac_mls_copy_effective(source, dest); 1081 } 1082 1083 static void 1084 mac_mls_create_sysv_sema(struct ucred *cred, struct semid_kernel *semakptr, 1085 struct label *semalabel) 1086 { 1087 struct mac_mls *source, *dest; 1088 1089 source = SLOT(cred->cr_label); 1090 dest = SLOT(semalabel); 1091 1092 mac_mls_copy_effective(source, dest); 1093 } 1094 1095 static void 1096 mac_mls_create_sysv_shm(struct ucred *cred, struct shmid_kernel *shmsegptr, 1097 struct label *shmlabel) 1098 { 1099 struct mac_mls *source, *dest; 1100 1101 source = SLOT(cred->cr_label); 1102 dest = SLOT(shmlabel); 1103 1104 mac_mls_copy_effective(source, dest); 1105 } 1106 1107 /* 1108 * Labeling event operations: network objects. 1109 */ 1110 static void 1111 mac_mls_set_socket_peer_from_socket(struct socket *oldsocket, 1112 struct label *oldsocketlabel, struct socket *newsocket, 1113 struct label *newsocketpeerlabel) 1114 { 1115 struct mac_mls *source, *dest; 1116 1117 source = SLOT(oldsocketlabel); 1118 dest = SLOT(newsocketpeerlabel); 1119 1120 mac_mls_copy_effective(source, dest); 1121 } 1122 1123 static void 1124 mac_mls_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1125 struct label *bpflabel) 1126 { 1127 struct mac_mls *source, *dest; 1128 1129 source = SLOT(cred->cr_label); 1130 dest = SLOT(bpflabel); 1131 1132 mac_mls_copy_effective(source, dest); 1133 } 1134 1135 static void 1136 mac_mls_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1137 { 1138 struct mac_mls *dest; 1139 int type; 1140 1141 dest = SLOT(ifnetlabel); 1142 1143 if (ifnet->if_type == IFT_LOOP) 1144 type = MAC_MLS_TYPE_EQUAL; 1145 else 1146 type = MAC_MLS_TYPE_LOW; 1147 1148 mac_mls_set_effective(dest, type, 0, NULL); 1149 mac_mls_set_range(dest, type, 0, NULL, type, 0, NULL); 1150 } 1151 1152 static void 1153 mac_mls_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1154 struct ipq *ipq, struct label *ipqlabel) 1155 { 1156 struct mac_mls *source, *dest; 1157 1158 source = SLOT(fragmentlabel); 1159 dest = SLOT(ipqlabel); 1160 1161 mac_mls_copy_effective(source, dest); 1162 } 1163 1164 static void 1165 mac_mls_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1166 struct mbuf *datagram, struct label *datagramlabel) 1167 { 1168 struct mac_mls *source, *dest; 1169 1170 source = SLOT(ipqlabel); 1171 dest = SLOT(datagramlabel); 1172 1173 /* Just use the head, since we require them all to match. */ 1174 mac_mls_copy_effective(source, dest); 1175 } 1176 1177 static void 1178 mac_mls_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1179 struct mbuf *fragment, struct label *fragmentlabel) 1180 { 1181 struct mac_mls *source, *dest; 1182 1183 source = SLOT(datagramlabel); 1184 dest = SLOT(fragmentlabel); 1185 1186 mac_mls_copy_effective(source, dest); 1187 } 1188 1189 static void 1190 mac_mls_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1191 struct mbuf *m, struct label *mlabel) 1192 { 1193 struct mac_mls *source, *dest; 1194 1195 source = SLOT(inplabel); 1196 dest = SLOT(mlabel); 1197 1198 mac_mls_copy_effective(source, dest); 1199 } 1200 1201 static void 1202 mac_mls_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1203 struct label *oldmbuflabel, struct mbuf *newmbuf, 1204 struct label *newmbuflabel) 1205 { 1206 struct mac_mls *source, *dest; 1207 1208 source = SLOT(oldmbuflabel); 1209 dest = SLOT(newmbuflabel); 1210 1211 /* 1212 * Because the source mbuf may not yet have been "created", 1213 * just initialized, we do a conditional copy. Since we don't 1214 * allow mbufs to have ranges, do a KASSERT to make sure that 1215 * doesn't happen. 1216 */ 1217 KASSERT((source->mm_flags & MAC_MLS_FLAG_RANGE) == 0, 1218 ("mac_mls_create_mbuf_from_mbuf: source mbuf has range")); 1219 mac_mls_copy(source, dest); 1220 } 1221 1222 static void 1223 mac_mls_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1224 struct mbuf *mbuf, struct label *mbuflabel) 1225 { 1226 struct mac_mls *dest; 1227 1228 dest = SLOT(mbuflabel); 1229 1230 mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1231 } 1232 1233 static void 1234 mac_mls_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1235 struct mbuf *mbuf, struct label *mbuflabel) 1236 { 1237 struct mac_mls *source, *dest; 1238 1239 source = SLOT(bpflabel); 1240 dest = SLOT(mbuflabel); 1241 1242 mac_mls_copy_effective(source, dest); 1243 } 1244 1245 static void 1246 mac_mls_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1247 struct mbuf *m, struct label *mbuflabel) 1248 { 1249 struct mac_mls *source, *dest; 1250 1251 source = SLOT(ifnetlabel); 1252 dest = SLOT(mbuflabel); 1253 1254 mac_mls_copy_effective(source, dest); 1255 } 1256 1257 static void 1258 mac_mls_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1259 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1260 struct mbuf *newmbuf, struct label *newmbuflabel) 1261 { 1262 struct mac_mls *source, *dest; 1263 1264 source = SLOT(oldmbuflabel); 1265 dest = SLOT(newmbuflabel); 1266 1267 mac_mls_copy_effective(source, dest); 1268 } 1269 1270 static void 1271 mac_mls_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1272 struct mbuf *newmbuf, struct label *newmbuflabel) 1273 { 1274 struct mac_mls *source, *dest; 1275 1276 source = SLOT(oldmbuflabel); 1277 dest = SLOT(newmbuflabel); 1278 1279 mac_mls_copy_effective(source, dest); 1280 } 1281 1282 static int 1283 mac_mls_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1284 struct ipq *ipq, struct label *ipqlabel) 1285 { 1286 struct mac_mls *a, *b; 1287 1288 a = SLOT(ipqlabel); 1289 b = SLOT(fragmentlabel); 1290 1291 return (mac_mls_equal_effective(a, b)); 1292 } 1293 1294 static void 1295 mac_mls_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1296 struct label *ifnetlabel, struct label *newlabel) 1297 { 1298 struct mac_mls *source, *dest; 1299 1300 source = SLOT(newlabel); 1301 dest = SLOT(ifnetlabel); 1302 1303 mac_mls_copy(source, dest); 1304 } 1305 1306 static void 1307 mac_mls_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1308 struct ipq *ipq, struct label *ipqlabel) 1309 { 1310 1311 /* NOOP: we only accept matching labels, so no need to update */ 1312 } 1313 1314 static void 1315 mac_mls_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1316 struct inpcb *inp, struct label *inplabel) 1317 { 1318 struct mac_mls *source, *dest; 1319 1320 source = SLOT(solabel); 1321 dest = SLOT(inplabel); 1322 1323 mac_mls_copy(source, dest); 1324 } 1325 1326 /* 1327 * Labeling event operations: processes. 1328 */ 1329 static void 1330 mac_mls_create_proc0(struct ucred *cred) 1331 { 1332 struct mac_mls *dest; 1333 1334 dest = SLOT(cred->cr_label); 1335 1336 mac_mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1337 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 1338 0, NULL); 1339 } 1340 1341 static void 1342 mac_mls_create_proc1(struct ucred *cred) 1343 { 1344 struct mac_mls *dest; 1345 1346 dest = SLOT(cred->cr_label); 1347 1348 mac_mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL); 1349 mac_mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 1350 0, NULL); 1351 } 1352 1353 static void 1354 mac_mls_relabel_cred(struct ucred *cred, struct label *newlabel) 1355 { 1356 struct mac_mls *source, *dest; 1357 1358 source = SLOT(newlabel); 1359 dest = SLOT(cred->cr_label); 1360 1361 mac_mls_copy(source, dest); 1362 } 1363 1364 /* 1365 * Label cleanup/flush operations. 1366 */ 1367 static void 1368 mac_mls_cleanup_sysv_msgmsg(struct label *msglabel) 1369 { 1370 1371 bzero(SLOT(msglabel), sizeof(struct mac_mls)); 1372 } 1373 1374 static void 1375 mac_mls_cleanup_sysv_msgqueue(struct label *msqlabel) 1376 { 1377 1378 bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 1379 } 1380 1381 static void 1382 mac_mls_cleanup_sysv_sema(struct label *semalabel) 1383 { 1384 1385 bzero(SLOT(semalabel), sizeof(struct mac_mls)); 1386 } 1387 1388 static void 1389 mac_mls_cleanup_sysv_shm(struct label *shmlabel) 1390 { 1391 1392 bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 1393 } 1394 1395 /* 1396 * Access control checks. 1397 */ 1398 static int 1399 mac_mls_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1400 struct ifnet *ifnet, struct label *ifnetlabel) 1401 { 1402 struct mac_mls *a, *b; 1403 1404 if (!mac_mls_enabled) 1405 return (0); 1406 1407 a = SLOT(bpflabel); 1408 b = SLOT(ifnetlabel); 1409 1410 if (mac_mls_equal_effective(a, b)) 1411 return (0); 1412 return (EACCES); 1413 } 1414 1415 static int 1416 mac_mls_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1417 { 1418 struct mac_mls *subj, *new; 1419 int error; 1420 1421 subj = SLOT(cred->cr_label); 1422 new = SLOT(newlabel); 1423 1424 /* 1425 * If there is an MLS label update for the credential, it may be 1426 * an update of effective, range, or both. 1427 */ 1428 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 1429 if (error) 1430 return (error); 1431 1432 /* 1433 * If the MLS label is to be changed, authorize as appropriate. 1434 */ 1435 if (new->mm_flags & MAC_MLS_FLAGS_BOTH) { 1436 /* 1437 * If the change request modifies both the MLS label effective 1438 * and range, check that the new effective will be in the 1439 * new range. 1440 */ 1441 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) == 1442 MAC_MLS_FLAGS_BOTH && 1443 !mac_mls_effective_in_range(new, new)) 1444 return (EINVAL); 1445 1446 /* 1447 * To change the MLS effective label on a credential, the 1448 * new effective label must be in the current range. 1449 */ 1450 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE && 1451 !mac_mls_effective_in_range(new, subj)) 1452 return (EPERM); 1453 1454 /* 1455 * To change the MLS range label on a credential, the 1456 * new range must be in the current range. 1457 */ 1458 if (new->mm_flags & MAC_MLS_FLAG_RANGE && 1459 !mac_mls_range_in_range(new, subj)) 1460 return (EPERM); 1461 1462 /* 1463 * To have EQUAL in any component of the new credential 1464 * MLS label, the subject must already have EQUAL in 1465 * their label. 1466 */ 1467 if (mac_mls_contains_equal(new)) { 1468 error = mac_mls_subject_privileged(subj); 1469 if (error) 1470 return (error); 1471 } 1472 } 1473 1474 return (0); 1475 } 1476 1477 static int 1478 mac_mls_check_cred_visible(struct ucred *u1, struct ucred *u2) 1479 { 1480 struct mac_mls *subj, *obj; 1481 1482 if (!mac_mls_enabled) 1483 return (0); 1484 1485 subj = SLOT(u1->cr_label); 1486 obj = SLOT(u2->cr_label); 1487 1488 /* XXX: range */ 1489 if (!mac_mls_dominate_effective(subj, obj)) 1490 return (ESRCH); 1491 1492 return (0); 1493 } 1494 1495 static int 1496 mac_mls_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1497 struct label *ifnetlabel, struct label *newlabel) 1498 { 1499 struct mac_mls *subj, *new; 1500 int error; 1501 1502 subj = SLOT(cred->cr_label); 1503 new = SLOT(newlabel); 1504 1505 /* 1506 * If there is an MLS label update for the interface, it may 1507 * be an update of effective, range, or both. 1508 */ 1509 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 1510 if (error) 1511 return (error); 1512 1513 /* 1514 * Relabeling network interfaces requires MLS privilege. 1515 */ 1516 error = mac_mls_subject_privileged(subj); 1517 1518 return (0); 1519 } 1520 1521 static int 1522 mac_mls_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1523 struct mbuf *m, struct label *mbuflabel) 1524 { 1525 struct mac_mls *p, *i; 1526 1527 if (!mac_mls_enabled) 1528 return (0); 1529 1530 p = SLOT(mbuflabel); 1531 i = SLOT(ifnetlabel); 1532 1533 return (mac_mls_effective_in_range(p, i) ? 0 : EACCES); 1534 } 1535 1536 static int 1537 mac_mls_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1538 struct mbuf *m, struct label *mlabel) 1539 { 1540 struct mac_mls *p, *i; 1541 1542 if (!mac_mls_enabled) 1543 return (0); 1544 1545 p = SLOT(mlabel); 1546 i = SLOT(inplabel); 1547 1548 return (mac_mls_equal_effective(p, i) ? 0 : EACCES); 1549 } 1550 1551 static int 1552 mac_mls_check_sysv_msgrcv(struct ucred *cred, struct msg *msgptr, 1553 struct label *msglabel) 1554 { 1555 struct mac_mls *subj, *obj; 1556 1557 if (!mac_mls_enabled) 1558 return (0); 1559 1560 subj = SLOT(cred->cr_label); 1561 obj = SLOT(msglabel); 1562 1563 if (!mac_mls_dominate_effective(subj, obj)) 1564 return (EACCES); 1565 1566 return (0); 1567 } 1568 1569 static int 1570 mac_mls_check_sysv_msgrmid(struct ucred *cred, struct msg *msgptr, 1571 struct label *msglabel) 1572 { 1573 struct mac_mls *subj, *obj; 1574 1575 if (!mac_mls_enabled) 1576 return (0); 1577 1578 subj = SLOT(cred->cr_label); 1579 obj = SLOT(msglabel); 1580 1581 if (!mac_mls_dominate_effective(obj, subj)) 1582 return (EACCES); 1583 1584 return (0); 1585 } 1586 1587 static int 1588 mac_mls_check_sysv_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1589 struct label *msqklabel) 1590 { 1591 struct mac_mls *subj, *obj; 1592 1593 if (!mac_mls_enabled) 1594 return (0); 1595 1596 subj = SLOT(cred->cr_label); 1597 obj = SLOT(msqklabel); 1598 1599 if (!mac_mls_dominate_effective(subj, obj)) 1600 return (EACCES); 1601 1602 return (0); 1603 } 1604 1605 static int 1606 mac_mls_check_sysv_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1607 struct label *msqklabel) 1608 { 1609 struct mac_mls *subj, *obj; 1610 1611 if (!mac_mls_enabled) 1612 return (0); 1613 1614 subj = SLOT(cred->cr_label); 1615 obj = SLOT(msqklabel); 1616 1617 if (!mac_mls_dominate_effective(obj, subj)) 1618 return (EACCES); 1619 1620 return (0); 1621 } 1622 1623 static int 1624 mac_mls_check_sysv_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1625 struct label *msqklabel) 1626 { 1627 struct mac_mls *subj, *obj; 1628 1629 if (!mac_mls_enabled) 1630 return (0); 1631 1632 subj = SLOT(cred->cr_label); 1633 obj = SLOT(msqklabel); 1634 1635 if (!mac_mls_dominate_effective(subj, obj)) 1636 return (EACCES); 1637 1638 return (0); 1639 } 1640 1641 static int 1642 mac_mls_check_sysv_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1643 struct label *msqklabel, int cmd) 1644 { 1645 struct mac_mls *subj, *obj; 1646 1647 if (!mac_mls_enabled) 1648 return (0); 1649 1650 subj = SLOT(cred->cr_label); 1651 obj = SLOT(msqklabel); 1652 1653 switch(cmd) { 1654 case IPC_RMID: 1655 case IPC_SET: 1656 if (!mac_mls_dominate_effective(obj, subj)) 1657 return (EACCES); 1658 break; 1659 1660 case IPC_STAT: 1661 if (!mac_mls_dominate_effective(subj, obj)) 1662 return (EACCES); 1663 break; 1664 1665 default: 1666 return (EACCES); 1667 } 1668 1669 return (0); 1670 } 1671 1672 static int 1673 mac_mls_check_sysv_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1674 struct label *semaklabel, int cmd) 1675 { 1676 struct mac_mls *subj, *obj; 1677 1678 if (!mac_mls_enabled) 1679 return (0); 1680 1681 subj = SLOT(cred->cr_label); 1682 obj = SLOT(semaklabel); 1683 1684 switch(cmd) { 1685 case IPC_RMID: 1686 case IPC_SET: 1687 case SETVAL: 1688 case SETALL: 1689 if (!mac_mls_dominate_effective(obj, subj)) 1690 return (EACCES); 1691 break; 1692 1693 case IPC_STAT: 1694 case GETVAL: 1695 case GETPID: 1696 case GETNCNT: 1697 case GETZCNT: 1698 case GETALL: 1699 if (!mac_mls_dominate_effective(subj, obj)) 1700 return (EACCES); 1701 break; 1702 1703 default: 1704 return (EACCES); 1705 } 1706 1707 return (0); 1708 } 1709 1710 static int 1711 mac_mls_check_sysv_semget(struct ucred *cred, struct semid_kernel *semakptr, 1712 struct label *semaklabel) 1713 { 1714 struct mac_mls *subj, *obj; 1715 1716 if (!mac_mls_enabled) 1717 return (0); 1718 1719 subj = SLOT(cred->cr_label); 1720 obj = SLOT(semaklabel); 1721 1722 if (!mac_mls_dominate_effective(subj, obj)) 1723 return (EACCES); 1724 1725 return (0); 1726 } 1727 1728 static int 1729 mac_mls_check_sysv_semop(struct ucred *cred, struct semid_kernel *semakptr, 1730 struct label *semaklabel, size_t accesstype) 1731 { 1732 struct mac_mls *subj, *obj; 1733 1734 if (!mac_mls_enabled) 1735 return (0); 1736 1737 subj = SLOT(cred->cr_label); 1738 obj = SLOT(semaklabel); 1739 1740 if( accesstype & SEM_R ) 1741 if (!mac_mls_dominate_effective(subj, obj)) 1742 return (EACCES); 1743 1744 if( accesstype & SEM_A ) 1745 if (!mac_mls_dominate_effective(obj, subj)) 1746 return (EACCES); 1747 1748 return (0); 1749 } 1750 1751 static int 1752 mac_mls_check_sysv_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 1753 struct label *shmseglabel, int shmflg) 1754 { 1755 struct mac_mls *subj, *obj; 1756 1757 if (!mac_mls_enabled) 1758 return (0); 1759 1760 subj = SLOT(cred->cr_label); 1761 obj = SLOT(shmseglabel); 1762 1763 if (!mac_mls_dominate_effective(subj, obj)) 1764 return (EACCES); 1765 if ((shmflg & SHM_RDONLY) == 0) 1766 if (!mac_mls_dominate_effective(obj, subj)) 1767 return (EACCES); 1768 1769 return (0); 1770 } 1771 1772 static int 1773 mac_mls_check_sysv_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 1774 struct label *shmseglabel, int cmd) 1775 { 1776 struct mac_mls *subj, *obj; 1777 1778 if (!mac_mls_enabled) 1779 return (0); 1780 1781 subj = SLOT(cred->cr_label); 1782 obj = SLOT(shmseglabel); 1783 1784 switch(cmd) { 1785 case IPC_RMID: 1786 case IPC_SET: 1787 if (!mac_mls_dominate_effective(obj, subj)) 1788 return (EACCES); 1789 break; 1790 1791 case IPC_STAT: 1792 case SHM_STAT: 1793 if (!mac_mls_dominate_effective(subj, obj)) 1794 return (EACCES); 1795 break; 1796 1797 default: 1798 return (EACCES); 1799 } 1800 1801 return (0); 1802 } 1803 1804 static int 1805 mac_mls_check_sysv_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 1806 struct label *shmseglabel, int shmflg) 1807 { 1808 struct mac_mls *subj, *obj; 1809 1810 if (!mac_mls_enabled) 1811 return (0); 1812 1813 subj = SLOT(cred->cr_label); 1814 obj = SLOT(shmseglabel); 1815 1816 if (!mac_mls_dominate_effective(obj, subj)) 1817 return (EACCES); 1818 1819 return (0); 1820 } 1821 1822 static int 1823 mac_mls_check_mount_stat(struct ucred *cred, struct mount *mp, 1824 struct label *mntlabel) 1825 { 1826 struct mac_mls *subj, *obj; 1827 1828 if (!mac_mls_enabled) 1829 return (0); 1830 1831 subj = SLOT(cred->cr_label); 1832 obj = SLOT(mntlabel); 1833 1834 if (!mac_mls_dominate_effective(subj, obj)) 1835 return (EACCES); 1836 1837 return (0); 1838 } 1839 1840 static int 1841 mac_mls_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1842 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1843 { 1844 1845 if(!mac_mls_enabled) 1846 return (0); 1847 1848 /* XXX: This will be implemented soon... */ 1849 1850 return (0); 1851 } 1852 1853 static int 1854 mac_mls_check_pipe_poll(struct ucred *cred, struct pipepair *pp, 1855 struct label *pipelabel) 1856 { 1857 struct mac_mls *subj, *obj; 1858 1859 if (!mac_mls_enabled) 1860 return (0); 1861 1862 subj = SLOT(cred->cr_label); 1863 obj = SLOT((pipelabel)); 1864 1865 if (!mac_mls_dominate_effective(subj, obj)) 1866 return (EACCES); 1867 1868 return (0); 1869 } 1870 1871 static int 1872 mac_mls_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1873 struct label *pipelabel) 1874 { 1875 struct mac_mls *subj, *obj; 1876 1877 if (!mac_mls_enabled) 1878 return (0); 1879 1880 subj = SLOT(cred->cr_label); 1881 obj = SLOT((pipelabel)); 1882 1883 if (!mac_mls_dominate_effective(subj, obj)) 1884 return (EACCES); 1885 1886 return (0); 1887 } 1888 1889 static int 1890 mac_mls_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1891 struct label *pipelabel, struct label *newlabel) 1892 { 1893 struct mac_mls *subj, *obj, *new; 1894 int error; 1895 1896 new = SLOT(newlabel); 1897 subj = SLOT(cred->cr_label); 1898 obj = SLOT(pipelabel); 1899 1900 /* 1901 * If there is an MLS label update for a pipe, it must be a 1902 * effective update. 1903 */ 1904 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1905 if (error) 1906 return (error); 1907 1908 /* 1909 * To perform a relabel of a pipe (MLS label or not), MLS must 1910 * authorize the relabel. 1911 */ 1912 if (!mac_mls_effective_in_range(obj, subj)) 1913 return (EPERM); 1914 1915 /* 1916 * If the MLS label is to be changed, authorize as appropriate. 1917 */ 1918 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1919 /* 1920 * To change the MLS label on a pipe, the new pipe label 1921 * must be in the subject range. 1922 */ 1923 if (!mac_mls_effective_in_range(new, subj)) 1924 return (EPERM); 1925 1926 /* 1927 * To change the MLS label on a pipe to be EQUAL, the 1928 * subject must have appropriate privilege. 1929 */ 1930 if (mac_mls_contains_equal(new)) { 1931 error = mac_mls_subject_privileged(subj); 1932 if (error) 1933 return (error); 1934 } 1935 } 1936 1937 return (0); 1938 } 1939 1940 static int 1941 mac_mls_check_pipe_stat(struct ucred *cred, struct pipepair *pp, 1942 struct label *pipelabel) 1943 { 1944 struct mac_mls *subj, *obj; 1945 1946 if (!mac_mls_enabled) 1947 return (0); 1948 1949 subj = SLOT(cred->cr_label); 1950 obj = SLOT((pipelabel)); 1951 1952 if (!mac_mls_dominate_effective(subj, obj)) 1953 return (EACCES); 1954 1955 return (0); 1956 } 1957 1958 static int 1959 mac_mls_check_pipe_write(struct ucred *cred, struct pipepair *pp, 1960 struct label *pipelabel) 1961 { 1962 struct mac_mls *subj, *obj; 1963 1964 if (!mac_mls_enabled) 1965 return (0); 1966 1967 subj = SLOT(cred->cr_label); 1968 obj = SLOT((pipelabel)); 1969 1970 if (!mac_mls_dominate_effective(obj, subj)) 1971 return (EACCES); 1972 1973 return (0); 1974 } 1975 1976 static int 1977 mac_mls_check_proc_debug(struct ucred *cred, struct proc *proc) 1978 { 1979 struct mac_mls *subj, *obj; 1980 1981 if (!mac_mls_enabled) 1982 return (0); 1983 1984 subj = SLOT(cred->cr_label); 1985 obj = SLOT(proc->p_ucred->cr_label); 1986 1987 /* XXX: range checks */ 1988 if (!mac_mls_dominate_effective(subj, obj)) 1989 return (ESRCH); 1990 if (!mac_mls_dominate_effective(obj, subj)) 1991 return (EACCES); 1992 1993 return (0); 1994 } 1995 1996 static int 1997 mac_mls_check_proc_sched(struct ucred *cred, struct proc *proc) 1998 { 1999 struct mac_mls *subj, *obj; 2000 2001 if (!mac_mls_enabled) 2002 return (0); 2003 2004 subj = SLOT(cred->cr_label); 2005 obj = SLOT(proc->p_ucred->cr_label); 2006 2007 /* XXX: range checks */ 2008 if (!mac_mls_dominate_effective(subj, obj)) 2009 return (ESRCH); 2010 if (!mac_mls_dominate_effective(obj, subj)) 2011 return (EACCES); 2012 2013 return (0); 2014 } 2015 2016 static int 2017 mac_mls_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2018 { 2019 struct mac_mls *subj, *obj; 2020 2021 if (!mac_mls_enabled) 2022 return (0); 2023 2024 subj = SLOT(cred->cr_label); 2025 obj = SLOT(proc->p_ucred->cr_label); 2026 2027 /* XXX: range checks */ 2028 if (!mac_mls_dominate_effective(subj, obj)) 2029 return (ESRCH); 2030 if (!mac_mls_dominate_effective(obj, subj)) 2031 return (EACCES); 2032 2033 return (0); 2034 } 2035 2036 static int 2037 mac_mls_check_socket_deliver(struct socket *so, struct label *socketlabel, 2038 struct mbuf *m, struct label *mbuflabel) 2039 { 2040 struct mac_mls *p, *s; 2041 2042 if (!mac_mls_enabled) 2043 return (0); 2044 2045 p = SLOT(mbuflabel); 2046 s = SLOT(socketlabel); 2047 2048 return (mac_mls_equal_effective(p, s) ? 0 : EACCES); 2049 } 2050 2051 static int 2052 mac_mls_check_socket_relabel(struct ucred *cred, struct socket *socket, 2053 struct label *socketlabel, struct label *newlabel) 2054 { 2055 struct mac_mls *subj, *obj, *new; 2056 int error; 2057 2058 new = SLOT(newlabel); 2059 subj = SLOT(cred->cr_label); 2060 obj = SLOT(socketlabel); 2061 2062 /* 2063 * If there is an MLS label update for the socket, it may be 2064 * an update of effective. 2065 */ 2066 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2067 if (error) 2068 return (error); 2069 2070 /* 2071 * To relabel a socket, the old socket effective must be in the subject 2072 * range. 2073 */ 2074 if (!mac_mls_effective_in_range(obj, subj)) 2075 return (EPERM); 2076 2077 /* 2078 * If the MLS label is to be changed, authorize as appropriate. 2079 */ 2080 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2081 /* 2082 * To relabel a socket, the new socket effective must be in 2083 * the subject range. 2084 */ 2085 if (!mac_mls_effective_in_range(new, subj)) 2086 return (EPERM); 2087 2088 /* 2089 * To change the MLS label on the socket to contain EQUAL, 2090 * the subject must have appropriate privilege. 2091 */ 2092 if (mac_mls_contains_equal(new)) { 2093 error = mac_mls_subject_privileged(subj); 2094 if (error) 2095 return (error); 2096 } 2097 } 2098 2099 return (0); 2100 } 2101 2102 static int 2103 mac_mls_check_socket_visible(struct ucred *cred, struct socket *socket, 2104 struct label *socketlabel) 2105 { 2106 struct mac_mls *subj, *obj; 2107 2108 if (!mac_mls_enabled) 2109 return (0); 2110 2111 subj = SLOT(cred->cr_label); 2112 obj = SLOT(socketlabel); 2113 2114 if (!mac_mls_dominate_effective(subj, obj)) 2115 return (ENOENT); 2116 2117 return (0); 2118 } 2119 2120 static int 2121 mac_mls_check_system_swapon(struct ucred *cred, struct vnode *vp, 2122 struct label *label) 2123 { 2124 struct mac_mls *subj, *obj; 2125 2126 if (!mac_mls_enabled) 2127 return (0); 2128 2129 subj = SLOT(cred->cr_label); 2130 obj = SLOT(label); 2131 2132 if (!mac_mls_dominate_effective(obj, subj) || 2133 !mac_mls_dominate_effective(subj, obj)) 2134 return (EACCES); 2135 2136 return (0); 2137 } 2138 2139 static int 2140 mac_mls_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2141 struct label *dlabel) 2142 { 2143 struct mac_mls *subj, *obj; 2144 2145 if (!mac_mls_enabled) 2146 return (0); 2147 2148 subj = SLOT(cred->cr_label); 2149 obj = SLOT(dlabel); 2150 2151 if (!mac_mls_dominate_effective(subj, obj)) 2152 return (EACCES); 2153 2154 return (0); 2155 } 2156 2157 static int 2158 mac_mls_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2159 struct label *dlabel) 2160 { 2161 struct mac_mls *subj, *obj; 2162 2163 if (!mac_mls_enabled) 2164 return (0); 2165 2166 subj = SLOT(cred->cr_label); 2167 obj = SLOT(dlabel); 2168 2169 if (!mac_mls_dominate_effective(subj, obj)) 2170 return (EACCES); 2171 2172 return (0); 2173 } 2174 2175 static int 2176 mac_mls_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2177 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2178 { 2179 struct mac_mls *subj, *obj; 2180 2181 if (!mac_mls_enabled) 2182 return (0); 2183 2184 subj = SLOT(cred->cr_label); 2185 obj = SLOT(dlabel); 2186 2187 if (!mac_mls_dominate_effective(obj, subj)) 2188 return (EACCES); 2189 2190 return (0); 2191 } 2192 2193 static int 2194 mac_mls_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2195 struct label *dlabel, struct vnode *vp, struct label *label, 2196 struct componentname *cnp) 2197 { 2198 struct mac_mls *subj, *obj; 2199 2200 if (!mac_mls_enabled) 2201 return (0); 2202 2203 subj = SLOT(cred->cr_label); 2204 obj = SLOT(dlabel); 2205 2206 if (!mac_mls_dominate_effective(obj, subj)) 2207 return (EACCES); 2208 2209 obj = SLOT(label); 2210 2211 if (!mac_mls_dominate_effective(obj, subj)) 2212 return (EACCES); 2213 2214 return (0); 2215 } 2216 2217 static int 2218 mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2219 struct label *label, acl_type_t type) 2220 { 2221 struct mac_mls *subj, *obj; 2222 2223 if (!mac_mls_enabled) 2224 return (0); 2225 2226 subj = SLOT(cred->cr_label); 2227 obj = SLOT(label); 2228 2229 if (!mac_mls_dominate_effective(obj, subj)) 2230 return (EACCES); 2231 2232 return (0); 2233 } 2234 2235 static int 2236 mac_mls_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2237 struct label *label, int attrnamespace, const char *name) 2238 { 2239 struct mac_mls *subj, *obj; 2240 2241 if (!mac_mls_enabled) 2242 return (0); 2243 2244 subj = SLOT(cred->cr_label); 2245 obj = SLOT(label); 2246 2247 if (!mac_mls_dominate_effective(obj, subj)) 2248 return (EACCES); 2249 2250 return (0); 2251 } 2252 2253 static int 2254 mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2255 struct label *label, struct image_params *imgp, 2256 struct label *execlabel) 2257 { 2258 struct mac_mls *subj, *obj, *exec; 2259 int error; 2260 2261 if (execlabel != NULL) { 2262 /* 2263 * We currently don't permit labels to be changed at 2264 * exec-time as part of MLS, so disallow non-NULL 2265 * MLS label elements in the execlabel. 2266 */ 2267 exec = SLOT(execlabel); 2268 error = mls_atmostflags(exec, 0); 2269 if (error) 2270 return (error); 2271 } 2272 2273 if (!mac_mls_enabled) 2274 return (0); 2275 2276 subj = SLOT(cred->cr_label); 2277 obj = SLOT(label); 2278 2279 if (!mac_mls_dominate_effective(subj, obj)) 2280 return (EACCES); 2281 2282 return (0); 2283 } 2284 2285 static int 2286 mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2287 struct label *label, acl_type_t type) 2288 { 2289 struct mac_mls *subj, *obj; 2290 2291 if (!mac_mls_enabled) 2292 return (0); 2293 2294 subj = SLOT(cred->cr_label); 2295 obj = SLOT(label); 2296 2297 if (!mac_mls_dominate_effective(subj, obj)) 2298 return (EACCES); 2299 2300 return (0); 2301 } 2302 2303 static int 2304 mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2305 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2306 { 2307 struct mac_mls *subj, *obj; 2308 2309 if (!mac_mls_enabled) 2310 return (0); 2311 2312 subj = SLOT(cred->cr_label); 2313 obj = SLOT(label); 2314 2315 if (!mac_mls_dominate_effective(subj, obj)) 2316 return (EACCES); 2317 2318 return (0); 2319 } 2320 2321 static int 2322 mac_mls_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2323 struct label *dlabel, struct vnode *vp, struct label *label, 2324 struct componentname *cnp) 2325 { 2326 struct mac_mls *subj, *obj; 2327 2328 if (!mac_mls_enabled) 2329 return (0); 2330 2331 subj = SLOT(cred->cr_label); 2332 obj = SLOT(dlabel); 2333 2334 if (!mac_mls_dominate_effective(obj, subj)) 2335 return (EACCES); 2336 2337 obj = SLOT(dlabel); 2338 if (!mac_mls_dominate_effective(obj, subj)) 2339 return (EACCES); 2340 2341 return (0); 2342 } 2343 2344 static int 2345 mac_mls_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2346 struct label *label, int attrnamespace) 2347 { 2348 2349 struct mac_mls *subj, *obj; 2350 2351 if (!mac_mls_enabled) 2352 return (0); 2353 2354 subj = SLOT(cred->cr_label); 2355 obj = SLOT(label); 2356 2357 if (!mac_mls_dominate_effective(subj, obj)) 2358 return (EACCES); 2359 2360 return (0); 2361 } 2362 2363 static int 2364 mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2365 struct label *dlabel, struct componentname *cnp) 2366 { 2367 struct mac_mls *subj, *obj; 2368 2369 if (!mac_mls_enabled) 2370 return (0); 2371 2372 subj = SLOT(cred->cr_label); 2373 obj = SLOT(dlabel); 2374 2375 if (!mac_mls_dominate_effective(subj, obj)) 2376 return (EACCES); 2377 2378 return (0); 2379 } 2380 2381 static int 2382 mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2383 struct label *label, int prot) 2384 { 2385 struct mac_mls *subj, *obj; 2386 2387 /* 2388 * Rely on the use of open()-time protections to handle 2389 * non-revocation cases. 2390 */ 2391 if (!mac_mls_enabled || !revocation_enabled) 2392 return (0); 2393 2394 subj = SLOT(cred->cr_label); 2395 obj = SLOT(label); 2396 2397 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2398 if (!mac_mls_dominate_effective(subj, obj)) 2399 return (EACCES); 2400 } 2401 if (prot & VM_PROT_WRITE) { 2402 if (!mac_mls_dominate_effective(obj, subj)) 2403 return (EACCES); 2404 } 2405 2406 return (0); 2407 } 2408 2409 static int 2410 mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, 2411 struct label *vnodelabel, int acc_mode) 2412 { 2413 struct mac_mls *subj, *obj; 2414 2415 if (!mac_mls_enabled) 2416 return (0); 2417 2418 subj = SLOT(cred->cr_label); 2419 obj = SLOT(vnodelabel); 2420 2421 /* XXX privilege override for admin? */ 2422 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2423 if (!mac_mls_dominate_effective(subj, obj)) 2424 return (EACCES); 2425 } 2426 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2427 if (!mac_mls_dominate_effective(obj, subj)) 2428 return (EACCES); 2429 } 2430 2431 return (0); 2432 } 2433 2434 static int 2435 mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2436 struct vnode *vp, struct label *label) 2437 { 2438 struct mac_mls *subj, *obj; 2439 2440 if (!mac_mls_enabled || !revocation_enabled) 2441 return (0); 2442 2443 subj = SLOT(active_cred->cr_label); 2444 obj = SLOT(label); 2445 2446 if (!mac_mls_dominate_effective(subj, obj)) 2447 return (EACCES); 2448 2449 return (0); 2450 } 2451 2452 static int 2453 mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2454 struct vnode *vp, struct label *label) 2455 { 2456 struct mac_mls *subj, *obj; 2457 2458 if (!mac_mls_enabled || !revocation_enabled) 2459 return (0); 2460 2461 subj = SLOT(active_cred->cr_label); 2462 obj = SLOT(label); 2463 2464 if (!mac_mls_dominate_effective(subj, obj)) 2465 return (EACCES); 2466 2467 return (0); 2468 } 2469 2470 static int 2471 mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2472 struct label *dlabel) 2473 { 2474 struct mac_mls *subj, *obj; 2475 2476 if (!mac_mls_enabled) 2477 return (0); 2478 2479 subj = SLOT(cred->cr_label); 2480 obj = SLOT(dlabel); 2481 2482 if (!mac_mls_dominate_effective(subj, obj)) 2483 return (EACCES); 2484 2485 return (0); 2486 } 2487 2488 static int 2489 mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2490 struct label *vnodelabel) 2491 { 2492 struct mac_mls *subj, *obj; 2493 2494 if (!mac_mls_enabled) 2495 return (0); 2496 2497 subj = SLOT(cred->cr_label); 2498 obj = SLOT(vnodelabel); 2499 2500 if (!mac_mls_dominate_effective(subj, obj)) 2501 return (EACCES); 2502 2503 return (0); 2504 } 2505 2506 static int 2507 mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2508 struct label *vnodelabel, struct label *newlabel) 2509 { 2510 struct mac_mls *old, *new, *subj; 2511 int error; 2512 2513 old = SLOT(vnodelabel); 2514 new = SLOT(newlabel); 2515 subj = SLOT(cred->cr_label); 2516 2517 /* 2518 * If there is an MLS label update for the vnode, it must be a 2519 * effective label. 2520 */ 2521 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2522 if (error) 2523 return (error); 2524 2525 /* 2526 * To perform a relabel of the vnode (MLS label or not), MLS must 2527 * authorize the relabel. 2528 */ 2529 if (!mac_mls_effective_in_range(old, subj)) 2530 return (EPERM); 2531 2532 /* 2533 * If the MLS label is to be changed, authorize as appropriate. 2534 */ 2535 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2536 /* 2537 * To change the MLS label on a vnode, the new vnode label 2538 * must be in the subject range. 2539 */ 2540 if (!mac_mls_effective_in_range(new, subj)) 2541 return (EPERM); 2542 2543 /* 2544 * To change the MLS label on the vnode to be EQUAL, 2545 * the subject must have appropriate privilege. 2546 */ 2547 if (mac_mls_contains_equal(new)) { 2548 error = mac_mls_subject_privileged(subj); 2549 if (error) 2550 return (error); 2551 } 2552 } 2553 2554 return (0); 2555 } 2556 2557 2558 static int 2559 mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2560 struct label *dlabel, struct vnode *vp, struct label *label, 2561 struct componentname *cnp) 2562 { 2563 struct mac_mls *subj, *obj; 2564 2565 if (!mac_mls_enabled) 2566 return (0); 2567 2568 subj = SLOT(cred->cr_label); 2569 obj = SLOT(dlabel); 2570 2571 if (!mac_mls_dominate_effective(obj, subj)) 2572 return (EACCES); 2573 2574 obj = SLOT(label); 2575 2576 if (!mac_mls_dominate_effective(obj, subj)) 2577 return (EACCES); 2578 2579 return (0); 2580 } 2581 2582 static int 2583 mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2584 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2585 struct componentname *cnp) 2586 { 2587 struct mac_mls *subj, *obj; 2588 2589 if (!mac_mls_enabled) 2590 return (0); 2591 2592 subj = SLOT(cred->cr_label); 2593 obj = SLOT(dlabel); 2594 2595 if (!mac_mls_dominate_effective(obj, subj)) 2596 return (EACCES); 2597 2598 if (vp != NULL) { 2599 obj = SLOT(label); 2600 2601 if (!mac_mls_dominate_effective(obj, subj)) 2602 return (EACCES); 2603 } 2604 2605 return (0); 2606 } 2607 2608 static int 2609 mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2610 struct label *label) 2611 { 2612 struct mac_mls *subj, *obj; 2613 2614 if (!mac_mls_enabled) 2615 return (0); 2616 2617 subj = SLOT(cred->cr_label); 2618 obj = SLOT(label); 2619 2620 if (!mac_mls_dominate_effective(obj, subj)) 2621 return (EACCES); 2622 2623 return (0); 2624 } 2625 2626 static int 2627 mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2628 struct label *label, acl_type_t type, struct acl *acl) 2629 { 2630 struct mac_mls *subj, *obj; 2631 2632 if (!mac_mls_enabled) 2633 return (0); 2634 2635 subj = SLOT(cred->cr_label); 2636 obj = SLOT(label); 2637 2638 if (!mac_mls_dominate_effective(obj, subj)) 2639 return (EACCES); 2640 2641 return (0); 2642 } 2643 2644 static int 2645 mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2646 struct label *vnodelabel, int attrnamespace, const char *name, 2647 struct uio *uio) 2648 { 2649 struct mac_mls *subj, *obj; 2650 2651 if (!mac_mls_enabled) 2652 return (0); 2653 2654 subj = SLOT(cred->cr_label); 2655 obj = SLOT(vnodelabel); 2656 2657 if (!mac_mls_dominate_effective(obj, subj)) 2658 return (EACCES); 2659 2660 /* XXX: protect the MAC EA in a special way? */ 2661 2662 return (0); 2663 } 2664 2665 static int 2666 mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2667 struct label *vnodelabel, u_long flags) 2668 { 2669 struct mac_mls *subj, *obj; 2670 2671 if (!mac_mls_enabled) 2672 return (0); 2673 2674 subj = SLOT(cred->cr_label); 2675 obj = SLOT(vnodelabel); 2676 2677 if (!mac_mls_dominate_effective(obj, subj)) 2678 return (EACCES); 2679 2680 return (0); 2681 } 2682 2683 static int 2684 mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2685 struct label *vnodelabel, mode_t mode) 2686 { 2687 struct mac_mls *subj, *obj; 2688 2689 if (!mac_mls_enabled) 2690 return (0); 2691 2692 subj = SLOT(cred->cr_label); 2693 obj = SLOT(vnodelabel); 2694 2695 if (!mac_mls_dominate_effective(obj, subj)) 2696 return (EACCES); 2697 2698 return (0); 2699 } 2700 2701 static int 2702 mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2703 struct label *vnodelabel, uid_t uid, gid_t gid) 2704 { 2705 struct mac_mls *subj, *obj; 2706 2707 if (!mac_mls_enabled) 2708 return (0); 2709 2710 subj = SLOT(cred->cr_label); 2711 obj = SLOT(vnodelabel); 2712 2713 if (!mac_mls_dominate_effective(obj, subj)) 2714 return (EACCES); 2715 2716 return (0); 2717 } 2718 2719 static int 2720 mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2721 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2722 { 2723 struct mac_mls *subj, *obj; 2724 2725 if (!mac_mls_enabled) 2726 return (0); 2727 2728 subj = SLOT(cred->cr_label); 2729 obj = SLOT(vnodelabel); 2730 2731 if (!mac_mls_dominate_effective(obj, subj)) 2732 return (EACCES); 2733 2734 return (0); 2735 } 2736 2737 static int 2738 mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2739 struct vnode *vp, struct label *vnodelabel) 2740 { 2741 struct mac_mls *subj, *obj; 2742 2743 if (!mac_mls_enabled) 2744 return (0); 2745 2746 subj = SLOT(active_cred->cr_label); 2747 obj = SLOT(vnodelabel); 2748 2749 if (!mac_mls_dominate_effective(subj, obj)) 2750 return (EACCES); 2751 2752 return (0); 2753 } 2754 2755 static int 2756 mac_mls_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 2757 struct vnode *vp, struct label *label) 2758 { 2759 struct mac_mls *subj, *obj; 2760 2761 if (!mac_mls_enabled || !revocation_enabled) 2762 return (0); 2763 2764 subj = SLOT(active_cred->cr_label); 2765 obj = SLOT(label); 2766 2767 if (!mac_mls_dominate_effective(obj, subj)) 2768 return (EACCES); 2769 2770 return (0); 2771 } 2772 2773 static struct mac_policy_ops mac_mls_ops = 2774 { 2775 .mpo_init = mac_mls_init, 2776 .mpo_init_bpfdesc_label = mac_mls_init_label, 2777 .mpo_init_cred_label = mac_mls_init_label, 2778 .mpo_init_devfsdirent_label = mac_mls_init_label, 2779 .mpo_init_ifnet_label = mac_mls_init_label, 2780 .mpo_init_inpcb_label = mac_mls_init_label_waitcheck, 2781 .mpo_init_sysv_msgmsg_label = mac_mls_init_label, 2782 .mpo_init_sysv_msgqueue_label = mac_mls_init_label, 2783 .mpo_init_sysv_sema_label = mac_mls_init_label, 2784 .mpo_init_sysv_shm_label = mac_mls_init_label, 2785 .mpo_init_ipq_label = mac_mls_init_label_waitcheck, 2786 .mpo_init_mbuf_label = mac_mls_init_label_waitcheck, 2787 .mpo_init_mount_label = mac_mls_init_label, 2788 .mpo_init_mount_fs_label = mac_mls_init_label, 2789 .mpo_init_pipe_label = mac_mls_init_label, 2790 .mpo_init_socket_label = mac_mls_init_label_waitcheck, 2791 .mpo_init_socket_peer_label = mac_mls_init_label_waitcheck, 2792 .mpo_init_vnode_label = mac_mls_init_label, 2793 .mpo_destroy_bpfdesc_label = mac_mls_destroy_label, 2794 .mpo_destroy_cred_label = mac_mls_destroy_label, 2795 .mpo_destroy_devfsdirent_label = mac_mls_destroy_label, 2796 .mpo_destroy_ifnet_label = mac_mls_destroy_label, 2797 .mpo_destroy_inpcb_label = mac_mls_destroy_label, 2798 .mpo_destroy_sysv_msgmsg_label = mac_mls_destroy_label, 2799 .mpo_destroy_sysv_msgqueue_label = mac_mls_destroy_label, 2800 .mpo_destroy_sysv_sema_label = mac_mls_destroy_label, 2801 .mpo_destroy_sysv_shm_label = mac_mls_destroy_label, 2802 .mpo_destroy_ipq_label = mac_mls_destroy_label, 2803 .mpo_destroy_mbuf_label = mac_mls_destroy_label, 2804 .mpo_destroy_mount_label = mac_mls_destroy_label, 2805 .mpo_destroy_mount_fs_label = mac_mls_destroy_label, 2806 .mpo_destroy_pipe_label = mac_mls_destroy_label, 2807 .mpo_destroy_socket_label = mac_mls_destroy_label, 2808 .mpo_destroy_socket_peer_label = mac_mls_destroy_label, 2809 .mpo_destroy_vnode_label = mac_mls_destroy_label, 2810 .mpo_copy_cred_label = mac_mls_copy_label, 2811 .mpo_copy_ifnet_label = mac_mls_copy_label, 2812 .mpo_copy_mbuf_label = mac_mls_copy_label, 2813 .mpo_copy_pipe_label = mac_mls_copy_label, 2814 .mpo_copy_socket_label = mac_mls_copy_label, 2815 .mpo_copy_vnode_label = mac_mls_copy_label, 2816 .mpo_externalize_cred_label = mac_mls_externalize_label, 2817 .mpo_externalize_ifnet_label = mac_mls_externalize_label, 2818 .mpo_externalize_pipe_label = mac_mls_externalize_label, 2819 .mpo_externalize_socket_label = mac_mls_externalize_label, 2820 .mpo_externalize_socket_peer_label = mac_mls_externalize_label, 2821 .mpo_externalize_vnode_label = mac_mls_externalize_label, 2822 .mpo_internalize_cred_label = mac_mls_internalize_label, 2823 .mpo_internalize_ifnet_label = mac_mls_internalize_label, 2824 .mpo_internalize_pipe_label = mac_mls_internalize_label, 2825 .mpo_internalize_socket_label = mac_mls_internalize_label, 2826 .mpo_internalize_vnode_label = mac_mls_internalize_label, 2827 .mpo_create_devfs_device = mac_mls_create_devfs_device, 2828 .mpo_create_devfs_directory = mac_mls_create_devfs_directory, 2829 .mpo_create_devfs_symlink = mac_mls_create_devfs_symlink, 2830 .mpo_create_mount = mac_mls_create_mount, 2831 .mpo_create_root_mount = mac_mls_create_root_mount, 2832 .mpo_relabel_vnode = mac_mls_relabel_vnode, 2833 .mpo_update_devfsdirent = mac_mls_update_devfsdirent, 2834 .mpo_associate_vnode_devfs = mac_mls_associate_vnode_devfs, 2835 .mpo_associate_vnode_extattr = mac_mls_associate_vnode_extattr, 2836 .mpo_associate_vnode_singlelabel = mac_mls_associate_vnode_singlelabel, 2837 .mpo_create_vnode_extattr = mac_mls_create_vnode_extattr, 2838 .mpo_setlabel_vnode_extattr = mac_mls_setlabel_vnode_extattr, 2839 .mpo_create_mbuf_from_socket = mac_mls_create_mbuf_from_socket, 2840 .mpo_create_pipe = mac_mls_create_pipe, 2841 .mpo_create_socket = mac_mls_create_socket, 2842 .mpo_create_socket_from_socket = mac_mls_create_socket_from_socket, 2843 .mpo_relabel_pipe = mac_mls_relabel_pipe, 2844 .mpo_relabel_socket = mac_mls_relabel_socket, 2845 .mpo_set_socket_peer_from_mbuf = mac_mls_set_socket_peer_from_mbuf, 2846 .mpo_set_socket_peer_from_socket = mac_mls_set_socket_peer_from_socket, 2847 .mpo_create_bpfdesc = mac_mls_create_bpfdesc, 2848 .mpo_create_datagram_from_ipq = mac_mls_create_datagram_from_ipq, 2849 .mpo_create_fragment = mac_mls_create_fragment, 2850 .mpo_create_ifnet = mac_mls_create_ifnet, 2851 .mpo_create_inpcb_from_socket = mac_mls_create_inpcb_from_socket, 2852 .mpo_create_ipq = mac_mls_create_ipq, 2853 .mpo_create_sysv_msgmsg = mac_mls_create_sysv_msgmsg, 2854 .mpo_create_sysv_msgqueue = mac_mls_create_sysv_msgqueue, 2855 .mpo_create_sysv_sema = mac_mls_create_sysv_sema, 2856 .mpo_create_sysv_shm = mac_mls_create_sysv_shm, 2857 .mpo_create_mbuf_from_inpcb = mac_mls_create_mbuf_from_inpcb, 2858 .mpo_create_mbuf_from_mbuf = mac_mls_create_mbuf_from_mbuf, 2859 .mpo_create_mbuf_linklayer = mac_mls_create_mbuf_linklayer, 2860 .mpo_create_mbuf_from_bpfdesc = mac_mls_create_mbuf_from_bpfdesc, 2861 .mpo_create_mbuf_from_ifnet = mac_mls_create_mbuf_from_ifnet, 2862 .mpo_create_mbuf_multicast_encap = mac_mls_create_mbuf_multicast_encap, 2863 .mpo_create_mbuf_netlayer = mac_mls_create_mbuf_netlayer, 2864 .mpo_fragment_match = mac_mls_fragment_match, 2865 .mpo_relabel_ifnet = mac_mls_relabel_ifnet, 2866 .mpo_update_ipq = mac_mls_update_ipq, 2867 .mpo_inpcb_sosetlabel = mac_mls_inpcb_sosetlabel, 2868 .mpo_create_proc0 = mac_mls_create_proc0, 2869 .mpo_create_proc1 = mac_mls_create_proc1, 2870 .mpo_relabel_cred = mac_mls_relabel_cred, 2871 .mpo_cleanup_sysv_msgmsg = mac_mls_cleanup_sysv_msgmsg, 2872 .mpo_cleanup_sysv_msgqueue = mac_mls_cleanup_sysv_msgqueue, 2873 .mpo_cleanup_sysv_sema = mac_mls_cleanup_sysv_sema, 2874 .mpo_cleanup_sysv_shm = mac_mls_cleanup_sysv_shm, 2875 .mpo_check_bpfdesc_receive = mac_mls_check_bpfdesc_receive, 2876 .mpo_check_cred_relabel = mac_mls_check_cred_relabel, 2877 .mpo_check_cred_visible = mac_mls_check_cred_visible, 2878 .mpo_check_ifnet_relabel = mac_mls_check_ifnet_relabel, 2879 .mpo_check_ifnet_transmit = mac_mls_check_ifnet_transmit, 2880 .mpo_check_inpcb_deliver = mac_mls_check_inpcb_deliver, 2881 .mpo_check_sysv_msgrcv = mac_mls_check_sysv_msgrcv, 2882 .mpo_check_sysv_msgrmid = mac_mls_check_sysv_msgrmid, 2883 .mpo_check_sysv_msqget = mac_mls_check_sysv_msqget, 2884 .mpo_check_sysv_msqsnd = mac_mls_check_sysv_msqsnd, 2885 .mpo_check_sysv_msqrcv = mac_mls_check_sysv_msqrcv, 2886 .mpo_check_sysv_msqctl = mac_mls_check_sysv_msqctl, 2887 .mpo_check_sysv_semctl = mac_mls_check_sysv_semctl, 2888 .mpo_check_sysv_semget = mac_mls_check_sysv_semget, 2889 .mpo_check_sysv_semop = mac_mls_check_sysv_semop, 2890 .mpo_check_sysv_shmat = mac_mls_check_sysv_shmat, 2891 .mpo_check_sysv_shmctl = mac_mls_check_sysv_shmctl, 2892 .mpo_check_sysv_shmget = mac_mls_check_sysv_shmget, 2893 .mpo_check_mount_stat = mac_mls_check_mount_stat, 2894 .mpo_check_pipe_ioctl = mac_mls_check_pipe_ioctl, 2895 .mpo_check_pipe_poll = mac_mls_check_pipe_poll, 2896 .mpo_check_pipe_read = mac_mls_check_pipe_read, 2897 .mpo_check_pipe_relabel = mac_mls_check_pipe_relabel, 2898 .mpo_check_pipe_stat = mac_mls_check_pipe_stat, 2899 .mpo_check_pipe_write = mac_mls_check_pipe_write, 2900 .mpo_check_proc_debug = mac_mls_check_proc_debug, 2901 .mpo_check_proc_sched = mac_mls_check_proc_sched, 2902 .mpo_check_proc_signal = mac_mls_check_proc_signal, 2903 .mpo_check_socket_deliver = mac_mls_check_socket_deliver, 2904 .mpo_check_socket_relabel = mac_mls_check_socket_relabel, 2905 .mpo_check_socket_visible = mac_mls_check_socket_visible, 2906 .mpo_check_system_swapon = mac_mls_check_system_swapon, 2907 .mpo_check_vnode_access = mac_mls_check_vnode_open, 2908 .mpo_check_vnode_chdir = mac_mls_check_vnode_chdir, 2909 .mpo_check_vnode_chroot = mac_mls_check_vnode_chroot, 2910 .mpo_check_vnode_create = mac_mls_check_vnode_create, 2911 .mpo_check_vnode_delete = mac_mls_check_vnode_delete, 2912 .mpo_check_vnode_deleteacl = mac_mls_check_vnode_deleteacl, 2913 .mpo_check_vnode_deleteextattr = mac_mls_check_vnode_deleteextattr, 2914 .mpo_check_vnode_exec = mac_mls_check_vnode_exec, 2915 .mpo_check_vnode_getacl = mac_mls_check_vnode_getacl, 2916 .mpo_check_vnode_getextattr = mac_mls_check_vnode_getextattr, 2917 .mpo_check_vnode_link = mac_mls_check_vnode_link, 2918 .mpo_check_vnode_listextattr = mac_mls_check_vnode_listextattr, 2919 .mpo_check_vnode_lookup = mac_mls_check_vnode_lookup, 2920 .mpo_check_vnode_mmap = mac_mls_check_vnode_mmap, 2921 .mpo_check_vnode_open = mac_mls_check_vnode_open, 2922 .mpo_check_vnode_poll = mac_mls_check_vnode_poll, 2923 .mpo_check_vnode_read = mac_mls_check_vnode_read, 2924 .mpo_check_vnode_readdir = mac_mls_check_vnode_readdir, 2925 .mpo_check_vnode_readlink = mac_mls_check_vnode_readlink, 2926 .mpo_check_vnode_relabel = mac_mls_check_vnode_relabel, 2927 .mpo_check_vnode_rename_from = mac_mls_check_vnode_rename_from, 2928 .mpo_check_vnode_rename_to = mac_mls_check_vnode_rename_to, 2929 .mpo_check_vnode_revoke = mac_mls_check_vnode_revoke, 2930 .mpo_check_vnode_setacl = mac_mls_check_vnode_setacl, 2931 .mpo_check_vnode_setextattr = mac_mls_check_vnode_setextattr, 2932 .mpo_check_vnode_setflags = mac_mls_check_vnode_setflags, 2933 .mpo_check_vnode_setmode = mac_mls_check_vnode_setmode, 2934 .mpo_check_vnode_setowner = mac_mls_check_vnode_setowner, 2935 .mpo_check_vnode_setutimes = mac_mls_check_vnode_setutimes, 2936 .mpo_check_vnode_stat = mac_mls_check_vnode_stat, 2937 .mpo_check_vnode_write = mac_mls_check_vnode_write, 2938 }; 2939 2940 MAC_POLICY_SET(&mac_mls_ops, mac_mls, "TrustedBSD MAC/MLS", 2941 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_mls_slot); 2942