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