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