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