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