mac_mls.c revision 168977
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: head/sys/security/mac_mls/mac_mls.c 168977 2007-04-23 13:36:54Z rwatson $ 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 87SYSCTL_DECL(_security_mac); 88 89SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0, 90 "TrustedBSD mac_mls policy controls"); 91 92static int mac_mls_label_size = sizeof(struct mac_mls); 93SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD, 94 &mac_mls_label_size, 0, "Size of struct mac_mls"); 95 96static int mac_mls_enabled = 1; 97SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW, 98 &mac_mls_enabled, 0, "Enforce MAC/MLS policy"); 99TUNABLE_INT("security.mac.mls.enabled", &mac_mls_enabled); 100 101static int destroyed_not_inited; 102SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 103 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 104 105static int ptys_equal = 0; 106SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW, 107 &ptys_equal, 0, "Label pty devices as mls/equal on create"); 108TUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal); 109 110static int revocation_enabled = 0; 111SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, 112 &revocation_enabled, 0, "Revoke access to objects on relabel"); 113TUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled); 114 115static int max_compartments = MAC_MLS_MAX_COMPARTMENTS; 116SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD, 117 &max_compartments, 0, "Maximum compartments the policy supports"); 118 119static 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 123static uma_zone_t zone_mls; 124 125static __inline int 126mls_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 135static struct mac_mls * 136mls_alloc(int flag) 137{ 138 139 return (uma_zalloc(zone_mls, flag | M_ZERO)); 140} 141 142static void 143mls_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 152static int 153mls_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 161static int 162mac_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 214static int 215mac_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 224static int 225mac_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 241static int 242mac_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 252static int 253mac_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 263static int 264mac_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 275static int 276mac_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 293static int 294mac_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 319static int 320mac_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 391static void 392mac_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 412static void 413mac_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 425static void 426mac_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 437static void 438mac_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 448static void 449mac_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 */ 461static void 462mac_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 */ 472static void 473mac_mls_init_label(struct label *label) 474{ 475 476 SLOT_SET(label, mls_alloc(M_WAITOK)); 477} 478 479static int 480mac_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 490static void 491mac_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 */ 503static int 504mac_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 */ 552static int 553mac_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 584static int 585mac_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 600static int 601mac_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 */ 659static int 660mac_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 714static int 715mac_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 736static void 737mac_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 */ 747static void 748mac_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 772static void 773mac_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 782static void 783mac_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 795static void 796mac_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 806static void 807mac_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 818static void 819mac_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 830static void 831mac_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 843static int 844mac_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 883static void 884mac_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 895static int 896mac_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 918static int 919mac_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 */ 943static void 944mac_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 955static void 956mac_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 967static void 968mac_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 979static void 980mac_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 991static void 992mac_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 1003static void 1004mac_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 1015static void 1016mac_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 1027static void 1028mac_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 1039static void 1040mac_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 */ 1054static void 1055mac_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 1067static void 1068mac_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 1079static void 1080mac_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 1091static void 1092mac_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 */ 1106static void 1107mac_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 1119static void 1120mac_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 1131static void 1132mac_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 1148static void 1149mac_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 1160static void 1161mac_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 1173static void 1174mac_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 1185static void 1186mac_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 1197static void 1198mac_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 1208static void 1209mac_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 1220static void 1221mac_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 1232static void 1233mac_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 1245static void 1246mac_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 1257static int 1258mac_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 1269static void 1270mac_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 1281static void 1282mac_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 1289static void 1290mac_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 1301static void 1302mac_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 1312static void 1313mac_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 1322static void 1323mac_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 */ 1336static void 1337mac_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 1348static void 1349mac_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 1360static void 1361mac_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 */ 1374static void 1375mac_mls_cleanup_sysv_msgmsg(struct label *msglabel) 1376{ 1377 1378 bzero(SLOT(msglabel), sizeof(struct mac_mls)); 1379} 1380 1381static void 1382mac_mls_cleanup_sysv_msgqueue(struct label *msqlabel) 1383{ 1384 1385 bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 1386} 1387 1388static void 1389mac_mls_cleanup_sysv_sem(struct label *semalabel) 1390{ 1391 1392 bzero(SLOT(semalabel), sizeof(struct mac_mls)); 1393} 1394 1395static void 1396mac_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 */ 1405static int 1406mac_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 1422static int 1423mac_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 1484static int 1485mac_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 1502static int 1503mac_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 1528static int 1529mac_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 1543static int 1544mac_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 1558static int 1559mac_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 1576static int 1577mac_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 1594static int 1595mac_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 1612static int 1613mac_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 1630static int 1631mac_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 1648static int 1649mac_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 1679static int 1680mac_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 1717static int 1718mac_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 1735static int 1736mac_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 1758static int 1759mac_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 1779static int 1780mac_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 1811static int 1812mac_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 1829static int 1830mac_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 1847static int 1848mac_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 1860static int 1861mac_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 1878static int 1879mac_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 1896static int 1897mac_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 1947static int 1948mac_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 1965static int 1966mac_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 1983static int 1984mac_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 2001static int 2002mac_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 2019static int 2020mac_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 2039static int 2040mac_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 2059static int 2060mac_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 2079static int 2080mac_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 2094static int 2095mac_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 2145static int 2146mac_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 2163static int 2164mac_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 2182static int 2183mac_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 2201static int 2202mac_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 2220static int 2221mac_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 2238static int 2239mac_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 2256static int 2257mac_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 2274static int 2275mac_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 2298static int 2299mac_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 2316static int 2317mac_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 2334static int 2335mac_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 2366static int 2367mac_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 2384static int 2385mac_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 2403static int 2404mac_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 2426static int 2427mac_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 2445static int 2446mac_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 2463static int 2464mac_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 2491static int 2492mac_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 2516static int 2517mac_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 2534static int 2535mac_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 2552static int 2553mac_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 2570static int 2571mac_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 2588static int 2589mac_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 2639static int 2640mac_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 2663static int 2664mac_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 2689static int 2690mac_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 2707static int 2708mac_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 2725static int 2726mac_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 2746static int 2747mac_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 2764static int 2765mac_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 2782static int 2783mac_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 2800static int 2801mac_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 2818static int 2819mac_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 2836static int 2837mac_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 2854static void 2855mac_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 2865static 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 3045MAC_POLICY_SET(&mac_mls_ops, mac_mls, "TrustedBSD MAC/MLS", 3046 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_mls_slot); 3047