mac_mls.c revision 181217
1/*- 2 * Copyright (c) 1999-2002, 2007 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 181217 2008-08-02 22:30:51Z 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, compartmentslow, 403 sizeof(mm->mm_rangelow.mme_compartments)); 404 mm->mm_rangehigh.mme_type = typehigh; 405 mm->mm_rangehigh.mme_level = levelhigh; 406 if (compartmentshigh != NULL) 407 memcpy(mm->mm_rangehigh.mme_compartments, compartmentshigh, 408 sizeof(mm->mm_rangehigh.mme_compartments)); 409 mm->mm_flags |= MAC_MLS_FLAG_RANGE; 410} 411 412static void 413mls_set_effective(struct mac_mls *mm, u_short type, u_short level, 414 u_char *compartments) 415{ 416 417 mm->mm_effective.mme_type = type; 418 mm->mm_effective.mme_level = level; 419 if (compartments != NULL) 420 memcpy(mm->mm_effective.mme_compartments, compartments, 421 sizeof(mm->mm_effective.mme_compartments)); 422 mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 423} 424 425static void 426mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 427{ 428 429 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 430 ("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 438mls_copy_effective(struct mac_mls *labelfrom, struct mac_mls *labelto) 439{ 440 441 KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 442 ("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 449mls_copy(struct mac_mls *source, struct mac_mls *dest) 450{ 451 452 if (source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 453 mls_copy_effective(source, dest); 454 if (source->mm_flags & MAC_MLS_FLAG_RANGE) 455 mls_copy_range(source, dest); 456} 457 458/* 459 * Policy module operations. 460 */ 461static void 462mls_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 473mls_init_label(struct label *label) 474{ 475 476 SLOT_SET(label, mls_alloc(M_WAITOK)); 477} 478 479static int 480mls_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 491mls_destroy_label(struct label *label) 492{ 493 494 mls_free(SLOT(label)); 495 SLOT_SET(label, NULL); 496} 497 498/* 499 * mls_element_to_string() accepts an sbuf and MLS element. It converts the 500 * MLS element to a string and stores the result in the sbuf; if there isn't 501 * space in the sbuf, -1 is returned. 502 */ 503static int 504mls_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("mls_element_to_string: invalid type (%d)", 541 element->mme_type); 542 } 543} 544 545/* 546 * mls_to_string() converts an MLS label to a string, and places the results 547 * in the passed sbuf. It returns 0 on success, or EINVAL if there isn't 548 * room in the sbuf. Note: the sbuf will be modified even in a failure case, 549 * so the caller may need to revert the sbuf by restoring the offset if 550 * that's undesired. 551 */ 552static int 553mls_to_string(struct sbuf *sb, struct mac_mls *mm) 554{ 555 556 if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 557 if (mls_element_to_string(sb, &mm->mm_effective) == -1) 558 return (EINVAL); 559 } 560 561 if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 562 if (sbuf_putc(sb, '(') == -1) 563 return (EINVAL); 564 565 if (mls_element_to_string(sb, &mm->mm_rangelow) == -1) 566 return (EINVAL); 567 568 if (sbuf_putc(sb, '-') == -1) 569 return (EINVAL); 570 571 if (mls_element_to_string(sb, &mm->mm_rangehigh) == -1) 572 return (EINVAL); 573 574 if (sbuf_putc(sb, ')') == -1) 575 return (EINVAL); 576 } 577 578 return (0); 579} 580 581static int 582mls_externalize_label(struct label *label, char *element_name, 583 struct sbuf *sb, int *claimed) 584{ 585 struct mac_mls *mm; 586 587 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 588 return (0); 589 590 (*claimed)++; 591 592 mm = SLOT(label); 593 594 return (mls_to_string(sb, mm)); 595} 596 597static int 598mls_parse_element(struct mac_mls_element *element, char *string) 599{ 600 char *compartment, *end, *level; 601 int value; 602 603 if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { 604 element->mme_type = MAC_MLS_TYPE_HIGH; 605 element->mme_level = MAC_MLS_TYPE_UNDEF; 606 } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { 607 element->mme_type = MAC_MLS_TYPE_LOW; 608 element->mme_level = MAC_MLS_TYPE_UNDEF; 609 } else if (strcmp(string, "equal") == 0 || 610 strcmp(string, "eq") == 0) { 611 element->mme_type = MAC_MLS_TYPE_EQUAL; 612 element->mme_level = MAC_MLS_TYPE_UNDEF; 613 } else { 614 element->mme_type = MAC_MLS_TYPE_LEVEL; 615 616 /* 617 * Numeric level piece of the element. 618 */ 619 level = strsep(&string, ":"); 620 value = strtol(level, &end, 10); 621 if (end == level || *end != '\0') 622 return (EINVAL); 623 if (value < 0 || value > 65535) 624 return (EINVAL); 625 element->mme_level = value; 626 627 /* 628 * Optional compartment piece of the element. If none are 629 * included, we assume that the label has no compartments. 630 */ 631 if (string == NULL) 632 return (0); 633 if (*string == '\0') 634 return (0); 635 636 while ((compartment = strsep(&string, "+")) != NULL) { 637 value = strtol(compartment, &end, 10); 638 if (compartment == end || *end != '\0') 639 return (EINVAL); 640 if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS) 641 return (EINVAL); 642 MAC_MLS_BIT_SET(value, element->mme_compartments); 643 } 644 } 645 646 return (0); 647} 648 649/* 650 * Note: destructively consumes the string, make a local copy before calling 651 * if that's a problem. 652 */ 653static int 654mls_parse(struct mac_mls *mm, char *string) 655{ 656 char *rangehigh, *rangelow, *effective; 657 int error; 658 659 effective = strsep(&string, "("); 660 if (*effective == '\0') 661 effective = NULL; 662 663 if (string != NULL) { 664 rangelow = strsep(&string, "-"); 665 if (string == NULL) 666 return (EINVAL); 667 rangehigh = strsep(&string, ")"); 668 if (string == NULL) 669 return (EINVAL); 670 if (*string != '\0') 671 return (EINVAL); 672 } else { 673 rangelow = NULL; 674 rangehigh = NULL; 675 } 676 677 KASSERT((rangelow != NULL && rangehigh != NULL) || 678 (rangelow == NULL && rangehigh == NULL), 679 ("mls_parse: range mismatch")); 680 681 bzero(mm, sizeof(*mm)); 682 if (effective != NULL) { 683 error = mls_parse_element(&mm->mm_effective, effective); 684 if (error) 685 return (error); 686 mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 687 } 688 689 if (rangelow != NULL) { 690 error = mls_parse_element(&mm->mm_rangelow, rangelow); 691 if (error) 692 return (error); 693 error = mls_parse_element(&mm->mm_rangehigh, rangehigh); 694 if (error) 695 return (error); 696 mm->mm_flags |= MAC_MLS_FLAG_RANGE; 697 } 698 699 error = mls_valid(mm); 700 if (error) 701 return (error); 702 703 return (0); 704} 705 706static int 707mls_internalize_label(struct label *label, char *element_name, 708 char *element_data, int *claimed) 709{ 710 struct mac_mls *mm, mm_temp; 711 int error; 712 713 if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 714 return (0); 715 716 (*claimed)++; 717 718 error = mls_parse(&mm_temp, element_data); 719 if (error) 720 return (error); 721 722 mm = SLOT(label); 723 *mm = mm_temp; 724 725 return (0); 726} 727 728static void 729mls_copy_label(struct label *src, struct label *dest) 730{ 731 732 *SLOT(dest) = *SLOT(src); 733} 734 735/* 736 * Object-specific entry point implementations are sorted alphabetically by 737 * object type name and then by operation. 738 */ 739static int 740mls_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 741 struct ifnet *ifp, struct label *ifplabel) 742{ 743 struct mac_mls *a, *b; 744 745 if (!mls_enabled) 746 return (0); 747 748 a = SLOT(dlabel); 749 b = SLOT(ifplabel); 750 751 if (mls_equal_effective(a, b)) 752 return (0); 753 return (EACCES); 754} 755 756static void 757mls_bpfdesc_create(struct ucred *cred, struct bpf_d *d, struct label *dlabel) 758{ 759 struct mac_mls *source, *dest; 760 761 source = SLOT(cred->cr_label); 762 dest = SLOT(dlabel); 763 764 mls_copy_effective(source, dest); 765} 766 767static void 768mls_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 769 struct mbuf *m, struct label *mlabel) 770{ 771 struct mac_mls *source, *dest; 772 773 source = SLOT(dlabel); 774 dest = SLOT(mlabel); 775 776 mls_copy_effective(source, dest); 777} 778 779static int 780mls_cred_check_relabel(struct ucred *cred, struct label *newlabel) 781{ 782 struct mac_mls *subj, *new; 783 int error; 784 785 subj = SLOT(cred->cr_label); 786 new = SLOT(newlabel); 787 788 /* 789 * If there is an MLS label update for the credential, it may be an 790 * update of effective, range, or both. 791 */ 792 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 793 if (error) 794 return (error); 795 796 /* 797 * If the MLS label is to be changed, authorize as appropriate. 798 */ 799 if (new->mm_flags & MAC_MLS_FLAGS_BOTH) { 800 /* 801 * If the change request modifies both the MLS label 802 * effective and range, check that the new effective will be 803 * in the new range. 804 */ 805 if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) == 806 MAC_MLS_FLAGS_BOTH && !mls_effective_in_range(new, new)) 807 return (EINVAL); 808 809 /* 810 * To change the MLS effective label on a credential, the new 811 * effective label must be in the current range. 812 */ 813 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE && 814 !mls_effective_in_range(new, subj)) 815 return (EPERM); 816 817 /* 818 * To change the MLS range label on a credential, the new 819 * range must be in the current range. 820 */ 821 if (new->mm_flags & MAC_MLS_FLAG_RANGE && 822 !mls_range_in_range(new, subj)) 823 return (EPERM); 824 825 /* 826 * To have EQUAL in any component of the new credential MLS 827 * label, the subject must already have EQUAL in their label. 828 */ 829 if (mls_contains_equal(new)) { 830 error = mls_subject_privileged(subj); 831 if (error) 832 return (error); 833 } 834 } 835 836 return (0); 837} 838 839static int 840mls_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 841{ 842 struct mac_mls *subj, *obj; 843 844 if (!mls_enabled) 845 return (0); 846 847 subj = SLOT(cr1->cr_label); 848 obj = SLOT(cr2->cr_label); 849 850 /* XXX: range */ 851 if (!mls_dominate_effective(subj, obj)) 852 return (ESRCH); 853 854 return (0); 855} 856 857static void 858mls_cred_relabel(struct ucred *cred, struct label *newlabel) 859{ 860 struct mac_mls *source, *dest; 861 862 source = SLOT(newlabel); 863 dest = SLOT(cred->cr_label); 864 865 mls_copy(source, dest); 866} 867 868static void 869mls_devfs_create_device(struct ucred *cred, struct mount *mp, 870 struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 871{ 872 struct mac_mls *mm; 873 int mls_type; 874 875 mm = SLOT(delabel); 876 if (strcmp(dev->si_name, "null") == 0 || 877 strcmp(dev->si_name, "zero") == 0 || 878 strcmp(dev->si_name, "random") == 0 || 879 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 880 mls_type = MAC_MLS_TYPE_EQUAL; 881 else if (strcmp(dev->si_name, "kmem") == 0 || 882 strcmp(dev->si_name, "mem") == 0) 883 mls_type = MAC_MLS_TYPE_HIGH; 884 else if (ptys_equal && 885 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 886 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 887 mls_type = MAC_MLS_TYPE_EQUAL; 888 else 889 mls_type = MAC_MLS_TYPE_LOW; 890 mls_set_effective(mm, mls_type, 0, NULL); 891} 892 893static void 894mls_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 895 struct devfs_dirent *de, struct label *delabel) 896{ 897 struct mac_mls *mm; 898 899 mm = SLOT(delabel); 900 mls_set_effective(mm, MAC_MLS_TYPE_LOW, 0, NULL); 901} 902 903static void 904mls_devfs_create_symlink(struct ucred *cred, struct mount *mp, 905 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 906 struct label *delabel) 907{ 908 struct mac_mls *source, *dest; 909 910 source = SLOT(cred->cr_label); 911 dest = SLOT(delabel); 912 913 mls_copy_effective(source, dest); 914} 915 916static void 917mls_devfs_update(struct mount *mp, struct devfs_dirent *de, 918 struct label *delabel, struct vnode *vp, struct label *vplabel) 919{ 920 struct mac_mls *source, *dest; 921 922 source = SLOT(vplabel); 923 dest = SLOT(delabel); 924 925 mls_copy_effective(source, dest); 926} 927 928static void 929mls_devfs_vnode_associate(struct mount *mp, struct label *mplabel, 930 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 931 struct label *vplabel) 932{ 933 struct mac_mls *source, *dest; 934 935 source = SLOT(delabel); 936 dest = SLOT(vplabel); 937 938 mls_copy_effective(source, dest); 939} 940 941static int 942mls_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 943 struct label *ifplabel, struct label *newlabel) 944{ 945 struct mac_mls *subj, *new; 946 int error; 947 948 subj = SLOT(cred->cr_label); 949 new = SLOT(newlabel); 950 951 /* 952 * If there is an MLS label update for the interface, it may be an 953 * update of effective, range, or both. 954 */ 955 error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 956 if (error) 957 return (error); 958 959 /* 960 * Relabeling network interfaces requires MLS privilege. 961 */ 962 return (mls_subject_privileged(subj)); 963} 964 965static int 966mls_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 967 struct mbuf *m, struct label *mlabel) 968{ 969 struct mac_mls *p, *i; 970 971 if (!mls_enabled) 972 return (0); 973 974 p = SLOT(mlabel); 975 i = SLOT(ifplabel); 976 977 return (mls_effective_in_range(p, i) ? 0 : EACCES); 978} 979 980static void 981mls_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 982{ 983 struct mac_mls *dest; 984 int type; 985 986 dest = SLOT(ifplabel); 987 988 if (ifp->if_type == IFT_LOOP) 989 type = MAC_MLS_TYPE_EQUAL; 990 else 991 type = MAC_MLS_TYPE_LOW; 992 993 mls_set_effective(dest, type, 0, NULL); 994 mls_set_range(dest, type, 0, NULL, type, 0, NULL); 995} 996 997static void 998mls_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 999 struct mbuf *m, struct label *mlabel) 1000{ 1001 struct mac_mls *source, *dest; 1002 1003 source = SLOT(ifplabel); 1004 dest = SLOT(mlabel); 1005 1006 mls_copy_effective(source, dest); 1007} 1008 1009static void 1010mls_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1011 struct label *ifplabel, struct label *newlabel) 1012{ 1013 struct mac_mls *source, *dest; 1014 1015 source = SLOT(newlabel); 1016 dest = SLOT(ifplabel); 1017 1018 mls_copy(source, dest); 1019} 1020 1021static int 1022mls_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1023 struct mbuf *m, struct label *mlabel) 1024{ 1025 struct mac_mls *p, *i; 1026 1027 if (!mls_enabled) 1028 return (0); 1029 1030 p = SLOT(mlabel); 1031 i = SLOT(inplabel); 1032 1033 return (mls_equal_effective(p, i) ? 0 : EACCES); 1034} 1035 1036static void 1037mls_inpcb_create(struct socket *so, struct label *solabel, struct inpcb *inp, 1038 struct label *inplabel) 1039{ 1040 struct mac_mls *source, *dest; 1041 1042 source = SLOT(solabel); 1043 dest = SLOT(inplabel); 1044 1045 mls_copy_effective(source, dest); 1046} 1047 1048static void 1049mls_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1050 struct mbuf *m, struct label *mlabel) 1051{ 1052 struct mac_mls *source, *dest; 1053 1054 source = SLOT(inplabel); 1055 dest = SLOT(mlabel); 1056 1057 mls_copy_effective(source, dest); 1058} 1059 1060static void 1061mls_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1062 struct inpcb *inp, struct label *inplabel) 1063{ 1064 struct mac_mls *source, *dest; 1065 1066 source = SLOT(solabel); 1067 dest = SLOT(inplabel); 1068 1069 mls_copy(source, dest); 1070} 1071 1072static void 1073mls_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1074 struct label *qlabel) 1075{ 1076 struct mac_mls *source, *dest; 1077 1078 source = SLOT(mlabel); 1079 dest = SLOT(qlabel); 1080 1081 mls_copy_effective(source, dest); 1082} 1083 1084static int 1085mls_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1086 struct label *qlabel) 1087{ 1088 struct mac_mls *a, *b; 1089 1090 a = SLOT(qlabel); 1091 b = SLOT(mlabel); 1092 1093 return (mls_equal_effective(a, b)); 1094} 1095 1096static void 1097mls_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1098 struct label *mlabel) 1099{ 1100 struct mac_mls *source, *dest; 1101 1102 source = SLOT(qlabel); 1103 dest = SLOT(mlabel); 1104 1105 /* Just use the head, since we require them all to match. */ 1106 mls_copy_effective(source, dest); 1107} 1108 1109static void 1110mls_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1111 struct label *qlabel) 1112{ 1113 1114 /* NOOP: we only accept matching labels, so no need to update */ 1115} 1116 1117static int 1118mls_mount_check_stat(struct ucred *cred, struct mount *mp, 1119 struct label *mntlabel) 1120{ 1121 struct mac_mls *subj, *obj; 1122 1123 if (!mls_enabled) 1124 return (0); 1125 1126 subj = SLOT(cred->cr_label); 1127 obj = SLOT(mntlabel); 1128 1129 if (!mls_dominate_effective(subj, obj)) 1130 return (EACCES); 1131 1132 return (0); 1133} 1134 1135static void 1136mls_mount_create(struct ucred *cred, struct mount *mp, struct label *mplabel) 1137{ 1138 struct mac_mls *source, *dest; 1139 1140 source = SLOT(cred->cr_label); 1141 dest = SLOT(mplabel); 1142 1143 mls_copy_effective(source, dest); 1144} 1145 1146static void 1147mls_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel, 1148 struct mbuf *m, struct label *mlabel) 1149{ 1150 struct mac_mls *dest; 1151 1152 dest = SLOT(mlabel); 1153 1154 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1155} 1156 1157static void 1158mls_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1159 struct mbuf *m, struct label *mlabel) 1160{ 1161 struct mac_mls *dest; 1162 1163 dest = SLOT(mlabel); 1164 1165 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1166} 1167 1168static void 1169mls_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1170 struct mbuf *msend, struct label *msendlabel) 1171{ 1172 struct mac_mls *source, *dest; 1173 1174 source = SLOT(mrecvlabel); 1175 dest = SLOT(msendlabel); 1176 1177 mls_copy_effective(source, dest); 1178} 1179 1180static void 1181mls_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1182{ 1183 struct mac_mls *dest; 1184 1185 dest = SLOT(mlabel); 1186 1187 /* XXX: where is the label for the firewall really comming from? */ 1188 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1189} 1190 1191static void 1192mls_netinet_fragment(struct mbuf *m, struct label *mlabel, struct mbuf *frag, 1193 struct label *fraglabel) 1194{ 1195 struct mac_mls *source, *dest; 1196 1197 source = SLOT(mlabel); 1198 dest = SLOT(fraglabel); 1199 1200 mls_copy_effective(source, dest); 1201} 1202 1203static void 1204mls_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1205 struct mbuf *msend, struct label *msendlabel) 1206{ 1207 struct mac_mls *source, *dest; 1208 1209 source = SLOT(mrecvlabel); 1210 dest = SLOT(msendlabel); 1211 1212 mls_copy_effective(source, dest); 1213} 1214 1215static void 1216mls_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1217 struct mbuf *m, struct label *mlabel) 1218{ 1219 struct mac_mls *dest; 1220 1221 dest = SLOT(mlabel); 1222 1223 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1224} 1225 1226static void 1227mls_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1228 struct mbuf *m, struct label *mlabel) 1229{ 1230 struct mac_mls *dest; 1231 1232 dest = SLOT(mlabel); 1233 1234 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1235} 1236 1237static int 1238mls_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1239 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1240{ 1241 1242 if (!mls_enabled) 1243 return (0); 1244 1245 /* XXX: This will be implemented soon... */ 1246 1247 return (0); 1248} 1249 1250static int 1251mls_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1252 struct label *pplabel) 1253{ 1254 struct mac_mls *subj, *obj; 1255 1256 if (!mls_enabled) 1257 return (0); 1258 1259 subj = SLOT(cred->cr_label); 1260 obj = SLOT(pplabel); 1261 1262 if (!mls_dominate_effective(subj, obj)) 1263 return (EACCES); 1264 1265 return (0); 1266} 1267 1268static int 1269mls_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1270 struct label *pplabel) 1271{ 1272 struct mac_mls *subj, *obj; 1273 1274 if (!mls_enabled) 1275 return (0); 1276 1277 subj = SLOT(cred->cr_label); 1278 obj = SLOT(pplabel); 1279 1280 if (!mls_dominate_effective(subj, obj)) 1281 return (EACCES); 1282 1283 return (0); 1284} 1285 1286static int 1287mls_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1288 struct label *pplabel, struct label *newlabel) 1289{ 1290 struct mac_mls *subj, *obj, *new; 1291 int error; 1292 1293 new = SLOT(newlabel); 1294 subj = SLOT(cred->cr_label); 1295 obj = SLOT(pplabel); 1296 1297 /* 1298 * If there is an MLS label update for a pipe, it must be a effective 1299 * update. 1300 */ 1301 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1302 if (error) 1303 return (error); 1304 1305 /* 1306 * To perform a relabel of a pipe (MLS label or not), MLS must 1307 * authorize the relabel. 1308 */ 1309 if (!mls_effective_in_range(obj, subj)) 1310 return (EPERM); 1311 1312 /* 1313 * If the MLS label is to be changed, authorize as appropriate. 1314 */ 1315 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1316 /* 1317 * To change the MLS label on a pipe, the new pipe label must 1318 * be in the subject range. 1319 */ 1320 if (!mls_effective_in_range(new, subj)) 1321 return (EPERM); 1322 1323 /* 1324 * To change the MLS label on a pipe to be EQUAL, the subject 1325 * must have appropriate privilege. 1326 */ 1327 if (mls_contains_equal(new)) { 1328 error = mls_subject_privileged(subj); 1329 if (error) 1330 return (error); 1331 } 1332 } 1333 1334 return (0); 1335} 1336 1337static int 1338mls_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 1339 struct label *pplabel) 1340{ 1341 struct mac_mls *subj, *obj; 1342 1343 if (!mls_enabled) 1344 return (0); 1345 1346 subj = SLOT(cred->cr_label); 1347 obj = SLOT(pplabel); 1348 1349 if (!mls_dominate_effective(subj, obj)) 1350 return (EACCES); 1351 1352 return (0); 1353} 1354 1355static int 1356mls_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1357 struct label *pplabel) 1358{ 1359 struct mac_mls *subj, *obj; 1360 1361 if (!mls_enabled) 1362 return (0); 1363 1364 subj = SLOT(cred->cr_label); 1365 obj = SLOT(pplabel); 1366 1367 if (!mls_dominate_effective(obj, subj)) 1368 return (EACCES); 1369 1370 return (0); 1371} 1372 1373static void 1374mls_pipe_create(struct ucred *cred, struct pipepair *pp, 1375 struct label *pplabel) 1376{ 1377 struct mac_mls *source, *dest; 1378 1379 source = SLOT(cred->cr_label); 1380 dest = SLOT(pplabel); 1381 1382 mls_copy_effective(source, dest); 1383} 1384 1385static void 1386mls_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1387 struct label *pplabel, struct label *newlabel) 1388{ 1389 struct mac_mls *source, *dest; 1390 1391 source = SLOT(newlabel); 1392 dest = SLOT(pplabel); 1393 1394 mls_copy(source, dest); 1395} 1396 1397static int 1398mls_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks, 1399 struct label *kslabel) 1400{ 1401 struct mac_mls *subj, *obj; 1402 1403 if (!mls_enabled) 1404 return (0); 1405 1406 subj = SLOT(cred->cr_label); 1407 obj = SLOT(kslabel); 1408 1409 if (!mls_dominate_effective(obj, subj)) 1410 return (EACCES); 1411 1412 return (0); 1413} 1414 1415static int 1416mls_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred, 1417 struct ksem *ks, struct label *kslabel) 1418{ 1419 struct mac_mls *subj, *obj; 1420 1421 if (!mls_enabled) 1422 return (0); 1423 1424 subj = SLOT(active_cred->cr_label); 1425 obj = SLOT(kslabel); 1426 1427 if (!mls_dominate_effective(subj, obj)) 1428 return (EACCES); 1429 1430 return (0); 1431} 1432 1433static int 1434mls_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred, 1435 struct ksem *ks, struct label *kslabel) 1436{ 1437 struct mac_mls *subj, *obj; 1438 1439 if (!mls_enabled) 1440 return (0); 1441 1442 subj = SLOT(active_cred->cr_label); 1443 obj = SLOT(kslabel); 1444 1445 if (!mls_dominate_effective(obj, subj)) 1446 return (EACCES); 1447 1448 return (0); 1449} 1450 1451static void 1452mls_posixsem_create(struct ucred *cred, struct ksem *ks, 1453 struct label *kslabel) 1454{ 1455 struct mac_mls *source, *dest; 1456 1457 source = SLOT(cred->cr_label); 1458 dest = SLOT(kslabel); 1459 1460 mls_copy_effective(source, dest); 1461} 1462 1463static void 1464mls_proc_associate_nfsd(struct ucred *cred) 1465{ 1466 struct mac_mls *label; 1467 1468 label = SLOT(cred->cr_label); 1469 mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL); 1470 mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1471 NULL); 1472} 1473 1474static int 1475mls_proc_check_debug(struct ucred *cred, struct proc *p) 1476{ 1477 struct mac_mls *subj, *obj; 1478 1479 if (!mls_enabled) 1480 return (0); 1481 1482 subj = SLOT(cred->cr_label); 1483 obj = SLOT(p->p_ucred->cr_label); 1484 1485 /* XXX: range checks */ 1486 if (!mls_dominate_effective(subj, obj)) 1487 return (ESRCH); 1488 if (!mls_dominate_effective(obj, subj)) 1489 return (EACCES); 1490 1491 return (0); 1492} 1493 1494static int 1495mls_proc_check_sched(struct ucred *cred, struct proc *p) 1496{ 1497 struct mac_mls *subj, *obj; 1498 1499 if (!mls_enabled) 1500 return (0); 1501 1502 subj = SLOT(cred->cr_label); 1503 obj = SLOT(p->p_ucred->cr_label); 1504 1505 /* XXX: range checks */ 1506 if (!mls_dominate_effective(subj, obj)) 1507 return (ESRCH); 1508 if (!mls_dominate_effective(obj, subj)) 1509 return (EACCES); 1510 1511 return (0); 1512} 1513 1514static int 1515mls_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1516{ 1517 struct mac_mls *subj, *obj; 1518 1519 if (!mls_enabled) 1520 return (0); 1521 1522 subj = SLOT(cred->cr_label); 1523 obj = SLOT(p->p_ucred->cr_label); 1524 1525 /* XXX: range checks */ 1526 if (!mls_dominate_effective(subj, obj)) 1527 return (ESRCH); 1528 if (!mls_dominate_effective(obj, subj)) 1529 return (EACCES); 1530 1531 return (0); 1532} 1533 1534static void 1535mls_proc_create_init(struct ucred *cred) 1536{ 1537 struct mac_mls *dest; 1538 1539 dest = SLOT(cred->cr_label); 1540 1541 mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL); 1542 mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1543 NULL); 1544} 1545 1546static void 1547mls_proc_create_swapper(struct ucred *cred) 1548{ 1549 struct mac_mls *dest; 1550 1551 dest = SLOT(cred->cr_label); 1552 1553 mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1554 mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 1555 NULL); 1556} 1557 1558static int 1559mls_socket_check_deliver(struct socket *so, struct label *solabel, 1560 struct mbuf *m, struct label *mlabel) 1561{ 1562 struct mac_mls *p, *s; 1563 1564 if (!mls_enabled) 1565 return (0); 1566 1567 p = SLOT(mlabel); 1568 s = SLOT(solabel); 1569 1570 return (mls_equal_effective(p, s) ? 0 : EACCES); 1571} 1572 1573static int 1574mls_socket_check_relabel(struct ucred *cred, struct socket *so, 1575 struct label *solabel, struct label *newlabel) 1576{ 1577 struct mac_mls *subj, *obj, *new; 1578 int error; 1579 1580 new = SLOT(newlabel); 1581 subj = SLOT(cred->cr_label); 1582 obj = SLOT(solabel); 1583 1584 /* 1585 * If there is an MLS label update for the socket, it may be an 1586 * update of effective. 1587 */ 1588 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1589 if (error) 1590 return (error); 1591 1592 /* 1593 * To relabel a socket, the old socket effective must be in the 1594 * subject range. 1595 */ 1596 if (!mls_effective_in_range(obj, subj)) 1597 return (EPERM); 1598 1599 /* 1600 * If the MLS label is to be changed, authorize as appropriate. 1601 */ 1602 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1603 /* 1604 * To relabel a socket, the new socket effective must be in 1605 * the subject range. 1606 */ 1607 if (!mls_effective_in_range(new, subj)) 1608 return (EPERM); 1609 1610 /* 1611 * To change the MLS label on the socket to contain EQUAL, 1612 * the subject must have appropriate privilege. 1613 */ 1614 if (mls_contains_equal(new)) { 1615 error = mls_subject_privileged(subj); 1616 if (error) 1617 return (error); 1618 } 1619 } 1620 1621 return (0); 1622} 1623 1624static int 1625mls_socket_check_visible(struct ucred *cred, struct socket *so, 1626 struct label *solabel) 1627{ 1628 struct mac_mls *subj, *obj; 1629 1630 if (!mls_enabled) 1631 return (0); 1632 1633 subj = SLOT(cred->cr_label); 1634 obj = SLOT(solabel); 1635 1636 if (!mls_dominate_effective(subj, obj)) 1637 return (ENOENT); 1638 1639 return (0); 1640} 1641 1642static void 1643mls_socket_create(struct ucred *cred, struct socket *so, 1644 struct label *solabel) 1645{ 1646 struct mac_mls *source, *dest; 1647 1648 source = SLOT(cred->cr_label); 1649 dest = SLOT(solabel); 1650 1651 mls_copy_effective(source, dest); 1652} 1653 1654static void 1655mls_socket_create_mbuf(struct socket *so, struct label *solabel, 1656 struct mbuf *m, struct label *mlabel) 1657{ 1658 struct mac_mls *source, *dest; 1659 1660 source = SLOT(solabel); 1661 dest = SLOT(mlabel); 1662 1663 mls_copy_effective(source, dest); 1664} 1665 1666static void 1667mls_socket_newconn(struct socket *oldso, struct label *oldsolabel, 1668 struct socket *newso, struct label *newsolabel) 1669{ 1670 struct mac_mls *source, *dest; 1671 1672 source = SLOT(oldsolabel); 1673 dest = SLOT(newsolabel); 1674 1675 mls_copy_effective(source, dest); 1676} 1677 1678static void 1679mls_socket_relabel(struct ucred *cred, struct socket *so, 1680 struct label *solabel, struct label *newlabel) 1681{ 1682 struct mac_mls *source, *dest; 1683 1684 source = SLOT(newlabel); 1685 dest = SLOT(solabel); 1686 1687 mls_copy(source, dest); 1688} 1689 1690static void 1691mls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 1692 struct socket *so, struct label *sopeerlabel) 1693{ 1694 struct mac_mls *source, *dest; 1695 1696 source = SLOT(mlabel); 1697 dest = SLOT(sopeerlabel); 1698 1699 mls_copy_effective(source, dest); 1700} 1701 1702static void 1703mls_socketpeer_set_from_socket(struct socket *oldso, 1704 struct label *oldsolabel, struct socket *newso, 1705 struct label *newsopeerlabel) 1706{ 1707 struct mac_mls *source, *dest; 1708 1709 source = SLOT(oldsolabel); 1710 dest = SLOT(newsopeerlabel); 1711 1712 mls_copy_effective(source, dest); 1713} 1714 1715static void 1716mls_syncache_create(struct label *label, struct inpcb *inp) 1717{ 1718 struct mac_mls *source, *dest; 1719 1720 source = SLOT(inp->inp_label); 1721 dest = SLOT(label); 1722 1723 mls_copy_effective(source, dest); 1724} 1725 1726static void 1727mls_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 1728 struct label *mlabel) 1729{ 1730 struct mac_mls *source, *dest; 1731 1732 source = SLOT(sc_label); 1733 dest = SLOT(mlabel); 1734 1735 mls_copy_effective(source, dest); 1736} 1737 1738static int 1739mls_system_check_acct(struct ucred *cred, struct vnode *vp, 1740 struct label *vplabel) 1741{ 1742 struct mac_mls *subj, *obj; 1743 1744 if (!mls_enabled) 1745 return (0); 1746 1747 subj = SLOT(cred->cr_label); 1748 obj = SLOT(vplabel); 1749 1750 if (!mls_dominate_effective(obj, subj) || 1751 !mls_dominate_effective(subj, obj)) 1752 return (EACCES); 1753 1754 return (0); 1755} 1756 1757static int 1758mls_system_check_auditctl(struct ucred *cred, struct vnode *vp, 1759 struct label *vplabel) 1760{ 1761 struct mac_mls *subj, *obj; 1762 1763 if (!mls_enabled) 1764 return (0); 1765 1766 subj = SLOT(cred->cr_label); 1767 obj = SLOT(vplabel); 1768 1769 if (!mls_dominate_effective(obj, subj) || 1770 !mls_dominate_effective(subj, obj)) 1771 return (EACCES); 1772 1773 return (0); 1774} 1775 1776static int 1777mls_system_check_swapon(struct ucred *cred, struct vnode *vp, 1778 struct label *vplabel) 1779{ 1780 struct mac_mls *subj, *obj; 1781 1782 if (!mls_enabled) 1783 return (0); 1784 1785 subj = SLOT(cred->cr_label); 1786 obj = SLOT(vplabel); 1787 1788 if (!mls_dominate_effective(obj, subj) || 1789 !mls_dominate_effective(subj, obj)) 1790 return (EACCES); 1791 1792 return (0); 1793} 1794 1795static void 1796mls_sysvmsg_cleanup(struct label *msglabel) 1797{ 1798 1799 bzero(SLOT(msglabel), sizeof(struct mac_mls)); 1800} 1801 1802static void 1803mls_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1804 struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1805{ 1806 struct mac_mls *source, *dest; 1807 1808 /* Ignore the msgq label. */ 1809 source = SLOT(cred->cr_label); 1810 dest = SLOT(msglabel); 1811 1812 mls_copy_effective(source, dest); 1813} 1814 1815static int 1816mls_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 1817 struct label *msglabel) 1818{ 1819 struct mac_mls *subj, *obj; 1820 1821 if (!mls_enabled) 1822 return (0); 1823 1824 subj = SLOT(cred->cr_label); 1825 obj = SLOT(msglabel); 1826 1827 if (!mls_dominate_effective(subj, obj)) 1828 return (EACCES); 1829 1830 return (0); 1831} 1832 1833static int 1834mls_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 1835 struct label *msglabel) 1836{ 1837 struct mac_mls *subj, *obj; 1838 1839 if (!mls_enabled) 1840 return (0); 1841 1842 subj = SLOT(cred->cr_label); 1843 obj = SLOT(msglabel); 1844 1845 if (!mls_dominate_effective(obj, subj)) 1846 return (EACCES); 1847 1848 return (0); 1849} 1850 1851static int 1852mls_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1853 struct label *msqklabel) 1854{ 1855 struct mac_mls *subj, *obj; 1856 1857 if (!mls_enabled) 1858 return (0); 1859 1860 subj = SLOT(cred->cr_label); 1861 obj = SLOT(msqklabel); 1862 1863 if (!mls_dominate_effective(subj, obj)) 1864 return (EACCES); 1865 1866 return (0); 1867} 1868 1869static int 1870mls_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1871 struct label *msqklabel) 1872{ 1873 struct mac_mls *subj, *obj; 1874 1875 if (!mls_enabled) 1876 return (0); 1877 1878 subj = SLOT(cred->cr_label); 1879 obj = SLOT(msqklabel); 1880 1881 if (!mls_dominate_effective(obj, subj)) 1882 return (EACCES); 1883 1884 return (0); 1885} 1886 1887static int 1888mls_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1889 struct label *msqklabel) 1890{ 1891 struct mac_mls *subj, *obj; 1892 1893 if (!mls_enabled) 1894 return (0); 1895 1896 subj = SLOT(cred->cr_label); 1897 obj = SLOT(msqklabel); 1898 1899 if (!mls_dominate_effective(subj, obj)) 1900 return (EACCES); 1901 1902 return (0); 1903} 1904 1905static int 1906mls_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1907 struct label *msqklabel, int cmd) 1908{ 1909 struct mac_mls *subj, *obj; 1910 1911 if (!mls_enabled) 1912 return (0); 1913 1914 subj = SLOT(cred->cr_label); 1915 obj = SLOT(msqklabel); 1916 1917 switch(cmd) { 1918 case IPC_RMID: 1919 case IPC_SET: 1920 if (!mls_dominate_effective(obj, subj)) 1921 return (EACCES); 1922 break; 1923 1924 case IPC_STAT: 1925 if (!mls_dominate_effective(subj, obj)) 1926 return (EACCES); 1927 break; 1928 1929 default: 1930 return (EACCES); 1931 } 1932 1933 return (0); 1934} 1935 1936static void 1937mls_sysvmsq_cleanup(struct label *msqlabel) 1938{ 1939 1940 bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 1941} 1942 1943static void 1944mls_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1945 struct label *msqlabel) 1946{ 1947 struct mac_mls *source, *dest; 1948 1949 source = SLOT(cred->cr_label); 1950 dest = SLOT(msqlabel); 1951 1952 mls_copy_effective(source, dest); 1953} 1954 1955static int 1956mls_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1957 struct label *semaklabel, int cmd) 1958{ 1959 struct mac_mls *subj, *obj; 1960 1961 if (!mls_enabled) 1962 return (0); 1963 1964 subj = SLOT(cred->cr_label); 1965 obj = SLOT(semaklabel); 1966 1967 switch(cmd) { 1968 case IPC_RMID: 1969 case IPC_SET: 1970 case SETVAL: 1971 case SETALL: 1972 if (!mls_dominate_effective(obj, subj)) 1973 return (EACCES); 1974 break; 1975 1976 case IPC_STAT: 1977 case GETVAL: 1978 case GETPID: 1979 case GETNCNT: 1980 case GETZCNT: 1981 case GETALL: 1982 if (!mls_dominate_effective(subj, obj)) 1983 return (EACCES); 1984 break; 1985 1986 default: 1987 return (EACCES); 1988 } 1989 1990 return (0); 1991} 1992 1993static int 1994mls_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 1995 struct label *semaklabel) 1996{ 1997 struct mac_mls *subj, *obj; 1998 1999 if (!mls_enabled) 2000 return (0); 2001 2002 subj = SLOT(cred->cr_label); 2003 obj = SLOT(semaklabel); 2004 2005 if (!mls_dominate_effective(subj, obj)) 2006 return (EACCES); 2007 2008 return (0); 2009} 2010 2011static int 2012mls_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2013 struct label *semaklabel, size_t accesstype) 2014{ 2015 struct mac_mls *subj, *obj; 2016 2017 if (!mls_enabled) 2018 return (0); 2019 2020 subj = SLOT(cred->cr_label); 2021 obj = SLOT(semaklabel); 2022 2023 if( accesstype & SEM_R ) 2024 if (!mls_dominate_effective(subj, obj)) 2025 return (EACCES); 2026 2027 if( accesstype & SEM_A ) 2028 if (!mls_dominate_effective(obj, subj)) 2029 return (EACCES); 2030 2031 return (0); 2032} 2033 2034static void 2035mls_sysvsem_cleanup(struct label *semalabel) 2036{ 2037 2038 bzero(SLOT(semalabel), sizeof(struct mac_mls)); 2039} 2040 2041static void 2042mls_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2043 struct label *semalabel) 2044{ 2045 struct mac_mls *source, *dest; 2046 2047 source = SLOT(cred->cr_label); 2048 dest = SLOT(semalabel); 2049 2050 mls_copy_effective(source, dest); 2051} 2052 2053static int 2054mls_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2055 struct label *shmseglabel, int shmflg) 2056{ 2057 struct mac_mls *subj, *obj; 2058 2059 if (!mls_enabled) 2060 return (0); 2061 2062 subj = SLOT(cred->cr_label); 2063 obj = SLOT(shmseglabel); 2064 2065 if (!mls_dominate_effective(subj, obj)) 2066 return (EACCES); 2067 if ((shmflg & SHM_RDONLY) == 0) { 2068 if (!mls_dominate_effective(obj, subj)) 2069 return (EACCES); 2070 } 2071 2072 return (0); 2073} 2074 2075static int 2076mls_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2077 struct label *shmseglabel, int cmd) 2078{ 2079 struct mac_mls *subj, *obj; 2080 2081 if (!mls_enabled) 2082 return (0); 2083 2084 subj = SLOT(cred->cr_label); 2085 obj = SLOT(shmseglabel); 2086 2087 switch(cmd) { 2088 case IPC_RMID: 2089 case IPC_SET: 2090 if (!mls_dominate_effective(obj, subj)) 2091 return (EACCES); 2092 break; 2093 2094 case IPC_STAT: 2095 case SHM_STAT: 2096 if (!mls_dominate_effective(subj, obj)) 2097 return (EACCES); 2098 break; 2099 2100 default: 2101 return (EACCES); 2102 } 2103 2104 return (0); 2105} 2106 2107static int 2108mls_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2109 struct label *shmseglabel, int shmflg) 2110{ 2111 struct mac_mls *subj, *obj; 2112 2113 if (!mls_enabled) 2114 return (0); 2115 2116 subj = SLOT(cred->cr_label); 2117 obj = SLOT(shmseglabel); 2118 2119 if (!mls_dominate_effective(obj, subj)) 2120 return (EACCES); 2121 2122 return (0); 2123} 2124 2125static void 2126mls_sysvshm_cleanup(struct label *shmlabel) 2127{ 2128 2129 bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 2130} 2131 2132static void 2133mls_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2134 struct label *shmlabel) 2135{ 2136 struct mac_mls *source, *dest; 2137 2138 source = SLOT(cred->cr_label); 2139 dest = SLOT(shmlabel); 2140 2141 mls_copy_effective(source, dest); 2142} 2143 2144static int 2145mls_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2146 struct vnode *vp, struct label *vplabel) 2147{ 2148 struct mac_mls mm_temp, *source, *dest; 2149 int buflen, error; 2150 2151 source = SLOT(mplabel); 2152 dest = SLOT(vplabel); 2153 2154 buflen = sizeof(mm_temp); 2155 bzero(&mm_temp, buflen); 2156 2157 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2158 MAC_MLS_EXTATTR_NAME, &buflen, (char *) &mm_temp, curthread); 2159 if (error == ENOATTR || error == EOPNOTSUPP) { 2160 /* Fall back to the mntlabel. */ 2161 mls_copy_effective(source, dest); 2162 return (0); 2163 } else if (error) 2164 return (error); 2165 2166 if (buflen != sizeof(mm_temp)) { 2167 printf("mls_vnode_associate_extattr: bad size %d\n", buflen); 2168 return (EPERM); 2169 } 2170 if (mls_valid(&mm_temp) != 0) { 2171 printf("mls_vnode_associate_extattr: invalid\n"); 2172 return (EPERM); 2173 } 2174 if ((mm_temp.mm_flags & MAC_MLS_FLAGS_BOTH) != 2175 MAC_MLS_FLAG_EFFECTIVE) { 2176 printf("mls_associated_vnode_extattr: not effective\n"); 2177 return (EPERM); 2178 } 2179 2180 mls_copy_effective(&mm_temp, dest); 2181 return (0); 2182} 2183 2184static void 2185mls_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2186 struct vnode *vp, struct label *vplabel) 2187{ 2188 struct mac_mls *source, *dest; 2189 2190 source = SLOT(mplabel); 2191 dest = SLOT(vplabel); 2192 2193 mls_copy_effective(source, dest); 2194} 2195 2196static int 2197mls_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2198 struct label *dvplabel) 2199{ 2200 struct mac_mls *subj, *obj; 2201 2202 if (!mls_enabled) 2203 return (0); 2204 2205 subj = SLOT(cred->cr_label); 2206 obj = SLOT(dvplabel); 2207 2208 if (!mls_dominate_effective(subj, obj)) 2209 return (EACCES); 2210 2211 return (0); 2212} 2213 2214static int 2215mls_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2216 struct label *dvplabel) 2217{ 2218 struct mac_mls *subj, *obj; 2219 2220 if (!mls_enabled) 2221 return (0); 2222 2223 subj = SLOT(cred->cr_label); 2224 obj = SLOT(dvplabel); 2225 2226 if (!mls_dominate_effective(subj, obj)) 2227 return (EACCES); 2228 2229 return (0); 2230} 2231 2232static int 2233mls_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2234 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2235{ 2236 struct mac_mls *subj, *obj; 2237 2238 if (!mls_enabled) 2239 return (0); 2240 2241 subj = SLOT(cred->cr_label); 2242 obj = SLOT(dvplabel); 2243 2244 if (!mls_dominate_effective(obj, subj)) 2245 return (EACCES); 2246 2247 return (0); 2248} 2249 2250static int 2251mls_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2252 struct label *vplabel, acl_type_t type) 2253{ 2254 struct mac_mls *subj, *obj; 2255 2256 if (!mls_enabled) 2257 return (0); 2258 2259 subj = SLOT(cred->cr_label); 2260 obj = SLOT(vplabel); 2261 2262 if (!mls_dominate_effective(obj, subj)) 2263 return (EACCES); 2264 2265 return (0); 2266} 2267 2268static int 2269mls_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2270 struct label *vplabel, int attrnamespace, const char *name) 2271{ 2272 struct mac_mls *subj, *obj; 2273 2274 if (!mls_enabled) 2275 return (0); 2276 2277 subj = SLOT(cred->cr_label); 2278 obj = SLOT(vplabel); 2279 2280 if (!mls_dominate_effective(obj, subj)) 2281 return (EACCES); 2282 2283 return (0); 2284} 2285 2286static int 2287mls_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2288 struct label *vplabel, struct image_params *imgp, 2289 struct label *execlabel) 2290{ 2291 struct mac_mls *subj, *obj, *exec; 2292 int error; 2293 2294 if (execlabel != NULL) { 2295 /* 2296 * We currently don't permit labels to be changed at 2297 * exec-time as part of MLS, so disallow non-NULL MLS label 2298 * elements in the execlabel. 2299 */ 2300 exec = SLOT(execlabel); 2301 error = mls_atmostflags(exec, 0); 2302 if (error) 2303 return (error); 2304 } 2305 2306 if (!mls_enabled) 2307 return (0); 2308 2309 subj = SLOT(cred->cr_label); 2310 obj = SLOT(vplabel); 2311 2312 if (!mls_dominate_effective(subj, obj)) 2313 return (EACCES); 2314 2315 return (0); 2316} 2317 2318static int 2319mls_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2320 struct label *vplabel, acl_type_t type) 2321{ 2322 struct mac_mls *subj, *obj; 2323 2324 if (!mls_enabled) 2325 return (0); 2326 2327 subj = SLOT(cred->cr_label); 2328 obj = SLOT(vplabel); 2329 2330 if (!mls_dominate_effective(subj, obj)) 2331 return (EACCES); 2332 2333 return (0); 2334} 2335 2336static int 2337mls_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 2338 struct label *vplabel, int attrnamespace, const char *name, 2339 struct uio *uio) 2340{ 2341 struct mac_mls *subj, *obj; 2342 2343 if (!mls_enabled) 2344 return (0); 2345 2346 subj = SLOT(cred->cr_label); 2347 obj = SLOT(vplabel); 2348 2349 if (!mls_dominate_effective(subj, obj)) 2350 return (EACCES); 2351 2352 return (0); 2353} 2354 2355static int 2356mls_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2357 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2358 struct componentname *cnp) 2359{ 2360 struct mac_mls *subj, *obj; 2361 2362 if (!mls_enabled) 2363 return (0); 2364 2365 subj = SLOT(cred->cr_label); 2366 obj = SLOT(dvplabel); 2367 2368 if (!mls_dominate_effective(obj, subj)) 2369 return (EACCES); 2370 2371 obj = SLOT(vplabel); 2372 if (!mls_dominate_effective(obj, subj)) 2373 return (EACCES); 2374 2375 return (0); 2376} 2377 2378static int 2379mls_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 2380 struct label *vplabel, int attrnamespace) 2381{ 2382 2383 struct mac_mls *subj, *obj; 2384 2385 if (!mls_enabled) 2386 return (0); 2387 2388 subj = SLOT(cred->cr_label); 2389 obj = SLOT(vplabel); 2390 2391 if (!mls_dominate_effective(subj, obj)) 2392 return (EACCES); 2393 2394 return (0); 2395} 2396 2397static int 2398mls_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 2399 struct label *dvplabel, struct componentname *cnp) 2400{ 2401 struct mac_mls *subj, *obj; 2402 2403 if (!mls_enabled) 2404 return (0); 2405 2406 subj = SLOT(cred->cr_label); 2407 obj = SLOT(dvplabel); 2408 2409 if (!mls_dominate_effective(subj, obj)) 2410 return (EACCES); 2411 2412 return (0); 2413} 2414 2415static int 2416mls_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2417 struct label *vplabel, int prot, int flags) 2418{ 2419 struct mac_mls *subj, *obj; 2420 2421 /* 2422 * Rely on the use of open()-time protections to handle 2423 * non-revocation cases. 2424 */ 2425 if (!mls_enabled || !revocation_enabled) 2426 return (0); 2427 2428 subj = SLOT(cred->cr_label); 2429 obj = SLOT(vplabel); 2430 2431 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2432 if (!mls_dominate_effective(subj, obj)) 2433 return (EACCES); 2434 } 2435 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2436 if (!mls_dominate_effective(obj, subj)) 2437 return (EACCES); 2438 } 2439 2440 return (0); 2441} 2442 2443static int 2444mls_vnode_check_open(struct ucred *cred, struct vnode *vp, 2445 struct label *vplabel, int acc_mode) 2446{ 2447 struct mac_mls *subj, *obj; 2448 2449 if (!mls_enabled) 2450 return (0); 2451 2452 subj = SLOT(cred->cr_label); 2453 obj = SLOT(vplabel); 2454 2455 /* XXX privilege override for admin? */ 2456 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2457 if (!mls_dominate_effective(subj, obj)) 2458 return (EACCES); 2459 } 2460 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2461 if (!mls_dominate_effective(obj, subj)) 2462 return (EACCES); 2463 } 2464 2465 return (0); 2466} 2467 2468static int 2469mls_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 2470 struct vnode *vp, struct label *vplabel) 2471{ 2472 struct mac_mls *subj, *obj; 2473 2474 if (!mls_enabled || !revocation_enabled) 2475 return (0); 2476 2477 subj = SLOT(active_cred->cr_label); 2478 obj = SLOT(vplabel); 2479 2480 if (!mls_dominate_effective(subj, obj)) 2481 return (EACCES); 2482 2483 return (0); 2484} 2485 2486static int 2487mls_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2488 struct vnode *vp, struct label *vplabel) 2489{ 2490 struct mac_mls *subj, *obj; 2491 2492 if (!mls_enabled || !revocation_enabled) 2493 return (0); 2494 2495 subj = SLOT(active_cred->cr_label); 2496 obj = SLOT(vplabel); 2497 2498 if (!mls_dominate_effective(subj, obj)) 2499 return (EACCES); 2500 2501 return (0); 2502} 2503 2504static int 2505mls_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 2506 struct label *dvplabel) 2507{ 2508 struct mac_mls *subj, *obj; 2509 2510 if (!mls_enabled) 2511 return (0); 2512 2513 subj = SLOT(cred->cr_label); 2514 obj = SLOT(dvplabel); 2515 2516 if (!mls_dominate_effective(subj, obj)) 2517 return (EACCES); 2518 2519 return (0); 2520} 2521 2522static int 2523mls_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 2524 struct label *vplabel) 2525{ 2526 struct mac_mls *subj, *obj; 2527 2528 if (!mls_enabled) 2529 return (0); 2530 2531 subj = SLOT(cred->cr_label); 2532 obj = SLOT(vplabel); 2533 2534 if (!mls_dominate_effective(subj, obj)) 2535 return (EACCES); 2536 2537 return (0); 2538} 2539 2540static int 2541mls_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2542 struct label *vplabel, struct label *newlabel) 2543{ 2544 struct mac_mls *old, *new, *subj; 2545 int error; 2546 2547 old = SLOT(vplabel); 2548 new = SLOT(newlabel); 2549 subj = SLOT(cred->cr_label); 2550 2551 /* 2552 * If there is an MLS label update for the vnode, it must be a 2553 * effective label. 2554 */ 2555 error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2556 if (error) 2557 return (error); 2558 2559 /* 2560 * To perform a relabel of the vnode (MLS label or not), MLS must 2561 * authorize the relabel. 2562 */ 2563 if (!mls_effective_in_range(old, subj)) 2564 return (EPERM); 2565 2566 /* 2567 * If the MLS label is to be changed, authorize as appropriate. 2568 */ 2569 if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2570 /* 2571 * To change the MLS label on a vnode, the new vnode label 2572 * must be in the subject range. 2573 */ 2574 if (!mls_effective_in_range(new, subj)) 2575 return (EPERM); 2576 2577 /* 2578 * To change the MLS label on the vnode to be EQUAL, the 2579 * subject must have appropriate privilege. 2580 */ 2581 if (mls_contains_equal(new)) { 2582 error = mls_subject_privileged(subj); 2583 if (error) 2584 return (error); 2585 } 2586 } 2587 2588 return (0); 2589} 2590 2591static int 2592mls_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2593 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2594 struct componentname *cnp) 2595{ 2596 struct mac_mls *subj, *obj; 2597 2598 if (!mls_enabled) 2599 return (0); 2600 2601 subj = SLOT(cred->cr_label); 2602 obj = SLOT(dvplabel); 2603 2604 if (!mls_dominate_effective(obj, subj)) 2605 return (EACCES); 2606 2607 obj = SLOT(vplabel); 2608 2609 if (!mls_dominate_effective(obj, subj)) 2610 return (EACCES); 2611 2612 return (0); 2613} 2614 2615static int 2616mls_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2617 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2618 int samedir, struct componentname *cnp) 2619{ 2620 struct mac_mls *subj, *obj; 2621 2622 if (!mls_enabled) 2623 return (0); 2624 2625 subj = SLOT(cred->cr_label); 2626 obj = SLOT(dvplabel); 2627 2628 if (!mls_dominate_effective(obj, subj)) 2629 return (EACCES); 2630 2631 if (vp != NULL) { 2632 obj = SLOT(vplabel); 2633 2634 if (!mls_dominate_effective(obj, subj)) 2635 return (EACCES); 2636 } 2637 2638 return (0); 2639} 2640 2641static int 2642mls_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2643 struct label *vplabel) 2644{ 2645 struct mac_mls *subj, *obj; 2646 2647 if (!mls_enabled) 2648 return (0); 2649 2650 subj = SLOT(cred->cr_label); 2651 obj = SLOT(vplabel); 2652 2653 if (!mls_dominate_effective(obj, subj)) 2654 return (EACCES); 2655 2656 return (0); 2657} 2658 2659static int 2660mls_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2661 struct label *vplabel, acl_type_t type, struct acl *acl) 2662{ 2663 struct mac_mls *subj, *obj; 2664 2665 if (!mls_enabled) 2666 return (0); 2667 2668 subj = SLOT(cred->cr_label); 2669 obj = SLOT(vplabel); 2670 2671 if (!mls_dominate_effective(obj, subj)) 2672 return (EACCES); 2673 2674 return (0); 2675} 2676 2677static int 2678mls_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2679 struct label *vplabel, int attrnamespace, const char *name, 2680 struct uio *uio) 2681{ 2682 struct mac_mls *subj, *obj; 2683 2684 if (!mls_enabled) 2685 return (0); 2686 2687 subj = SLOT(cred->cr_label); 2688 obj = SLOT(vplabel); 2689 2690 if (!mls_dominate_effective(obj, subj)) 2691 return (EACCES); 2692 2693 /* XXX: protect the MAC EA in a special way? */ 2694 2695 return (0); 2696} 2697 2698static int 2699mls_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2700 struct label *vplabel, u_long flags) 2701{ 2702 struct mac_mls *subj, *obj; 2703 2704 if (!mls_enabled) 2705 return (0); 2706 2707 subj = SLOT(cred->cr_label); 2708 obj = SLOT(vplabel); 2709 2710 if (!mls_dominate_effective(obj, subj)) 2711 return (EACCES); 2712 2713 return (0); 2714} 2715 2716static int 2717mls_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 2718 struct label *vplabel, mode_t mode) 2719{ 2720 struct mac_mls *subj, *obj; 2721 2722 if (!mls_enabled) 2723 return (0); 2724 2725 subj = SLOT(cred->cr_label); 2726 obj = SLOT(vplabel); 2727 2728 if (!mls_dominate_effective(obj, subj)) 2729 return (EACCES); 2730 2731 return (0); 2732} 2733 2734static int 2735mls_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 2736 struct label *vplabel, uid_t uid, gid_t gid) 2737{ 2738 struct mac_mls *subj, *obj; 2739 2740 if (!mls_enabled) 2741 return (0); 2742 2743 subj = SLOT(cred->cr_label); 2744 obj = SLOT(vplabel); 2745 2746 if (!mls_dominate_effective(obj, subj)) 2747 return (EACCES); 2748 2749 return (0); 2750} 2751 2752static int 2753mls_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 2754 struct label *vplabel, struct timespec atime, struct timespec mtime) 2755{ 2756 struct mac_mls *subj, *obj; 2757 2758 if (!mls_enabled) 2759 return (0); 2760 2761 subj = SLOT(cred->cr_label); 2762 obj = SLOT(vplabel); 2763 2764 if (!mls_dominate_effective(obj, subj)) 2765 return (EACCES); 2766 2767 return (0); 2768} 2769 2770static int 2771mls_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 2772 struct vnode *vp, struct label *vplabel) 2773{ 2774 struct mac_mls *subj, *obj; 2775 2776 if (!mls_enabled) 2777 return (0); 2778 2779 subj = SLOT(active_cred->cr_label); 2780 obj = SLOT(vplabel); 2781 2782 if (!mls_dominate_effective(subj, obj)) 2783 return (EACCES); 2784 2785 return (0); 2786} 2787 2788static int 2789mls_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 2790 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2791 struct componentname *cnp) 2792{ 2793 struct mac_mls *subj, *obj; 2794 2795 if (!mls_enabled) 2796 return (0); 2797 2798 subj = SLOT(cred->cr_label); 2799 obj = SLOT(dvplabel); 2800 2801 if (!mls_dominate_effective(obj, subj)) 2802 return (EACCES); 2803 2804 obj = SLOT(vplabel); 2805 2806 if (!mls_dominate_effective(obj, subj)) 2807 return (EACCES); 2808 2809 return (0); 2810} 2811 2812static int 2813mls_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred, 2814 struct vnode *vp, struct label *vplabel) 2815{ 2816 struct mac_mls *subj, *obj; 2817 2818 if (!mls_enabled || !revocation_enabled) 2819 return (0); 2820 2821 subj = SLOT(active_cred->cr_label); 2822 obj = SLOT(vplabel); 2823 2824 if (!mls_dominate_effective(obj, subj)) 2825 return (EACCES); 2826 2827 return (0); 2828} 2829 2830static int 2831mls_vnode_create_extattr(struct ucred *cred, struct mount *mp, 2832 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 2833 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 2834{ 2835 struct mac_mls *source, *dest, mm_temp; 2836 size_t buflen; 2837 int error; 2838 2839 buflen = sizeof(mm_temp); 2840 bzero(&mm_temp, buflen); 2841 2842 source = SLOT(cred->cr_label); 2843 dest = SLOT(vplabel); 2844 mls_copy_effective(source, &mm_temp); 2845 2846 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2847 MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 2848 if (error == 0) 2849 mls_copy_effective(source, dest); 2850 return (error); 2851} 2852 2853static void 2854mls_vnode_relabel(struct ucred *cred, struct vnode *vp, 2855 struct label *vplabel, struct label *label) 2856{ 2857 struct mac_mls *source, *dest; 2858 2859 source = SLOT(label); 2860 dest = SLOT(vplabel); 2861 2862 mls_copy(source, dest); 2863} 2864 2865static int 2866mls_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 2867 struct label *vplabel, struct label *intlabel) 2868{ 2869 struct mac_mls *source, mm_temp; 2870 size_t buflen; 2871 int error; 2872 2873 buflen = sizeof(mm_temp); 2874 bzero(&mm_temp, buflen); 2875 2876 source = SLOT(intlabel); 2877 if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 2878 return (0); 2879 2880 mls_copy_effective(source, &mm_temp); 2881 2882 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2883 MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 2884 return (error); 2885} 2886 2887static struct mac_policy_ops mls_ops = 2888{ 2889 .mpo_init = mls_init, 2890 2891 .mpo_bpfdesc_check_receive = mls_bpfdesc_check_receive, 2892 .mpo_bpfdesc_create = mls_bpfdesc_create, 2893 .mpo_bpfdesc_create_mbuf = mls_bpfdesc_create_mbuf, 2894 .mpo_bpfdesc_destroy_label = mls_destroy_label, 2895 .mpo_bpfdesc_init_label = mls_init_label, 2896 2897 .mpo_cred_check_relabel = mls_cred_check_relabel, 2898 .mpo_cred_check_visible = mls_cred_check_visible, 2899 .mpo_cred_copy_label = mls_copy_label, 2900 .mpo_cred_destroy_label = mls_destroy_label, 2901 .mpo_cred_externalize_label = mls_externalize_label, 2902 .mpo_cred_init_label = mls_init_label, 2903 .mpo_cred_internalize_label = mls_internalize_label, 2904 .mpo_cred_relabel = mls_cred_relabel, 2905 2906 .mpo_devfs_create_device = mls_devfs_create_device, 2907 .mpo_devfs_create_directory = mls_devfs_create_directory, 2908 .mpo_devfs_create_symlink = mls_devfs_create_symlink, 2909 .mpo_devfs_destroy_label = mls_destroy_label, 2910 .mpo_devfs_init_label = mls_init_label, 2911 .mpo_devfs_update = mls_devfs_update, 2912 .mpo_devfs_vnode_associate = mls_devfs_vnode_associate, 2913 2914 .mpo_ifnet_check_relabel = mls_ifnet_check_relabel, 2915 .mpo_ifnet_check_transmit = mls_ifnet_check_transmit, 2916 .mpo_ifnet_copy_label = mls_copy_label, 2917 .mpo_ifnet_create = mls_ifnet_create, 2918 .mpo_ifnet_create_mbuf = mls_ifnet_create_mbuf, 2919 .mpo_ifnet_destroy_label = mls_destroy_label, 2920 .mpo_ifnet_externalize_label = mls_externalize_label, 2921 .mpo_ifnet_init_label = mls_init_label, 2922 .mpo_ifnet_internalize_label = mls_internalize_label, 2923 .mpo_ifnet_relabel = mls_ifnet_relabel, 2924 2925 .mpo_inpcb_check_deliver = mls_inpcb_check_deliver, 2926 .mpo_inpcb_create = mls_inpcb_create, 2927 .mpo_inpcb_create_mbuf = mls_inpcb_create_mbuf, 2928 .mpo_inpcb_destroy_label = mls_destroy_label, 2929 .mpo_inpcb_init_label = mls_init_label_waitcheck, 2930 .mpo_inpcb_sosetlabel = mls_inpcb_sosetlabel, 2931 2932 .mpo_ipq_create = mls_ipq_create, 2933 .mpo_ipq_destroy_label = mls_destroy_label, 2934 .mpo_ipq_init_label = mls_init_label_waitcheck, 2935 .mpo_ipq_match = mls_ipq_match, 2936 .mpo_ipq_reassemble = mls_ipq_reassemble, 2937 .mpo_ipq_update = mls_ipq_update, 2938 2939 .mpo_mbuf_copy_label = mls_copy_label, 2940 .mpo_mbuf_destroy_label = mls_destroy_label, 2941 .mpo_mbuf_init_label = mls_init_label_waitcheck, 2942 2943 .mpo_mount_check_stat = mls_mount_check_stat, 2944 .mpo_mount_create = mls_mount_create, 2945 .mpo_mount_destroy_label = mls_destroy_label, 2946 .mpo_mount_init_label = mls_init_label, 2947 2948 .mpo_netatalk_aarp_send = mls_netatalk_aarp_send, 2949 2950 .mpo_netinet_arp_send = mls_netinet_arp_send, 2951 .mpo_netinet_firewall_reply = mls_netinet_firewall_reply, 2952 .mpo_netinet_firewall_send = mls_netinet_firewall_send, 2953 .mpo_netinet_fragment = mls_netinet_fragment, 2954 .mpo_netinet_icmp_reply = mls_netinet_icmp_reply, 2955 .mpo_netinet_igmp_send = mls_netinet_igmp_send, 2956 2957 .mpo_netinet6_nd6_send = mls_netinet6_nd6_send, 2958 2959 .mpo_pipe_check_ioctl = mls_pipe_check_ioctl, 2960 .mpo_pipe_check_poll = mls_pipe_check_poll, 2961 .mpo_pipe_check_read = mls_pipe_check_read, 2962 .mpo_pipe_check_relabel = mls_pipe_check_relabel, 2963 .mpo_pipe_check_stat = mls_pipe_check_stat, 2964 .mpo_pipe_check_write = mls_pipe_check_write, 2965 .mpo_pipe_copy_label = mls_copy_label, 2966 .mpo_pipe_create = mls_pipe_create, 2967 .mpo_pipe_destroy_label = mls_destroy_label, 2968 .mpo_pipe_externalize_label = mls_externalize_label, 2969 .mpo_pipe_init_label = mls_init_label, 2970 .mpo_pipe_internalize_label = mls_internalize_label, 2971 .mpo_pipe_relabel = mls_pipe_relabel, 2972 2973 .mpo_posixsem_check_getvalue = mls_posixsem_check_rdonly, 2974 .mpo_posixsem_check_open = mls_posixsem_check_openunlink, 2975 .mpo_posixsem_check_post = mls_posixsem_check_write, 2976 .mpo_posixsem_check_stat = mls_posixsem_check_rdonly, 2977 .mpo_posixsem_check_unlink = mls_posixsem_check_openunlink, 2978 .mpo_posixsem_check_wait = mls_posixsem_check_write, 2979 .mpo_posixsem_create = mls_posixsem_create, 2980 .mpo_posixsem_destroy_label = mls_destroy_label, 2981 .mpo_posixsem_init_label = mls_init_label, 2982 2983 .mpo_proc_associate_nfsd = mls_proc_associate_nfsd, 2984 .mpo_proc_check_debug = mls_proc_check_debug, 2985 .mpo_proc_check_sched = mls_proc_check_sched, 2986 .mpo_proc_check_signal = mls_proc_check_signal, 2987 .mpo_proc_create_init = mls_proc_create_init, 2988 .mpo_proc_create_swapper = mls_proc_create_swapper, 2989 2990 .mpo_socket_check_deliver = mls_socket_check_deliver, 2991 .mpo_socket_check_relabel = mls_socket_check_relabel, 2992 .mpo_socket_check_visible = mls_socket_check_visible, 2993 .mpo_socket_copy_label = mls_copy_label, 2994 .mpo_socket_create = mls_socket_create, 2995 .mpo_socket_create_mbuf = mls_socket_create_mbuf, 2996 .mpo_socket_destroy_label = mls_destroy_label, 2997 .mpo_socket_externalize_label = mls_externalize_label, 2998 .mpo_socket_init_label = mls_init_label_waitcheck, 2999 .mpo_socket_internalize_label = mls_internalize_label, 3000 .mpo_socket_newconn = mls_socket_newconn, 3001 .mpo_socket_relabel = mls_socket_relabel, 3002 3003 .mpo_socketpeer_destroy_label = mls_destroy_label, 3004 .mpo_socketpeer_externalize_label = mls_externalize_label, 3005 .mpo_socketpeer_init_label = mls_init_label_waitcheck, 3006 .mpo_socketpeer_set_from_mbuf = mls_socketpeer_set_from_mbuf, 3007 .mpo_socketpeer_set_from_socket = mls_socketpeer_set_from_socket, 3008 3009 .mpo_syncache_create = mls_syncache_create, 3010 .mpo_syncache_create_mbuf = mls_syncache_create_mbuf, 3011 .mpo_syncache_destroy_label = mls_destroy_label, 3012 .mpo_syncache_init_label = mls_init_label_waitcheck, 3013 3014 .mpo_sysvmsg_cleanup = mls_sysvmsg_cleanup, 3015 .mpo_sysvmsg_create = mls_sysvmsg_create, 3016 .mpo_sysvmsg_destroy_label = mls_destroy_label, 3017 .mpo_sysvmsg_init_label = mls_init_label, 3018 3019 .mpo_sysvmsq_check_msgrcv = mls_sysvmsq_check_msgrcv, 3020 .mpo_sysvmsq_check_msgrmid = mls_sysvmsq_check_msgrmid, 3021 .mpo_sysvmsq_check_msqget = mls_sysvmsq_check_msqget, 3022 .mpo_sysvmsq_check_msqsnd = mls_sysvmsq_check_msqsnd, 3023 .mpo_sysvmsq_check_msqrcv = mls_sysvmsq_check_msqrcv, 3024 .mpo_sysvmsq_check_msqctl = mls_sysvmsq_check_msqctl, 3025 .mpo_sysvmsq_cleanup = mls_sysvmsq_cleanup, 3026 .mpo_sysvmsq_destroy_label = mls_destroy_label, 3027 .mpo_sysvmsq_init_label = mls_init_label, 3028 .mpo_sysvmsq_create = mls_sysvmsq_create, 3029 3030 .mpo_sysvsem_check_semctl = mls_sysvsem_check_semctl, 3031 .mpo_sysvsem_check_semget = mls_sysvsem_check_semget, 3032 .mpo_sysvsem_check_semop = mls_sysvsem_check_semop, 3033 .mpo_sysvsem_cleanup = mls_sysvsem_cleanup, 3034 .mpo_sysvsem_create = mls_sysvsem_create, 3035 .mpo_sysvsem_destroy_label = mls_destroy_label, 3036 .mpo_sysvsem_init_label = mls_init_label, 3037 3038 .mpo_sysvshm_check_shmat = mls_sysvshm_check_shmat, 3039 .mpo_sysvshm_check_shmctl = mls_sysvshm_check_shmctl, 3040 .mpo_sysvshm_check_shmget = mls_sysvshm_check_shmget, 3041 .mpo_sysvshm_cleanup = mls_sysvshm_cleanup, 3042 .mpo_sysvshm_create = mls_sysvshm_create, 3043 .mpo_sysvshm_destroy_label = mls_destroy_label, 3044 .mpo_sysvshm_init_label = mls_init_label, 3045 3046 3047 .mpo_system_check_acct = mls_system_check_acct, 3048 .mpo_system_check_auditctl = mls_system_check_auditctl, 3049 .mpo_system_check_swapon = mls_system_check_swapon, 3050 3051 .mpo_vnode_associate_extattr = mls_vnode_associate_extattr, 3052 .mpo_vnode_associate_singlelabel = mls_vnode_associate_singlelabel, 3053 .mpo_vnode_check_access = mls_vnode_check_open, 3054 .mpo_vnode_check_chdir = mls_vnode_check_chdir, 3055 .mpo_vnode_check_chroot = mls_vnode_check_chroot, 3056 .mpo_vnode_check_create = mls_vnode_check_create, 3057 .mpo_vnode_check_deleteacl = mls_vnode_check_deleteacl, 3058 .mpo_vnode_check_deleteextattr = mls_vnode_check_deleteextattr, 3059 .mpo_vnode_check_exec = mls_vnode_check_exec, 3060 .mpo_vnode_check_getacl = mls_vnode_check_getacl, 3061 .mpo_vnode_check_getextattr = mls_vnode_check_getextattr, 3062 .mpo_vnode_check_link = mls_vnode_check_link, 3063 .mpo_vnode_check_listextattr = mls_vnode_check_listextattr, 3064 .mpo_vnode_check_lookup = mls_vnode_check_lookup, 3065 .mpo_vnode_check_mmap = mls_vnode_check_mmap, 3066 .mpo_vnode_check_open = mls_vnode_check_open, 3067 .mpo_vnode_check_poll = mls_vnode_check_poll, 3068 .mpo_vnode_check_read = mls_vnode_check_read, 3069 .mpo_vnode_check_readdir = mls_vnode_check_readdir, 3070 .mpo_vnode_check_readlink = mls_vnode_check_readlink, 3071 .mpo_vnode_check_relabel = mls_vnode_check_relabel, 3072 .mpo_vnode_check_rename_from = mls_vnode_check_rename_from, 3073 .mpo_vnode_check_rename_to = mls_vnode_check_rename_to, 3074 .mpo_vnode_check_revoke = mls_vnode_check_revoke, 3075 .mpo_vnode_check_setacl = mls_vnode_check_setacl, 3076 .mpo_vnode_check_setextattr = mls_vnode_check_setextattr, 3077 .mpo_vnode_check_setflags = mls_vnode_check_setflags, 3078 .mpo_vnode_check_setmode = mls_vnode_check_setmode, 3079 .mpo_vnode_check_setowner = mls_vnode_check_setowner, 3080 .mpo_vnode_check_setutimes = mls_vnode_check_setutimes, 3081 .mpo_vnode_check_stat = mls_vnode_check_stat, 3082 .mpo_vnode_check_unlink = mls_vnode_check_unlink, 3083 .mpo_vnode_check_write = mls_vnode_check_write, 3084 .mpo_vnode_copy_label = mls_copy_label, 3085 .mpo_vnode_create_extattr = mls_vnode_create_extattr, 3086 .mpo_vnode_destroy_label = mls_destroy_label, 3087 .mpo_vnode_externalize_label = mls_externalize_label, 3088 .mpo_vnode_init_label = mls_init_label, 3089 .mpo_vnode_internalize_label = mls_internalize_label, 3090 .mpo_vnode_relabel = mls_vnode_relabel, 3091 .mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr, 3092}; 3093 3094MAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS", 3095 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mls_slot); 3096