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_delete(struct ucred *cred, struct vnode *dvp, 2276 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2277 struct componentname *cnp) 2278 { 2279 struct mac_mls *subj, *obj; 2280 2281 if (!mac_mls_enabled) 2282 return (0); 2283 2284 subj = SLOT(cred->cr_label); 2285 obj = SLOT(dvplabel); 2286 2287 if (!mac_mls_dominate_effective(obj, subj)) 2288 return (EACCES); 2289 2290 obj = SLOT(vplabel); 2291 2292 if (!mac_mls_dominate_effective(obj, subj)) 2293 return (EACCES); 2294 2295 return (0); 2296 } 2297 2298 static int 2299 mac_mls_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2300 struct label *vplabel, acl_type_t type) 2301 { 2302 struct mac_mls *subj, *obj; 2303 2304 if (!mac_mls_enabled) 2305 return (0); 2306 2307 subj = SLOT(cred->cr_label); 2308 obj = SLOT(vplabel); 2309 2310 if (!mac_mls_dominate_effective(obj, subj)) 2311 return (EACCES); 2312 2313 return (0); 2314 } 2315 2316 static int 2317 mac_mls_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2318 struct label *vplabel, int attrnamespace, const char *name) 2319 { 2320 struct mac_mls *subj, *obj; 2321 2322 if (!mac_mls_enabled) 2323 return (0); 2324 2325 subj = SLOT(cred->cr_label); 2326 obj = SLOT(vplabel); 2327 2328 if (!mac_mls_dominate_effective(obj, subj)) 2329 return (EACCES); 2330 2331 return (0); 2332 } 2333 2334 static int 2335 mac_mls_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2336 struct label *vplabel, struct image_params *imgp, 2337 struct label *execlabel) 2338 { 2339 struct mac_mls *subj, *obj, *exec; 2340 int error; 2341 2342 if (execlabel != NULL) { 2343 /* 2344 * We currently don't permit labels to be changed at 2345 * exec-time as part of MLS, so disallow non-NULL 2346 * MLS label elements in the execlabel. 2347 */ 2348 exec = SLOT(execlabel); 2349 error = mls_atmostflags(exec, 0); 2350 if (error) 2351 return (error); 2352 } 2353 2354 if (!mac_mls_enabled) 2355 return (0); 2356 2357 subj = SLOT(cred->cr_label); 2358 obj = SLOT(vplabel); 2359 2360 if (!mac_mls_dominate_effective(subj, obj)) 2361 return (EACCES); 2362 2363 return (0); 2364 } 2365 2366 static int 2367 mac_mls_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2368 struct label *vplabel, acl_type_t type) 2369 { 2370 struct mac_mls *subj, *obj; 2371 2372 if (!mac_mls_enabled) 2373 return (0); 2374 2375 subj = SLOT(cred->cr_label); 2376 obj = SLOT(vplabel); 2377 2378 if (!mac_mls_dominate_effective(subj, obj)) 2379 return (EACCES); 2380 2381 return (0); 2382 } 2383 2384 static int 2385 mac_mls_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2386 struct label *vplabel, int attrnamespace, const char *name, 2387 struct uio *uio) 2388 { 2389 struct mac_mls *subj, *obj; 2390 2391 if (!mac_mls_enabled) 2392 return (0); 2393 2394 subj = SLOT(cred->cr_label); 2395 obj = SLOT(vplabel); 2396 2397 if (!mac_mls_dominate_effective(subj, obj)) 2398 return (EACCES); 2399 2400 return (0); 2401 } 2402 2403 static int 2404 mac_mls_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2405 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2406 struct componentname *cnp) 2407 { 2408 struct mac_mls *subj, *obj; 2409 2410 if (!mac_mls_enabled) 2411 return (0); 2412 2413 subj = SLOT(cred->cr_label); 2414 obj = SLOT(dvplabel); 2415 2416 if (!mac_mls_dominate_effective(obj, subj)) 2417 return (EACCES); 2418 2419 obj = SLOT(dvplabel); 2420 if (!mac_mls_dominate_effective(obj, subj)) 2421 return (EACCES); 2422 2423 return (0); 2424 } 2425 2426 static int 2427 mac_mls_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2428 struct label *vplabel, int attrnamespace) 2429 { 2430 2431 struct mac_mls *subj, *obj; 2432 2433 if (!mac_mls_enabled) 2434 return (0); 2435 2436 subj = SLOT(cred->cr_label); 2437 obj = SLOT(vplabel); 2438 2439 if (!mac_mls_dominate_effective(subj, obj)) 2440 return (EACCES); 2441 2442 return (0); 2443 } 2444 2445 static int 2446 mac_mls_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2447 struct label *dvplabel, struct componentname *cnp) 2448 { 2449 struct mac_mls *subj, *obj; 2450 2451 if (!mac_mls_enabled) 2452 return (0); 2453 2454 subj = SLOT(cred->cr_label); 2455 obj = SLOT(dvplabel); 2456 2457 if (!mac_mls_dominate_effective(subj, obj)) 2458 return (EACCES); 2459 2460 return (0); 2461 } 2462 2463 static int 2464 mac_mls_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2465 struct label *vplabel, int prot, int flags) 2466 { 2467 struct mac_mls *subj, *obj; 2468 2469 /* 2470 * Rely on the use of open()-time protections to handle 2471 * non-revocation cases. 2472 */ 2473 if (!mac_mls_enabled || !revocation_enabled) 2474 return (0); 2475 2476 subj = SLOT(cred->cr_label); 2477 obj = SLOT(vplabel); 2478 2479 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2480 if (!mac_mls_dominate_effective(subj, obj)) 2481 return (EACCES); 2482 } 2483 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2484 if (!mac_mls_dominate_effective(obj, subj)) 2485 return (EACCES); 2486 } 2487 2488 return (0); 2489 } 2490 2491 static int 2492 mac_mls_check_vnode_open(struct ucred *cred, struct vnode *vp, 2493 struct label *vplabel, int acc_mode) 2494 { 2495 struct mac_mls *subj, *obj; 2496 2497 if (!mac_mls_enabled) 2498 return (0); 2499 2500 subj = SLOT(cred->cr_label); 2501 obj = SLOT(vplabel); 2502 2503 /* XXX privilege override for admin? */ 2504 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2505 if (!mac_mls_dominate_effective(subj, obj)) 2506 return (EACCES); 2507 } 2508 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2509 if (!mac_mls_dominate_effective(obj, subj)) 2510 return (EACCES); 2511 } 2512 2513 return (0); 2514 } 2515 2516 static int 2517 mac_mls_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2518 struct vnode *vp, struct label *vplabel) 2519 { 2520 struct mac_mls *subj, *obj; 2521 2522 if (!mac_mls_enabled || !revocation_enabled) 2523 return (0); 2524 2525 subj = SLOT(active_cred->cr_label); 2526 obj = SLOT(vplabel); 2527 2528 if (!mac_mls_dominate_effective(subj, obj)) 2529 return (EACCES); 2530 2531 return (0); 2532 } 2533 2534 static int 2535 mac_mls_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2536 struct vnode *vp, struct label *vplabel) 2537 { 2538 struct mac_mls *subj, *obj; 2539 2540 if (!mac_mls_enabled || !revocation_enabled) 2541 return (0); 2542 2543 subj = SLOT(active_cred->cr_label); 2544 obj = SLOT(vplabel); 2545 2546 if (!mac_mls_dominate_effective(subj, obj)) 2547 return (EACCES); 2548 2549 return (0); 2550 } 2551 2552 static int 2553 mac_mls_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2554 struct label *dvplabel) 2555 { 2556 struct mac_mls *subj, *obj; 2557 2558 if (!mac_mls_enabled) 2559 return (0); 2560 2561 subj = SLOT(cred->cr_label); 2562 obj = SLOT(dvplabel); 2563 2564 if (!mac_mls_dominate_effective(subj, obj)) 2565 return (EACCES); 2566 2567 return (0); 2568 } 2569 2570 static int 2571 mac_mls_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2572 struct label *vplabel) 2573 { 2574 struct mac_mls *subj, *obj; 2575 2576 if (!mac_mls_enabled) 2577 return (0); 2578 2579 subj = SLOT(cred->cr_label); 2580 obj = SLOT(vplabel); 2581 2582 if (!mac_mls_dominate_effective(subj, obj)) 2583 return (EACCES); 2584 2585 return (0); 2586 } 2587 2588 static int 2589 mac_mls_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2590 struct label *vplabel, struct label *newlabel) 2591 { 2592 struct mac_mls *old, *new, *subj; 2593 int error; 2594 2595 old = SLOT(vplabel); 2596 new = SLOT(newlabel); 2597 subj = SLOT(cred->cr_label); 2598 2599 /* 2600 * If there is an MLS label update for the vnode, it must be a 2601 * effective label. 2602 */ 2603 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2604 if (error) 2605 return (error); 2606 2607 /* 2608 * To perform a relabel of the vnode (MLS label or not), MLS must 2609 * authorize the relabel. 2610 */ 2611 if (!mac_mls_effective_in_range(old, subj)) 2612 return (EPERM); 2613 2614 /* 2615 * If the MLS label is to be changed, authorize as appropriate. 2616 */ 2617 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2618 /* 2619 * To change the MLS label on a vnode, the new vnode label 2620 * must be in the subject range. 2621 */ 2622 if (!mac_mls_effective_in_range(new, subj)) 2623 return (EPERM); 2624 2625 /* 2626 * To change the MLS label on the vnode to be EQUAL, 2627 * the subject must have appropriate privilege. 2628 */ 2629 if (mac_mls_contains_equal(new)) { 2630 error = mac_mls_subject_privileged(subj); 2631 if (error) 2632 return (error); 2633 } 2634 } 2635 2636 return (0); 2637 } 2638 2639 static int 2640 mac_mls_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2641 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2642 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 obj = SLOT(vplabel); 2656 2657 if (!mac_mls_dominate_effective(obj, subj)) 2658 return (EACCES); 2659 2660 return (0); 2661 } 2662 2663 static int 2664 mac_mls_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2665 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2666 int samedir, struct componentname *cnp) 2667 { 2668 struct mac_mls *subj, *obj; 2669 2670 if (!mac_mls_enabled) 2671 return (0); 2672 2673 subj = SLOT(cred->cr_label); 2674 obj = SLOT(dvplabel); 2675 2676 if (!mac_mls_dominate_effective(obj, subj)) 2677 return (EACCES); 2678 2679 if (vp != NULL) { 2680 obj = SLOT(vplabel); 2681 2682 if (!mac_mls_dominate_effective(obj, subj)) 2683 return (EACCES); 2684 } 2685 2686 return (0); 2687 } 2688 2689 static int 2690 mac_mls_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2691 struct label *vplabel) 2692 { 2693 struct mac_mls *subj, *obj; 2694 2695 if (!mac_mls_enabled) 2696 return (0); 2697 2698 subj = SLOT(cred->cr_label); 2699 obj = SLOT(vplabel); 2700 2701 if (!mac_mls_dominate_effective(obj, subj)) 2702 return (EACCES); 2703 2704 return (0); 2705 } 2706 2707 static int 2708 mac_mls_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2709 struct label *vplabel, acl_type_t type, struct acl *acl) 2710 { 2711 struct mac_mls *subj, *obj; 2712 2713 if (!mac_mls_enabled) 2714 return (0); 2715 2716 subj = SLOT(cred->cr_label); 2717 obj = SLOT(vplabel); 2718 2719 if (!mac_mls_dominate_effective(obj, subj)) 2720 return (EACCES); 2721 2722 return (0); 2723 } 2724 2725 static int 2726 mac_mls_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2727 struct label *vplabel, int attrnamespace, const char *name, 2728 struct uio *uio) 2729 { 2730 struct mac_mls *subj, *obj; 2731 2732 if (!mac_mls_enabled) 2733 return (0); 2734 2735 subj = SLOT(cred->cr_label); 2736 obj = SLOT(vplabel); 2737 2738 if (!mac_mls_dominate_effective(obj, subj)) 2739 return (EACCES); 2740 2741 /* XXX: protect the MAC EA in a special way? */ 2742 2743 return (0); 2744 } 2745 2746 static int 2747 mac_mls_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2748 struct label *vplabel, u_long flags) 2749 { 2750 struct mac_mls *subj, *obj; 2751 2752 if (!mac_mls_enabled) 2753 return (0); 2754 2755 subj = SLOT(cred->cr_label); 2756 obj = SLOT(vplabel); 2757 2758 if (!mac_mls_dominate_effective(obj, subj)) 2759 return (EACCES); 2760 2761 return (0); 2762 } 2763 2764 static int 2765 mac_mls_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2766 struct label *vplabel, mode_t mode) 2767 { 2768 struct mac_mls *subj, *obj; 2769 2770 if (!mac_mls_enabled) 2771 return (0); 2772 2773 subj = SLOT(cred->cr_label); 2774 obj = SLOT(vplabel); 2775 2776 if (!mac_mls_dominate_effective(obj, subj)) 2777 return (EACCES); 2778 2779 return (0); 2780 } 2781 2782 static int 2783 mac_mls_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2784 struct label *vplabel, uid_t uid, gid_t gid) 2785 { 2786 struct mac_mls *subj, *obj; 2787 2788 if (!mac_mls_enabled) 2789 return (0); 2790 2791 subj = SLOT(cred->cr_label); 2792 obj = SLOT(vplabel); 2793 2794 if (!mac_mls_dominate_effective(obj, subj)) 2795 return (EACCES); 2796 2797 return (0); 2798 } 2799 2800 static int 2801 mac_mls_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2802 struct label *vplabel, struct timespec atime, struct timespec mtime) 2803 { 2804 struct mac_mls *subj, *obj; 2805 2806 if (!mac_mls_enabled) 2807 return (0); 2808 2809 subj = SLOT(cred->cr_label); 2810 obj = SLOT(vplabel); 2811 2812 if (!mac_mls_dominate_effective(obj, subj)) 2813 return (EACCES); 2814 2815 return (0); 2816 } 2817 2818 static int 2819 mac_mls_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2820 struct vnode *vp, struct label *vplabel) 2821 { 2822 struct mac_mls *subj, *obj; 2823 2824 if (!mac_mls_enabled) 2825 return (0); 2826 2827 subj = SLOT(active_cred->cr_label); 2828 obj = SLOT(vplabel); 2829 2830 if (!mac_mls_dominate_effective(subj, obj)) 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_delete = mac_mls_check_vnode_delete, 3015 .mpo_check_vnode_deleteacl = mac_mls_check_vnode_deleteacl, 3016 .mpo_check_vnode_deleteextattr = mac_mls_check_vnode_deleteextattr, 3017 .mpo_check_vnode_exec = mac_mls_check_vnode_exec, 3018 .mpo_check_vnode_getacl = mac_mls_check_vnode_getacl, 3019 .mpo_check_vnode_getextattr = mac_mls_check_vnode_getextattr, 3020 .mpo_check_vnode_link = mac_mls_check_vnode_link, 3021 .mpo_check_vnode_listextattr = mac_mls_check_vnode_listextattr, 3022 .mpo_check_vnode_lookup = mac_mls_check_vnode_lookup, 3023 .mpo_check_vnode_mmap = mac_mls_check_vnode_mmap, 3024 .mpo_check_vnode_open = mac_mls_check_vnode_open, 3025 .mpo_check_vnode_poll = mac_mls_check_vnode_poll, 3026 .mpo_check_vnode_read = mac_mls_check_vnode_read, 3027 .mpo_check_vnode_readdir = mac_mls_check_vnode_readdir, 3028 .mpo_check_vnode_readlink = mac_mls_check_vnode_readlink, 3029 .mpo_check_vnode_relabel = mac_mls_check_vnode_relabel, 3030 .mpo_check_vnode_rename_from = mac_mls_check_vnode_rename_from, 3031 .mpo_check_vnode_rename_to = mac_mls_check_vnode_rename_to, 3032 .mpo_check_vnode_revoke = mac_mls_check_vnode_revoke, 3033 .mpo_check_vnode_setacl = mac_mls_check_vnode_setacl, 3034 .mpo_check_vnode_setextattr = mac_mls_check_vnode_setextattr, 3035 .mpo_check_vnode_setflags = mac_mls_check_vnode_setflags, 3036 .mpo_check_vnode_setmode = mac_mls_check_vnode_setmode, 3037 .mpo_check_vnode_setowner = mac_mls_check_vnode_setowner, 3038 .mpo_check_vnode_setutimes = mac_mls_check_vnode_setutimes, 3039 .mpo_check_vnode_stat = mac_mls_check_vnode_stat, 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