1101099Srwatson/*- 2225344Srwatson * Copyright (c) 1999-2002, 2007-2011 Robert N. M. Watson 3140629Srwatson * Copyright (c) 2001-2005 McAfee, Inc. 4172930Srwatson * Copyright (c) 2006 SPARTA, Inc. 5101099Srwatson * All rights reserved. 6101099Srwatson * 7101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 8101099Srwatson * 9140629Srwatson * This software was developed for the FreeBSD Project in part by McAfee 10140629Srwatson * Research, the Security Research Division of McAfee, Inc. under 11140629Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 12140629Srwatson * CHATS research program. 13101099Srwatson * 14172930Srwatson * This software was enhanced by SPARTA ISSO under SPAWAR contract 15172930Srwatson * N66001-04-C-6019 ("SEFOS"). 16172930Srwatson * 17225344Srwatson * This software was developed at the University of Cambridge Computer 18225344Srwatson * Laboratory with support from a grant from Google, Inc. 19225344Srwatson * 20101099Srwatson * Redistribution and use in source and binary forms, with or without 21101099Srwatson * modification, are permitted provided that the following conditions 22101099Srwatson * are met: 23101099Srwatson * 1. Redistributions of source code must retain the above copyright 24101099Srwatson * notice, this list of conditions and the following disclaimer. 25101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright 26101099Srwatson * notice, this list of conditions and the following disclaimer in the 27101099Srwatson * documentation and/or other materials provided with the distribution. 28101099Srwatson * 29101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 30101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 33101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39101099Srwatson * SUCH DAMAGE. 40101099Srwatson * 41101099Srwatson * $FreeBSD$ 42101099Srwatson */ 43101099Srwatson 44101099Srwatson/* 45101099Srwatson * Developed by the TrustedBSD Project. 46168977Srwatson * 47101099Srwatson * MLS fixed label mandatory confidentiality policy. 48101099Srwatson */ 49101099Srwatson 50101099Srwatson#include <sys/types.h> 51101099Srwatson#include <sys/param.h> 52101099Srwatson#include <sys/acl.h> 53101099Srwatson#include <sys/conf.h> 54105988Srwatson#include <sys/extattr.h> 55101099Srwatson#include <sys/kernel.h> 56164184Strhodes#include <sys/ksem.h> 57145076Scsjp#include <sys/mman.h> 58103183Sbde#include <sys/malloc.h> 59101099Srwatson#include <sys/mount.h> 60101099Srwatson#include <sys/proc.h> 61115497Srwatson#include <sys/sbuf.h> 62101099Srwatson#include <sys/systm.h> 63101099Srwatson#include <sys/sysproto.h> 64101099Srwatson#include <sys/sysent.h> 65105696Srwatson#include <sys/systm.h> 66101099Srwatson#include <sys/vnode.h> 67101099Srwatson#include <sys/file.h> 68101099Srwatson#include <sys/socket.h> 69101099Srwatson#include <sys/socketvar.h> 70101099Srwatson#include <sys/pipe.h> 71150340Sphk#include <sys/sx.h> 72101099Srwatson#include <sys/sysctl.h> 73140629Srwatson#include <sys/msg.h> 74140629Srwatson#include <sys/sem.h> 75140629Srwatson#include <sys/shm.h> 76101099Srwatson 77101099Srwatson#include <fs/devfs/devfs.h> 78101099Srwatson 79101099Srwatson#include <net/bpfdesc.h> 80101099Srwatson#include <net/if.h> 81101099Srwatson#include <net/if_types.h> 82101099Srwatson#include <net/if_var.h> 83101099Srwatson 84101099Srwatson#include <netinet/in.h> 85122875Srwatson#include <netinet/in_pcb.h> 86101099Srwatson#include <netinet/ip_var.h> 87101099Srwatson 88122879Srwatson#include <vm/uma.h> 89101099Srwatson#include <vm/vm.h> 90101099Srwatson 91165469Srwatson#include <security/mac/mac_policy.h> 92101099Srwatson#include <security/mac_mls/mac_mls.h> 93101099Srwatson 94101099SrwatsonSYSCTL_DECL(_security_mac); 95101099Srwatson 96248085Smariusstatic SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0, 97101099Srwatson "TrustedBSD mac_mls policy controls"); 98101099Srwatson 99172955Srwatsonstatic int mls_label_size = sizeof(struct mac_mls); 100105988SrwatsonSYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD, 101172955Srwatson &mls_label_size, 0, "Size of struct mac_mls"); 102105988Srwatson 103172955Srwatsonstatic int mls_enabled = 1; 104172955SrwatsonSYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW, &mls_enabled, 0, 105172955Srwatson "Enforce MAC/MLS policy"); 106172955SrwatsonTUNABLE_INT("security.mac.mls.enabled", &mls_enabled); 107101099Srwatson 108101099Srwatsonstatic int destroyed_not_inited; 109101099SrwatsonSYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 110101099Srwatson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 111101099Srwatson 112105606Srwatsonstatic int ptys_equal = 0; 113105606SrwatsonSYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RW, 114105606Srwatson &ptys_equal, 0, "Label pty devices as mls/equal on create"); 115105606SrwatsonTUNABLE_INT("security.mac.mls.ptys_equal", &ptys_equal); 116105606Srwatson 117105640Srwatsonstatic int revocation_enabled = 0; 118101099SrwatsonSYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RW, 119105640Srwatson &revocation_enabled, 0, "Revoke access to objects on relabel"); 120105640SrwatsonTUNABLE_INT("security.mac.mls.revocation_enabled", &revocation_enabled); 121101099Srwatson 122105643Srwatsonstatic int max_compartments = MAC_MLS_MAX_COMPARTMENTS; 123105643SrwatsonSYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD, 124105643Srwatson &max_compartments, 0, "Maximum compartments the policy supports"); 125105643Srwatson 126172955Srwatsonstatic int mls_slot; 127172955Srwatson#define SLOT(l) ((struct mac_mls *)mac_label_get((l), mls_slot)) 128172955Srwatson#define SLOT_SET(l, val) mac_label_set((l), mls_slot, (uintptr_t)(val)) 129101099Srwatson 130122879Srwatsonstatic uma_zone_t zone_mls; 131101099Srwatson 132105643Srwatsonstatic __inline int 133105643Srwatsonmls_bit_set_empty(u_char *set) { 134105643Srwatson int i; 135105643Srwatson 136105643Srwatson for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++) 137105643Srwatson if (set[i] != 0) 138105643Srwatson return (0); 139105643Srwatson return (1); 140105643Srwatson} 141105643Srwatson 142101099Srwatsonstatic struct mac_mls * 143104514Srwatsonmls_alloc(int flag) 144101099Srwatson{ 145101099Srwatson 146122879Srwatson return (uma_zalloc(zone_mls, flag | M_ZERO)); 147101099Srwatson} 148101099Srwatson 149101099Srwatsonstatic void 150172955Srwatsonmls_free(struct mac_mls *mm) 151101099Srwatson{ 152101099Srwatson 153172955Srwatson if (mm != NULL) 154172955Srwatson uma_zfree(zone_mls, mm); 155101099Srwatson else 156101099Srwatson atomic_add_int(&destroyed_not_inited, 1); 157101099Srwatson} 158101099Srwatson 159101099Srwatsonstatic int 160172955Srwatsonmls_atmostflags(struct mac_mls *mm, int flags) 161105634Srwatson{ 162105634Srwatson 163172955Srwatson if ((mm->mm_flags & flags) != mm->mm_flags) 164105634Srwatson return (EINVAL); 165105634Srwatson return (0); 166105634Srwatson} 167105634Srwatson 168105634Srwatsonstatic int 169172955Srwatsonmls_dominate_element(struct mac_mls_element *a, struct mac_mls_element *b) 170101099Srwatson{ 171105643Srwatson int bit; 172101099Srwatson 173105736Srwatson switch (a->mme_type) { 174101099Srwatson case MAC_MLS_TYPE_EQUAL: 175101099Srwatson case MAC_MLS_TYPE_HIGH: 176101099Srwatson return (1); 177101099Srwatson 178101099Srwatson case MAC_MLS_TYPE_LOW: 179101099Srwatson switch (b->mme_type) { 180101099Srwatson case MAC_MLS_TYPE_LEVEL: 181101099Srwatson case MAC_MLS_TYPE_HIGH: 182101099Srwatson return (0); 183101099Srwatson 184101099Srwatson case MAC_MLS_TYPE_EQUAL: 185101099Srwatson case MAC_MLS_TYPE_LOW: 186101099Srwatson return (1); 187101099Srwatson 188101099Srwatson default: 189172955Srwatson panic("mls_dominate_element: b->mme_type invalid"); 190101099Srwatson } 191101099Srwatson 192101099Srwatson case MAC_MLS_TYPE_LEVEL: 193101099Srwatson switch (b->mme_type) { 194101099Srwatson case MAC_MLS_TYPE_EQUAL: 195101099Srwatson case MAC_MLS_TYPE_LOW: 196101099Srwatson return (1); 197101099Srwatson 198101099Srwatson case MAC_MLS_TYPE_HIGH: 199101099Srwatson return (0); 200101099Srwatson 201101099Srwatson case MAC_MLS_TYPE_LEVEL: 202105643Srwatson for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) 203105643Srwatson if (!MAC_MLS_BIT_TEST(bit, 204105643Srwatson a->mme_compartments) && 205105643Srwatson MAC_MLS_BIT_TEST(bit, b->mme_compartments)) 206105643Srwatson return (0); 207101099Srwatson return (a->mme_level >= b->mme_level); 208101099Srwatson 209101099Srwatson default: 210172955Srwatson panic("mls_dominate_element: b->mme_type invalid"); 211101099Srwatson } 212101099Srwatson 213101099Srwatson default: 214172955Srwatson panic("mls_dominate_element: a->mme_type invalid"); 215101099Srwatson } 216101099Srwatson 217101099Srwatson return (0); 218101099Srwatson} 219101099Srwatson 220101099Srwatsonstatic int 221172955Srwatsonmls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) 222101099Srwatson{ 223101099Srwatson 224172955Srwatson return (mls_dominate_element(&rangeb->mm_rangehigh, 225101099Srwatson &rangea->mm_rangehigh) && 226172955Srwatson mls_dominate_element(&rangea->mm_rangelow, 227101099Srwatson &rangeb->mm_rangelow)); 228101099Srwatson} 229101099Srwatson 230101099Srwatsonstatic int 231172955Srwatsonmls_effective_in_range(struct mac_mls *effective, struct mac_mls *range) 232101099Srwatson{ 233101099Srwatson 234132232Srwatson KASSERT((effective->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 235172955Srwatson ("mls_effective_in_range: a not effective")); 236103750Srwatson KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 237172955Srwatson ("mls_effective_in_range: b not range")); 238101099Srwatson 239172955Srwatson return (mls_dominate_element(&range->mm_rangehigh, 240132232Srwatson &effective->mm_effective) && 241172955Srwatson mls_dominate_element(&effective->mm_effective, 242101099Srwatson &range->mm_rangelow)); 243101099Srwatson 244101099Srwatson return (1); 245101099Srwatson} 246101099Srwatson 247101099Srwatsonstatic int 248172955Srwatsonmls_dominate_effective(struct mac_mls *a, struct mac_mls *b) 249101099Srwatson{ 250132232Srwatson KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 251172955Srwatson ("mls_dominate_effective: a not effective")); 252132232Srwatson KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 253172955Srwatson ("mls_dominate_effective: b not effective")); 254101099Srwatson 255172955Srwatson return (mls_dominate_element(&a->mm_effective, &b->mm_effective)); 256101099Srwatson} 257101099Srwatson 258101099Srwatsonstatic int 259172955Srwatsonmls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) 260101099Srwatson{ 261101099Srwatson 262101099Srwatson if (a->mme_type == MAC_MLS_TYPE_EQUAL || 263101099Srwatson b->mme_type == MAC_MLS_TYPE_EQUAL) 264101099Srwatson return (1); 265101099Srwatson 266101099Srwatson return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); 267101099Srwatson} 268101099Srwatson 269101099Srwatsonstatic int 270172955Srwatsonmls_equal_effective(struct mac_mls *a, struct mac_mls *b) 271101099Srwatson{ 272101099Srwatson 273132232Srwatson KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 274172955Srwatson ("mls_equal_effective: a not effective")); 275132232Srwatson KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 276172955Srwatson ("mls_equal_effective: b not effective")); 277101099Srwatson 278172955Srwatson return (mls_equal_element(&a->mm_effective, &b->mm_effective)); 279101099Srwatson} 280101099Srwatson 281101099Srwatsonstatic int 282172955Srwatsonmls_contains_equal(struct mac_mls *mm) 283105634Srwatson{ 284105634Srwatson 285172955Srwatson if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 286172955Srwatson if (mm->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 287105634Srwatson return (1); 288105634Srwatson 289172955Srwatson if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 290172955Srwatson if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL) 291105634Srwatson return (1); 292172955Srwatson if (mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 293105634Srwatson return (1); 294105634Srwatson } 295105634Srwatson 296105634Srwatson return (0); 297105634Srwatson} 298105634Srwatson 299105634Srwatsonstatic int 300172955Srwatsonmls_subject_privileged(struct mac_mls *mm) 301105634Srwatson{ 302105634Srwatson 303172955Srwatson KASSERT((mm->mm_flags & MAC_MLS_FLAGS_BOTH) == MAC_MLS_FLAGS_BOTH, 304172955Srwatson ("mls_subject_privileged: subject doesn't have both labels")); 305105634Srwatson 306132232Srwatson /* If the effective is EQUAL, it's ok. */ 307172955Srwatson if (mm->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 308105634Srwatson return (0); 309105634Srwatson 310105634Srwatson /* If either range endpoint is EQUAL, it's ok. */ 311172955Srwatson if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL || 312172955Srwatson mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 313105634Srwatson return (0); 314105634Srwatson 315105634Srwatson /* If the range is low-high, it's ok. */ 316172955Srwatson if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW && 317172955Srwatson mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH) 318105634Srwatson return (0); 319105634Srwatson 320105634Srwatson /* It's not ok. */ 321105634Srwatson return (EPERM); 322105634Srwatson} 323105634Srwatson 324105634Srwatsonstatic int 325172955Srwatsonmls_valid(struct mac_mls *mm) 326101099Srwatson{ 327101099Srwatson 328172955Srwatson if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 329172955Srwatson switch (mm->mm_effective.mme_type) { 330101099Srwatson case MAC_MLS_TYPE_LEVEL: 331101099Srwatson break; 332101099Srwatson 333101099Srwatson case MAC_MLS_TYPE_EQUAL: 334101099Srwatson case MAC_MLS_TYPE_HIGH: 335101099Srwatson case MAC_MLS_TYPE_LOW: 336172955Srwatson if (mm->mm_effective.mme_level != 0 || 337105643Srwatson !MAC_MLS_BIT_SET_EMPTY( 338172955Srwatson mm->mm_effective.mme_compartments)) 339101099Srwatson return (EINVAL); 340101099Srwatson break; 341101099Srwatson 342101099Srwatson default: 343101099Srwatson return (EINVAL); 344101099Srwatson } 345101099Srwatson } else { 346172955Srwatson if (mm->mm_effective.mme_type != MAC_MLS_TYPE_UNDEF) 347101099Srwatson return (EINVAL); 348101099Srwatson } 349101099Srwatson 350172955Srwatson if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 351172955Srwatson switch (mm->mm_rangelow.mme_type) { 352101099Srwatson case MAC_MLS_TYPE_LEVEL: 353101099Srwatson break; 354101099Srwatson 355101099Srwatson case MAC_MLS_TYPE_EQUAL: 356101099Srwatson case MAC_MLS_TYPE_HIGH: 357101099Srwatson case MAC_MLS_TYPE_LOW: 358172955Srwatson if (mm->mm_rangelow.mme_level != 0 || 359105643Srwatson !MAC_MLS_BIT_SET_EMPTY( 360172955Srwatson mm->mm_rangelow.mme_compartments)) 361101099Srwatson return (EINVAL); 362101099Srwatson break; 363101099Srwatson 364101099Srwatson default: 365101099Srwatson return (EINVAL); 366101099Srwatson } 367101099Srwatson 368172955Srwatson switch (mm->mm_rangehigh.mme_type) { 369101099Srwatson case MAC_MLS_TYPE_LEVEL: 370101099Srwatson break; 371101099Srwatson 372101099Srwatson case MAC_MLS_TYPE_EQUAL: 373101099Srwatson case MAC_MLS_TYPE_HIGH: 374101099Srwatson case MAC_MLS_TYPE_LOW: 375172955Srwatson if (mm->mm_rangehigh.mme_level != 0 || 376105643Srwatson !MAC_MLS_BIT_SET_EMPTY( 377172955Srwatson mm->mm_rangehigh.mme_compartments)) 378101099Srwatson return (EINVAL); 379101099Srwatson break; 380101099Srwatson 381101099Srwatson default: 382101099Srwatson return (EINVAL); 383101099Srwatson } 384172955Srwatson if (!mls_dominate_element(&mm->mm_rangehigh, 385172955Srwatson &mm->mm_rangelow)) 386101099Srwatson return (EINVAL); 387101099Srwatson } else { 388172955Srwatson if (mm->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || 389172955Srwatson mm->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) 390101099Srwatson return (EINVAL); 391101099Srwatson } 392101099Srwatson 393101099Srwatson return (0); 394101099Srwatson} 395101099Srwatson 396101099Srwatsonstatic void 397172955Srwatsonmls_set_range(struct mac_mls *mm, u_short typelow, u_short levellow, 398172955Srwatson u_char *compartmentslow, u_short typehigh, u_short levelhigh, 399172955Srwatson u_char *compartmentshigh) 400101099Srwatson{ 401101099Srwatson 402172955Srwatson mm->mm_rangelow.mme_type = typelow; 403172955Srwatson mm->mm_rangelow.mme_level = levellow; 404105643Srwatson if (compartmentslow != NULL) 405181217Srwatson memcpy(mm->mm_rangelow.mme_compartments, compartmentslow, 406172955Srwatson sizeof(mm->mm_rangelow.mme_compartments)); 407172955Srwatson mm->mm_rangehigh.mme_type = typehigh; 408172955Srwatson mm->mm_rangehigh.mme_level = levelhigh; 409105643Srwatson if (compartmentshigh != NULL) 410181217Srwatson memcpy(mm->mm_rangehigh.mme_compartments, compartmentshigh, 411172955Srwatson sizeof(mm->mm_rangehigh.mme_compartments)); 412172955Srwatson mm->mm_flags |= MAC_MLS_FLAG_RANGE; 413101099Srwatson} 414101099Srwatson 415101099Srwatsonstatic void 416172955Srwatsonmls_set_effective(struct mac_mls *mm, u_short type, u_short level, 417105643Srwatson u_char *compartments) 418101099Srwatson{ 419101099Srwatson 420172955Srwatson mm->mm_effective.mme_type = type; 421172955Srwatson mm->mm_effective.mme_level = level; 422105643Srwatson if (compartments != NULL) 423172955Srwatson memcpy(mm->mm_effective.mme_compartments, compartments, 424172955Srwatson sizeof(mm->mm_effective.mme_compartments)); 425172955Srwatson mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 426101099Srwatson} 427101099Srwatson 428101099Srwatsonstatic void 429172955Srwatsonmls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 430101099Srwatson{ 431105643Srwatson 432101099Srwatson KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 433172955Srwatson ("mls_copy_range: labelfrom not range")); 434101099Srwatson 435101099Srwatson labelto->mm_rangelow = labelfrom->mm_rangelow; 436101099Srwatson labelto->mm_rangehigh = labelfrom->mm_rangehigh; 437101099Srwatson labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 438101099Srwatson} 439101099Srwatson 440101099Srwatsonstatic void 441172955Srwatsonmls_copy_effective(struct mac_mls *labelfrom, struct mac_mls *labelto) 442101099Srwatson{ 443101099Srwatson 444132232Srwatson KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 445172955Srwatson ("mls_copy_effective: labelfrom not effective")); 446101099Srwatson 447132232Srwatson labelto->mm_effective = labelfrom->mm_effective; 448132232Srwatson labelto->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 449101099Srwatson} 450101099Srwatson 451105656Srwatsonstatic void 452172955Srwatsonmls_copy(struct mac_mls *source, struct mac_mls *dest) 453105656Srwatson{ 454105656Srwatson 455132232Srwatson if (source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 456172955Srwatson mls_copy_effective(source, dest); 457105656Srwatson if (source->mm_flags & MAC_MLS_FLAG_RANGE) 458172955Srwatson mls_copy_range(source, dest); 459105656Srwatson} 460105656Srwatson 461101099Srwatson/* 462101099Srwatson * Policy module operations. 463101099Srwatson */ 464101099Srwatsonstatic void 465172955Srwatsonmls_init(struct mac_policy_conf *conf) 466101099Srwatson{ 467101099Srwatson 468122879Srwatson zone_mls = uma_zcreate("mac_mls", sizeof(struct mac_mls), NULL, 469122879Srwatson NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 470101099Srwatson} 471101099Srwatson 472101099Srwatson/* 473101099Srwatson * Label operations. 474101099Srwatson */ 475101099Srwatsonstatic void 476172955Srwatsonmls_init_label(struct label *label) 477101099Srwatson{ 478101099Srwatson 479132781Skan SLOT_SET(label, mls_alloc(M_WAITOK)); 480101099Srwatson} 481101099Srwatson 482101099Srwatsonstatic int 483172955Srwatsonmls_init_label_waitcheck(struct label *label, int flag) 484101099Srwatson{ 485101099Srwatson 486132781Skan SLOT_SET(label, mls_alloc(flag)); 487101099Srwatson if (SLOT(label) == NULL) 488101099Srwatson return (ENOMEM); 489101099Srwatson 490101099Srwatson return (0); 491101099Srwatson} 492101099Srwatson 493101099Srwatsonstatic void 494172955Srwatsonmls_destroy_label(struct label *label) 495101099Srwatson{ 496101099Srwatson 497101099Srwatson mls_free(SLOT(label)); 498132781Skan SLOT_SET(label, NULL); 499101099Srwatson} 500101099Srwatson 501105696Srwatson/* 502172955Srwatson * mls_element_to_string() accepts an sbuf and MLS element. It converts the 503172955Srwatson * MLS element to a string and stores the result in the sbuf; if there isn't 504172955Srwatson * space in the sbuf, -1 is returned. 505105696Srwatson */ 506115497Srwatsonstatic int 507172955Srwatsonmls_element_to_string(struct sbuf *sb, struct mac_mls_element *element) 508105696Srwatson{ 509115497Srwatson int i, first; 510105696Srwatson 511105696Srwatson switch (element->mme_type) { 512105696Srwatson case MAC_MLS_TYPE_HIGH: 513115497Srwatson return (sbuf_printf(sb, "high")); 514105696Srwatson 515105696Srwatson case MAC_MLS_TYPE_LOW: 516115497Srwatson return (sbuf_printf(sb, "low")); 517105696Srwatson 518105696Srwatson case MAC_MLS_TYPE_EQUAL: 519115497Srwatson return (sbuf_printf(sb, "equal")); 520105696Srwatson 521105696Srwatson case MAC_MLS_TYPE_LEVEL: 522115497Srwatson if (sbuf_printf(sb, "%d", element->mme_level) == -1) 523115497Srwatson return (-1); 524115497Srwatson 525115497Srwatson first = 1; 526115497Srwatson for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) { 527115497Srwatson if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) { 528115497Srwatson if (first) { 529115497Srwatson if (sbuf_putc(sb, ':') == -1) 530115497Srwatson return (-1); 531115497Srwatson if (sbuf_printf(sb, "%d", i) == -1) 532115497Srwatson return (-1); 533115497Srwatson first = 0; 534115497Srwatson } else { 535115497Srwatson if (sbuf_printf(sb, "+%d", i) == -1) 536115497Srwatson return (-1); 537115497Srwatson } 538115497Srwatson } 539105696Srwatson } 540115497Srwatson return (0); 541105696Srwatson 542105696Srwatson default: 543172955Srwatson panic("mls_element_to_string: invalid type (%d)", 544105696Srwatson element->mme_type); 545105696Srwatson } 546105696Srwatson} 547105696Srwatson 548115497Srwatson/* 549172955Srwatson * mls_to_string() converts an MLS label to a string, and places the results 550172955Srwatson * in the passed sbuf. It returns 0 on success, or EINVAL if there isn't 551172955Srwatson * room in the sbuf. Note: the sbuf will be modified even in a failure case, 552172955Srwatson * so the caller may need to revert the sbuf by restoring the offset if 553172955Srwatson * that's undesired. 554115497Srwatson */ 555115497Srwatsonstatic int 556172955Srwatsonmls_to_string(struct sbuf *sb, struct mac_mls *mm) 557105696Srwatson{ 558105696Srwatson 559172955Srwatson if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 560172955Srwatson if (mls_element_to_string(sb, &mm->mm_effective) == -1) 561105696Srwatson return (EINVAL); 562105696Srwatson } 563105696Srwatson 564172955Srwatson if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 565116701Srwatson if (sbuf_putc(sb, '(') == -1) 566105696Srwatson return (EINVAL); 567105696Srwatson 568172955Srwatson if (mls_element_to_string(sb, &mm->mm_rangelow) == -1) 569105696Srwatson return (EINVAL); 570105696Srwatson 571116701Srwatson if (sbuf_putc(sb, '-') == -1) 572105696Srwatson return (EINVAL); 573105696Srwatson 574172955Srwatson if (mls_element_to_string(sb, &mm->mm_rangehigh) == -1) 575105696Srwatson return (EINVAL); 576105696Srwatson 577116701Srwatson if (sbuf_putc(sb, ')') == -1) 578105696Srwatson return (EINVAL); 579105696Srwatson } 580105696Srwatson 581105696Srwatson return (0); 582105696Srwatson} 583105696Srwatson 584101099Srwatsonstatic int 585172955Srwatsonmls_externalize_label(struct label *label, char *element_name, 586116701Srwatson struct sbuf *sb, int *claimed) 587101099Srwatson{ 588172955Srwatson struct mac_mls *mm; 589101099Srwatson 590105696Srwatson if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 591105696Srwatson return (0); 592105696Srwatson 593105696Srwatson (*claimed)++; 594105696Srwatson 595172955Srwatson mm = SLOT(label); 596101099Srwatson 597172955Srwatson return (mls_to_string(sb, mm)); 598105696Srwatson} 599105696Srwatson 600105696Srwatsonstatic int 601172955Srwatsonmls_parse_element(struct mac_mls_element *element, char *string) 602101099Srwatson{ 603115395Srwatson char *compartment, *end, *level; 604115395Srwatson int value; 605105696Srwatson 606172955Srwatson if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { 607105696Srwatson element->mme_type = MAC_MLS_TYPE_HIGH; 608105696Srwatson element->mme_level = MAC_MLS_TYPE_UNDEF; 609172955Srwatson } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { 610105696Srwatson element->mme_type = MAC_MLS_TYPE_LOW; 611105696Srwatson element->mme_level = MAC_MLS_TYPE_UNDEF; 612105696Srwatson } else if (strcmp(string, "equal") == 0 || 613105696Srwatson strcmp(string, "eq") == 0) { 614105696Srwatson element->mme_type = MAC_MLS_TYPE_EQUAL; 615105696Srwatson element->mme_level = MAC_MLS_TYPE_UNDEF; 616105696Srwatson } else { 617115395Srwatson element->mme_type = MAC_MLS_TYPE_LEVEL; 618105696Srwatson 619115395Srwatson /* 620115395Srwatson * Numeric level piece of the element. 621115395Srwatson */ 622115395Srwatson level = strsep(&string, ":"); 623115395Srwatson value = strtol(level, &end, 10); 624115395Srwatson if (end == level || *end != '\0') 625105696Srwatson return (EINVAL); 626115395Srwatson if (value < 0 || value > 65535) 627115395Srwatson return (EINVAL); 628115395Srwatson element->mme_level = value; 629105696Srwatson 630115395Srwatson /* 631172955Srwatson * Optional compartment piece of the element. If none are 632172955Srwatson * included, we assume that the label has no compartments. 633115395Srwatson */ 634115395Srwatson if (string == NULL) 635115395Srwatson return (0); 636115395Srwatson if (*string == '\0') 637115395Srwatson return (0); 638105696Srwatson 639115395Srwatson while ((compartment = strsep(&string, "+")) != NULL) { 640115395Srwatson value = strtol(compartment, &end, 10); 641115395Srwatson if (compartment == end || *end != '\0') 642105696Srwatson return (EINVAL); 643115395Srwatson if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS) 644105696Srwatson return (EINVAL); 645115395Srwatson MAC_MLS_BIT_SET(value, element->mme_compartments); 646105696Srwatson } 647105696Srwatson } 648105696Srwatson 649105696Srwatson return (0); 650105696Srwatson} 651105696Srwatson 652105696Srwatson/* 653172955Srwatson * Note: destructively consumes the string, make a local copy before calling 654172955Srwatson * if that's a problem. 655105696Srwatson */ 656105696Srwatsonstatic int 657172955Srwatsonmls_parse(struct mac_mls *mm, char *string) 658105696Srwatson{ 659132232Srwatson char *rangehigh, *rangelow, *effective; 660101099Srwatson int error; 661101099Srwatson 662132232Srwatson effective = strsep(&string, "("); 663132232Srwatson if (*effective == '\0') 664132232Srwatson effective = NULL; 665115395Srwatson 666115395Srwatson if (string != NULL) { 667115395Srwatson rangelow = strsep(&string, "-"); 668115395Srwatson if (string == NULL) 669105696Srwatson return (EINVAL); 670115395Srwatson rangehigh = strsep(&string, ")"); 671115395Srwatson if (string == NULL) 672105696Srwatson return (EINVAL); 673115395Srwatson if (*string != '\0') 674105696Srwatson return (EINVAL); 675115414Srwatson } else { 676115414Srwatson rangelow = NULL; 677115414Srwatson rangehigh = NULL; 678105696Srwatson } 679115395Srwatson 680105696Srwatson KASSERT((rangelow != NULL && rangehigh != NULL) || 681105696Srwatson (rangelow == NULL && rangehigh == NULL), 682172955Srwatson ("mls_parse: range mismatch")); 683101099Srwatson 684172955Srwatson bzero(mm, sizeof(*mm)); 685132232Srwatson if (effective != NULL) { 686172955Srwatson error = mls_parse_element(&mm->mm_effective, effective); 687105696Srwatson if (error) 688105696Srwatson return (error); 689172955Srwatson mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 690105696Srwatson } 691105696Srwatson 692105696Srwatson if (rangelow != NULL) { 693181217Srwatson error = mls_parse_element(&mm->mm_rangelow, rangelow); 694105696Srwatson if (error) 695105696Srwatson return (error); 696181217Srwatson error = mls_parse_element(&mm->mm_rangehigh, rangehigh); 697105696Srwatson if (error) 698105696Srwatson return (error); 699172955Srwatson mm->mm_flags |= MAC_MLS_FLAG_RANGE; 700105696Srwatson } 701105696Srwatson 702172955Srwatson error = mls_valid(mm); 703101099Srwatson if (error) 704101099Srwatson return (error); 705101099Srwatson 706105696Srwatson return (0); 707105696Srwatson} 708101099Srwatson 709105696Srwatsonstatic int 710172955Srwatsonmls_internalize_label(struct label *label, char *element_name, 711105696Srwatson char *element_data, int *claimed) 712105696Srwatson{ 713172955Srwatson struct mac_mls *mm, mm_temp; 714105696Srwatson int error; 715105696Srwatson 716105696Srwatson if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 717105696Srwatson return (0); 718105696Srwatson 719105696Srwatson (*claimed)++; 720105696Srwatson 721172955Srwatson error = mls_parse(&mm_temp, element_data); 722105696Srwatson if (error) 723105696Srwatson return (error); 724105696Srwatson 725172955Srwatson mm = SLOT(label); 726172955Srwatson *mm = mm_temp; 727105696Srwatson 728101099Srwatson return (0); 729101099Srwatson} 730101099Srwatson 731105696Srwatsonstatic void 732172955Srwatsonmls_copy_label(struct label *src, struct label *dest) 733105696Srwatson{ 734105696Srwatson 735105696Srwatson *SLOT(dest) = *SLOT(src); 736105696Srwatson} 737105696Srwatson 738101099Srwatson/* 739173138Srwatson * Object-specific entry point implementations are sorted alphabetically by 740173138Srwatson * object type name and then by operation. 741101099Srwatson */ 742173138Srwatsonstatic int 743173138Srwatsonmls_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 744173138Srwatson struct ifnet *ifp, struct label *ifplabel) 745173138Srwatson{ 746173138Srwatson struct mac_mls *a, *b; 747173138Srwatson 748173138Srwatson if (!mls_enabled) 749173138Srwatson return (0); 750173138Srwatson 751173138Srwatson a = SLOT(dlabel); 752173138Srwatson b = SLOT(ifplabel); 753173138Srwatson 754173138Srwatson if (mls_equal_effective(a, b)) 755173138Srwatson return (0); 756173138Srwatson return (EACCES); 757173138Srwatson} 758173138Srwatson 759101099Srwatsonstatic void 760173138Srwatsonmls_bpfdesc_create(struct ucred *cred, struct bpf_d *d, struct label *dlabel) 761173138Srwatson{ 762173138Srwatson struct mac_mls *source, *dest; 763173138Srwatson 764173138Srwatson source = SLOT(cred->cr_label); 765173138Srwatson dest = SLOT(dlabel); 766173138Srwatson 767173138Srwatson mls_copy_effective(source, dest); 768173138Srwatson} 769173138Srwatson 770173138Srwatsonstatic void 771173138Srwatsonmls_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 772173138Srwatson struct mbuf *m, struct label *mlabel) 773173138Srwatson{ 774173138Srwatson struct mac_mls *source, *dest; 775173138Srwatson 776173138Srwatson source = SLOT(dlabel); 777173138Srwatson dest = SLOT(mlabel); 778173138Srwatson 779173138Srwatson mls_copy_effective(source, dest); 780173138Srwatson} 781173138Srwatson 782184407Srwatsonstatic void 783184407Srwatsonmls_cred_associate_nfsd(struct ucred *cred) 784184407Srwatson{ 785184407Srwatson struct mac_mls *label; 786184407Srwatson 787184407Srwatson label = SLOT(cred->cr_label); 788184407Srwatson mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL); 789184407Srwatson mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 790184407Srwatson NULL); 791184407Srwatson} 792184407Srwatson 793173138Srwatsonstatic int 794173138Srwatsonmls_cred_check_relabel(struct ucred *cred, struct label *newlabel) 795173138Srwatson{ 796173138Srwatson struct mac_mls *subj, *new; 797173138Srwatson int error; 798173138Srwatson 799173138Srwatson subj = SLOT(cred->cr_label); 800173138Srwatson new = SLOT(newlabel); 801173138Srwatson 802173138Srwatson /* 803173138Srwatson * If there is an MLS label update for the credential, it may be an 804173138Srwatson * update of effective, range, or both. 805173138Srwatson */ 806173138Srwatson error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 807173138Srwatson if (error) 808173138Srwatson return (error); 809173138Srwatson 810173138Srwatson /* 811173138Srwatson * If the MLS label is to be changed, authorize as appropriate. 812173138Srwatson */ 813173138Srwatson if (new->mm_flags & MAC_MLS_FLAGS_BOTH) { 814173138Srwatson /* 815173138Srwatson * If the change request modifies both the MLS label 816173138Srwatson * effective and range, check that the new effective will be 817173138Srwatson * in the new range. 818173138Srwatson */ 819173138Srwatson if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) == 820173138Srwatson MAC_MLS_FLAGS_BOTH && !mls_effective_in_range(new, new)) 821173138Srwatson return (EINVAL); 822173138Srwatson 823173138Srwatson /* 824173138Srwatson * To change the MLS effective label on a credential, the new 825173138Srwatson * effective label must be in the current range. 826173138Srwatson */ 827173138Srwatson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE && 828173138Srwatson !mls_effective_in_range(new, subj)) 829173138Srwatson return (EPERM); 830173138Srwatson 831173138Srwatson /* 832173138Srwatson * To change the MLS range label on a credential, the new 833173138Srwatson * range must be in the current range. 834173138Srwatson */ 835173138Srwatson if (new->mm_flags & MAC_MLS_FLAG_RANGE && 836173138Srwatson !mls_range_in_range(new, subj)) 837173138Srwatson return (EPERM); 838173138Srwatson 839173138Srwatson /* 840173138Srwatson * To have EQUAL in any component of the new credential MLS 841173138Srwatson * label, the subject must already have EQUAL in their label. 842173138Srwatson */ 843173138Srwatson if (mls_contains_equal(new)) { 844173138Srwatson error = mls_subject_privileged(subj); 845173138Srwatson if (error) 846173138Srwatson return (error); 847173138Srwatson } 848173138Srwatson } 849173138Srwatson 850173138Srwatson return (0); 851173138Srwatson} 852173138Srwatson 853173138Srwatsonstatic int 854173138Srwatsonmls_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 855173138Srwatson{ 856173138Srwatson struct mac_mls *subj, *obj; 857173138Srwatson 858173138Srwatson if (!mls_enabled) 859173138Srwatson return (0); 860173138Srwatson 861173138Srwatson subj = SLOT(cr1->cr_label); 862173138Srwatson obj = SLOT(cr2->cr_label); 863173138Srwatson 864173138Srwatson /* XXX: range */ 865173138Srwatson if (!mls_dominate_effective(subj, obj)) 866173138Srwatson return (ESRCH); 867173138Srwatson 868173138Srwatson return (0); 869173138Srwatson} 870173138Srwatson 871173138Srwatsonstatic void 872184407Srwatsonmls_cred_create_init(struct ucred *cred) 873184407Srwatson{ 874184407Srwatson struct mac_mls *dest; 875184407Srwatson 876184407Srwatson dest = SLOT(cred->cr_label); 877184407Srwatson 878184407Srwatson mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL); 879184407Srwatson mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 880184407Srwatson NULL); 881184407Srwatson} 882184407Srwatson 883184407Srwatsonstatic void 884184407Srwatsonmls_cred_create_swapper(struct ucred *cred) 885184407Srwatson{ 886184407Srwatson struct mac_mls *dest; 887184407Srwatson 888184407Srwatson dest = SLOT(cred->cr_label); 889184407Srwatson 890184407Srwatson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 891184407Srwatson mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 892184407Srwatson NULL); 893184407Srwatson} 894184407Srwatson 895184407Srwatsonstatic void 896173138Srwatsonmls_cred_relabel(struct ucred *cred, struct label *newlabel) 897173138Srwatson{ 898173138Srwatson struct mac_mls *source, *dest; 899173138Srwatson 900173138Srwatson source = SLOT(newlabel); 901173138Srwatson dest = SLOT(cred->cr_label); 902173138Srwatson 903173138Srwatson mls_copy(source, dest); 904173138Srwatson} 905173138Srwatson 906173138Srwatsonstatic void 907172955Srwatsonmls_devfs_create_device(struct ucred *cred, struct mount *mp, 908168976Srwatson struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 909101099Srwatson{ 910172955Srwatson struct mac_mls *mm; 911232405Sed const char *dn; 912101099Srwatson int mls_type; 913101099Srwatson 914172955Srwatson mm = SLOT(delabel); 915232405Sed dn = devtoname(dev); 916232405Sed if (strcmp(dn, "null") == 0 || 917232405Sed strcmp(dn, "zero") == 0 || 918232405Sed strcmp(dn, "random") == 0 || 919232405Sed strncmp(dn, "fd/", strlen("fd/")) == 0) 920101099Srwatson mls_type = MAC_MLS_TYPE_EQUAL; 921232405Sed else if (strcmp(dn, "kmem") == 0 || 922232405Sed strcmp(dn, "mem") == 0) 923101099Srwatson mls_type = MAC_MLS_TYPE_HIGH; 924105606Srwatson else if (ptys_equal && 925232405Sed (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 926232405Sed strncmp(dn, "pts/", strlen("pts/")) == 0 || 927232405Sed strncmp(dn, "ptyp", strlen("ptyp")) == 0)) 928105606Srwatson mls_type = MAC_MLS_TYPE_EQUAL; 929101099Srwatson else 930101099Srwatson mls_type = MAC_MLS_TYPE_LOW; 931172955Srwatson mls_set_effective(mm, mls_type, 0, NULL); 932101099Srwatson} 933101099Srwatson 934101099Srwatsonstatic void 935172955Srwatsonmls_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 936172955Srwatson struct devfs_dirent *de, struct label *delabel) 937101099Srwatson{ 938172955Srwatson struct mac_mls *mm; 939101099Srwatson 940172955Srwatson mm = SLOT(delabel); 941172955Srwatson mls_set_effective(mm, MAC_MLS_TYPE_LOW, 0, NULL); 942101099Srwatson} 943101099Srwatson 944101099Srwatsonstatic void 945172955Srwatsonmls_devfs_create_symlink(struct ucred *cred, struct mount *mp, 946107698Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 947122563Srwatson struct label *delabel) 948104535Srwatson{ 949104535Srwatson struct mac_mls *source, *dest; 950104535Srwatson 951122524Srwatson source = SLOT(cred->cr_label); 952104535Srwatson dest = SLOT(delabel); 953104535Srwatson 954172955Srwatson mls_copy_effective(source, dest); 955104535Srwatson} 956104535Srwatson 957104535Srwatsonstatic void 958172955Srwatsonmls_devfs_update(struct mount *mp, struct devfs_dirent *de, 959168976Srwatson struct label *delabel, struct vnode *vp, struct label *vplabel) 960101099Srwatson{ 961101099Srwatson struct mac_mls *source, *dest; 962101099Srwatson 963168976Srwatson source = SLOT(vplabel); 964168976Srwatson dest = SLOT(delabel); 965101099Srwatson 966172955Srwatson mls_copy_effective(source, dest); 967101099Srwatson} 968101099Srwatson 969101099Srwatsonstatic void 970172955Srwatsonmls_devfs_vnode_associate(struct mount *mp, struct label *mplabel, 971105988Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 972168976Srwatson struct label *vplabel) 973101099Srwatson{ 974101099Srwatson struct mac_mls *source, *dest; 975101099Srwatson 976105988Srwatson source = SLOT(delabel); 977168976Srwatson dest = SLOT(vplabel); 978101099Srwatson 979172955Srwatson mls_copy_effective(source, dest); 980101099Srwatson} 981101099Srwatson 982101099Srwatsonstatic int 983173138Srwatsonmls_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 984173138Srwatson struct label *ifplabel, struct label *newlabel) 985101099Srwatson{ 986173138Srwatson struct mac_mls *subj, *new; 987173138Srwatson int error; 988101099Srwatson 989173138Srwatson subj = SLOT(cred->cr_label); 990173138Srwatson new = SLOT(newlabel); 991101099Srwatson 992173138Srwatson /* 993173138Srwatson * If there is an MLS label update for the interface, it may be an 994173138Srwatson * update of effective, range, or both. 995173138Srwatson */ 996173138Srwatson error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 997173138Srwatson if (error) 998101099Srwatson return (error); 999101099Srwatson 1000173138Srwatson /* 1001173138Srwatson * Relabeling network interfaces requires MLS privilege. 1002173138Srwatson */ 1003175747Srwatson return (mls_subject_privileged(subj)); 1004101099Srwatson} 1005101099Srwatson 1006105988Srwatsonstatic int 1007173138Srwatsonmls_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1008173138Srwatson struct mbuf *m, struct label *mlabel) 1009105988Srwatson{ 1010173138Srwatson struct mac_mls *p, *i; 1011105988Srwatson 1012173138Srwatson if (!mls_enabled) 1013105988Srwatson return (0); 1014105988Srwatson 1015173138Srwatson p = SLOT(mlabel); 1016173138Srwatson i = SLOT(ifplabel); 1017105988Srwatson 1018173138Srwatson return (mls_effective_in_range(p, i) ? 0 : EACCES); 1019105988Srwatson} 1020105988Srwatson 1021101099Srwatsonstatic void 1022173138Srwatsonmls_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1023122875Srwatson{ 1024173138Srwatson struct mac_mls *dest; 1025173138Srwatson int type; 1026122875Srwatson 1027173138Srwatson dest = SLOT(ifplabel); 1028122875Srwatson 1029173138Srwatson if (ifp->if_type == IFT_LOOP) 1030173138Srwatson type = MAC_MLS_TYPE_EQUAL; 1031173138Srwatson else 1032173138Srwatson type = MAC_MLS_TYPE_LOW; 1033173138Srwatson 1034173138Srwatson mls_set_effective(dest, type, 0, NULL); 1035173138Srwatson mls_set_range(dest, type, 0, NULL, type, 0, NULL); 1036122875Srwatson} 1037122875Srwatson 1038122875Srwatsonstatic void 1039173138Srwatsonmls_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1040168976Srwatson struct mbuf *m, struct label *mlabel) 1041101099Srwatson{ 1042101099Srwatson struct mac_mls *source, *dest; 1043101099Srwatson 1044173138Srwatson source = SLOT(ifplabel); 1045168976Srwatson dest = SLOT(mlabel); 1046101099Srwatson 1047172955Srwatson mls_copy_effective(source, dest); 1048101099Srwatson} 1049101099Srwatson 1050101099Srwatsonstatic void 1051173138Srwatsonmls_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1052173138Srwatson struct label *ifplabel, struct label *newlabel) 1053101099Srwatson{ 1054101099Srwatson struct mac_mls *source, *dest; 1055101099Srwatson 1056173138Srwatson source = SLOT(newlabel); 1057173138Srwatson dest = SLOT(ifplabel); 1058101099Srwatson 1059173138Srwatson mls_copy(source, dest); 1060101099Srwatson} 1061101099Srwatson 1062173138Srwatsonstatic int 1063173138Srwatsonmls_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1064173138Srwatson struct mbuf *m, struct label *mlabel) 1065101099Srwatson{ 1066173138Srwatson struct mac_mls *p, *i; 1067101099Srwatson 1068173138Srwatson if (!mls_enabled) 1069173138Srwatson return (0); 1070101099Srwatson 1071173138Srwatson p = SLOT(mlabel); 1072173138Srwatson i = SLOT(inplabel); 1073173138Srwatson 1074173138Srwatson return (mls_equal_effective(p, i) ? 0 : EACCES); 1075101099Srwatson} 1076101099Srwatson 1077183980Sbzstatic int 1078183980Sbzmls_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 1079183980Sbz struct label *inplabel) 1080183980Sbz{ 1081183980Sbz struct mac_mls *subj, *obj; 1082183980Sbz 1083183980Sbz if (!mls_enabled) 1084183980Sbz return (0); 1085183980Sbz 1086183980Sbz subj = SLOT(cred->cr_label); 1087183980Sbz obj = SLOT(inplabel); 1088183980Sbz 1089183980Sbz if (!mls_dominate_effective(subj, obj)) 1090183980Sbz return (ENOENT); 1091183980Sbz 1092183980Sbz return (0); 1093183980Sbz} 1094183980Sbz 1095101099Srwatsonstatic void 1096173138Srwatsonmls_inpcb_create(struct socket *so, struct label *solabel, struct inpcb *inp, 1097173138Srwatson struct label *inplabel) 1098145855Srwatson{ 1099145855Srwatson struct mac_mls *source, *dest; 1100145855Srwatson 1101173138Srwatson source = SLOT(solabel); 1102173138Srwatson dest = SLOT(inplabel); 1103145855Srwatson 1104172955Srwatson mls_copy_effective(source, dest); 1105145855Srwatson} 1106145855Srwatson 1107145855Srwatsonstatic void 1108173138Srwatsonmls_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1109173138Srwatson struct mbuf *m, struct label *mlabel) 1110101099Srwatson{ 1111101099Srwatson struct mac_mls *source, *dest; 1112101099Srwatson 1113173138Srwatson source = SLOT(inplabel); 1114173138Srwatson dest = SLOT(mlabel); 1115101099Srwatson 1116172955Srwatson mls_copy_effective(source, dest); 1117101099Srwatson} 1118101099Srwatson 1119101099Srwatsonstatic void 1120173138Srwatsonmls_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1121173138Srwatson struct inpcb *inp, struct label *inplabel) 1122101099Srwatson{ 1123101099Srwatson struct mac_mls *source, *dest; 1124101099Srwatson 1125193391Srwatson SOCK_LOCK_ASSERT(so); 1126193391Srwatson 1127173138Srwatson source = SLOT(solabel); 1128173138Srwatson dest = SLOT(inplabel); 1129101099Srwatson 1130172955Srwatson mls_copy(source, dest); 1131101099Srwatson} 1132101099Srwatson 1133101099Srwatsonstatic void 1134184308Srwatsonmls_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1135184308Srwatson struct label *q6label) 1136184308Srwatson{ 1137184308Srwatson struct mac_mls *source, *dest; 1138184308Srwatson 1139184308Srwatson source = SLOT(mlabel); 1140184308Srwatson dest = SLOT(q6label); 1141184308Srwatson 1142184308Srwatson mls_copy_effective(source, dest); 1143184308Srwatson} 1144184308Srwatson 1145184308Srwatsonstatic int 1146184308Srwatsonmls_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1147184308Srwatson struct label *q6label) 1148184308Srwatson{ 1149184308Srwatson struct mac_mls *a, *b; 1150184308Srwatson 1151184308Srwatson a = SLOT(q6label); 1152184308Srwatson b = SLOT(mlabel); 1153184308Srwatson 1154184308Srwatson return (mls_equal_effective(a, b)); 1155184308Srwatson} 1156184308Srwatson 1157184308Srwatsonstatic void 1158184308Srwatsonmls_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1159184308Srwatson struct label *mlabel) 1160184308Srwatson{ 1161184308Srwatson struct mac_mls *source, *dest; 1162184308Srwatson 1163184308Srwatson source = SLOT(q6label); 1164184308Srwatson dest = SLOT(mlabel); 1165184308Srwatson 1166184308Srwatson /* Just use the head, since we require them all to match. */ 1167184308Srwatson mls_copy_effective(source, dest); 1168184308Srwatson} 1169184308Srwatson 1170184308Srwatsonstatic void 1171184308Srwatsonmls_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1172184308Srwatson struct label *q6label) 1173184308Srwatson{ 1174184308Srwatson 1175184308Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1176184308Srwatson} 1177184308Srwatson 1178184308Srwatsonstatic void 1179179781Srwatsonmls_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1180179781Srwatson struct label *qlabel) 1181101099Srwatson{ 1182101099Srwatson struct mac_mls *source, *dest; 1183101099Srwatson 1184173138Srwatson source = SLOT(mlabel); 1185179781Srwatson dest = SLOT(qlabel); 1186101099Srwatson 1187173138Srwatson mls_copy_effective(source, dest); 1188101099Srwatson} 1189101099Srwatson 1190173138Srwatsonstatic int 1191179781Srwatsonmls_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1192179781Srwatson struct label *qlabel) 1193101099Srwatson{ 1194173138Srwatson struct mac_mls *a, *b; 1195101099Srwatson 1196179781Srwatson a = SLOT(qlabel); 1197173138Srwatson b = SLOT(mlabel); 1198101099Srwatson 1199173138Srwatson return (mls_equal_effective(a, b)); 1200101099Srwatson} 1201101099Srwatson 1202140629Srwatsonstatic void 1203179781Srwatsonmls_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1204173138Srwatson struct label *mlabel) 1205140629Srwatson{ 1206140629Srwatson struct mac_mls *source, *dest; 1207140629Srwatson 1208179781Srwatson source = SLOT(qlabel); 1209173138Srwatson dest = SLOT(mlabel); 1210140629Srwatson 1211173138Srwatson /* Just use the head, since we require them all to match. */ 1212172955Srwatson mls_copy_effective(source, dest); 1213140629Srwatson} 1214140629Srwatson 1215140629Srwatsonstatic void 1216179781Srwatsonmls_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1217179781Srwatson struct label *qlabel) 1218140629Srwatson{ 1219140629Srwatson 1220173138Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1221140629Srwatson} 1222140629Srwatson 1223173138Srwatsonstatic int 1224173138Srwatsonmls_mount_check_stat(struct ucred *cred, struct mount *mp, 1225173138Srwatson struct label *mntlabel) 1226140629Srwatson{ 1227173138Srwatson struct mac_mls *subj, *obj; 1228140629Srwatson 1229173138Srwatson if (!mls_enabled) 1230173138Srwatson return (0); 1231140629Srwatson 1232173138Srwatson subj = SLOT(cred->cr_label); 1233173138Srwatson obj = SLOT(mntlabel); 1234140629Srwatson 1235173138Srwatson if (!mls_dominate_effective(subj, obj)) 1236173138Srwatson return (EACCES); 1237140629Srwatson 1238173138Srwatson return (0); 1239140629Srwatson} 1240140629Srwatson 1241101099Srwatsonstatic void 1242173138Srwatsonmls_mount_create(struct ucred *cred, struct mount *mp, struct label *mplabel) 1243101099Srwatson{ 1244101099Srwatson struct mac_mls *source, *dest; 1245101099Srwatson 1246173138Srwatson source = SLOT(cred->cr_label); 1247173138Srwatson dest = SLOT(mplabel); 1248101099Srwatson 1249172955Srwatson mls_copy_effective(source, dest); 1250101099Srwatson} 1251101099Srwatson 1252101099Srwatsonstatic void 1253173138Srwatsonmls_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel, 1254173138Srwatson struct mbuf *m, struct label *mlabel) 1255101099Srwatson{ 1256173138Srwatson struct mac_mls *dest; 1257101099Srwatson 1258173138Srwatson dest = SLOT(mlabel); 1259101099Srwatson 1260173138Srwatson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1261101099Srwatson} 1262101099Srwatson 1263101099Srwatsonstatic void 1264173138Srwatsonmls_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1265173138Srwatson struct mbuf *m, struct label *mlabel) 1266101099Srwatson{ 1267101099Srwatson struct mac_mls *dest; 1268101099Srwatson 1269173138Srwatson dest = SLOT(mlabel); 1270101099Srwatson 1271173138Srwatson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1272101099Srwatson} 1273101099Srwatson 1274101099Srwatsonstatic void 1275173138Srwatsonmls_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1276173138Srwatson struct mbuf *msend, struct label *msendlabel) 1277101099Srwatson{ 1278101099Srwatson struct mac_mls *source, *dest; 1279101099Srwatson 1280173138Srwatson source = SLOT(mrecvlabel); 1281173138Srwatson dest = SLOT(msendlabel); 1282101099Srwatson 1283172955Srwatson mls_copy_effective(source, dest); 1284101099Srwatson} 1285101099Srwatson 1286101099Srwatsonstatic void 1287173138Srwatsonmls_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1288101099Srwatson{ 1289173138Srwatson struct mac_mls *dest; 1290101099Srwatson 1291168976Srwatson dest = SLOT(mlabel); 1292101099Srwatson 1293173138Srwatson /* XXX: where is the label for the firewall really comming from? */ 1294173138Srwatson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1295101099Srwatson} 1296101099Srwatson 1297101099Srwatsonstatic void 1298172955Srwatsonmls_netinet_fragment(struct mbuf *m, struct label *mlabel, struct mbuf *frag, 1299172955Srwatson struct label *fraglabel) 1300101099Srwatson{ 1301101099Srwatson struct mac_mls *source, *dest; 1302101099Srwatson 1303168976Srwatson source = SLOT(mlabel); 1304168976Srwatson dest = SLOT(fraglabel); 1305101099Srwatson 1306172955Srwatson mls_copy_effective(source, dest); 1307101099Srwatson} 1308101099Srwatson 1309101099Srwatsonstatic void 1310173138Srwatsonmls_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1311173138Srwatson struct mbuf *msend, struct label *msendlabel) 1312123607Srwatson{ 1313123607Srwatson struct mac_mls *source, *dest; 1314123607Srwatson 1315173138Srwatson source = SLOT(mrecvlabel); 1316173138Srwatson dest = SLOT(msendlabel); 1317123607Srwatson 1318172955Srwatson mls_copy_effective(source, dest); 1319123607Srwatson} 1320123607Srwatson 1321123607Srwatsonstatic void 1322173138Srwatsonmls_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1323168976Srwatson struct mbuf *m, struct label *mlabel) 1324101099Srwatson{ 1325173138Srwatson struct mac_mls *dest; 1326101099Srwatson 1327168976Srwatson dest = SLOT(mlabel); 1328101099Srwatson 1329173138Srwatson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1330101099Srwatson} 1331101099Srwatson 1332101099Srwatsonstatic void 1333173138Srwatsonmls_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1334168976Srwatson struct mbuf *m, struct label *mlabel) 1335101099Srwatson{ 1336173138Srwatson struct mac_mls *dest; 1337101099Srwatson 1338168976Srwatson dest = SLOT(mlabel); 1339101099Srwatson 1340173138Srwatson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1341101099Srwatson} 1342101099Srwatson 1343101099Srwatsonstatic int 1344173138Srwatsonmls_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1345173138Srwatson struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1346101099Srwatson{ 1347101099Srwatson 1348173138Srwatson if (!mls_enabled) 1349173138Srwatson return (0); 1350101099Srwatson 1351173138Srwatson /* XXX: This will be implemented soon... */ 1352173138Srwatson 1353173138Srwatson return (0); 1354101099Srwatson} 1355101099Srwatson 1356173138Srwatsonstatic int 1357173138Srwatsonmls_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1358173138Srwatson struct label *pplabel) 1359101099Srwatson{ 1360173138Srwatson struct mac_mls *subj, *obj; 1361101099Srwatson 1362173138Srwatson if (!mls_enabled) 1363173138Srwatson return (0); 1364101099Srwatson 1365173138Srwatson subj = SLOT(cred->cr_label); 1366173138Srwatson obj = SLOT(pplabel); 1367101099Srwatson 1368173138Srwatson if (!mls_dominate_effective(subj, obj)) 1369173138Srwatson return (EACCES); 1370101099Srwatson 1371173138Srwatson return (0); 1372101099Srwatson} 1373101099Srwatson 1374173138Srwatsonstatic int 1375173138Srwatsonmls_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1376173138Srwatson struct label *pplabel) 1377122875Srwatson{ 1378173138Srwatson struct mac_mls *subj, *obj; 1379122875Srwatson 1380173138Srwatson if (!mls_enabled) 1381173138Srwatson return (0); 1382122875Srwatson 1383173138Srwatson subj = SLOT(cred->cr_label); 1384173138Srwatson obj = SLOT(pplabel); 1385173138Srwatson 1386173138Srwatson if (!mls_dominate_effective(subj, obj)) 1387173138Srwatson return (EACCES); 1388173138Srwatson 1389173138Srwatson return (0); 1390122875Srwatson} 1391122875Srwatson 1392173138Srwatsonstatic int 1393173138Srwatsonmls_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1394173138Srwatson struct label *pplabel, struct label *newlabel) 1395173095Srwatson{ 1396173138Srwatson struct mac_mls *subj, *obj, *new; 1397173138Srwatson int error; 1398173095Srwatson 1399173138Srwatson new = SLOT(newlabel); 1400173138Srwatson subj = SLOT(cred->cr_label); 1401173138Srwatson obj = SLOT(pplabel); 1402173095Srwatson 1403173138Srwatson /* 1404173138Srwatson * If there is an MLS label update for a pipe, it must be a effective 1405173138Srwatson * update. 1406173138Srwatson */ 1407173138Srwatson error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1408173138Srwatson if (error) 1409173138Srwatson return (error); 1410173095Srwatson 1411173138Srwatson /* 1412173138Srwatson * To perform a relabel of a pipe (MLS label or not), MLS must 1413173138Srwatson * authorize the relabel. 1414173138Srwatson */ 1415173138Srwatson if (!mls_effective_in_range(obj, subj)) 1416173138Srwatson return (EPERM); 1417173095Srwatson 1418173138Srwatson /* 1419173138Srwatson * If the MLS label is to be changed, authorize as appropriate. 1420173138Srwatson */ 1421173138Srwatson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1422173138Srwatson /* 1423173138Srwatson * To change the MLS label on a pipe, the new pipe label must 1424173138Srwatson * be in the subject range. 1425173138Srwatson */ 1426173138Srwatson if (!mls_effective_in_range(new, subj)) 1427173138Srwatson return (EPERM); 1428173095Srwatson 1429173138Srwatson /* 1430173138Srwatson * To change the MLS label on a pipe to be EQUAL, the subject 1431173138Srwatson * must have appropriate privilege. 1432173138Srwatson */ 1433173138Srwatson if (mls_contains_equal(new)) { 1434173138Srwatson error = mls_subject_privileged(subj); 1435173138Srwatson if (error) 1436173138Srwatson return (error); 1437173138Srwatson } 1438173138Srwatson } 1439173138Srwatson 1440173138Srwatson return (0); 1441173095Srwatson} 1442173095Srwatson 1443173138Srwatsonstatic int 1444173138Srwatsonmls_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 1445173138Srwatson struct label *pplabel) 1446173102Srwatson{ 1447173138Srwatson struct mac_mls *subj, *obj; 1448173102Srwatson 1449173138Srwatson if (!mls_enabled) 1450173138Srwatson return (0); 1451173102Srwatson 1452173138Srwatson subj = SLOT(cred->cr_label); 1453173138Srwatson obj = SLOT(pplabel); 1454173138Srwatson 1455173138Srwatson if (!mls_dominate_effective(subj, obj)) 1456173138Srwatson return (EACCES); 1457173138Srwatson 1458173138Srwatson return (0); 1459173102Srwatson} 1460173102Srwatson 1461173138Srwatsonstatic int 1462173138Srwatsonmls_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1463173138Srwatson struct label *pplabel) 1464162238Scsjp{ 1465173138Srwatson struct mac_mls *subj, *obj; 1466162238Scsjp 1467173138Srwatson if (!mls_enabled) 1468173138Srwatson return (0); 1469162238Scsjp 1470173138Srwatson subj = SLOT(cred->cr_label); 1471173138Srwatson obj = SLOT(pplabel); 1472173138Srwatson 1473173138Srwatson if (!mls_dominate_effective(obj, subj)) 1474173138Srwatson return (EACCES); 1475173138Srwatson 1476173138Srwatson return (0); 1477162238Scsjp} 1478162238Scsjp 1479165150Scsjpstatic void 1480173138Srwatsonmls_pipe_create(struct ucred *cred, struct pipepair *pp, 1481173138Srwatson struct label *pplabel) 1482173102Srwatson{ 1483173102Srwatson struct mac_mls *source, *dest; 1484173102Srwatson 1485173138Srwatson source = SLOT(cred->cr_label); 1486173138Srwatson dest = SLOT(pplabel); 1487173102Srwatson 1488173102Srwatson mls_copy_effective(source, dest); 1489173102Srwatson} 1490173102Srwatson 1491173102Srwatsonstatic void 1492173138Srwatsonmls_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1493173138Srwatson struct label *pplabel, struct label *newlabel) 1494173095Srwatson{ 1495173138Srwatson struct mac_mls *source, *dest; 1496173095Srwatson 1497173138Srwatson source = SLOT(newlabel); 1498173138Srwatson dest = SLOT(pplabel); 1499173095Srwatson 1500173138Srwatson mls_copy(source, dest); 1501173095Srwatson} 1502173095Srwatson 1503173138Srwatsonstatic int 1504180059Sjhbmls_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks, 1505173138Srwatson struct label *kslabel) 1506173095Srwatson{ 1507173138Srwatson struct mac_mls *subj, *obj; 1508173095Srwatson 1509173138Srwatson if (!mls_enabled) 1510173138Srwatson return (0); 1511173095Srwatson 1512173138Srwatson subj = SLOT(cred->cr_label); 1513173138Srwatson obj = SLOT(kslabel); 1514173095Srwatson 1515180059Sjhb if (!mls_dominate_effective(obj, subj)) 1516180059Sjhb return (EACCES); 1517180059Sjhb 1518180059Sjhb return (0); 1519180059Sjhb} 1520180059Sjhb 1521180059Sjhbstatic int 1522180059Sjhbmls_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred, 1523180059Sjhb struct ksem *ks, struct label *kslabel) 1524180059Sjhb{ 1525180059Sjhb struct mac_mls *subj, *obj; 1526180059Sjhb 1527180059Sjhb if (!mls_enabled) 1528180059Sjhb return (0); 1529180059Sjhb 1530180059Sjhb subj = SLOT(active_cred->cr_label); 1531180059Sjhb obj = SLOT(kslabel); 1532180059Sjhb 1533173138Srwatson if (!mls_dominate_effective(subj, obj)) 1534173138Srwatson return (EACCES); 1535165150Scsjp 1536173138Srwatson return (0); 1537165150Scsjp} 1538165150Scsjp 1539173138Srwatsonstatic int 1540225344Srwatsonmls_posixsem_check_setmode(struct ucred *cred, struct ksem *ks, 1541225344Srwatson struct label *shmlabel, mode_t mode) 1542225344Srwatson{ 1543225344Srwatson struct mac_mls *subj, *obj; 1544225344Srwatson 1545225344Srwatson if (!mls_enabled) 1546225344Srwatson return (0); 1547225344Srwatson 1548225344Srwatson subj = SLOT(cred->cr_label); 1549225344Srwatson obj = SLOT(shmlabel); 1550225344Srwatson 1551225344Srwatson if (!mls_dominate_effective(obj, subj)) 1552225344Srwatson return (EACCES); 1553225344Srwatson 1554225344Srwatson return (0); 1555225344Srwatson} 1556225344Srwatson 1557225344Srwatsonstatic int 1558225344Srwatsonmls_posixsem_check_setowner(struct ucred *cred, struct ksem *ks, 1559225344Srwatson struct label *shmlabel, uid_t uid, gid_t gid) 1560225344Srwatson{ 1561225344Srwatson struct mac_mls *subj, *obj; 1562225344Srwatson 1563225344Srwatson if (!mls_enabled) 1564225344Srwatson return (0); 1565225344Srwatson 1566225344Srwatson subj = SLOT(cred->cr_label); 1567225344Srwatson obj = SLOT(shmlabel); 1568225344Srwatson 1569225344Srwatson if (!mls_dominate_effective(obj, subj)) 1570225344Srwatson return (EACCES); 1571225344Srwatson 1572225344Srwatson return (0); 1573225344Srwatson} 1574225344Srwatson 1575225344Srwatsonstatic int 1576180059Sjhbmls_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred, 1577180059Sjhb struct ksem *ks, struct label *kslabel) 1578165150Scsjp{ 1579173138Srwatson struct mac_mls *subj, *obj; 1580165150Scsjp 1581173138Srwatson if (!mls_enabled) 1582173138Srwatson return (0); 1583172955Srwatson 1584180059Sjhb subj = SLOT(active_cred->cr_label); 1585173138Srwatson obj = SLOT(kslabel); 1586165150Scsjp 1587173138Srwatson if (!mls_dominate_effective(obj, subj)) 1588173138Srwatson return (EACCES); 1589101099Srwatson 1590173138Srwatson return (0); 1591101099Srwatson} 1592101099Srwatson 1593101099Srwatsonstatic void 1594173138Srwatsonmls_posixsem_create(struct ucred *cred, struct ksem *ks, 1595173138Srwatson struct label *kslabel) 1596101099Srwatson{ 1597173138Srwatson struct mac_mls *source, *dest; 1598101099Srwatson 1599173138Srwatson source = SLOT(cred->cr_label); 1600173138Srwatson dest = SLOT(kslabel); 1601101099Srwatson 1602173138Srwatson mls_copy_effective(source, dest); 1603101099Srwatson} 1604101099Srwatson 1605173138Srwatsonstatic int 1606225344Srwatsonmls_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd, 1607225344Srwatson struct label *shmlabel, int prot, int flags) 1608225344Srwatson{ 1609225344Srwatson struct mac_mls *subj, *obj; 1610225344Srwatson 1611225344Srwatson if (!mls_enabled) 1612225344Srwatson return (0); 1613225344Srwatson 1614225344Srwatson subj = SLOT(cred->cr_label); 1615225344Srwatson obj = SLOT(shmlabel); 1616225344Srwatson 1617225344Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 1618225344Srwatson if (!mls_dominate_effective(subj, obj)) 1619225344Srwatson return (EACCES); 1620225344Srwatson } 1621225344Srwatson if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 1622225344Srwatson if (!mls_dominate_effective(obj, subj)) 1623225344Srwatson return (EACCES); 1624225344Srwatson } 1625225344Srwatson 1626225344Srwatson return (0); 1627225344Srwatson} 1628225344Srwatson 1629225344Srwatsonstatic int 1630225344Srwatsonmls_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd, 1631225344Srwatson struct label *shmlabel, accmode_t accmode) 1632225344Srwatson{ 1633225344Srwatson struct mac_mls *subj, *obj; 1634225344Srwatson 1635225344Srwatson if (!mls_enabled) 1636225344Srwatson return (0); 1637225344Srwatson 1638225344Srwatson subj = SLOT(cred->cr_label); 1639225344Srwatson obj = SLOT(shmlabel); 1640225344Srwatson 1641225344Srwatson if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 1642225344Srwatson if (!mls_dominate_effective(subj, obj)) 1643225344Srwatson return (EACCES); 1644225344Srwatson } 1645225344Srwatson if (accmode & VMODIFY_PERMS) { 1646225344Srwatson if (!mls_dominate_effective(obj, subj)) 1647225344Srwatson return (EACCES); 1648225344Srwatson } 1649225344Srwatson 1650225344Srwatson return (0); 1651225344Srwatson} 1652225344Srwatson 1653225344Srwatsonstatic int 1654225344Srwatsonmls_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd, 1655225344Srwatson struct label *shmlabel, mode_t mode) 1656225344Srwatson{ 1657225344Srwatson struct mac_mls *subj, *obj; 1658225344Srwatson 1659225344Srwatson if (!mls_enabled) 1660225344Srwatson return (0); 1661225344Srwatson 1662225344Srwatson subj = SLOT(cred->cr_label); 1663225344Srwatson obj = SLOT(shmlabel); 1664225344Srwatson 1665225344Srwatson if (!mls_dominate_effective(obj, subj)) 1666225344Srwatson return (EACCES); 1667225344Srwatson 1668225344Srwatson return (0); 1669225344Srwatson} 1670225344Srwatson 1671225344Srwatsonstatic int 1672225344Srwatsonmls_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd, 1673225344Srwatson struct label *shmlabel, uid_t uid, gid_t gid) 1674225344Srwatson{ 1675225344Srwatson struct mac_mls *subj, *obj; 1676225344Srwatson 1677225344Srwatson if (!mls_enabled) 1678225344Srwatson return (0); 1679225344Srwatson 1680225344Srwatson subj = SLOT(cred->cr_label); 1681225344Srwatson obj = SLOT(shmlabel); 1682225344Srwatson 1683225344Srwatson if (!mls_dominate_effective(obj, subj)) 1684225344Srwatson return (EACCES); 1685225344Srwatson 1686225344Srwatson return (0); 1687225344Srwatson} 1688225344Srwatson 1689225344Srwatsonstatic int 1690225344Srwatsonmls_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred, 1691225344Srwatson struct shmfd *shmfd, struct label *shmlabel) 1692225344Srwatson{ 1693225344Srwatson struct mac_mls *subj, *obj; 1694225344Srwatson 1695225344Srwatson if (!mls_enabled) 1696225344Srwatson return (0); 1697225344Srwatson 1698225344Srwatson subj = SLOT(active_cred->cr_label); 1699225344Srwatson obj = SLOT(shmlabel); 1700225344Srwatson 1701225344Srwatson if (!mls_dominate_effective(subj, obj)) 1702225344Srwatson return (EACCES); 1703225344Srwatson 1704225344Srwatson return (0); 1705225344Srwatson} 1706225344Srwatson 1707225344Srwatsonstatic int 1708225344Srwatsonmls_posixshm_check_truncate(struct ucred *active_cred, 1709225344Srwatson struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel) 1710225344Srwatson{ 1711225344Srwatson struct mac_mls *subj, *obj; 1712225344Srwatson 1713225344Srwatson if (!mls_enabled) 1714225344Srwatson return (0); 1715225344Srwatson 1716225344Srwatson subj = SLOT(active_cred->cr_label); 1717225344Srwatson obj = SLOT(shmlabel); 1718225344Srwatson 1719225344Srwatson if (!mls_dominate_effective(obj, subj)) 1720225344Srwatson return (EACCES); 1721225344Srwatson 1722225344Srwatson return (0); 1723225344Srwatson} 1724225344Srwatson 1725225344Srwatsonstatic int 1726225344Srwatsonmls_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd, 1727225344Srwatson struct label *shmlabel) 1728225344Srwatson{ 1729225344Srwatson struct mac_mls *subj, *obj; 1730225344Srwatson 1731225344Srwatson if (!mls_enabled) 1732225344Srwatson return (0); 1733225344Srwatson 1734225344Srwatson subj = SLOT(cred->cr_label); 1735225344Srwatson obj = SLOT(shmlabel); 1736225344Srwatson 1737225344Srwatson if (!mls_dominate_effective(obj, subj)) 1738225344Srwatson return (EACCES); 1739225344Srwatson 1740225344Srwatson return (0); 1741225344Srwatson} 1742225344Srwatson 1743225344Srwatsonstatic void 1744225344Srwatsonmls_posixshm_create(struct ucred *cred, struct shmfd *shmfd, 1745225344Srwatson struct label *shmlabel) 1746225344Srwatson{ 1747225344Srwatson struct mac_mls *source, *dest; 1748225344Srwatson 1749225344Srwatson source = SLOT(cred->cr_label); 1750225344Srwatson dest = SLOT(shmlabel); 1751225344Srwatson 1752225344Srwatson mls_copy_effective(source, dest); 1753225344Srwatson} 1754225344Srwatson 1755225344Srwatsonstatic int 1756173138Srwatsonmls_proc_check_debug(struct ucred *cred, struct proc *p) 1757101099Srwatson{ 1758173138Srwatson struct mac_mls *subj, *obj; 1759101099Srwatson 1760173138Srwatson if (!mls_enabled) 1761173138Srwatson return (0); 1762101099Srwatson 1763173138Srwatson subj = SLOT(cred->cr_label); 1764173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1765173138Srwatson 1766173138Srwatson /* XXX: range checks */ 1767173138Srwatson if (!mls_dominate_effective(subj, obj)) 1768173138Srwatson return (ESRCH); 1769173138Srwatson if (!mls_dominate_effective(obj, subj)) 1770173138Srwatson return (EACCES); 1771173138Srwatson 1772173138Srwatson return (0); 1773101099Srwatson} 1774101099Srwatson 1775173138Srwatsonstatic int 1776173138Srwatsonmls_proc_check_sched(struct ucred *cred, struct proc *p) 1777140629Srwatson{ 1778173138Srwatson struct mac_mls *subj, *obj; 1779140629Srwatson 1780173138Srwatson if (!mls_enabled) 1781173138Srwatson return (0); 1782173138Srwatson 1783173138Srwatson subj = SLOT(cred->cr_label); 1784173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1785173138Srwatson 1786173138Srwatson /* XXX: range checks */ 1787173138Srwatson if (!mls_dominate_effective(subj, obj)) 1788173138Srwatson return (ESRCH); 1789173138Srwatson if (!mls_dominate_effective(obj, subj)) 1790173138Srwatson return (EACCES); 1791173138Srwatson 1792173138Srwatson return (0); 1793140629Srwatson} 1794140629Srwatson 1795173138Srwatsonstatic int 1796173138Srwatsonmls_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1797140629Srwatson{ 1798173138Srwatson struct mac_mls *subj, *obj; 1799140629Srwatson 1800173138Srwatson if (!mls_enabled) 1801173138Srwatson return (0); 1802173138Srwatson 1803173138Srwatson subj = SLOT(cred->cr_label); 1804173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1805173138Srwatson 1806173138Srwatson /* XXX: range checks */ 1807173138Srwatson if (!mls_dominate_effective(subj, obj)) 1808173138Srwatson return (ESRCH); 1809173138Srwatson if (!mls_dominate_effective(obj, subj)) 1810173138Srwatson return (EACCES); 1811173138Srwatson 1812173138Srwatson return (0); 1813140629Srwatson} 1814140629Srwatson 1815101099Srwatsonstatic int 1816173138Srwatsonmls_socket_check_deliver(struct socket *so, struct label *solabel, 1817173138Srwatson struct mbuf *m, struct label *mlabel) 1818101099Srwatson{ 1819173138Srwatson struct mac_mls *p, *s; 1820193391Srwatson int error; 1821101099Srwatson 1822172955Srwatson if (!mls_enabled) 1823101099Srwatson return (0); 1824101099Srwatson 1825173138Srwatson p = SLOT(mlabel); 1826173138Srwatson s = SLOT(solabel); 1827101099Srwatson 1828193391Srwatson SOCK_LOCK(so); 1829193391Srwatson error = mls_equal_effective(p, s) ? 0 : EACCES; 1830193391Srwatson SOCK_UNLOCK(so); 1831193391Srwatson 1832193391Srwatson return (error); 1833101099Srwatson} 1834101099Srwatson 1835101099Srwatsonstatic int 1836173138Srwatsonmls_socket_check_relabel(struct ucred *cred, struct socket *so, 1837173138Srwatson struct label *solabel, struct label *newlabel) 1838101099Srwatson{ 1839173138Srwatson struct mac_mls *subj, *obj, *new; 1840105634Srwatson int error; 1841101099Srwatson 1842193391Srwatson SOCK_LOCK_ASSERT(so); 1843193391Srwatson 1844173138Srwatson new = SLOT(newlabel); 1845122524Srwatson subj = SLOT(cred->cr_label); 1846173138Srwatson obj = SLOT(solabel); 1847101099Srwatson 1848101099Srwatson /* 1849173138Srwatson * If there is an MLS label update for the socket, it may be an 1850173138Srwatson * update of effective. 1851101099Srwatson */ 1852173138Srwatson error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1853105634Srwatson if (error) 1854105634Srwatson return (error); 1855101099Srwatson 1856101099Srwatson /* 1857173138Srwatson * To relabel a socket, the old socket effective must be in the 1858173138Srwatson * subject range. 1859173138Srwatson */ 1860173138Srwatson if (!mls_effective_in_range(obj, subj)) 1861173138Srwatson return (EPERM); 1862173138Srwatson 1863173138Srwatson /* 1864105634Srwatson * If the MLS label is to be changed, authorize as appropriate. 1865101099Srwatson */ 1866173138Srwatson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1867105634Srwatson /* 1868173138Srwatson * To relabel a socket, the new socket effective must be in 1869173138Srwatson * the subject range. 1870110351Srwatson */ 1871173138Srwatson if (!mls_effective_in_range(new, subj)) 1872105634Srwatson return (EPERM); 1873101099Srwatson 1874105634Srwatson /* 1875173138Srwatson * To change the MLS label on the socket to contain EQUAL, 1876173138Srwatson * the subject must have appropriate privilege. 1877105634Srwatson */ 1878172955Srwatson if (mls_contains_equal(new)) { 1879172955Srwatson error = mls_subject_privileged(subj); 1880105634Srwatson if (error) 1881105634Srwatson return (error); 1882105634Srwatson } 1883105634Srwatson } 1884105634Srwatson 1885101099Srwatson return (0); 1886101099Srwatson} 1887101099Srwatson 1888101099Srwatsonstatic int 1889173138Srwatsonmls_socket_check_visible(struct ucred *cred, struct socket *so, 1890173138Srwatson struct label *solabel) 1891101099Srwatson{ 1892101099Srwatson struct mac_mls *subj, *obj; 1893101099Srwatson 1894172955Srwatson if (!mls_enabled) 1895101099Srwatson return (0); 1896101099Srwatson 1897173138Srwatson subj = SLOT(cred->cr_label); 1898173138Srwatson obj = SLOT(solabel); 1899101099Srwatson 1900193391Srwatson SOCK_LOCK(so); 1901193391Srwatson if (!mls_dominate_effective(subj, obj)) { 1902193391Srwatson SOCK_UNLOCK(so); 1903173138Srwatson return (ENOENT); 1904193391Srwatson } 1905193391Srwatson SOCK_UNLOCK(so); 1906101099Srwatson 1907101099Srwatson return (0); 1908101099Srwatson} 1909101099Srwatson 1910173138Srwatsonstatic void 1911173138Srwatsonmls_socket_create(struct ucred *cred, struct socket *so, 1912173138Srwatson struct label *solabel) 1913173138Srwatson{ 1914173138Srwatson struct mac_mls *source, *dest; 1915173138Srwatson 1916173138Srwatson source = SLOT(cred->cr_label); 1917173138Srwatson dest = SLOT(solabel); 1918173138Srwatson 1919173138Srwatson mls_copy_effective(source, dest); 1920173138Srwatson} 1921173138Srwatson 1922173138Srwatsonstatic void 1923173138Srwatsonmls_socket_create_mbuf(struct socket *so, struct label *solabel, 1924173138Srwatson struct mbuf *m, struct label *mlabel) 1925173138Srwatson{ 1926173138Srwatson struct mac_mls *source, *dest; 1927173138Srwatson 1928173138Srwatson source = SLOT(solabel); 1929173138Srwatson dest = SLOT(mlabel); 1930173138Srwatson 1931193391Srwatson SOCK_LOCK(so); 1932173138Srwatson mls_copy_effective(source, dest); 1933193391Srwatson SOCK_UNLOCK(so); 1934173138Srwatson} 1935173138Srwatson 1936173138Srwatsonstatic void 1937173138Srwatsonmls_socket_newconn(struct socket *oldso, struct label *oldsolabel, 1938173138Srwatson struct socket *newso, struct label *newsolabel) 1939173138Srwatson{ 1940193391Srwatson struct mac_mls source, *dest; 1941173138Srwatson 1942193391Srwatson SOCK_LOCK(oldso); 1943193391Srwatson source = *SLOT(oldsolabel); 1944193391Srwatson SOCK_UNLOCK(oldso); 1945193391Srwatson 1946173138Srwatson dest = SLOT(newsolabel); 1947173138Srwatson 1948193391Srwatson SOCK_LOCK(newso); 1949193391Srwatson mls_copy_effective(&source, dest); 1950193391Srwatson SOCK_UNLOCK(newso); 1951173138Srwatson} 1952173138Srwatson 1953173138Srwatsonstatic void 1954173138Srwatsonmls_socket_relabel(struct ucred *cred, struct socket *so, 1955173138Srwatson struct label *solabel, struct label *newlabel) 1956173138Srwatson{ 1957173138Srwatson struct mac_mls *source, *dest; 1958173138Srwatson 1959193391Srwatson SOCK_LOCK_ASSERT(so); 1960193391Srwatson 1961173138Srwatson source = SLOT(newlabel); 1962173138Srwatson dest = SLOT(solabel); 1963173138Srwatson 1964173138Srwatson mls_copy(source, dest); 1965173138Srwatson} 1966173138Srwatson 1967173138Srwatsonstatic void 1968173138Srwatsonmls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 1969173138Srwatson struct socket *so, struct label *sopeerlabel) 1970173138Srwatson{ 1971173138Srwatson struct mac_mls *source, *dest; 1972173138Srwatson 1973173138Srwatson source = SLOT(mlabel); 1974173138Srwatson dest = SLOT(sopeerlabel); 1975173138Srwatson 1976193391Srwatson SOCK_LOCK(so); 1977173138Srwatson mls_copy_effective(source, dest); 1978193391Srwatson SOCK_UNLOCK(so); 1979173138Srwatson} 1980173138Srwatson 1981173138Srwatsonstatic void 1982173138Srwatsonmls_socketpeer_set_from_socket(struct socket *oldso, 1983173138Srwatson struct label *oldsolabel, struct socket *newso, 1984173138Srwatson struct label *newsopeerlabel) 1985173138Srwatson{ 1986193391Srwatson struct mac_mls source, *dest; 1987173138Srwatson 1988193391Srwatson SOCK_LOCK(oldso); 1989193391Srwatson source = *SLOT(oldsolabel); 1990193391Srwatson SOCK_UNLOCK(oldso); 1991193391Srwatson 1992173138Srwatson dest = SLOT(newsopeerlabel); 1993173138Srwatson 1994193391Srwatson SOCK_LOCK(newso); 1995193391Srwatson mls_copy_effective(&source, dest); 1996193391Srwatson SOCK_UNLOCK(newso); 1997173138Srwatson} 1998173138Srwatson 1999173138Srwatsonstatic void 2000173138Srwatsonmls_syncache_create(struct label *label, struct inpcb *inp) 2001173138Srwatson{ 2002173138Srwatson struct mac_mls *source, *dest; 2003173138Srwatson 2004173138Srwatson source = SLOT(inp->inp_label); 2005173138Srwatson dest = SLOT(label); 2006173138Srwatson 2007173138Srwatson mls_copy_effective(source, dest); 2008173138Srwatson} 2009173138Srwatson 2010173138Srwatsonstatic void 2011173138Srwatsonmls_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2012173138Srwatson struct label *mlabel) 2013173138Srwatson{ 2014173138Srwatson struct mac_mls *source, *dest; 2015173138Srwatson 2016173138Srwatson source = SLOT(sc_label); 2017173138Srwatson dest = SLOT(mlabel); 2018173138Srwatson 2019173138Srwatson mls_copy_effective(source, dest); 2020173138Srwatson} 2021173138Srwatson 2022101099Srwatsonstatic int 2023173138Srwatsonmls_system_check_acct(struct ucred *cred, struct vnode *vp, 2024173138Srwatson struct label *vplabel) 2025101099Srwatson{ 2026173138Srwatson struct mac_mls *subj, *obj; 2027101099Srwatson 2028173138Srwatson if (!mls_enabled) 2029173138Srwatson return (0); 2030173138Srwatson 2031235511Sbrueffer if (vplabel == NULL) 2032235511Sbrueffer return (0); 2033235511Sbrueffer 2034122524Srwatson subj = SLOT(cred->cr_label); 2035173138Srwatson obj = SLOT(vplabel); 2036101099Srwatson 2037173138Srwatson if (!mls_dominate_effective(obj, subj) || 2038173138Srwatson !mls_dominate_effective(subj, obj)) 2039173138Srwatson return (EACCES); 2040101099Srwatson 2041105634Srwatson return (0); 2042101099Srwatson} 2043101099Srwatson 2044101099Srwatsonstatic int 2045173138Srwatsonmls_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2046173138Srwatson struct label *vplabel) 2047101099Srwatson{ 2048173138Srwatson struct mac_mls *subj, *obj; 2049101099Srwatson 2050172955Srwatson if (!mls_enabled) 2051101099Srwatson return (0); 2052101099Srwatson 2053173138Srwatson subj = SLOT(cred->cr_label); 2054173138Srwatson obj = SLOT(vplabel); 2055101099Srwatson 2056173138Srwatson if (!mls_dominate_effective(obj, subj) || 2057173138Srwatson !mls_dominate_effective(subj, obj)) 2058173138Srwatson return (EACCES); 2059173138Srwatson 2060173138Srwatson return (0); 2061101099Srwatson} 2062101099Srwatson 2063101099Srwatsonstatic int 2064173138Srwatsonmls_system_check_swapon(struct ucred *cred, struct vnode *vp, 2065173138Srwatson struct label *vplabel) 2066122875Srwatson{ 2067173138Srwatson struct mac_mls *subj, *obj; 2068122875Srwatson 2069172955Srwatson if (!mls_enabled) 2070122875Srwatson return (0); 2071122875Srwatson 2072173138Srwatson subj = SLOT(cred->cr_label); 2073173138Srwatson obj = SLOT(vplabel); 2074122875Srwatson 2075173138Srwatson if (!mls_dominate_effective(obj, subj) || 2076173138Srwatson !mls_dominate_effective(subj, obj)) 2077173138Srwatson return (EACCES); 2078173138Srwatson 2079173138Srwatson return (0); 2080122875Srwatson} 2081122875Srwatson 2082173138Srwatsonstatic void 2083173138Srwatsonmls_sysvmsg_cleanup(struct label *msglabel) 2084173138Srwatson{ 2085173138Srwatson 2086173138Srwatson bzero(SLOT(msglabel), sizeof(struct mac_mls)); 2087173138Srwatson} 2088173138Srwatson 2089173138Srwatsonstatic void 2090173138Srwatsonmls_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2091173138Srwatson struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 2092173138Srwatson{ 2093173138Srwatson struct mac_mls *source, *dest; 2094173138Srwatson 2095173138Srwatson /* Ignore the msgq label. */ 2096173138Srwatson source = SLOT(cred->cr_label); 2097173138Srwatson dest = SLOT(msglabel); 2098173138Srwatson 2099173138Srwatson mls_copy_effective(source, dest); 2100173138Srwatson} 2101173138Srwatson 2102122875Srwatsonstatic int 2103172955Srwatsonmls_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 2104140629Srwatson struct label *msglabel) 2105140629Srwatson{ 2106140629Srwatson struct mac_mls *subj, *obj; 2107140629Srwatson 2108172955Srwatson if (!mls_enabled) 2109140629Srwatson return (0); 2110140629Srwatson 2111140629Srwatson subj = SLOT(cred->cr_label); 2112140629Srwatson obj = SLOT(msglabel); 2113140629Srwatson 2114172955Srwatson if (!mls_dominate_effective(subj, obj)) 2115140629Srwatson return (EACCES); 2116140629Srwatson 2117140629Srwatson return (0); 2118140629Srwatson} 2119140629Srwatson 2120140629Srwatsonstatic int 2121172955Srwatsonmls_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 2122140629Srwatson struct label *msglabel) 2123140629Srwatson{ 2124140629Srwatson struct mac_mls *subj, *obj; 2125140629Srwatson 2126172955Srwatson if (!mls_enabled) 2127140629Srwatson return (0); 2128140629Srwatson 2129140629Srwatson subj = SLOT(cred->cr_label); 2130140629Srwatson obj = SLOT(msglabel); 2131140629Srwatson 2132172955Srwatson if (!mls_dominate_effective(obj, subj)) 2133140629Srwatson return (EACCES); 2134140629Srwatson 2135140629Srwatson return (0); 2136140629Srwatson} 2137140629Srwatson 2138140629Srwatsonstatic int 2139172955Srwatsonmls_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 2140172955Srwatson struct label *msqklabel) 2141140629Srwatson{ 2142140629Srwatson struct mac_mls *subj, *obj; 2143140629Srwatson 2144172955Srwatson if (!mls_enabled) 2145140629Srwatson return (0); 2146140629Srwatson 2147140629Srwatson subj = SLOT(cred->cr_label); 2148140629Srwatson obj = SLOT(msqklabel); 2149140629Srwatson 2150172955Srwatson if (!mls_dominate_effective(subj, obj)) 2151140629Srwatson return (EACCES); 2152140629Srwatson 2153140629Srwatson return (0); 2154140629Srwatson} 2155140629Srwatson 2156140629Srwatsonstatic int 2157172955Srwatsonmls_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 2158172955Srwatson struct label *msqklabel) 2159140629Srwatson{ 2160140629Srwatson struct mac_mls *subj, *obj; 2161140629Srwatson 2162172955Srwatson if (!mls_enabled) 2163140629Srwatson return (0); 2164140629Srwatson 2165140629Srwatson subj = SLOT(cred->cr_label); 2166140629Srwatson obj = SLOT(msqklabel); 2167140629Srwatson 2168172955Srwatson if (!mls_dominate_effective(obj, subj)) 2169140629Srwatson return (EACCES); 2170140629Srwatson 2171140629Srwatson return (0); 2172140629Srwatson} 2173140629Srwatson 2174140629Srwatsonstatic int 2175172955Srwatsonmls_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 2176172955Srwatson struct label *msqklabel) 2177140629Srwatson{ 2178140629Srwatson struct mac_mls *subj, *obj; 2179140629Srwatson 2180172955Srwatson if (!mls_enabled) 2181140629Srwatson return (0); 2182140629Srwatson 2183140629Srwatson subj = SLOT(cred->cr_label); 2184140629Srwatson obj = SLOT(msqklabel); 2185140629Srwatson 2186172955Srwatson if (!mls_dominate_effective(subj, obj)) 2187140629Srwatson return (EACCES); 2188140629Srwatson 2189140629Srwatson return (0); 2190140629Srwatson} 2191140629Srwatson 2192140629Srwatsonstatic int 2193172955Srwatsonmls_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 2194172955Srwatson struct label *msqklabel, int cmd) 2195140629Srwatson{ 2196140629Srwatson struct mac_mls *subj, *obj; 2197140629Srwatson 2198172955Srwatson if (!mls_enabled) 2199140629Srwatson return (0); 2200140629Srwatson 2201140629Srwatson subj = SLOT(cred->cr_label); 2202140629Srwatson obj = SLOT(msqklabel); 2203140629Srwatson 2204140629Srwatson switch(cmd) { 2205140629Srwatson case IPC_RMID: 2206140629Srwatson case IPC_SET: 2207172955Srwatson if (!mls_dominate_effective(obj, subj)) 2208140629Srwatson return (EACCES); 2209140629Srwatson break; 2210140629Srwatson 2211140629Srwatson case IPC_STAT: 2212172955Srwatson if (!mls_dominate_effective(subj, obj)) 2213140629Srwatson return (EACCES); 2214140629Srwatson break; 2215140629Srwatson 2216140629Srwatson default: 2217140629Srwatson return (EACCES); 2218140629Srwatson } 2219140629Srwatson 2220140629Srwatson return (0); 2221140629Srwatson} 2222140629Srwatson 2223173138Srwatsonstatic void 2224173138Srwatsonmls_sysvmsq_cleanup(struct label *msqlabel) 2225173138Srwatson{ 2226173138Srwatson 2227173138Srwatson bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 2228173138Srwatson} 2229173138Srwatson 2230173138Srwatsonstatic void 2231173138Srwatsonmls_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2232173138Srwatson struct label *msqlabel) 2233173138Srwatson{ 2234173138Srwatson struct mac_mls *source, *dest; 2235173138Srwatson 2236173138Srwatson source = SLOT(cred->cr_label); 2237173138Srwatson dest = SLOT(msqlabel); 2238173138Srwatson 2239173138Srwatson mls_copy_effective(source, dest); 2240173138Srwatson} 2241173138Srwatson 2242140629Srwatsonstatic int 2243172955Srwatsonmls_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 2244172955Srwatson struct label *semaklabel, int cmd) 2245140629Srwatson{ 2246140629Srwatson struct mac_mls *subj, *obj; 2247140629Srwatson 2248172955Srwatson if (!mls_enabled) 2249140629Srwatson return (0); 2250140629Srwatson 2251140629Srwatson subj = SLOT(cred->cr_label); 2252140629Srwatson obj = SLOT(semaklabel); 2253140629Srwatson 2254140629Srwatson switch(cmd) { 2255140629Srwatson case IPC_RMID: 2256140629Srwatson case IPC_SET: 2257140629Srwatson case SETVAL: 2258140629Srwatson case SETALL: 2259172955Srwatson if (!mls_dominate_effective(obj, subj)) 2260140629Srwatson return (EACCES); 2261140629Srwatson break; 2262140629Srwatson 2263140629Srwatson case IPC_STAT: 2264140629Srwatson case GETVAL: 2265140629Srwatson case GETPID: 2266140629Srwatson case GETNCNT: 2267140629Srwatson case GETZCNT: 2268140629Srwatson case GETALL: 2269172955Srwatson if (!mls_dominate_effective(subj, obj)) 2270140629Srwatson return (EACCES); 2271140629Srwatson break; 2272140629Srwatson 2273140629Srwatson default: 2274140629Srwatson return (EACCES); 2275140629Srwatson } 2276140629Srwatson 2277140629Srwatson return (0); 2278140629Srwatson} 2279140629Srwatson 2280140629Srwatsonstatic int 2281172955Srwatsonmls_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 2282172955Srwatson struct label *semaklabel) 2283140629Srwatson{ 2284140629Srwatson struct mac_mls *subj, *obj; 2285140629Srwatson 2286172955Srwatson if (!mls_enabled) 2287140629Srwatson return (0); 2288140629Srwatson 2289140629Srwatson subj = SLOT(cred->cr_label); 2290140629Srwatson obj = SLOT(semaklabel); 2291140629Srwatson 2292172955Srwatson if (!mls_dominate_effective(subj, obj)) 2293140629Srwatson return (EACCES); 2294140629Srwatson 2295140629Srwatson return (0); 2296140629Srwatson} 2297140629Srwatson 2298140629Srwatsonstatic int 2299172955Srwatsonmls_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2300172955Srwatson struct label *semaklabel, size_t accesstype) 2301140629Srwatson{ 2302140629Srwatson struct mac_mls *subj, *obj; 2303140629Srwatson 2304172955Srwatson if (!mls_enabled) 2305140629Srwatson return (0); 2306140629Srwatson 2307140629Srwatson subj = SLOT(cred->cr_label); 2308140629Srwatson obj = SLOT(semaklabel); 2309140629Srwatson 2310140629Srwatson if( accesstype & SEM_R ) 2311172955Srwatson if (!mls_dominate_effective(subj, obj)) 2312140629Srwatson return (EACCES); 2313140629Srwatson 2314140629Srwatson if( accesstype & SEM_A ) 2315172955Srwatson if (!mls_dominate_effective(obj, subj)) 2316140629Srwatson return (EACCES); 2317140629Srwatson 2318140629Srwatson return (0); 2319140629Srwatson} 2320140629Srwatson 2321173138Srwatsonstatic void 2322173138Srwatsonmls_sysvsem_cleanup(struct label *semalabel) 2323173138Srwatson{ 2324173138Srwatson 2325173138Srwatson bzero(SLOT(semalabel), sizeof(struct mac_mls)); 2326173138Srwatson} 2327173138Srwatson 2328173138Srwatsonstatic void 2329173138Srwatsonmls_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2330173138Srwatson struct label *semalabel) 2331173138Srwatson{ 2332173138Srwatson struct mac_mls *source, *dest; 2333173138Srwatson 2334173138Srwatson source = SLOT(cred->cr_label); 2335173138Srwatson dest = SLOT(semalabel); 2336173138Srwatson 2337173138Srwatson mls_copy_effective(source, dest); 2338173138Srwatson} 2339173138Srwatson 2340140629Srwatsonstatic int 2341172955Srwatsonmls_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2342172955Srwatson struct label *shmseglabel, int shmflg) 2343140629Srwatson{ 2344140629Srwatson struct mac_mls *subj, *obj; 2345140629Srwatson 2346172955Srwatson if (!mls_enabled) 2347140629Srwatson return (0); 2348140629Srwatson 2349140629Srwatson subj = SLOT(cred->cr_label); 2350140629Srwatson obj = SLOT(shmseglabel); 2351140629Srwatson 2352172955Srwatson if (!mls_dominate_effective(subj, obj)) 2353172955Srwatson return (EACCES); 2354172955Srwatson if ((shmflg & SHM_RDONLY) == 0) { 2355172955Srwatson if (!mls_dominate_effective(obj, subj)) 2356140629Srwatson return (EACCES); 2357172955Srwatson } 2358140629Srwatson 2359140629Srwatson return (0); 2360140629Srwatson} 2361140629Srwatson 2362140629Srwatsonstatic int 2363172955Srwatsonmls_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2364172955Srwatson struct label *shmseglabel, int cmd) 2365140629Srwatson{ 2366140629Srwatson struct mac_mls *subj, *obj; 2367140629Srwatson 2368172955Srwatson if (!mls_enabled) 2369140629Srwatson return (0); 2370140629Srwatson 2371140629Srwatson subj = SLOT(cred->cr_label); 2372140629Srwatson obj = SLOT(shmseglabel); 2373140629Srwatson 2374140629Srwatson switch(cmd) { 2375140629Srwatson case IPC_RMID: 2376140629Srwatson case IPC_SET: 2377172955Srwatson if (!mls_dominate_effective(obj, subj)) 2378140629Srwatson return (EACCES); 2379140629Srwatson break; 2380140629Srwatson 2381140629Srwatson case IPC_STAT: 2382140629Srwatson case SHM_STAT: 2383172955Srwatson if (!mls_dominate_effective(subj, obj)) 2384140629Srwatson return (EACCES); 2385140629Srwatson break; 2386140629Srwatson 2387140629Srwatson default: 2388140629Srwatson return (EACCES); 2389140629Srwatson } 2390140629Srwatson 2391140629Srwatson return (0); 2392140629Srwatson} 2393140629Srwatson 2394140629Srwatsonstatic int 2395172955Srwatsonmls_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2396172955Srwatson struct label *shmseglabel, int shmflg) 2397140629Srwatson{ 2398140629Srwatson struct mac_mls *subj, *obj; 2399140629Srwatson 2400172955Srwatson if (!mls_enabled) 2401140629Srwatson return (0); 2402140629Srwatson 2403140629Srwatson subj = SLOT(cred->cr_label); 2404140629Srwatson obj = SLOT(shmseglabel); 2405140629Srwatson 2406172955Srwatson if (!mls_dominate_effective(obj, subj)) 2407140629Srwatson return (EACCES); 2408140629Srwatson 2409140629Srwatson return (0); 2410140629Srwatson} 2411140629Srwatson 2412173138Srwatsonstatic void 2413173138Srwatsonmls_sysvshm_cleanup(struct label *shmlabel) 2414101099Srwatson{ 2415101099Srwatson 2416173138Srwatson bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 2417101099Srwatson} 2418101099Srwatson 2419173138Srwatsonstatic void 2420173138Srwatsonmls_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2421173138Srwatson struct label *shmlabel) 2422101099Srwatson{ 2423173138Srwatson struct mac_mls *source, *dest; 2424103759Srwatson 2425173138Srwatson source = SLOT(cred->cr_label); 2426173138Srwatson dest = SLOT(shmlabel); 2427101099Srwatson 2428173138Srwatson mls_copy_effective(source, dest); 2429101099Srwatson} 2430101099Srwatson 2431101099Srwatsonstatic int 2432173138Srwatsonmls_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2433173138Srwatson struct vnode *vp, struct label *vplabel) 2434101099Srwatson{ 2435173138Srwatson struct mac_mls mm_temp, *source, *dest; 2436173138Srwatson int buflen, error; 2437101099Srwatson 2438173138Srwatson source = SLOT(mplabel); 2439173138Srwatson dest = SLOT(vplabel); 2440101099Srwatson 2441173138Srwatson buflen = sizeof(mm_temp); 2442173138Srwatson bzero(&mm_temp, buflen); 2443101099Srwatson 2444173138Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2445173138Srwatson MAC_MLS_EXTATTR_NAME, &buflen, (char *) &mm_temp, curthread); 2446173138Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 2447173138Srwatson /* Fall back to the mntlabel. */ 2448173138Srwatson mls_copy_effective(source, dest); 2449102115Srwatson return (0); 2450173138Srwatson } else if (error) 2451105634Srwatson return (error); 2452101099Srwatson 2453173138Srwatson if (buflen != sizeof(mm_temp)) { 2454173138Srwatson printf("mls_vnode_associate_extattr: bad size %d\n", buflen); 2455101099Srwatson return (EPERM); 2456105634Srwatson } 2457173138Srwatson if (mls_valid(&mm_temp) != 0) { 2458173138Srwatson printf("mls_vnode_associate_extattr: invalid\n"); 2459101099Srwatson return (EPERM); 2460105634Srwatson } 2461173138Srwatson if ((mm_temp.mm_flags & MAC_MLS_FLAGS_BOTH) != 2462173138Srwatson MAC_MLS_FLAG_EFFECTIVE) { 2463173138Srwatson printf("mls_associated_vnode_extattr: not effective\n"); 2464173138Srwatson return (EPERM); 2465173138Srwatson } 2466105634Srwatson 2467173138Srwatson mls_copy_effective(&mm_temp, dest); 2468101099Srwatson return (0); 2469101099Srwatson} 2470101099Srwatson 2471173138Srwatsonstatic void 2472173138Srwatsonmls_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2473173138Srwatson struct vnode *vp, struct label *vplabel) 2474101099Srwatson{ 2475173138Srwatson struct mac_mls *source, *dest; 2476101099Srwatson 2477173138Srwatson source = SLOT(mplabel); 2478173138Srwatson dest = SLOT(vplabel); 2479101099Srwatson 2480173138Srwatson mls_copy_effective(source, dest); 2481101099Srwatson} 2482101099Srwatson 2483101099Srwatsonstatic int 2484172955Srwatsonmls_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2485168976Srwatson struct label *dvplabel) 2486101099Srwatson{ 2487101099Srwatson struct mac_mls *subj, *obj; 2488101099Srwatson 2489172955Srwatson if (!mls_enabled) 2490101099Srwatson return (0); 2491101099Srwatson 2492122524Srwatson subj = SLOT(cred->cr_label); 2493168976Srwatson obj = SLOT(dvplabel); 2494101099Srwatson 2495172955Srwatson if (!mls_dominate_effective(subj, obj)) 2496101099Srwatson return (EACCES); 2497101099Srwatson 2498101099Srwatson return (0); 2499101099Srwatson} 2500101099Srwatson 2501101099Srwatsonstatic int 2502172955Srwatsonmls_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2503168976Srwatson struct label *dvplabel) 2504101099Srwatson{ 2505101099Srwatson struct mac_mls *subj, *obj; 2506101099Srwatson 2507172955Srwatson if (!mls_enabled) 2508101099Srwatson return (0); 2509101099Srwatson 2510122524Srwatson subj = SLOT(cred->cr_label); 2511168976Srwatson obj = SLOT(dvplabel); 2512101099Srwatson 2513172955Srwatson if (!mls_dominate_effective(subj, obj)) 2514101099Srwatson return (EACCES); 2515101099Srwatson 2516101099Srwatson return (0); 2517101099Srwatson} 2518101099Srwatson 2519101099Srwatsonstatic int 2520172955Srwatsonmls_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2521168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2522101099Srwatson{ 2523101099Srwatson struct mac_mls *subj, *obj; 2524101099Srwatson 2525172955Srwatson if (!mls_enabled) 2526101099Srwatson return (0); 2527101099Srwatson 2528122524Srwatson subj = SLOT(cred->cr_label); 2529168976Srwatson obj = SLOT(dvplabel); 2530101099Srwatson 2531172955Srwatson if (!mls_dominate_effective(obj, subj)) 2532101099Srwatson return (EACCES); 2533101099Srwatson 2534101099Srwatson return (0); 2535101099Srwatson} 2536101099Srwatson 2537101099Srwatsonstatic int 2538172955Srwatsonmls_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2539168976Srwatson struct label *vplabel, acl_type_t type) 2540101099Srwatson{ 2541101099Srwatson struct mac_mls *subj, *obj; 2542101099Srwatson 2543172955Srwatson if (!mls_enabled) 2544101099Srwatson return (0); 2545101099Srwatson 2546122524Srwatson subj = SLOT(cred->cr_label); 2547168976Srwatson obj = SLOT(vplabel); 2548101099Srwatson 2549172955Srwatson if (!mls_dominate_effective(obj, subj)) 2550101099Srwatson return (EACCES); 2551101099Srwatson 2552101099Srwatson return (0); 2553101099Srwatson} 2554101099Srwatson 2555101099Srwatsonstatic int 2556172955Srwatsonmls_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2557168976Srwatson struct label *vplabel, int attrnamespace, const char *name) 2558119202Srwatson{ 2559119202Srwatson struct mac_mls *subj, *obj; 2560119202Srwatson 2561172955Srwatson if (!mls_enabled) 2562119202Srwatson return (0); 2563119202Srwatson 2564122524Srwatson subj = SLOT(cred->cr_label); 2565168976Srwatson obj = SLOT(vplabel); 2566119202Srwatson 2567172955Srwatson if (!mls_dominate_effective(obj, subj)) 2568119202Srwatson return (EACCES); 2569119202Srwatson 2570119202Srwatson return (0); 2571119202Srwatson} 2572119202Srwatson 2573119202Srwatsonstatic int 2574172955Srwatsonmls_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2575168976Srwatson struct label *vplabel, struct image_params *imgp, 2576106648Srwatson struct label *execlabel) 2577101099Srwatson{ 2578106648Srwatson struct mac_mls *subj, *obj, *exec; 2579106648Srwatson int error; 2580101099Srwatson 2581106648Srwatson if (execlabel != NULL) { 2582106648Srwatson /* 2583106648Srwatson * We currently don't permit labels to be changed at 2584172955Srwatson * exec-time as part of MLS, so disallow non-NULL MLS label 2585172955Srwatson * elements in the execlabel. 2586106648Srwatson */ 2587106648Srwatson exec = SLOT(execlabel); 2588106648Srwatson error = mls_atmostflags(exec, 0); 2589106648Srwatson if (error) 2590106648Srwatson return (error); 2591106648Srwatson } 2592106648Srwatson 2593172955Srwatson if (!mls_enabled) 2594101099Srwatson return (0); 2595101099Srwatson 2596122524Srwatson subj = SLOT(cred->cr_label); 2597168976Srwatson obj = SLOT(vplabel); 2598101099Srwatson 2599172955Srwatson if (!mls_dominate_effective(subj, obj)) 2600101099Srwatson return (EACCES); 2601101099Srwatson 2602101099Srwatson return (0); 2603101099Srwatson} 2604101099Srwatson 2605101099Srwatsonstatic int 2606172955Srwatsonmls_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2607168976Srwatson struct label *vplabel, acl_type_t type) 2608101099Srwatson{ 2609101099Srwatson struct mac_mls *subj, *obj; 2610101099Srwatson 2611172955Srwatson if (!mls_enabled) 2612101099Srwatson return (0); 2613101099Srwatson 2614122524Srwatson subj = SLOT(cred->cr_label); 2615168976Srwatson obj = SLOT(vplabel); 2616101099Srwatson 2617172955Srwatson if (!mls_dominate_effective(subj, obj)) 2618101099Srwatson return (EACCES); 2619101099Srwatson 2620101099Srwatson return (0); 2621101099Srwatson} 2622101099Srwatson 2623101099Srwatsonstatic int 2624172955Srwatsonmls_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 2625189533Srwatson struct label *vplabel, int attrnamespace, const char *name) 2626101099Srwatson{ 2627101099Srwatson struct mac_mls *subj, *obj; 2628101099Srwatson 2629172955Srwatson if (!mls_enabled) 2630101099Srwatson return (0); 2631101099Srwatson 2632122524Srwatson subj = SLOT(cred->cr_label); 2633168976Srwatson obj = SLOT(vplabel); 2634101099Srwatson 2635172955Srwatson if (!mls_dominate_effective(subj, obj)) 2636101099Srwatson return (EACCES); 2637101099Srwatson 2638101099Srwatson return (0); 2639101099Srwatson} 2640101099Srwatson 2641105634Srwatsonstatic int 2642172955Srwatsonmls_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2643168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2644104530Srwatson struct componentname *cnp) 2645104530Srwatson{ 2646104530Srwatson struct mac_mls *subj, *obj; 2647104530Srwatson 2648172955Srwatson if (!mls_enabled) 2649104530Srwatson return (0); 2650104530Srwatson 2651122524Srwatson subj = SLOT(cred->cr_label); 2652168976Srwatson obj = SLOT(dvplabel); 2653104530Srwatson 2654172955Srwatson if (!mls_dominate_effective(obj, subj)) 2655104530Srwatson return (EACCES); 2656104530Srwatson 2657171555Srwatson obj = SLOT(vplabel); 2658172955Srwatson if (!mls_dominate_effective(obj, subj)) 2659104530Srwatson return (EACCES); 2660104530Srwatson 2661104530Srwatson return (0); 2662104530Srwatson} 2663104530Srwatson 2664101099Srwatsonstatic int 2665172955Srwatsonmls_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 2666168976Srwatson struct label *vplabel, int attrnamespace) 2667119202Srwatson{ 2668119202Srwatson 2669119202Srwatson struct mac_mls *subj, *obj; 2670119202Srwatson 2671172955Srwatson if (!mls_enabled) 2672119202Srwatson return (0); 2673119202Srwatson 2674122524Srwatson subj = SLOT(cred->cr_label); 2675168976Srwatson obj = SLOT(vplabel); 2676119202Srwatson 2677172955Srwatson if (!mls_dominate_effective(subj, obj)) 2678119202Srwatson return (EACCES); 2679119202Srwatson 2680119202Srwatson return (0); 2681119202Srwatson} 2682119202Srwatson 2683119202Srwatsonstatic int 2684172955Srwatsonmls_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 2685168976Srwatson struct label *dvplabel, struct componentname *cnp) 2686101099Srwatson{ 2687101099Srwatson struct mac_mls *subj, *obj; 2688103759Srwatson 2689172955Srwatson if (!mls_enabled) 2690101099Srwatson return (0); 2691103759Srwatson 2692122524Srwatson subj = SLOT(cred->cr_label); 2693168976Srwatson obj = SLOT(dvplabel); 2694103759Srwatson 2695172955Srwatson if (!mls_dominate_effective(subj, obj)) 2696101099Srwatson return (EACCES); 2697101099Srwatson 2698103759Srwatson return (0); 2699101099Srwatson} 2700101099Srwatson 2701101099Srwatsonstatic int 2702172955Srwatsonmls_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2703168976Srwatson struct label *vplabel, int prot, int flags) 2704104546Srwatson{ 2705104546Srwatson struct mac_mls *subj, *obj; 2706104546Srwatson 2707104546Srwatson /* 2708104546Srwatson * Rely on the use of open()-time protections to handle 2709104546Srwatson * non-revocation cases. 2710104546Srwatson */ 2711172955Srwatson if (!mls_enabled || !revocation_enabled) 2712104546Srwatson return (0); 2713104546Srwatson 2714122524Srwatson subj = SLOT(cred->cr_label); 2715168976Srwatson obj = SLOT(vplabel); 2716104546Srwatson 2717104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2718172955Srwatson if (!mls_dominate_effective(subj, obj)) 2719104546Srwatson return (EACCES); 2720104546Srwatson } 2721145076Scsjp if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2722172955Srwatson if (!mls_dominate_effective(obj, subj)) 2723104546Srwatson return (EACCES); 2724104546Srwatson } 2725104546Srwatson 2726105634Srwatson return (0); 2727104546Srwatson} 2728104546Srwatson 2729104546Srwatsonstatic int 2730172955Srwatsonmls_vnode_check_open(struct ucred *cred, struct vnode *vp, 2731184413Strasz struct label *vplabel, accmode_t accmode) 2732101099Srwatson{ 2733101099Srwatson struct mac_mls *subj, *obj; 2734101099Srwatson 2735172955Srwatson if (!mls_enabled) 2736101099Srwatson return (0); 2737101099Srwatson 2738122524Srwatson subj = SLOT(cred->cr_label); 2739168976Srwatson obj = SLOT(vplabel); 2740101099Srwatson 2741101099Srwatson /* XXX privilege override for admin? */ 2742190524Strasz if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 2743172955Srwatson if (!mls_dominate_effective(subj, obj)) 2744101099Srwatson return (EACCES); 2745101099Srwatson } 2746190524Strasz if (accmode & VMODIFY_PERMS) { 2747172955Srwatson if (!mls_dominate_effective(obj, subj)) 2748101099Srwatson return (EACCES); 2749101099Srwatson } 2750101099Srwatson 2751101099Srwatson return (0); 2752101099Srwatson} 2753101099Srwatson 2754101099Srwatsonstatic int 2755172955Srwatsonmls_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 2756168976Srwatson struct vnode *vp, struct label *vplabel) 2757102112Srwatson{ 2758102112Srwatson struct mac_mls *subj, *obj; 2759102112Srwatson 2760172955Srwatson if (!mls_enabled || !revocation_enabled) 2761102112Srwatson return (0); 2762102112Srwatson 2763122524Srwatson subj = SLOT(active_cred->cr_label); 2764168976Srwatson obj = SLOT(vplabel); 2765102112Srwatson 2766172955Srwatson if (!mls_dominate_effective(subj, obj)) 2767102112Srwatson return (EACCES); 2768102112Srwatson 2769102112Srwatson return (0); 2770102112Srwatson} 2771102112Srwatson 2772102112Srwatsonstatic int 2773172955Srwatsonmls_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2774168976Srwatson struct vnode *vp, struct label *vplabel) 2775102112Srwatson{ 2776102112Srwatson struct mac_mls *subj, *obj; 2777102112Srwatson 2778172955Srwatson if (!mls_enabled || !revocation_enabled) 2779102112Srwatson return (0); 2780102112Srwatson 2781122524Srwatson subj = SLOT(active_cred->cr_label); 2782168976Srwatson obj = SLOT(vplabel); 2783102112Srwatson 2784172955Srwatson if (!mls_dominate_effective(subj, obj)) 2785102112Srwatson return (EACCES); 2786102112Srwatson 2787102112Srwatson return (0); 2788102112Srwatson} 2789102112Srwatson 2790102112Srwatsonstatic int 2791172955Srwatsonmls_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 2792168976Srwatson struct label *dvplabel) 2793101099Srwatson{ 2794101099Srwatson struct mac_mls *subj, *obj; 2795101099Srwatson 2796172955Srwatson if (!mls_enabled) 2797101099Srwatson return (0); 2798101099Srwatson 2799122524Srwatson subj = SLOT(cred->cr_label); 2800168976Srwatson obj = SLOT(dvplabel); 2801101099Srwatson 2802172955Srwatson if (!mls_dominate_effective(subj, obj)) 2803101099Srwatson return (EACCES); 2804101099Srwatson 2805101099Srwatson return (0); 2806101099Srwatson} 2807101099Srwatson 2808101099Srwatsonstatic int 2809172955Srwatsonmls_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 2810168976Srwatson struct label *vplabel) 2811101099Srwatson{ 2812101099Srwatson struct mac_mls *subj, *obj; 2813101099Srwatson 2814172955Srwatson if (!mls_enabled) 2815101099Srwatson return (0); 2816101099Srwatson 2817122524Srwatson subj = SLOT(cred->cr_label); 2818168976Srwatson obj = SLOT(vplabel); 2819101099Srwatson 2820172955Srwatson if (!mls_dominate_effective(subj, obj)) 2821101099Srwatson return (EACCES); 2822101099Srwatson 2823101099Srwatson return (0); 2824101099Srwatson} 2825101099Srwatson 2826101099Srwatsonstatic int 2827172955Srwatsonmls_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2828168976Srwatson struct label *vplabel, struct label *newlabel) 2829101099Srwatson{ 2830101099Srwatson struct mac_mls *old, *new, *subj; 2831105634Srwatson int error; 2832101099Srwatson 2833168976Srwatson old = SLOT(vplabel); 2834101099Srwatson new = SLOT(newlabel); 2835122524Srwatson subj = SLOT(cred->cr_label); 2836101099Srwatson 2837101099Srwatson /* 2838105634Srwatson * If there is an MLS label update for the vnode, it must be a 2839132232Srwatson * effective label. 2840101099Srwatson */ 2841132232Srwatson error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2842105634Srwatson if (error) 2843105634Srwatson return (error); 2844101099Srwatson 2845101099Srwatson /* 2846105634Srwatson * To perform a relabel of the vnode (MLS label or not), MLS must 2847105634Srwatson * authorize the relabel. 2848101099Srwatson */ 2849172955Srwatson if (!mls_effective_in_range(old, subj)) 2850101099Srwatson return (EPERM); 2851101099Srwatson 2852101099Srwatson /* 2853105634Srwatson * If the MLS label is to be changed, authorize as appropriate. 2854101099Srwatson */ 2855132232Srwatson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2856105634Srwatson /* 2857105634Srwatson * To change the MLS label on a vnode, the new vnode label 2858105634Srwatson * must be in the subject range. 2859105634Srwatson */ 2860172955Srwatson if (!mls_effective_in_range(new, subj)) 2861105634Srwatson return (EPERM); 2862101099Srwatson 2863105634Srwatson /* 2864172955Srwatson * To change the MLS label on the vnode to be EQUAL, the 2865172955Srwatson * subject must have appropriate privilege. 2866105634Srwatson */ 2867172955Srwatson if (mls_contains_equal(new)) { 2868172955Srwatson error = mls_subject_privileged(subj); 2869105634Srwatson if (error) 2870105634Srwatson return (error); 2871105634Srwatson } 2872105634Srwatson } 2873105634Srwatson 2874105634Srwatson return (0); 2875101099Srwatson} 2876101099Srwatson 2877101099Srwatsonstatic int 2878172955Srwatsonmls_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2879168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2880101099Srwatson struct componentname *cnp) 2881101099Srwatson{ 2882101099Srwatson struct mac_mls *subj, *obj; 2883101099Srwatson 2884172955Srwatson if (!mls_enabled) 2885101099Srwatson return (0); 2886101099Srwatson 2887122524Srwatson subj = SLOT(cred->cr_label); 2888168976Srwatson obj = SLOT(dvplabel); 2889101099Srwatson 2890172955Srwatson if (!mls_dominate_effective(obj, subj)) 2891101099Srwatson return (EACCES); 2892101099Srwatson 2893168976Srwatson obj = SLOT(vplabel); 2894101099Srwatson 2895172955Srwatson if (!mls_dominate_effective(obj, subj)) 2896101099Srwatson return (EACCES); 2897101099Srwatson 2898101099Srwatson return (0); 2899101099Srwatson} 2900101099Srwatson 2901101099Srwatsonstatic int 2902172955Srwatsonmls_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2903168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2904168976Srwatson int samedir, struct componentname *cnp) 2905101099Srwatson{ 2906101099Srwatson struct mac_mls *subj, *obj; 2907101099Srwatson 2908172955Srwatson if (!mls_enabled) 2909101099Srwatson return (0); 2910101099Srwatson 2911122524Srwatson subj = SLOT(cred->cr_label); 2912168976Srwatson obj = SLOT(dvplabel); 2913101099Srwatson 2914172955Srwatson if (!mls_dominate_effective(obj, subj)) 2915101099Srwatson return (EACCES); 2916101099Srwatson 2917101099Srwatson if (vp != NULL) { 2918168976Srwatson obj = SLOT(vplabel); 2919101099Srwatson 2920172955Srwatson if (!mls_dominate_effective(obj, subj)) 2921101099Srwatson return (EACCES); 2922101099Srwatson } 2923101099Srwatson 2924101099Srwatson return (0); 2925101099Srwatson} 2926101099Srwatson 2927101099Srwatsonstatic int 2928172955Srwatsonmls_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2929168976Srwatson struct label *vplabel) 2930101099Srwatson{ 2931101099Srwatson struct mac_mls *subj, *obj; 2932101099Srwatson 2933172955Srwatson if (!mls_enabled) 2934101099Srwatson return (0); 2935101099Srwatson 2936122524Srwatson subj = SLOT(cred->cr_label); 2937168976Srwatson obj = SLOT(vplabel); 2938101099Srwatson 2939172955Srwatson if (!mls_dominate_effective(obj, subj)) 2940101099Srwatson return (EACCES); 2941101099Srwatson 2942101099Srwatson return (0); 2943101099Srwatson} 2944101099Srwatson 2945101099Srwatsonstatic int 2946172955Srwatsonmls_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2947168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 2948101099Srwatson{ 2949101099Srwatson struct mac_mls *subj, *obj; 2950101099Srwatson 2951172955Srwatson if (!mls_enabled) 2952101099Srwatson return (0); 2953101099Srwatson 2954122524Srwatson subj = SLOT(cred->cr_label); 2955168976Srwatson obj = SLOT(vplabel); 2956101099Srwatson 2957172955Srwatson if (!mls_dominate_effective(obj, subj)) 2958101099Srwatson return (EACCES); 2959101099Srwatson 2960101099Srwatson return (0); 2961101099Srwatson} 2962101099Srwatson 2963101099Srwatsonstatic int 2964172955Srwatsonmls_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2965189533Srwatson struct label *vplabel, int attrnamespace, const char *name) 2966101099Srwatson{ 2967101099Srwatson struct mac_mls *subj, *obj; 2968101099Srwatson 2969172955Srwatson if (!mls_enabled) 2970101099Srwatson return (0); 2971101099Srwatson 2972122524Srwatson subj = SLOT(cred->cr_label); 2973168976Srwatson obj = SLOT(vplabel); 2974101099Srwatson 2975172955Srwatson if (!mls_dominate_effective(obj, subj)) 2976101099Srwatson return (EACCES); 2977101099Srwatson 2978101099Srwatson /* XXX: protect the MAC EA in a special way? */ 2979101099Srwatson 2980101099Srwatson return (0); 2981101099Srwatson} 2982101099Srwatson 2983101099Srwatsonstatic int 2984172955Srwatsonmls_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2985168976Srwatson struct label *vplabel, u_long flags) 2986101099Srwatson{ 2987101099Srwatson struct mac_mls *subj, *obj; 2988101099Srwatson 2989172955Srwatson if (!mls_enabled) 2990101099Srwatson return (0); 2991101099Srwatson 2992122524Srwatson subj = SLOT(cred->cr_label); 2993168976Srwatson obj = SLOT(vplabel); 2994101099Srwatson 2995172955Srwatson if (!mls_dominate_effective(obj, subj)) 2996101099Srwatson return (EACCES); 2997101099Srwatson 2998101099Srwatson return (0); 2999101099Srwatson} 3000101099Srwatson 3001101099Srwatsonstatic int 3002172955Srwatsonmls_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 3003168976Srwatson struct label *vplabel, mode_t mode) 3004101099Srwatson{ 3005101099Srwatson struct mac_mls *subj, *obj; 3006101099Srwatson 3007172955Srwatson if (!mls_enabled) 3008101099Srwatson return (0); 3009101099Srwatson 3010122524Srwatson subj = SLOT(cred->cr_label); 3011168976Srwatson obj = SLOT(vplabel); 3012101099Srwatson 3013172955Srwatson if (!mls_dominate_effective(obj, subj)) 3014101099Srwatson return (EACCES); 3015101099Srwatson 3016101099Srwatson return (0); 3017101099Srwatson} 3018101099Srwatson 3019101099Srwatsonstatic int 3020172955Srwatsonmls_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 3021168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 3022101099Srwatson{ 3023101099Srwatson struct mac_mls *subj, *obj; 3024101099Srwatson 3025172955Srwatson if (!mls_enabled) 3026101099Srwatson return (0); 3027101099Srwatson 3028122524Srwatson subj = SLOT(cred->cr_label); 3029168976Srwatson obj = SLOT(vplabel); 3030101099Srwatson 3031172955Srwatson if (!mls_dominate_effective(obj, subj)) 3032101099Srwatson return (EACCES); 3033101099Srwatson 3034101099Srwatson return (0); 3035101099Srwatson} 3036101099Srwatson 3037101099Srwatsonstatic int 3038172955Srwatsonmls_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 3039168976Srwatson struct label *vplabel, struct timespec atime, struct timespec mtime) 3040101099Srwatson{ 3041101099Srwatson struct mac_mls *subj, *obj; 3042101099Srwatson 3043172955Srwatson if (!mls_enabled) 3044101099Srwatson return (0); 3045101099Srwatson 3046122524Srwatson subj = SLOT(cred->cr_label); 3047168976Srwatson obj = SLOT(vplabel); 3048101099Srwatson 3049172955Srwatson if (!mls_dominate_effective(obj, subj)) 3050101099Srwatson return (EACCES); 3051101099Srwatson 3052101099Srwatson return (0); 3053101099Srwatson} 3054101099Srwatson 3055101099Srwatsonstatic int 3056172955Srwatsonmls_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 3057168976Srwatson struct vnode *vp, struct label *vplabel) 3058101099Srwatson{ 3059101099Srwatson struct mac_mls *subj, *obj; 3060101099Srwatson 3061172955Srwatson if (!mls_enabled) 3062101099Srwatson return (0); 3063101099Srwatson 3064122524Srwatson subj = SLOT(active_cred->cr_label); 3065168976Srwatson obj = SLOT(vplabel); 3066101099Srwatson 3067172955Srwatson if (!mls_dominate_effective(subj, obj)) 3068101099Srwatson return (EACCES); 3069101099Srwatson 3070101099Srwatson return (0); 3071101099Srwatson} 3072101099Srwatson 3073102112Srwatsonstatic int 3074172955Srwatsonmls_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 3075172107Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3076172107Srwatson struct componentname *cnp) 3077172107Srwatson{ 3078172107Srwatson struct mac_mls *subj, *obj; 3079172107Srwatson 3080172955Srwatson if (!mls_enabled) 3081172107Srwatson return (0); 3082172107Srwatson 3083172107Srwatson subj = SLOT(cred->cr_label); 3084172107Srwatson obj = SLOT(dvplabel); 3085172107Srwatson 3086172955Srwatson if (!mls_dominate_effective(obj, subj)) 3087172107Srwatson return (EACCES); 3088172107Srwatson 3089172107Srwatson obj = SLOT(vplabel); 3090172107Srwatson 3091172955Srwatson if (!mls_dominate_effective(obj, subj)) 3092172107Srwatson return (EACCES); 3093172107Srwatson 3094172107Srwatson return (0); 3095172107Srwatson} 3096172107Srwatson 3097172107Srwatsonstatic int 3098172955Srwatsonmls_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred, 3099168976Srwatson struct vnode *vp, struct label *vplabel) 3100102112Srwatson{ 3101102112Srwatson struct mac_mls *subj, *obj; 3102102112Srwatson 3103172955Srwatson if (!mls_enabled || !revocation_enabled) 3104102112Srwatson return (0); 3105102112Srwatson 3106122524Srwatson subj = SLOT(active_cred->cr_label); 3107168976Srwatson obj = SLOT(vplabel); 3108102112Srwatson 3109172955Srwatson if (!mls_dominate_effective(obj, subj)) 3110102112Srwatson return (EACCES); 3111102112Srwatson 3112102112Srwatson return (0); 3113102112Srwatson} 3114102112Srwatson 3115173138Srwatsonstatic int 3116173138Srwatsonmls_vnode_create_extattr(struct ucred *cred, struct mount *mp, 3117173138Srwatson struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 3118173138Srwatson struct vnode *vp, struct label *vplabel, struct componentname *cnp) 3119173138Srwatson{ 3120173138Srwatson struct mac_mls *source, *dest, mm_temp; 3121173138Srwatson size_t buflen; 3122173138Srwatson int error; 3123173138Srwatson 3124173138Srwatson buflen = sizeof(mm_temp); 3125173138Srwatson bzero(&mm_temp, buflen); 3126173138Srwatson 3127173138Srwatson source = SLOT(cred->cr_label); 3128173138Srwatson dest = SLOT(vplabel); 3129173138Srwatson mls_copy_effective(source, &mm_temp); 3130173138Srwatson 3131173138Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 3132173138Srwatson MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 3133173138Srwatson if (error == 0) 3134173138Srwatson mls_copy_effective(source, dest); 3135173138Srwatson return (error); 3136173138Srwatson} 3137173138Srwatson 3138173138Srwatsonstatic void 3139173138Srwatsonmls_vnode_relabel(struct ucred *cred, struct vnode *vp, 3140173138Srwatson struct label *vplabel, struct label *label) 3141173138Srwatson{ 3142173138Srwatson struct mac_mls *source, *dest; 3143173138Srwatson 3144173138Srwatson source = SLOT(label); 3145173138Srwatson dest = SLOT(vplabel); 3146173138Srwatson 3147173138Srwatson mls_copy(source, dest); 3148173138Srwatson} 3149173138Srwatson 3150173138Srwatsonstatic int 3151173138Srwatsonmls_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 3152173138Srwatson struct label *vplabel, struct label *intlabel) 3153173138Srwatson{ 3154173138Srwatson struct mac_mls *source, mm_temp; 3155173138Srwatson size_t buflen; 3156173138Srwatson int error; 3157173138Srwatson 3158173138Srwatson buflen = sizeof(mm_temp); 3159173138Srwatson bzero(&mm_temp, buflen); 3160173138Srwatson 3161173138Srwatson source = SLOT(intlabel); 3162173138Srwatson if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 3163173138Srwatson return (0); 3164173138Srwatson 3165173138Srwatson mls_copy_effective(source, &mm_temp); 3166173138Srwatson 3167173138Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 3168173138Srwatson MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 3169173138Srwatson return (error); 3170173138Srwatson} 3171173138Srwatson 3172172955Srwatsonstatic struct mac_policy_ops mls_ops = 3173101099Srwatson{ 3174172955Srwatson .mpo_init = mls_init, 3175173138Srwatson 3176173138Srwatson .mpo_bpfdesc_check_receive = mls_bpfdesc_check_receive, 3177173138Srwatson .mpo_bpfdesc_create = mls_bpfdesc_create, 3178173138Srwatson .mpo_bpfdesc_create_mbuf = mls_bpfdesc_create_mbuf, 3179173138Srwatson .mpo_bpfdesc_destroy_label = mls_destroy_label, 3180172955Srwatson .mpo_bpfdesc_init_label = mls_init_label, 3181173138Srwatson 3182184407Srwatson .mpo_cred_associate_nfsd = mls_cred_associate_nfsd, 3183173138Srwatson .mpo_cred_check_relabel = mls_cred_check_relabel, 3184173138Srwatson .mpo_cred_check_visible = mls_cred_check_visible, 3185173138Srwatson .mpo_cred_copy_label = mls_copy_label, 3186184407Srwatson .mpo_cred_create_init = mls_cred_create_init, 3187184407Srwatson .mpo_cred_create_swapper = mls_cred_create_swapper, 3188172955Srwatson .mpo_cred_destroy_label = mls_destroy_label, 3189172955Srwatson .mpo_cred_externalize_label = mls_externalize_label, 3190173138Srwatson .mpo_cred_init_label = mls_init_label, 3191172955Srwatson .mpo_cred_internalize_label = mls_internalize_label, 3192173138Srwatson .mpo_cred_relabel = mls_cred_relabel, 3193173138Srwatson 3194172955Srwatson .mpo_devfs_create_device = mls_devfs_create_device, 3195172955Srwatson .mpo_devfs_create_directory = mls_devfs_create_directory, 3196172955Srwatson .mpo_devfs_create_symlink = mls_devfs_create_symlink, 3197173138Srwatson .mpo_devfs_destroy_label = mls_destroy_label, 3198173138Srwatson .mpo_devfs_init_label = mls_init_label, 3199172955Srwatson .mpo_devfs_update = mls_devfs_update, 3200172955Srwatson .mpo_devfs_vnode_associate = mls_devfs_vnode_associate, 3201173138Srwatson 3202173138Srwatson .mpo_ifnet_check_relabel = mls_ifnet_check_relabel, 3203173138Srwatson .mpo_ifnet_check_transmit = mls_ifnet_check_transmit, 3204173138Srwatson .mpo_ifnet_copy_label = mls_copy_label, 3205172955Srwatson .mpo_ifnet_create = mls_ifnet_create, 3206173138Srwatson .mpo_ifnet_create_mbuf = mls_ifnet_create_mbuf, 3207173138Srwatson .mpo_ifnet_destroy_label = mls_destroy_label, 3208173138Srwatson .mpo_ifnet_externalize_label = mls_externalize_label, 3209173138Srwatson .mpo_ifnet_init_label = mls_init_label, 3210173138Srwatson .mpo_ifnet_internalize_label = mls_internalize_label, 3211173138Srwatson .mpo_ifnet_relabel = mls_ifnet_relabel, 3212173138Srwatson 3213173138Srwatson .mpo_inpcb_check_deliver = mls_inpcb_check_deliver, 3214183980Sbz .mpo_inpcb_check_visible = mls_inpcb_check_visible, 3215172955Srwatson .mpo_inpcb_create = mls_inpcb_create, 3216173138Srwatson .mpo_inpcb_create_mbuf = mls_inpcb_create_mbuf, 3217173138Srwatson .mpo_inpcb_destroy_label = mls_destroy_label, 3218173138Srwatson .mpo_inpcb_init_label = mls_init_label_waitcheck, 3219173138Srwatson .mpo_inpcb_sosetlabel = mls_inpcb_sosetlabel, 3220173138Srwatson 3221184308Srwatson .mpo_ip6q_create = mls_ip6q_create, 3222184308Srwatson .mpo_ip6q_destroy_label = mls_destroy_label, 3223184308Srwatson .mpo_ip6q_init_label = mls_init_label_waitcheck, 3224184308Srwatson .mpo_ip6q_match = mls_ip6q_match, 3225184308Srwatson .mpo_ip6q_reassemble = mls_ip6q_reassemble, 3226184308Srwatson .mpo_ip6q_update = mls_ip6q_update, 3227184308Srwatson 3228172955Srwatson .mpo_ipq_create = mls_ipq_create, 3229173138Srwatson .mpo_ipq_destroy_label = mls_destroy_label, 3230173138Srwatson .mpo_ipq_init_label = mls_init_label_waitcheck, 3231172955Srwatson .mpo_ipq_match = mls_ipq_match, 3232173138Srwatson .mpo_ipq_reassemble = mls_ipq_reassemble, 3233172955Srwatson .mpo_ipq_update = mls_ipq_update, 3234173138Srwatson 3235173138Srwatson .mpo_mbuf_copy_label = mls_copy_label, 3236173138Srwatson .mpo_mbuf_destroy_label = mls_destroy_label, 3237173138Srwatson .mpo_mbuf_init_label = mls_init_label_waitcheck, 3238173138Srwatson 3239172955Srwatson .mpo_mount_check_stat = mls_mount_check_stat, 3240173138Srwatson .mpo_mount_create = mls_mount_create, 3241173138Srwatson .mpo_mount_destroy_label = mls_destroy_label, 3242173138Srwatson .mpo_mount_init_label = mls_init_label, 3243173138Srwatson 3244173138Srwatson .mpo_netatalk_aarp_send = mls_netatalk_aarp_send, 3245173138Srwatson 3246173138Srwatson .mpo_netinet_arp_send = mls_netinet_arp_send, 3247173138Srwatson .mpo_netinet_firewall_reply = mls_netinet_firewall_reply, 3248173138Srwatson .mpo_netinet_firewall_send = mls_netinet_firewall_send, 3249173138Srwatson .mpo_netinet_fragment = mls_netinet_fragment, 3250173138Srwatson .mpo_netinet_icmp_reply = mls_netinet_icmp_reply, 3251173138Srwatson .mpo_netinet_igmp_send = mls_netinet_igmp_send, 3252173138Srwatson 3253173138Srwatson .mpo_netinet6_nd6_send = mls_netinet6_nd6_send, 3254173138Srwatson 3255172955Srwatson .mpo_pipe_check_ioctl = mls_pipe_check_ioctl, 3256172955Srwatson .mpo_pipe_check_poll = mls_pipe_check_poll, 3257172955Srwatson .mpo_pipe_check_read = mls_pipe_check_read, 3258172955Srwatson .mpo_pipe_check_relabel = mls_pipe_check_relabel, 3259172955Srwatson .mpo_pipe_check_stat = mls_pipe_check_stat, 3260172955Srwatson .mpo_pipe_check_write = mls_pipe_check_write, 3261173138Srwatson .mpo_pipe_copy_label = mls_copy_label, 3262173138Srwatson .mpo_pipe_create = mls_pipe_create, 3263173138Srwatson .mpo_pipe_destroy_label = mls_destroy_label, 3264173138Srwatson .mpo_pipe_externalize_label = mls_externalize_label, 3265173138Srwatson .mpo_pipe_init_label = mls_init_label, 3266173138Srwatson .mpo_pipe_internalize_label = mls_internalize_label, 3267173138Srwatson .mpo_pipe_relabel = mls_pipe_relabel, 3268173138Srwatson 3269172955Srwatson .mpo_posixsem_check_getvalue = mls_posixsem_check_rdonly, 3270180059Sjhb .mpo_posixsem_check_open = mls_posixsem_check_openunlink, 3271172955Srwatson .mpo_posixsem_check_post = mls_posixsem_check_write, 3272225344Srwatson .mpo_posixsem_check_setmode = mls_posixsem_check_setmode, 3273225344Srwatson .mpo_posixsem_check_setowner = mls_posixsem_check_setowner, 3274180059Sjhb .mpo_posixsem_check_stat = mls_posixsem_check_rdonly, 3275180059Sjhb .mpo_posixsem_check_unlink = mls_posixsem_check_openunlink, 3276172955Srwatson .mpo_posixsem_check_wait = mls_posixsem_check_write, 3277173138Srwatson .mpo_posixsem_create = mls_posixsem_create, 3278173138Srwatson .mpo_posixsem_destroy_label = mls_destroy_label, 3279173138Srwatson .mpo_posixsem_init_label = mls_init_label, 3280173138Srwatson 3281225344Srwatson .mpo_posixshm_check_mmap = mls_posixshm_check_mmap, 3282225344Srwatson .mpo_posixshm_check_open = mls_posixshm_check_open, 3283225344Srwatson .mpo_posixshm_check_setmode = mls_posixshm_check_setmode, 3284225344Srwatson .mpo_posixshm_check_setowner = mls_posixshm_check_setowner, 3285225344Srwatson .mpo_posixshm_check_stat = mls_posixshm_check_stat, 3286225344Srwatson .mpo_posixshm_check_truncate = mls_posixshm_check_truncate, 3287225344Srwatson .mpo_posixshm_check_unlink = mls_posixshm_check_unlink, 3288225344Srwatson .mpo_posixshm_create = mls_posixshm_create, 3289225344Srwatson .mpo_posixshm_destroy_label = mls_destroy_label, 3290225344Srwatson .mpo_posixshm_init_label = mls_init_label, 3291225344Srwatson 3292172955Srwatson .mpo_proc_check_debug = mls_proc_check_debug, 3293172955Srwatson .mpo_proc_check_sched = mls_proc_check_sched, 3294172955Srwatson .mpo_proc_check_signal = mls_proc_check_signal, 3295173138Srwatson 3296172955Srwatson .mpo_socket_check_deliver = mls_socket_check_deliver, 3297172955Srwatson .mpo_socket_check_relabel = mls_socket_check_relabel, 3298172955Srwatson .mpo_socket_check_visible = mls_socket_check_visible, 3299173138Srwatson .mpo_socket_copy_label = mls_copy_label, 3300173138Srwatson .mpo_socket_create = mls_socket_create, 3301173138Srwatson .mpo_socket_create_mbuf = mls_socket_create_mbuf, 3302173138Srwatson .mpo_socket_destroy_label = mls_destroy_label, 3303173138Srwatson .mpo_socket_externalize_label = mls_externalize_label, 3304173138Srwatson .mpo_socket_init_label = mls_init_label_waitcheck, 3305173138Srwatson .mpo_socket_internalize_label = mls_internalize_label, 3306173138Srwatson .mpo_socket_newconn = mls_socket_newconn, 3307173138Srwatson .mpo_socket_relabel = mls_socket_relabel, 3308173138Srwatson 3309173138Srwatson .mpo_socketpeer_destroy_label = mls_destroy_label, 3310173138Srwatson .mpo_socketpeer_externalize_label = mls_externalize_label, 3311173138Srwatson .mpo_socketpeer_init_label = mls_init_label_waitcheck, 3312173138Srwatson .mpo_socketpeer_set_from_mbuf = mls_socketpeer_set_from_mbuf, 3313173138Srwatson .mpo_socketpeer_set_from_socket = mls_socketpeer_set_from_socket, 3314173138Srwatson 3315173138Srwatson .mpo_syncache_create = mls_syncache_create, 3316173138Srwatson .mpo_syncache_create_mbuf = mls_syncache_create_mbuf, 3317173138Srwatson .mpo_syncache_destroy_label = mls_destroy_label, 3318173138Srwatson .mpo_syncache_init_label = mls_init_label_waitcheck, 3319173138Srwatson 3320173138Srwatson .mpo_sysvmsg_cleanup = mls_sysvmsg_cleanup, 3321173138Srwatson .mpo_sysvmsg_create = mls_sysvmsg_create, 3322173138Srwatson .mpo_sysvmsg_destroy_label = mls_destroy_label, 3323173138Srwatson .mpo_sysvmsg_init_label = mls_init_label, 3324173138Srwatson 3325173138Srwatson .mpo_sysvmsq_check_msgrcv = mls_sysvmsq_check_msgrcv, 3326173138Srwatson .mpo_sysvmsq_check_msgrmid = mls_sysvmsq_check_msgrmid, 3327173138Srwatson .mpo_sysvmsq_check_msqget = mls_sysvmsq_check_msqget, 3328173138Srwatson .mpo_sysvmsq_check_msqsnd = mls_sysvmsq_check_msqsnd, 3329173138Srwatson .mpo_sysvmsq_check_msqrcv = mls_sysvmsq_check_msqrcv, 3330173138Srwatson .mpo_sysvmsq_check_msqctl = mls_sysvmsq_check_msqctl, 3331173138Srwatson .mpo_sysvmsq_cleanup = mls_sysvmsq_cleanup, 3332173138Srwatson .mpo_sysvmsq_destroy_label = mls_destroy_label, 3333173138Srwatson .mpo_sysvmsq_init_label = mls_init_label, 3334173138Srwatson .mpo_sysvmsq_create = mls_sysvmsq_create, 3335173138Srwatson 3336173138Srwatson .mpo_sysvsem_check_semctl = mls_sysvsem_check_semctl, 3337173138Srwatson .mpo_sysvsem_check_semget = mls_sysvsem_check_semget, 3338173138Srwatson .mpo_sysvsem_check_semop = mls_sysvsem_check_semop, 3339173138Srwatson .mpo_sysvsem_cleanup = mls_sysvsem_cleanup, 3340173138Srwatson .mpo_sysvsem_create = mls_sysvsem_create, 3341173138Srwatson .mpo_sysvsem_destroy_label = mls_destroy_label, 3342173138Srwatson .mpo_sysvsem_init_label = mls_init_label, 3343173138Srwatson 3344173138Srwatson .mpo_sysvshm_check_shmat = mls_sysvshm_check_shmat, 3345173138Srwatson .mpo_sysvshm_check_shmctl = mls_sysvshm_check_shmctl, 3346173138Srwatson .mpo_sysvshm_check_shmget = mls_sysvshm_check_shmget, 3347173138Srwatson .mpo_sysvshm_cleanup = mls_sysvshm_cleanup, 3348173138Srwatson .mpo_sysvshm_create = mls_sysvshm_create, 3349173138Srwatson .mpo_sysvshm_destroy_label = mls_destroy_label, 3350173138Srwatson .mpo_sysvshm_init_label = mls_init_label, 3351173138Srwatson 3352173138Srwatson 3353172955Srwatson .mpo_system_check_acct = mls_system_check_acct, 3354172955Srwatson .mpo_system_check_auditctl = mls_system_check_auditctl, 3355172955Srwatson .mpo_system_check_swapon = mls_system_check_swapon, 3356173138Srwatson 3357173138Srwatson .mpo_vnode_associate_extattr = mls_vnode_associate_extattr, 3358173138Srwatson .mpo_vnode_associate_singlelabel = mls_vnode_associate_singlelabel, 3359172955Srwatson .mpo_vnode_check_access = mls_vnode_check_open, 3360172955Srwatson .mpo_vnode_check_chdir = mls_vnode_check_chdir, 3361172955Srwatson .mpo_vnode_check_chroot = mls_vnode_check_chroot, 3362172955Srwatson .mpo_vnode_check_create = mls_vnode_check_create, 3363172955Srwatson .mpo_vnode_check_deleteacl = mls_vnode_check_deleteacl, 3364172955Srwatson .mpo_vnode_check_deleteextattr = mls_vnode_check_deleteextattr, 3365172955Srwatson .mpo_vnode_check_exec = mls_vnode_check_exec, 3366172955Srwatson .mpo_vnode_check_getacl = mls_vnode_check_getacl, 3367172955Srwatson .mpo_vnode_check_getextattr = mls_vnode_check_getextattr, 3368172955Srwatson .mpo_vnode_check_link = mls_vnode_check_link, 3369172955Srwatson .mpo_vnode_check_listextattr = mls_vnode_check_listextattr, 3370172955Srwatson .mpo_vnode_check_lookup = mls_vnode_check_lookup, 3371172955Srwatson .mpo_vnode_check_mmap = mls_vnode_check_mmap, 3372172955Srwatson .mpo_vnode_check_open = mls_vnode_check_open, 3373172955Srwatson .mpo_vnode_check_poll = mls_vnode_check_poll, 3374172955Srwatson .mpo_vnode_check_read = mls_vnode_check_read, 3375172955Srwatson .mpo_vnode_check_readdir = mls_vnode_check_readdir, 3376172955Srwatson .mpo_vnode_check_readlink = mls_vnode_check_readlink, 3377172955Srwatson .mpo_vnode_check_relabel = mls_vnode_check_relabel, 3378172955Srwatson .mpo_vnode_check_rename_from = mls_vnode_check_rename_from, 3379172955Srwatson .mpo_vnode_check_rename_to = mls_vnode_check_rename_to, 3380172955Srwatson .mpo_vnode_check_revoke = mls_vnode_check_revoke, 3381172955Srwatson .mpo_vnode_check_setacl = mls_vnode_check_setacl, 3382172955Srwatson .mpo_vnode_check_setextattr = mls_vnode_check_setextattr, 3383172955Srwatson .mpo_vnode_check_setflags = mls_vnode_check_setflags, 3384172955Srwatson .mpo_vnode_check_setmode = mls_vnode_check_setmode, 3385172955Srwatson .mpo_vnode_check_setowner = mls_vnode_check_setowner, 3386172955Srwatson .mpo_vnode_check_setutimes = mls_vnode_check_setutimes, 3387172955Srwatson .mpo_vnode_check_stat = mls_vnode_check_stat, 3388172955Srwatson .mpo_vnode_check_unlink = mls_vnode_check_unlink, 3389172955Srwatson .mpo_vnode_check_write = mls_vnode_check_write, 3390173138Srwatson .mpo_vnode_copy_label = mls_copy_label, 3391173138Srwatson .mpo_vnode_create_extattr = mls_vnode_create_extattr, 3392173138Srwatson .mpo_vnode_destroy_label = mls_destroy_label, 3393173138Srwatson .mpo_vnode_externalize_label = mls_externalize_label, 3394173138Srwatson .mpo_vnode_init_label = mls_init_label, 3395173138Srwatson .mpo_vnode_internalize_label = mls_internalize_label, 3396173138Srwatson .mpo_vnode_relabel = mls_vnode_relabel, 3397173138Srwatson .mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr, 3398101099Srwatson}; 3399101099Srwatson 3400172955SrwatsonMAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS", 3401187016Srwatson MPC_LOADTIME_FLAG_NOTLATE, &mls_slot); 3402