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 96227309Sedstatic 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; 911231378Sed const char *dn; 912101099Srwatson int mls_type; 913101099Srwatson 914172955Srwatson mm = SLOT(delabel); 915231378Sed dn = devtoname(dev); 916231378Sed if (strcmp(dn, "null") == 0 || 917231378Sed strcmp(dn, "zero") == 0 || 918231378Sed strcmp(dn, "random") == 0 || 919231378Sed strncmp(dn, "fd/", strlen("fd/")) == 0) 920101099Srwatson mls_type = MAC_MLS_TYPE_EQUAL; 921231378Sed else if (strcmp(dn, "kmem") == 0 || 922231378Sed strcmp(dn, "mem") == 0) 923101099Srwatson mls_type = MAC_MLS_TYPE_HIGH; 924105606Srwatson else if (ptys_equal && 925231378Sed (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 926231378Sed strncmp(dn, "pts/", strlen("pts/")) == 0 || 927231378Sed 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 1654254603Skibmls_posixshm_check_read(struct ucred *active_cred, struct ucred *file_cred, 1655254603Skib struct shmfd *shm, struct label *shmlabel) 1656254603Skib{ 1657254603Skib struct mac_mls *subj, *obj; 1658254603Skib 1659254603Skib if (!mls_enabled || !revocation_enabled) 1660254603Skib return (0); 1661254603Skib 1662254603Skib subj = SLOT(active_cred->cr_label); 1663254603Skib obj = SLOT(shmlabel); 1664254603Skib 1665254603Skib if (!mls_dominate_effective(subj, obj)) 1666254603Skib return (EACCES); 1667254603Skib 1668254603Skib return (0); 1669254603Skib} 1670254603Skib 1671254603Skibstatic int 1672225344Srwatsonmls_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd, 1673225344Srwatson struct label *shmlabel, mode_t mode) 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_setowner(struct ucred *cred, struct shmfd *shmfd, 1691225344Srwatson struct label *shmlabel, uid_t uid, gid_t gid) 1692225344Srwatson{ 1693225344Srwatson struct mac_mls *subj, *obj; 1694225344Srwatson 1695225344Srwatson if (!mls_enabled) 1696225344Srwatson return (0); 1697225344Srwatson 1698225344Srwatson subj = SLOT(cred->cr_label); 1699225344Srwatson obj = SLOT(shmlabel); 1700225344Srwatson 1701225344Srwatson if (!mls_dominate_effective(obj, subj)) 1702225344Srwatson return (EACCES); 1703225344Srwatson 1704225344Srwatson return (0); 1705225344Srwatson} 1706225344Srwatson 1707225344Srwatsonstatic int 1708225344Srwatsonmls_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred, 1709225344Srwatson 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(subj, obj)) 1720225344Srwatson return (EACCES); 1721225344Srwatson 1722225344Srwatson return (0); 1723225344Srwatson} 1724225344Srwatson 1725225344Srwatsonstatic int 1726225344Srwatsonmls_posixshm_check_truncate(struct ucred *active_cred, 1727225344Srwatson struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel) 1728225344Srwatson{ 1729225344Srwatson struct mac_mls *subj, *obj; 1730225344Srwatson 1731225344Srwatson if (!mls_enabled) 1732225344Srwatson return (0); 1733225344Srwatson 1734225344Srwatson subj = SLOT(active_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 int 1744225344Srwatsonmls_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd, 1745225344Srwatson struct label *shmlabel) 1746225344Srwatson{ 1747225344Srwatson struct mac_mls *subj, *obj; 1748225344Srwatson 1749225344Srwatson if (!mls_enabled) 1750225344Srwatson return (0); 1751225344Srwatson 1752225344Srwatson subj = SLOT(cred->cr_label); 1753225344Srwatson obj = SLOT(shmlabel); 1754225344Srwatson 1755225344Srwatson if (!mls_dominate_effective(obj, subj)) 1756225344Srwatson return (EACCES); 1757225344Srwatson 1758225344Srwatson return (0); 1759225344Srwatson} 1760225344Srwatson 1761254603Skibstatic int 1762254603Skibmls_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred, 1763254603Skib struct shmfd *shm, struct label *shmlabel) 1764254603Skib{ 1765254603Skib struct mac_mls *subj, *obj; 1766254603Skib 1767254603Skib if (!mls_enabled || !revocation_enabled) 1768254603Skib return (0); 1769254603Skib 1770254603Skib subj = SLOT(active_cred->cr_label); 1771254603Skib obj = SLOT(shmlabel); 1772254603Skib 1773254603Skib if (!mls_dominate_effective(subj, obj)) 1774254603Skib return (EACCES); 1775254603Skib 1776254603Skib return (0); 1777254603Skib} 1778254603Skib 1779225344Srwatsonstatic void 1780225344Srwatsonmls_posixshm_create(struct ucred *cred, struct shmfd *shmfd, 1781225344Srwatson struct label *shmlabel) 1782225344Srwatson{ 1783225344Srwatson struct mac_mls *source, *dest; 1784225344Srwatson 1785225344Srwatson source = SLOT(cred->cr_label); 1786225344Srwatson dest = SLOT(shmlabel); 1787225344Srwatson 1788225344Srwatson mls_copy_effective(source, dest); 1789225344Srwatson} 1790225344Srwatson 1791225344Srwatsonstatic int 1792173138Srwatsonmls_proc_check_debug(struct ucred *cred, struct proc *p) 1793101099Srwatson{ 1794173138Srwatson struct mac_mls *subj, *obj; 1795101099Srwatson 1796173138Srwatson if (!mls_enabled) 1797173138Srwatson return (0); 1798101099Srwatson 1799173138Srwatson subj = SLOT(cred->cr_label); 1800173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1801173138Srwatson 1802173138Srwatson /* XXX: range checks */ 1803173138Srwatson if (!mls_dominate_effective(subj, obj)) 1804173138Srwatson return (ESRCH); 1805173138Srwatson if (!mls_dominate_effective(obj, subj)) 1806173138Srwatson return (EACCES); 1807173138Srwatson 1808173138Srwatson return (0); 1809101099Srwatson} 1810101099Srwatson 1811173138Srwatsonstatic int 1812173138Srwatsonmls_proc_check_sched(struct ucred *cred, struct proc *p) 1813140629Srwatson{ 1814173138Srwatson struct mac_mls *subj, *obj; 1815140629Srwatson 1816173138Srwatson if (!mls_enabled) 1817173138Srwatson return (0); 1818173138Srwatson 1819173138Srwatson subj = SLOT(cred->cr_label); 1820173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1821173138Srwatson 1822173138Srwatson /* XXX: range checks */ 1823173138Srwatson if (!mls_dominate_effective(subj, obj)) 1824173138Srwatson return (ESRCH); 1825173138Srwatson if (!mls_dominate_effective(obj, subj)) 1826173138Srwatson return (EACCES); 1827173138Srwatson 1828173138Srwatson return (0); 1829140629Srwatson} 1830140629Srwatson 1831173138Srwatsonstatic int 1832173138Srwatsonmls_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1833140629Srwatson{ 1834173138Srwatson struct mac_mls *subj, *obj; 1835140629Srwatson 1836173138Srwatson if (!mls_enabled) 1837173138Srwatson return (0); 1838173138Srwatson 1839173138Srwatson subj = SLOT(cred->cr_label); 1840173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1841173138Srwatson 1842173138Srwatson /* XXX: range checks */ 1843173138Srwatson if (!mls_dominate_effective(subj, obj)) 1844173138Srwatson return (ESRCH); 1845173138Srwatson if (!mls_dominate_effective(obj, subj)) 1846173138Srwatson return (EACCES); 1847173138Srwatson 1848173138Srwatson return (0); 1849140629Srwatson} 1850140629Srwatson 1851101099Srwatsonstatic int 1852173138Srwatsonmls_socket_check_deliver(struct socket *so, struct label *solabel, 1853173138Srwatson struct mbuf *m, struct label *mlabel) 1854101099Srwatson{ 1855173138Srwatson struct mac_mls *p, *s; 1856193391Srwatson int error; 1857101099Srwatson 1858172955Srwatson if (!mls_enabled) 1859101099Srwatson return (0); 1860101099Srwatson 1861173138Srwatson p = SLOT(mlabel); 1862173138Srwatson s = SLOT(solabel); 1863101099Srwatson 1864193391Srwatson SOCK_LOCK(so); 1865193391Srwatson error = mls_equal_effective(p, s) ? 0 : EACCES; 1866193391Srwatson SOCK_UNLOCK(so); 1867193391Srwatson 1868193391Srwatson return (error); 1869101099Srwatson} 1870101099Srwatson 1871101099Srwatsonstatic int 1872173138Srwatsonmls_socket_check_relabel(struct ucred *cred, struct socket *so, 1873173138Srwatson struct label *solabel, struct label *newlabel) 1874101099Srwatson{ 1875173138Srwatson struct mac_mls *subj, *obj, *new; 1876105634Srwatson int error; 1877101099Srwatson 1878193391Srwatson SOCK_LOCK_ASSERT(so); 1879193391Srwatson 1880173138Srwatson new = SLOT(newlabel); 1881122524Srwatson subj = SLOT(cred->cr_label); 1882173138Srwatson obj = SLOT(solabel); 1883101099Srwatson 1884101099Srwatson /* 1885173138Srwatson * If there is an MLS label update for the socket, it may be an 1886173138Srwatson * update of effective. 1887101099Srwatson */ 1888173138Srwatson error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1889105634Srwatson if (error) 1890105634Srwatson return (error); 1891101099Srwatson 1892101099Srwatson /* 1893173138Srwatson * To relabel a socket, the old socket effective must be in the 1894173138Srwatson * subject range. 1895173138Srwatson */ 1896173138Srwatson if (!mls_effective_in_range(obj, subj)) 1897173138Srwatson return (EPERM); 1898173138Srwatson 1899173138Srwatson /* 1900105634Srwatson * If the MLS label is to be changed, authorize as appropriate. 1901101099Srwatson */ 1902173138Srwatson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1903105634Srwatson /* 1904173138Srwatson * To relabel a socket, the new socket effective must be in 1905173138Srwatson * the subject range. 1906110351Srwatson */ 1907173138Srwatson if (!mls_effective_in_range(new, subj)) 1908105634Srwatson return (EPERM); 1909101099Srwatson 1910105634Srwatson /* 1911173138Srwatson * To change the MLS label on the socket to contain EQUAL, 1912173138Srwatson * the subject must have appropriate privilege. 1913105634Srwatson */ 1914172955Srwatson if (mls_contains_equal(new)) { 1915172955Srwatson error = mls_subject_privileged(subj); 1916105634Srwatson if (error) 1917105634Srwatson return (error); 1918105634Srwatson } 1919105634Srwatson } 1920105634Srwatson 1921101099Srwatson return (0); 1922101099Srwatson} 1923101099Srwatson 1924101099Srwatsonstatic int 1925173138Srwatsonmls_socket_check_visible(struct ucred *cred, struct socket *so, 1926173138Srwatson struct label *solabel) 1927101099Srwatson{ 1928101099Srwatson struct mac_mls *subj, *obj; 1929101099Srwatson 1930172955Srwatson if (!mls_enabled) 1931101099Srwatson return (0); 1932101099Srwatson 1933173138Srwatson subj = SLOT(cred->cr_label); 1934173138Srwatson obj = SLOT(solabel); 1935101099Srwatson 1936193391Srwatson SOCK_LOCK(so); 1937193391Srwatson if (!mls_dominate_effective(subj, obj)) { 1938193391Srwatson SOCK_UNLOCK(so); 1939173138Srwatson return (ENOENT); 1940193391Srwatson } 1941193391Srwatson SOCK_UNLOCK(so); 1942101099Srwatson 1943101099Srwatson return (0); 1944101099Srwatson} 1945101099Srwatson 1946173138Srwatsonstatic void 1947173138Srwatsonmls_socket_create(struct ucred *cred, struct socket *so, 1948173138Srwatson struct label *solabel) 1949173138Srwatson{ 1950173138Srwatson struct mac_mls *source, *dest; 1951173138Srwatson 1952173138Srwatson source = SLOT(cred->cr_label); 1953173138Srwatson dest = SLOT(solabel); 1954173138Srwatson 1955173138Srwatson mls_copy_effective(source, dest); 1956173138Srwatson} 1957173138Srwatson 1958173138Srwatsonstatic void 1959173138Srwatsonmls_socket_create_mbuf(struct socket *so, struct label *solabel, 1960173138Srwatson struct mbuf *m, struct label *mlabel) 1961173138Srwatson{ 1962173138Srwatson struct mac_mls *source, *dest; 1963173138Srwatson 1964173138Srwatson source = SLOT(solabel); 1965173138Srwatson dest = SLOT(mlabel); 1966173138Srwatson 1967193391Srwatson SOCK_LOCK(so); 1968173138Srwatson mls_copy_effective(source, dest); 1969193391Srwatson SOCK_UNLOCK(so); 1970173138Srwatson} 1971173138Srwatson 1972173138Srwatsonstatic void 1973173138Srwatsonmls_socket_newconn(struct socket *oldso, struct label *oldsolabel, 1974173138Srwatson struct socket *newso, struct label *newsolabel) 1975173138Srwatson{ 1976193391Srwatson struct mac_mls source, *dest; 1977173138Srwatson 1978193391Srwatson SOCK_LOCK(oldso); 1979193391Srwatson source = *SLOT(oldsolabel); 1980193391Srwatson SOCK_UNLOCK(oldso); 1981193391Srwatson 1982173138Srwatson dest = SLOT(newsolabel); 1983173138Srwatson 1984193391Srwatson SOCK_LOCK(newso); 1985193391Srwatson mls_copy_effective(&source, dest); 1986193391Srwatson SOCK_UNLOCK(newso); 1987173138Srwatson} 1988173138Srwatson 1989173138Srwatsonstatic void 1990173138Srwatsonmls_socket_relabel(struct ucred *cred, struct socket *so, 1991173138Srwatson struct label *solabel, struct label *newlabel) 1992173138Srwatson{ 1993173138Srwatson struct mac_mls *source, *dest; 1994173138Srwatson 1995193391Srwatson SOCK_LOCK_ASSERT(so); 1996193391Srwatson 1997173138Srwatson source = SLOT(newlabel); 1998173138Srwatson dest = SLOT(solabel); 1999173138Srwatson 2000173138Srwatson mls_copy(source, dest); 2001173138Srwatson} 2002173138Srwatson 2003173138Srwatsonstatic void 2004173138Srwatsonmls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 2005173138Srwatson struct socket *so, struct label *sopeerlabel) 2006173138Srwatson{ 2007173138Srwatson struct mac_mls *source, *dest; 2008173138Srwatson 2009173138Srwatson source = SLOT(mlabel); 2010173138Srwatson dest = SLOT(sopeerlabel); 2011173138Srwatson 2012193391Srwatson SOCK_LOCK(so); 2013173138Srwatson mls_copy_effective(source, dest); 2014193391Srwatson SOCK_UNLOCK(so); 2015173138Srwatson} 2016173138Srwatson 2017173138Srwatsonstatic void 2018173138Srwatsonmls_socketpeer_set_from_socket(struct socket *oldso, 2019173138Srwatson struct label *oldsolabel, struct socket *newso, 2020173138Srwatson struct label *newsopeerlabel) 2021173138Srwatson{ 2022193391Srwatson struct mac_mls source, *dest; 2023173138Srwatson 2024193391Srwatson SOCK_LOCK(oldso); 2025193391Srwatson source = *SLOT(oldsolabel); 2026193391Srwatson SOCK_UNLOCK(oldso); 2027193391Srwatson 2028173138Srwatson dest = SLOT(newsopeerlabel); 2029173138Srwatson 2030193391Srwatson SOCK_LOCK(newso); 2031193391Srwatson mls_copy_effective(&source, dest); 2032193391Srwatson SOCK_UNLOCK(newso); 2033173138Srwatson} 2034173138Srwatson 2035173138Srwatsonstatic void 2036173138Srwatsonmls_syncache_create(struct label *label, struct inpcb *inp) 2037173138Srwatson{ 2038173138Srwatson struct mac_mls *source, *dest; 2039173138Srwatson 2040173138Srwatson source = SLOT(inp->inp_label); 2041173138Srwatson dest = SLOT(label); 2042173138Srwatson 2043173138Srwatson mls_copy_effective(source, dest); 2044173138Srwatson} 2045173138Srwatson 2046173138Srwatsonstatic void 2047173138Srwatsonmls_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2048173138Srwatson struct label *mlabel) 2049173138Srwatson{ 2050173138Srwatson struct mac_mls *source, *dest; 2051173138Srwatson 2052173138Srwatson source = SLOT(sc_label); 2053173138Srwatson dest = SLOT(mlabel); 2054173138Srwatson 2055173138Srwatson mls_copy_effective(source, dest); 2056173138Srwatson} 2057173138Srwatson 2058101099Srwatsonstatic int 2059173138Srwatsonmls_system_check_acct(struct ucred *cred, struct vnode *vp, 2060173138Srwatson struct label *vplabel) 2061101099Srwatson{ 2062173138Srwatson struct mac_mls *subj, *obj; 2063101099Srwatson 2064173138Srwatson if (!mls_enabled) 2065173138Srwatson return (0); 2066173138Srwatson 2067234957Sbrueffer if (vplabel == NULL) 2068234957Sbrueffer return (0); 2069234957Sbrueffer 2070122524Srwatson subj = SLOT(cred->cr_label); 2071173138Srwatson obj = SLOT(vplabel); 2072101099Srwatson 2073173138Srwatson if (!mls_dominate_effective(obj, subj) || 2074173138Srwatson !mls_dominate_effective(subj, obj)) 2075173138Srwatson return (EACCES); 2076101099Srwatson 2077105634Srwatson return (0); 2078101099Srwatson} 2079101099Srwatson 2080101099Srwatsonstatic int 2081173138Srwatsonmls_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2082173138Srwatson struct label *vplabel) 2083101099Srwatson{ 2084173138Srwatson struct mac_mls *subj, *obj; 2085101099Srwatson 2086172955Srwatson if (!mls_enabled) 2087101099Srwatson return (0); 2088101099Srwatson 2089173138Srwatson subj = SLOT(cred->cr_label); 2090173138Srwatson obj = SLOT(vplabel); 2091101099Srwatson 2092173138Srwatson if (!mls_dominate_effective(obj, subj) || 2093173138Srwatson !mls_dominate_effective(subj, obj)) 2094173138Srwatson return (EACCES); 2095173138Srwatson 2096173138Srwatson return (0); 2097101099Srwatson} 2098101099Srwatson 2099101099Srwatsonstatic int 2100173138Srwatsonmls_system_check_swapon(struct ucred *cred, struct vnode *vp, 2101173138Srwatson struct label *vplabel) 2102122875Srwatson{ 2103173138Srwatson struct mac_mls *subj, *obj; 2104122875Srwatson 2105172955Srwatson if (!mls_enabled) 2106122875Srwatson return (0); 2107122875Srwatson 2108173138Srwatson subj = SLOT(cred->cr_label); 2109173138Srwatson obj = SLOT(vplabel); 2110122875Srwatson 2111173138Srwatson if (!mls_dominate_effective(obj, subj) || 2112173138Srwatson !mls_dominate_effective(subj, obj)) 2113173138Srwatson return (EACCES); 2114173138Srwatson 2115173138Srwatson return (0); 2116122875Srwatson} 2117122875Srwatson 2118173138Srwatsonstatic void 2119173138Srwatsonmls_sysvmsg_cleanup(struct label *msglabel) 2120173138Srwatson{ 2121173138Srwatson 2122173138Srwatson bzero(SLOT(msglabel), sizeof(struct mac_mls)); 2123173138Srwatson} 2124173138Srwatson 2125173138Srwatsonstatic void 2126173138Srwatsonmls_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2127173138Srwatson struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 2128173138Srwatson{ 2129173138Srwatson struct mac_mls *source, *dest; 2130173138Srwatson 2131173138Srwatson /* Ignore the msgq label. */ 2132173138Srwatson source = SLOT(cred->cr_label); 2133173138Srwatson dest = SLOT(msglabel); 2134173138Srwatson 2135173138Srwatson mls_copy_effective(source, dest); 2136173138Srwatson} 2137173138Srwatson 2138122875Srwatsonstatic int 2139172955Srwatsonmls_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 2140140629Srwatson struct label *msglabel) 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(msglabel); 2149140629Srwatson 2150172955Srwatson if (!mls_dominate_effective(subj, obj)) 2151140629Srwatson return (EACCES); 2152140629Srwatson 2153140629Srwatson return (0); 2154140629Srwatson} 2155140629Srwatson 2156140629Srwatsonstatic int 2157172955Srwatsonmls_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 2158140629Srwatson struct label *msglabel) 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(msglabel); 2167140629Srwatson 2168172955Srwatson if (!mls_dominate_effective(obj, subj)) 2169140629Srwatson return (EACCES); 2170140629Srwatson 2171140629Srwatson return (0); 2172140629Srwatson} 2173140629Srwatson 2174140629Srwatsonstatic int 2175172955Srwatsonmls_sysvmsq_check_msqget(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_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 2194172955Srwatson struct label *msqklabel) 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 2204172955Srwatson if (!mls_dominate_effective(obj, subj)) 2205140629Srwatson return (EACCES); 2206140629Srwatson 2207140629Srwatson return (0); 2208140629Srwatson} 2209140629Srwatson 2210140629Srwatsonstatic int 2211172955Srwatsonmls_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 2212172955Srwatson struct label *msqklabel) 2213140629Srwatson{ 2214140629Srwatson struct mac_mls *subj, *obj; 2215140629Srwatson 2216172955Srwatson if (!mls_enabled) 2217140629Srwatson return (0); 2218140629Srwatson 2219140629Srwatson subj = SLOT(cred->cr_label); 2220140629Srwatson obj = SLOT(msqklabel); 2221140629Srwatson 2222172955Srwatson if (!mls_dominate_effective(subj, obj)) 2223140629Srwatson return (EACCES); 2224140629Srwatson 2225140629Srwatson return (0); 2226140629Srwatson} 2227140629Srwatson 2228140629Srwatsonstatic int 2229172955Srwatsonmls_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 2230172955Srwatson struct label *msqklabel, int cmd) 2231140629Srwatson{ 2232140629Srwatson struct mac_mls *subj, *obj; 2233140629Srwatson 2234172955Srwatson if (!mls_enabled) 2235140629Srwatson return (0); 2236140629Srwatson 2237140629Srwatson subj = SLOT(cred->cr_label); 2238140629Srwatson obj = SLOT(msqklabel); 2239140629Srwatson 2240140629Srwatson switch(cmd) { 2241140629Srwatson case IPC_RMID: 2242140629Srwatson case IPC_SET: 2243172955Srwatson if (!mls_dominate_effective(obj, subj)) 2244140629Srwatson return (EACCES); 2245140629Srwatson break; 2246140629Srwatson 2247140629Srwatson case IPC_STAT: 2248172955Srwatson if (!mls_dominate_effective(subj, obj)) 2249140629Srwatson return (EACCES); 2250140629Srwatson break; 2251140629Srwatson 2252140629Srwatson default: 2253140629Srwatson return (EACCES); 2254140629Srwatson } 2255140629Srwatson 2256140629Srwatson return (0); 2257140629Srwatson} 2258140629Srwatson 2259173138Srwatsonstatic void 2260173138Srwatsonmls_sysvmsq_cleanup(struct label *msqlabel) 2261173138Srwatson{ 2262173138Srwatson 2263173138Srwatson bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 2264173138Srwatson} 2265173138Srwatson 2266173138Srwatsonstatic void 2267173138Srwatsonmls_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2268173138Srwatson struct label *msqlabel) 2269173138Srwatson{ 2270173138Srwatson struct mac_mls *source, *dest; 2271173138Srwatson 2272173138Srwatson source = SLOT(cred->cr_label); 2273173138Srwatson dest = SLOT(msqlabel); 2274173138Srwatson 2275173138Srwatson mls_copy_effective(source, dest); 2276173138Srwatson} 2277173138Srwatson 2278140629Srwatsonstatic int 2279172955Srwatsonmls_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 2280172955Srwatson struct label *semaklabel, int cmd) 2281140629Srwatson{ 2282140629Srwatson struct mac_mls *subj, *obj; 2283140629Srwatson 2284172955Srwatson if (!mls_enabled) 2285140629Srwatson return (0); 2286140629Srwatson 2287140629Srwatson subj = SLOT(cred->cr_label); 2288140629Srwatson obj = SLOT(semaklabel); 2289140629Srwatson 2290140629Srwatson switch(cmd) { 2291140629Srwatson case IPC_RMID: 2292140629Srwatson case IPC_SET: 2293140629Srwatson case SETVAL: 2294140629Srwatson case SETALL: 2295172955Srwatson if (!mls_dominate_effective(obj, subj)) 2296140629Srwatson return (EACCES); 2297140629Srwatson break; 2298140629Srwatson 2299140629Srwatson case IPC_STAT: 2300140629Srwatson case GETVAL: 2301140629Srwatson case GETPID: 2302140629Srwatson case GETNCNT: 2303140629Srwatson case GETZCNT: 2304140629Srwatson case GETALL: 2305172955Srwatson if (!mls_dominate_effective(subj, obj)) 2306140629Srwatson return (EACCES); 2307140629Srwatson break; 2308140629Srwatson 2309140629Srwatson default: 2310140629Srwatson return (EACCES); 2311140629Srwatson } 2312140629Srwatson 2313140629Srwatson return (0); 2314140629Srwatson} 2315140629Srwatson 2316140629Srwatsonstatic int 2317172955Srwatsonmls_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 2318172955Srwatson struct label *semaklabel) 2319140629Srwatson{ 2320140629Srwatson struct mac_mls *subj, *obj; 2321140629Srwatson 2322172955Srwatson if (!mls_enabled) 2323140629Srwatson return (0); 2324140629Srwatson 2325140629Srwatson subj = SLOT(cred->cr_label); 2326140629Srwatson obj = SLOT(semaklabel); 2327140629Srwatson 2328172955Srwatson if (!mls_dominate_effective(subj, obj)) 2329140629Srwatson return (EACCES); 2330140629Srwatson 2331140629Srwatson return (0); 2332140629Srwatson} 2333140629Srwatson 2334140629Srwatsonstatic int 2335172955Srwatsonmls_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2336172955Srwatson struct label *semaklabel, size_t accesstype) 2337140629Srwatson{ 2338140629Srwatson struct mac_mls *subj, *obj; 2339140629Srwatson 2340172955Srwatson if (!mls_enabled) 2341140629Srwatson return (0); 2342140629Srwatson 2343140629Srwatson subj = SLOT(cred->cr_label); 2344140629Srwatson obj = SLOT(semaklabel); 2345140629Srwatson 2346140629Srwatson if( accesstype & SEM_R ) 2347172955Srwatson if (!mls_dominate_effective(subj, obj)) 2348140629Srwatson return (EACCES); 2349140629Srwatson 2350140629Srwatson if( accesstype & SEM_A ) 2351172955Srwatson if (!mls_dominate_effective(obj, subj)) 2352140629Srwatson return (EACCES); 2353140629Srwatson 2354140629Srwatson return (0); 2355140629Srwatson} 2356140629Srwatson 2357173138Srwatsonstatic void 2358173138Srwatsonmls_sysvsem_cleanup(struct label *semalabel) 2359173138Srwatson{ 2360173138Srwatson 2361173138Srwatson bzero(SLOT(semalabel), sizeof(struct mac_mls)); 2362173138Srwatson} 2363173138Srwatson 2364173138Srwatsonstatic void 2365173138Srwatsonmls_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2366173138Srwatson struct label *semalabel) 2367173138Srwatson{ 2368173138Srwatson struct mac_mls *source, *dest; 2369173138Srwatson 2370173138Srwatson source = SLOT(cred->cr_label); 2371173138Srwatson dest = SLOT(semalabel); 2372173138Srwatson 2373173138Srwatson mls_copy_effective(source, dest); 2374173138Srwatson} 2375173138Srwatson 2376140629Srwatsonstatic int 2377172955Srwatsonmls_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2378172955Srwatson struct label *shmseglabel, int shmflg) 2379140629Srwatson{ 2380140629Srwatson struct mac_mls *subj, *obj; 2381140629Srwatson 2382172955Srwatson if (!mls_enabled) 2383140629Srwatson return (0); 2384140629Srwatson 2385140629Srwatson subj = SLOT(cred->cr_label); 2386140629Srwatson obj = SLOT(shmseglabel); 2387140629Srwatson 2388172955Srwatson if (!mls_dominate_effective(subj, obj)) 2389172955Srwatson return (EACCES); 2390172955Srwatson if ((shmflg & SHM_RDONLY) == 0) { 2391172955Srwatson if (!mls_dominate_effective(obj, subj)) 2392140629Srwatson return (EACCES); 2393172955Srwatson } 2394140629Srwatson 2395140629Srwatson return (0); 2396140629Srwatson} 2397140629Srwatson 2398140629Srwatsonstatic int 2399172955Srwatsonmls_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2400172955Srwatson struct label *shmseglabel, int cmd) 2401140629Srwatson{ 2402140629Srwatson struct mac_mls *subj, *obj; 2403140629Srwatson 2404172955Srwatson if (!mls_enabled) 2405140629Srwatson return (0); 2406140629Srwatson 2407140629Srwatson subj = SLOT(cred->cr_label); 2408140629Srwatson obj = SLOT(shmseglabel); 2409140629Srwatson 2410140629Srwatson switch(cmd) { 2411140629Srwatson case IPC_RMID: 2412140629Srwatson case IPC_SET: 2413172955Srwatson if (!mls_dominate_effective(obj, subj)) 2414140629Srwatson return (EACCES); 2415140629Srwatson break; 2416140629Srwatson 2417140629Srwatson case IPC_STAT: 2418140629Srwatson case SHM_STAT: 2419172955Srwatson if (!mls_dominate_effective(subj, obj)) 2420140629Srwatson return (EACCES); 2421140629Srwatson break; 2422140629Srwatson 2423140629Srwatson default: 2424140629Srwatson return (EACCES); 2425140629Srwatson } 2426140629Srwatson 2427140629Srwatson return (0); 2428140629Srwatson} 2429140629Srwatson 2430140629Srwatsonstatic int 2431172955Srwatsonmls_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2432172955Srwatson struct label *shmseglabel, int shmflg) 2433140629Srwatson{ 2434140629Srwatson struct mac_mls *subj, *obj; 2435140629Srwatson 2436172955Srwatson if (!mls_enabled) 2437140629Srwatson return (0); 2438140629Srwatson 2439140629Srwatson subj = SLOT(cred->cr_label); 2440140629Srwatson obj = SLOT(shmseglabel); 2441140629Srwatson 2442172955Srwatson if (!mls_dominate_effective(obj, subj)) 2443140629Srwatson return (EACCES); 2444140629Srwatson 2445140629Srwatson return (0); 2446140629Srwatson} 2447140629Srwatson 2448173138Srwatsonstatic void 2449173138Srwatsonmls_sysvshm_cleanup(struct label *shmlabel) 2450101099Srwatson{ 2451101099Srwatson 2452173138Srwatson bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 2453101099Srwatson} 2454101099Srwatson 2455173138Srwatsonstatic void 2456173138Srwatsonmls_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2457173138Srwatson struct label *shmlabel) 2458101099Srwatson{ 2459173138Srwatson struct mac_mls *source, *dest; 2460103759Srwatson 2461173138Srwatson source = SLOT(cred->cr_label); 2462173138Srwatson dest = SLOT(shmlabel); 2463101099Srwatson 2464173138Srwatson mls_copy_effective(source, dest); 2465101099Srwatson} 2466101099Srwatson 2467101099Srwatsonstatic int 2468173138Srwatsonmls_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2469173138Srwatson struct vnode *vp, struct label *vplabel) 2470101099Srwatson{ 2471173138Srwatson struct mac_mls mm_temp, *source, *dest; 2472173138Srwatson int buflen, error; 2473101099Srwatson 2474173138Srwatson source = SLOT(mplabel); 2475173138Srwatson dest = SLOT(vplabel); 2476101099Srwatson 2477173138Srwatson buflen = sizeof(mm_temp); 2478173138Srwatson bzero(&mm_temp, buflen); 2479101099Srwatson 2480173138Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2481173138Srwatson MAC_MLS_EXTATTR_NAME, &buflen, (char *) &mm_temp, curthread); 2482173138Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 2483173138Srwatson /* Fall back to the mntlabel. */ 2484173138Srwatson mls_copy_effective(source, dest); 2485102115Srwatson return (0); 2486173138Srwatson } else if (error) 2487105634Srwatson return (error); 2488101099Srwatson 2489173138Srwatson if (buflen != sizeof(mm_temp)) { 2490173138Srwatson printf("mls_vnode_associate_extattr: bad size %d\n", buflen); 2491101099Srwatson return (EPERM); 2492105634Srwatson } 2493173138Srwatson if (mls_valid(&mm_temp) != 0) { 2494173138Srwatson printf("mls_vnode_associate_extattr: invalid\n"); 2495101099Srwatson return (EPERM); 2496105634Srwatson } 2497173138Srwatson if ((mm_temp.mm_flags & MAC_MLS_FLAGS_BOTH) != 2498173138Srwatson MAC_MLS_FLAG_EFFECTIVE) { 2499173138Srwatson printf("mls_associated_vnode_extattr: not effective\n"); 2500173138Srwatson return (EPERM); 2501173138Srwatson } 2502105634Srwatson 2503173138Srwatson mls_copy_effective(&mm_temp, dest); 2504101099Srwatson return (0); 2505101099Srwatson} 2506101099Srwatson 2507173138Srwatsonstatic void 2508173138Srwatsonmls_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2509173138Srwatson struct vnode *vp, struct label *vplabel) 2510101099Srwatson{ 2511173138Srwatson struct mac_mls *source, *dest; 2512101099Srwatson 2513173138Srwatson source = SLOT(mplabel); 2514173138Srwatson dest = SLOT(vplabel); 2515101099Srwatson 2516173138Srwatson mls_copy_effective(source, dest); 2517101099Srwatson} 2518101099Srwatson 2519101099Srwatsonstatic int 2520172955Srwatsonmls_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2521168976Srwatson struct label *dvplabel) 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(subj, obj)) 2532101099Srwatson return (EACCES); 2533101099Srwatson 2534101099Srwatson return (0); 2535101099Srwatson} 2536101099Srwatson 2537101099Srwatsonstatic int 2538172955Srwatsonmls_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2539168976Srwatson struct label *dvplabel) 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(dvplabel); 2548101099Srwatson 2549172955Srwatson if (!mls_dominate_effective(subj, obj)) 2550101099Srwatson return (EACCES); 2551101099Srwatson 2552101099Srwatson return (0); 2553101099Srwatson} 2554101099Srwatson 2555101099Srwatsonstatic int 2556172955Srwatsonmls_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2557168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2558101099Srwatson{ 2559101099Srwatson struct mac_mls *subj, *obj; 2560101099Srwatson 2561172955Srwatson if (!mls_enabled) 2562101099Srwatson return (0); 2563101099Srwatson 2564122524Srwatson subj = SLOT(cred->cr_label); 2565168976Srwatson obj = SLOT(dvplabel); 2566101099Srwatson 2567172955Srwatson if (!mls_dominate_effective(obj, subj)) 2568101099Srwatson return (EACCES); 2569101099Srwatson 2570101099Srwatson return (0); 2571101099Srwatson} 2572101099Srwatson 2573101099Srwatsonstatic int 2574172955Srwatsonmls_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2575168976Srwatson struct label *vplabel, acl_type_t type) 2576101099Srwatson{ 2577101099Srwatson struct mac_mls *subj, *obj; 2578101099Srwatson 2579172955Srwatson if (!mls_enabled) 2580101099Srwatson return (0); 2581101099Srwatson 2582122524Srwatson subj = SLOT(cred->cr_label); 2583168976Srwatson obj = SLOT(vplabel); 2584101099Srwatson 2585172955Srwatson if (!mls_dominate_effective(obj, subj)) 2586101099Srwatson return (EACCES); 2587101099Srwatson 2588101099Srwatson return (0); 2589101099Srwatson} 2590101099Srwatson 2591101099Srwatsonstatic int 2592172955Srwatsonmls_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2593168976Srwatson struct label *vplabel, int attrnamespace, const char *name) 2594119202Srwatson{ 2595119202Srwatson struct mac_mls *subj, *obj; 2596119202Srwatson 2597172955Srwatson if (!mls_enabled) 2598119202Srwatson return (0); 2599119202Srwatson 2600122524Srwatson subj = SLOT(cred->cr_label); 2601168976Srwatson obj = SLOT(vplabel); 2602119202Srwatson 2603172955Srwatson if (!mls_dominate_effective(obj, subj)) 2604119202Srwatson return (EACCES); 2605119202Srwatson 2606119202Srwatson return (0); 2607119202Srwatson} 2608119202Srwatson 2609119202Srwatsonstatic int 2610172955Srwatsonmls_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2611168976Srwatson struct label *vplabel, struct image_params *imgp, 2612106648Srwatson struct label *execlabel) 2613101099Srwatson{ 2614106648Srwatson struct mac_mls *subj, *obj, *exec; 2615106648Srwatson int error; 2616101099Srwatson 2617106648Srwatson if (execlabel != NULL) { 2618106648Srwatson /* 2619106648Srwatson * We currently don't permit labels to be changed at 2620172955Srwatson * exec-time as part of MLS, so disallow non-NULL MLS label 2621172955Srwatson * elements in the execlabel. 2622106648Srwatson */ 2623106648Srwatson exec = SLOT(execlabel); 2624106648Srwatson error = mls_atmostflags(exec, 0); 2625106648Srwatson if (error) 2626106648Srwatson return (error); 2627106648Srwatson } 2628106648Srwatson 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 2641101099Srwatsonstatic int 2642172955Srwatsonmls_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2643168976Srwatson struct label *vplabel, acl_type_t type) 2644101099Srwatson{ 2645101099Srwatson struct mac_mls *subj, *obj; 2646101099Srwatson 2647172955Srwatson if (!mls_enabled) 2648101099Srwatson return (0); 2649101099Srwatson 2650122524Srwatson subj = SLOT(cred->cr_label); 2651168976Srwatson obj = SLOT(vplabel); 2652101099Srwatson 2653172955Srwatson if (!mls_dominate_effective(subj, obj)) 2654101099Srwatson return (EACCES); 2655101099Srwatson 2656101099Srwatson return (0); 2657101099Srwatson} 2658101099Srwatson 2659101099Srwatsonstatic int 2660172955Srwatsonmls_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 2661189533Srwatson struct label *vplabel, int attrnamespace, const char *name) 2662101099Srwatson{ 2663101099Srwatson struct mac_mls *subj, *obj; 2664101099Srwatson 2665172955Srwatson if (!mls_enabled) 2666101099Srwatson return (0); 2667101099Srwatson 2668122524Srwatson subj = SLOT(cred->cr_label); 2669168976Srwatson obj = SLOT(vplabel); 2670101099Srwatson 2671172955Srwatson if (!mls_dominate_effective(subj, obj)) 2672101099Srwatson return (EACCES); 2673101099Srwatson 2674101099Srwatson return (0); 2675101099Srwatson} 2676101099Srwatson 2677105634Srwatsonstatic int 2678172955Srwatsonmls_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2679168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2680104530Srwatson struct componentname *cnp) 2681104530Srwatson{ 2682104530Srwatson struct mac_mls *subj, *obj; 2683104530Srwatson 2684172955Srwatson if (!mls_enabled) 2685104530Srwatson return (0); 2686104530Srwatson 2687122524Srwatson subj = SLOT(cred->cr_label); 2688168976Srwatson obj = SLOT(dvplabel); 2689104530Srwatson 2690172955Srwatson if (!mls_dominate_effective(obj, subj)) 2691104530Srwatson return (EACCES); 2692104530Srwatson 2693171555Srwatson obj = SLOT(vplabel); 2694172955Srwatson if (!mls_dominate_effective(obj, subj)) 2695104530Srwatson return (EACCES); 2696104530Srwatson 2697104530Srwatson return (0); 2698104530Srwatson} 2699104530Srwatson 2700101099Srwatsonstatic int 2701172955Srwatsonmls_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 2702168976Srwatson struct label *vplabel, int attrnamespace) 2703119202Srwatson{ 2704119202Srwatson 2705119202Srwatson struct mac_mls *subj, *obj; 2706119202Srwatson 2707172955Srwatson if (!mls_enabled) 2708119202Srwatson return (0); 2709119202Srwatson 2710122524Srwatson subj = SLOT(cred->cr_label); 2711168976Srwatson obj = SLOT(vplabel); 2712119202Srwatson 2713172955Srwatson if (!mls_dominate_effective(subj, obj)) 2714119202Srwatson return (EACCES); 2715119202Srwatson 2716119202Srwatson return (0); 2717119202Srwatson} 2718119202Srwatson 2719119202Srwatsonstatic int 2720172955Srwatsonmls_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 2721168976Srwatson struct label *dvplabel, struct componentname *cnp) 2722101099Srwatson{ 2723101099Srwatson struct mac_mls *subj, *obj; 2724103759Srwatson 2725172955Srwatson if (!mls_enabled) 2726101099Srwatson return (0); 2727103759Srwatson 2728122524Srwatson subj = SLOT(cred->cr_label); 2729168976Srwatson obj = SLOT(dvplabel); 2730103759Srwatson 2731172955Srwatson if (!mls_dominate_effective(subj, obj)) 2732101099Srwatson return (EACCES); 2733101099Srwatson 2734103759Srwatson return (0); 2735101099Srwatson} 2736101099Srwatson 2737101099Srwatsonstatic int 2738172955Srwatsonmls_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2739168976Srwatson struct label *vplabel, int prot, int flags) 2740104546Srwatson{ 2741104546Srwatson struct mac_mls *subj, *obj; 2742104546Srwatson 2743104546Srwatson /* 2744104546Srwatson * Rely on the use of open()-time protections to handle 2745104546Srwatson * non-revocation cases. 2746104546Srwatson */ 2747172955Srwatson if (!mls_enabled || !revocation_enabled) 2748104546Srwatson return (0); 2749104546Srwatson 2750122524Srwatson subj = SLOT(cred->cr_label); 2751168976Srwatson obj = SLOT(vplabel); 2752104546Srwatson 2753104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2754172955Srwatson if (!mls_dominate_effective(subj, obj)) 2755104546Srwatson return (EACCES); 2756104546Srwatson } 2757145076Scsjp if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2758172955Srwatson if (!mls_dominate_effective(obj, subj)) 2759104546Srwatson return (EACCES); 2760104546Srwatson } 2761104546Srwatson 2762105634Srwatson return (0); 2763104546Srwatson} 2764104546Srwatson 2765104546Srwatsonstatic int 2766172955Srwatsonmls_vnode_check_open(struct ucred *cred, struct vnode *vp, 2767184413Strasz struct label *vplabel, accmode_t accmode) 2768101099Srwatson{ 2769101099Srwatson struct mac_mls *subj, *obj; 2770101099Srwatson 2771172955Srwatson if (!mls_enabled) 2772101099Srwatson return (0); 2773101099Srwatson 2774122524Srwatson subj = SLOT(cred->cr_label); 2775168976Srwatson obj = SLOT(vplabel); 2776101099Srwatson 2777101099Srwatson /* XXX privilege override for admin? */ 2778190524Strasz if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 2779172955Srwatson if (!mls_dominate_effective(subj, obj)) 2780101099Srwatson return (EACCES); 2781101099Srwatson } 2782190524Strasz if (accmode & VMODIFY_PERMS) { 2783172955Srwatson if (!mls_dominate_effective(obj, subj)) 2784101099Srwatson return (EACCES); 2785101099Srwatson } 2786101099Srwatson 2787101099Srwatson return (0); 2788101099Srwatson} 2789101099Srwatson 2790101099Srwatsonstatic int 2791172955Srwatsonmls_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 2792168976Srwatson struct vnode *vp, struct label *vplabel) 2793102112Srwatson{ 2794102112Srwatson struct mac_mls *subj, *obj; 2795102112Srwatson 2796172955Srwatson if (!mls_enabled || !revocation_enabled) 2797102112Srwatson return (0); 2798102112Srwatson 2799122524Srwatson subj = SLOT(active_cred->cr_label); 2800168976Srwatson obj = SLOT(vplabel); 2801102112Srwatson 2802172955Srwatson if (!mls_dominate_effective(subj, obj)) 2803102112Srwatson return (EACCES); 2804102112Srwatson 2805102112Srwatson return (0); 2806102112Srwatson} 2807102112Srwatson 2808102112Srwatsonstatic int 2809172955Srwatsonmls_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2810168976Srwatson struct vnode *vp, struct label *vplabel) 2811102112Srwatson{ 2812102112Srwatson struct mac_mls *subj, *obj; 2813102112Srwatson 2814172955Srwatson if (!mls_enabled || !revocation_enabled) 2815102112Srwatson return (0); 2816102112Srwatson 2817122524Srwatson subj = SLOT(active_cred->cr_label); 2818168976Srwatson obj = SLOT(vplabel); 2819102112Srwatson 2820172955Srwatson if (!mls_dominate_effective(subj, obj)) 2821102112Srwatson return (EACCES); 2822102112Srwatson 2823102112Srwatson return (0); 2824102112Srwatson} 2825102112Srwatson 2826102112Srwatsonstatic int 2827172955Srwatsonmls_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 2828168976Srwatson struct label *dvplabel) 2829101099Srwatson{ 2830101099Srwatson struct mac_mls *subj, *obj; 2831101099Srwatson 2832172955Srwatson if (!mls_enabled) 2833101099Srwatson return (0); 2834101099Srwatson 2835122524Srwatson subj = SLOT(cred->cr_label); 2836168976Srwatson obj = SLOT(dvplabel); 2837101099Srwatson 2838172955Srwatson if (!mls_dominate_effective(subj, obj)) 2839101099Srwatson return (EACCES); 2840101099Srwatson 2841101099Srwatson return (0); 2842101099Srwatson} 2843101099Srwatson 2844101099Srwatsonstatic int 2845172955Srwatsonmls_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 2846168976Srwatson struct label *vplabel) 2847101099Srwatson{ 2848101099Srwatson struct mac_mls *subj, *obj; 2849101099Srwatson 2850172955Srwatson if (!mls_enabled) 2851101099Srwatson return (0); 2852101099Srwatson 2853122524Srwatson subj = SLOT(cred->cr_label); 2854168976Srwatson obj = SLOT(vplabel); 2855101099Srwatson 2856172955Srwatson if (!mls_dominate_effective(subj, obj)) 2857101099Srwatson return (EACCES); 2858101099Srwatson 2859101099Srwatson return (0); 2860101099Srwatson} 2861101099Srwatson 2862101099Srwatsonstatic int 2863172955Srwatsonmls_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2864168976Srwatson struct label *vplabel, struct label *newlabel) 2865101099Srwatson{ 2866101099Srwatson struct mac_mls *old, *new, *subj; 2867105634Srwatson int error; 2868101099Srwatson 2869168976Srwatson old = SLOT(vplabel); 2870101099Srwatson new = SLOT(newlabel); 2871122524Srwatson subj = SLOT(cred->cr_label); 2872101099Srwatson 2873101099Srwatson /* 2874105634Srwatson * If there is an MLS label update for the vnode, it must be a 2875132232Srwatson * effective label. 2876101099Srwatson */ 2877132232Srwatson error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2878105634Srwatson if (error) 2879105634Srwatson return (error); 2880101099Srwatson 2881101099Srwatson /* 2882105634Srwatson * To perform a relabel of the vnode (MLS label or not), MLS must 2883105634Srwatson * authorize the relabel. 2884101099Srwatson */ 2885172955Srwatson if (!mls_effective_in_range(old, subj)) 2886101099Srwatson return (EPERM); 2887101099Srwatson 2888101099Srwatson /* 2889105634Srwatson * If the MLS label is to be changed, authorize as appropriate. 2890101099Srwatson */ 2891132232Srwatson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2892105634Srwatson /* 2893105634Srwatson * To change the MLS label on a vnode, the new vnode label 2894105634Srwatson * must be in the subject range. 2895105634Srwatson */ 2896172955Srwatson if (!mls_effective_in_range(new, subj)) 2897105634Srwatson return (EPERM); 2898101099Srwatson 2899105634Srwatson /* 2900172955Srwatson * To change the MLS label on the vnode to be EQUAL, the 2901172955Srwatson * subject must have appropriate privilege. 2902105634Srwatson */ 2903172955Srwatson if (mls_contains_equal(new)) { 2904172955Srwatson error = mls_subject_privileged(subj); 2905105634Srwatson if (error) 2906105634Srwatson return (error); 2907105634Srwatson } 2908105634Srwatson } 2909105634Srwatson 2910105634Srwatson return (0); 2911101099Srwatson} 2912101099Srwatson 2913101099Srwatsonstatic int 2914172955Srwatsonmls_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2915168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2916101099Srwatson struct componentname *cnp) 2917101099Srwatson{ 2918101099Srwatson struct mac_mls *subj, *obj; 2919101099Srwatson 2920172955Srwatson if (!mls_enabled) 2921101099Srwatson return (0); 2922101099Srwatson 2923122524Srwatson subj = SLOT(cred->cr_label); 2924168976Srwatson obj = SLOT(dvplabel); 2925101099Srwatson 2926172955Srwatson if (!mls_dominate_effective(obj, subj)) 2927101099Srwatson return (EACCES); 2928101099Srwatson 2929168976Srwatson obj = SLOT(vplabel); 2930101099Srwatson 2931172955Srwatson if (!mls_dominate_effective(obj, subj)) 2932101099Srwatson return (EACCES); 2933101099Srwatson 2934101099Srwatson return (0); 2935101099Srwatson} 2936101099Srwatson 2937101099Srwatsonstatic int 2938172955Srwatsonmls_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2939168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2940168976Srwatson int samedir, struct componentname *cnp) 2941101099Srwatson{ 2942101099Srwatson struct mac_mls *subj, *obj; 2943101099Srwatson 2944172955Srwatson if (!mls_enabled) 2945101099Srwatson return (0); 2946101099Srwatson 2947122524Srwatson subj = SLOT(cred->cr_label); 2948168976Srwatson obj = SLOT(dvplabel); 2949101099Srwatson 2950172955Srwatson if (!mls_dominate_effective(obj, subj)) 2951101099Srwatson return (EACCES); 2952101099Srwatson 2953101099Srwatson if (vp != NULL) { 2954168976Srwatson obj = SLOT(vplabel); 2955101099Srwatson 2956172955Srwatson if (!mls_dominate_effective(obj, subj)) 2957101099Srwatson return (EACCES); 2958101099Srwatson } 2959101099Srwatson 2960101099Srwatson return (0); 2961101099Srwatson} 2962101099Srwatson 2963101099Srwatsonstatic int 2964172955Srwatsonmls_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2965168976Srwatson struct label *vplabel) 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 return (0); 2979101099Srwatson} 2980101099Srwatson 2981101099Srwatsonstatic int 2982172955Srwatsonmls_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2983168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 2984101099Srwatson{ 2985101099Srwatson struct mac_mls *subj, *obj; 2986101099Srwatson 2987172955Srwatson if (!mls_enabled) 2988101099Srwatson return (0); 2989101099Srwatson 2990122524Srwatson subj = SLOT(cred->cr_label); 2991168976Srwatson obj = SLOT(vplabel); 2992101099Srwatson 2993172955Srwatson if (!mls_dominate_effective(obj, subj)) 2994101099Srwatson return (EACCES); 2995101099Srwatson 2996101099Srwatson return (0); 2997101099Srwatson} 2998101099Srwatson 2999101099Srwatsonstatic int 3000172955Srwatsonmls_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 3001189533Srwatson struct label *vplabel, int attrnamespace, const char *name) 3002101099Srwatson{ 3003101099Srwatson struct mac_mls *subj, *obj; 3004101099Srwatson 3005172955Srwatson if (!mls_enabled) 3006101099Srwatson return (0); 3007101099Srwatson 3008122524Srwatson subj = SLOT(cred->cr_label); 3009168976Srwatson obj = SLOT(vplabel); 3010101099Srwatson 3011172955Srwatson if (!mls_dominate_effective(obj, subj)) 3012101099Srwatson return (EACCES); 3013101099Srwatson 3014101099Srwatson /* XXX: protect the MAC EA in a special way? */ 3015101099Srwatson 3016101099Srwatson return (0); 3017101099Srwatson} 3018101099Srwatson 3019101099Srwatsonstatic int 3020172955Srwatsonmls_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 3021168976Srwatson struct label *vplabel, u_long flags) 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_setmode(struct ucred *cred, struct vnode *vp, 3039168976Srwatson struct label *vplabel, mode_t mode) 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_setowner(struct ucred *cred, struct vnode *vp, 3057168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 3058101099Srwatson{ 3059101099Srwatson struct mac_mls *subj, *obj; 3060101099Srwatson 3061172955Srwatson if (!mls_enabled) 3062101099Srwatson return (0); 3063101099Srwatson 3064122524Srwatson subj = SLOT(cred->cr_label); 3065168976Srwatson obj = SLOT(vplabel); 3066101099Srwatson 3067172955Srwatson if (!mls_dominate_effective(obj, subj)) 3068101099Srwatson return (EACCES); 3069101099Srwatson 3070101099Srwatson return (0); 3071101099Srwatson} 3072101099Srwatson 3073101099Srwatsonstatic int 3074172955Srwatsonmls_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 3075168976Srwatson struct label *vplabel, struct timespec atime, struct timespec mtime) 3076101099Srwatson{ 3077101099Srwatson struct mac_mls *subj, *obj; 3078101099Srwatson 3079172955Srwatson if (!mls_enabled) 3080101099Srwatson return (0); 3081101099Srwatson 3082122524Srwatson subj = SLOT(cred->cr_label); 3083168976Srwatson obj = SLOT(vplabel); 3084101099Srwatson 3085172955Srwatson if (!mls_dominate_effective(obj, subj)) 3086101099Srwatson return (EACCES); 3087101099Srwatson 3088101099Srwatson return (0); 3089101099Srwatson} 3090101099Srwatson 3091101099Srwatsonstatic int 3092172955Srwatsonmls_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 3093168976Srwatson struct vnode *vp, struct label *vplabel) 3094101099Srwatson{ 3095101099Srwatson struct mac_mls *subj, *obj; 3096101099Srwatson 3097172955Srwatson if (!mls_enabled) 3098101099Srwatson return (0); 3099101099Srwatson 3100122524Srwatson subj = SLOT(active_cred->cr_label); 3101168976Srwatson obj = SLOT(vplabel); 3102101099Srwatson 3103172955Srwatson if (!mls_dominate_effective(subj, obj)) 3104101099Srwatson return (EACCES); 3105101099Srwatson 3106101099Srwatson return (0); 3107101099Srwatson} 3108101099Srwatson 3109102112Srwatsonstatic int 3110172955Srwatsonmls_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 3111172107Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3112172107Srwatson struct componentname *cnp) 3113172107Srwatson{ 3114172107Srwatson struct mac_mls *subj, *obj; 3115172107Srwatson 3116172955Srwatson if (!mls_enabled) 3117172107Srwatson return (0); 3118172107Srwatson 3119172107Srwatson subj = SLOT(cred->cr_label); 3120172107Srwatson obj = SLOT(dvplabel); 3121172107Srwatson 3122172955Srwatson if (!mls_dominate_effective(obj, subj)) 3123172107Srwatson return (EACCES); 3124172107Srwatson 3125172107Srwatson obj = SLOT(vplabel); 3126172107Srwatson 3127172955Srwatson if (!mls_dominate_effective(obj, subj)) 3128172107Srwatson return (EACCES); 3129172107Srwatson 3130172107Srwatson return (0); 3131172107Srwatson} 3132172107Srwatson 3133172107Srwatsonstatic int 3134172955Srwatsonmls_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred, 3135168976Srwatson struct vnode *vp, struct label *vplabel) 3136102112Srwatson{ 3137102112Srwatson struct mac_mls *subj, *obj; 3138102112Srwatson 3139172955Srwatson if (!mls_enabled || !revocation_enabled) 3140102112Srwatson return (0); 3141102112Srwatson 3142122524Srwatson subj = SLOT(active_cred->cr_label); 3143168976Srwatson obj = SLOT(vplabel); 3144102112Srwatson 3145172955Srwatson if (!mls_dominate_effective(obj, subj)) 3146102112Srwatson return (EACCES); 3147102112Srwatson 3148102112Srwatson return (0); 3149102112Srwatson} 3150102112Srwatson 3151173138Srwatsonstatic int 3152173138Srwatsonmls_vnode_create_extattr(struct ucred *cred, struct mount *mp, 3153173138Srwatson struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 3154173138Srwatson struct vnode *vp, struct label *vplabel, struct componentname *cnp) 3155173138Srwatson{ 3156173138Srwatson struct mac_mls *source, *dest, mm_temp; 3157173138Srwatson size_t buflen; 3158173138Srwatson int error; 3159173138Srwatson 3160173138Srwatson buflen = sizeof(mm_temp); 3161173138Srwatson bzero(&mm_temp, buflen); 3162173138Srwatson 3163173138Srwatson source = SLOT(cred->cr_label); 3164173138Srwatson dest = SLOT(vplabel); 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 if (error == 0) 3170173138Srwatson mls_copy_effective(source, dest); 3171173138Srwatson return (error); 3172173138Srwatson} 3173173138Srwatson 3174173138Srwatsonstatic void 3175173138Srwatsonmls_vnode_relabel(struct ucred *cred, struct vnode *vp, 3176173138Srwatson struct label *vplabel, struct label *label) 3177173138Srwatson{ 3178173138Srwatson struct mac_mls *source, *dest; 3179173138Srwatson 3180173138Srwatson source = SLOT(label); 3181173138Srwatson dest = SLOT(vplabel); 3182173138Srwatson 3183173138Srwatson mls_copy(source, dest); 3184173138Srwatson} 3185173138Srwatson 3186173138Srwatsonstatic int 3187173138Srwatsonmls_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 3188173138Srwatson struct label *vplabel, struct label *intlabel) 3189173138Srwatson{ 3190173138Srwatson struct mac_mls *source, mm_temp; 3191173138Srwatson size_t buflen; 3192173138Srwatson int error; 3193173138Srwatson 3194173138Srwatson buflen = sizeof(mm_temp); 3195173138Srwatson bzero(&mm_temp, buflen); 3196173138Srwatson 3197173138Srwatson source = SLOT(intlabel); 3198173138Srwatson if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 3199173138Srwatson return (0); 3200173138Srwatson 3201173138Srwatson mls_copy_effective(source, &mm_temp); 3202173138Srwatson 3203173138Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 3204173138Srwatson MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 3205173138Srwatson return (error); 3206173138Srwatson} 3207173138Srwatson 3208172955Srwatsonstatic struct mac_policy_ops mls_ops = 3209101099Srwatson{ 3210172955Srwatson .mpo_init = mls_init, 3211173138Srwatson 3212173138Srwatson .mpo_bpfdesc_check_receive = mls_bpfdesc_check_receive, 3213173138Srwatson .mpo_bpfdesc_create = mls_bpfdesc_create, 3214173138Srwatson .mpo_bpfdesc_create_mbuf = mls_bpfdesc_create_mbuf, 3215173138Srwatson .mpo_bpfdesc_destroy_label = mls_destroy_label, 3216172955Srwatson .mpo_bpfdesc_init_label = mls_init_label, 3217173138Srwatson 3218184407Srwatson .mpo_cred_associate_nfsd = mls_cred_associate_nfsd, 3219173138Srwatson .mpo_cred_check_relabel = mls_cred_check_relabel, 3220173138Srwatson .mpo_cred_check_visible = mls_cred_check_visible, 3221173138Srwatson .mpo_cred_copy_label = mls_copy_label, 3222184407Srwatson .mpo_cred_create_init = mls_cred_create_init, 3223184407Srwatson .mpo_cred_create_swapper = mls_cred_create_swapper, 3224172955Srwatson .mpo_cred_destroy_label = mls_destroy_label, 3225172955Srwatson .mpo_cred_externalize_label = mls_externalize_label, 3226173138Srwatson .mpo_cred_init_label = mls_init_label, 3227172955Srwatson .mpo_cred_internalize_label = mls_internalize_label, 3228173138Srwatson .mpo_cred_relabel = mls_cred_relabel, 3229173138Srwatson 3230172955Srwatson .mpo_devfs_create_device = mls_devfs_create_device, 3231172955Srwatson .mpo_devfs_create_directory = mls_devfs_create_directory, 3232172955Srwatson .mpo_devfs_create_symlink = mls_devfs_create_symlink, 3233173138Srwatson .mpo_devfs_destroy_label = mls_destroy_label, 3234173138Srwatson .mpo_devfs_init_label = mls_init_label, 3235172955Srwatson .mpo_devfs_update = mls_devfs_update, 3236172955Srwatson .mpo_devfs_vnode_associate = mls_devfs_vnode_associate, 3237173138Srwatson 3238173138Srwatson .mpo_ifnet_check_relabel = mls_ifnet_check_relabel, 3239173138Srwatson .mpo_ifnet_check_transmit = mls_ifnet_check_transmit, 3240173138Srwatson .mpo_ifnet_copy_label = mls_copy_label, 3241172955Srwatson .mpo_ifnet_create = mls_ifnet_create, 3242173138Srwatson .mpo_ifnet_create_mbuf = mls_ifnet_create_mbuf, 3243173138Srwatson .mpo_ifnet_destroy_label = mls_destroy_label, 3244173138Srwatson .mpo_ifnet_externalize_label = mls_externalize_label, 3245173138Srwatson .mpo_ifnet_init_label = mls_init_label, 3246173138Srwatson .mpo_ifnet_internalize_label = mls_internalize_label, 3247173138Srwatson .mpo_ifnet_relabel = mls_ifnet_relabel, 3248173138Srwatson 3249173138Srwatson .mpo_inpcb_check_deliver = mls_inpcb_check_deliver, 3250183980Sbz .mpo_inpcb_check_visible = mls_inpcb_check_visible, 3251172955Srwatson .mpo_inpcb_create = mls_inpcb_create, 3252173138Srwatson .mpo_inpcb_create_mbuf = mls_inpcb_create_mbuf, 3253173138Srwatson .mpo_inpcb_destroy_label = mls_destroy_label, 3254173138Srwatson .mpo_inpcb_init_label = mls_init_label_waitcheck, 3255173138Srwatson .mpo_inpcb_sosetlabel = mls_inpcb_sosetlabel, 3256173138Srwatson 3257184308Srwatson .mpo_ip6q_create = mls_ip6q_create, 3258184308Srwatson .mpo_ip6q_destroy_label = mls_destroy_label, 3259184308Srwatson .mpo_ip6q_init_label = mls_init_label_waitcheck, 3260184308Srwatson .mpo_ip6q_match = mls_ip6q_match, 3261184308Srwatson .mpo_ip6q_reassemble = mls_ip6q_reassemble, 3262184308Srwatson .mpo_ip6q_update = mls_ip6q_update, 3263184308Srwatson 3264172955Srwatson .mpo_ipq_create = mls_ipq_create, 3265173138Srwatson .mpo_ipq_destroy_label = mls_destroy_label, 3266173138Srwatson .mpo_ipq_init_label = mls_init_label_waitcheck, 3267172955Srwatson .mpo_ipq_match = mls_ipq_match, 3268173138Srwatson .mpo_ipq_reassemble = mls_ipq_reassemble, 3269172955Srwatson .mpo_ipq_update = mls_ipq_update, 3270173138Srwatson 3271173138Srwatson .mpo_mbuf_copy_label = mls_copy_label, 3272173138Srwatson .mpo_mbuf_destroy_label = mls_destroy_label, 3273173138Srwatson .mpo_mbuf_init_label = mls_init_label_waitcheck, 3274173138Srwatson 3275172955Srwatson .mpo_mount_check_stat = mls_mount_check_stat, 3276173138Srwatson .mpo_mount_create = mls_mount_create, 3277173138Srwatson .mpo_mount_destroy_label = mls_destroy_label, 3278173138Srwatson .mpo_mount_init_label = mls_init_label, 3279173138Srwatson 3280173138Srwatson .mpo_netatalk_aarp_send = mls_netatalk_aarp_send, 3281173138Srwatson 3282173138Srwatson .mpo_netinet_arp_send = mls_netinet_arp_send, 3283173138Srwatson .mpo_netinet_firewall_reply = mls_netinet_firewall_reply, 3284173138Srwatson .mpo_netinet_firewall_send = mls_netinet_firewall_send, 3285173138Srwatson .mpo_netinet_fragment = mls_netinet_fragment, 3286173138Srwatson .mpo_netinet_icmp_reply = mls_netinet_icmp_reply, 3287173138Srwatson .mpo_netinet_igmp_send = mls_netinet_igmp_send, 3288173138Srwatson 3289173138Srwatson .mpo_netinet6_nd6_send = mls_netinet6_nd6_send, 3290173138Srwatson 3291172955Srwatson .mpo_pipe_check_ioctl = mls_pipe_check_ioctl, 3292172955Srwatson .mpo_pipe_check_poll = mls_pipe_check_poll, 3293172955Srwatson .mpo_pipe_check_read = mls_pipe_check_read, 3294172955Srwatson .mpo_pipe_check_relabel = mls_pipe_check_relabel, 3295172955Srwatson .mpo_pipe_check_stat = mls_pipe_check_stat, 3296172955Srwatson .mpo_pipe_check_write = mls_pipe_check_write, 3297173138Srwatson .mpo_pipe_copy_label = mls_copy_label, 3298173138Srwatson .mpo_pipe_create = mls_pipe_create, 3299173138Srwatson .mpo_pipe_destroy_label = mls_destroy_label, 3300173138Srwatson .mpo_pipe_externalize_label = mls_externalize_label, 3301173138Srwatson .mpo_pipe_init_label = mls_init_label, 3302173138Srwatson .mpo_pipe_internalize_label = mls_internalize_label, 3303173138Srwatson .mpo_pipe_relabel = mls_pipe_relabel, 3304173138Srwatson 3305172955Srwatson .mpo_posixsem_check_getvalue = mls_posixsem_check_rdonly, 3306180059Sjhb .mpo_posixsem_check_open = mls_posixsem_check_openunlink, 3307172955Srwatson .mpo_posixsem_check_post = mls_posixsem_check_write, 3308225344Srwatson .mpo_posixsem_check_setmode = mls_posixsem_check_setmode, 3309225344Srwatson .mpo_posixsem_check_setowner = mls_posixsem_check_setowner, 3310180059Sjhb .mpo_posixsem_check_stat = mls_posixsem_check_rdonly, 3311180059Sjhb .mpo_posixsem_check_unlink = mls_posixsem_check_openunlink, 3312172955Srwatson .mpo_posixsem_check_wait = mls_posixsem_check_write, 3313173138Srwatson .mpo_posixsem_create = mls_posixsem_create, 3314173138Srwatson .mpo_posixsem_destroy_label = mls_destroy_label, 3315173138Srwatson .mpo_posixsem_init_label = mls_init_label, 3316173138Srwatson 3317225344Srwatson .mpo_posixshm_check_mmap = mls_posixshm_check_mmap, 3318225344Srwatson .mpo_posixshm_check_open = mls_posixshm_check_open, 3319254603Skib .mpo_posixshm_check_read = mls_posixshm_check_read, 3320225344Srwatson .mpo_posixshm_check_setmode = mls_posixshm_check_setmode, 3321225344Srwatson .mpo_posixshm_check_setowner = mls_posixshm_check_setowner, 3322225344Srwatson .mpo_posixshm_check_stat = mls_posixshm_check_stat, 3323225344Srwatson .mpo_posixshm_check_truncate = mls_posixshm_check_truncate, 3324225344Srwatson .mpo_posixshm_check_unlink = mls_posixshm_check_unlink, 3325254603Skib .mpo_posixshm_check_write = mls_posixshm_check_write, 3326225344Srwatson .mpo_posixshm_create = mls_posixshm_create, 3327225344Srwatson .mpo_posixshm_destroy_label = mls_destroy_label, 3328225344Srwatson .mpo_posixshm_init_label = mls_init_label, 3329225344Srwatson 3330172955Srwatson .mpo_proc_check_debug = mls_proc_check_debug, 3331172955Srwatson .mpo_proc_check_sched = mls_proc_check_sched, 3332172955Srwatson .mpo_proc_check_signal = mls_proc_check_signal, 3333173138Srwatson 3334172955Srwatson .mpo_socket_check_deliver = mls_socket_check_deliver, 3335172955Srwatson .mpo_socket_check_relabel = mls_socket_check_relabel, 3336172955Srwatson .mpo_socket_check_visible = mls_socket_check_visible, 3337173138Srwatson .mpo_socket_copy_label = mls_copy_label, 3338173138Srwatson .mpo_socket_create = mls_socket_create, 3339173138Srwatson .mpo_socket_create_mbuf = mls_socket_create_mbuf, 3340173138Srwatson .mpo_socket_destroy_label = mls_destroy_label, 3341173138Srwatson .mpo_socket_externalize_label = mls_externalize_label, 3342173138Srwatson .mpo_socket_init_label = mls_init_label_waitcheck, 3343173138Srwatson .mpo_socket_internalize_label = mls_internalize_label, 3344173138Srwatson .mpo_socket_newconn = mls_socket_newconn, 3345173138Srwatson .mpo_socket_relabel = mls_socket_relabel, 3346173138Srwatson 3347173138Srwatson .mpo_socketpeer_destroy_label = mls_destroy_label, 3348173138Srwatson .mpo_socketpeer_externalize_label = mls_externalize_label, 3349173138Srwatson .mpo_socketpeer_init_label = mls_init_label_waitcheck, 3350173138Srwatson .mpo_socketpeer_set_from_mbuf = mls_socketpeer_set_from_mbuf, 3351173138Srwatson .mpo_socketpeer_set_from_socket = mls_socketpeer_set_from_socket, 3352173138Srwatson 3353173138Srwatson .mpo_syncache_create = mls_syncache_create, 3354173138Srwatson .mpo_syncache_create_mbuf = mls_syncache_create_mbuf, 3355173138Srwatson .mpo_syncache_destroy_label = mls_destroy_label, 3356173138Srwatson .mpo_syncache_init_label = mls_init_label_waitcheck, 3357173138Srwatson 3358173138Srwatson .mpo_sysvmsg_cleanup = mls_sysvmsg_cleanup, 3359173138Srwatson .mpo_sysvmsg_create = mls_sysvmsg_create, 3360173138Srwatson .mpo_sysvmsg_destroy_label = mls_destroy_label, 3361173138Srwatson .mpo_sysvmsg_init_label = mls_init_label, 3362173138Srwatson 3363173138Srwatson .mpo_sysvmsq_check_msgrcv = mls_sysvmsq_check_msgrcv, 3364173138Srwatson .mpo_sysvmsq_check_msgrmid = mls_sysvmsq_check_msgrmid, 3365173138Srwatson .mpo_sysvmsq_check_msqget = mls_sysvmsq_check_msqget, 3366173138Srwatson .mpo_sysvmsq_check_msqsnd = mls_sysvmsq_check_msqsnd, 3367173138Srwatson .mpo_sysvmsq_check_msqrcv = mls_sysvmsq_check_msqrcv, 3368173138Srwatson .mpo_sysvmsq_check_msqctl = mls_sysvmsq_check_msqctl, 3369173138Srwatson .mpo_sysvmsq_cleanup = mls_sysvmsq_cleanup, 3370173138Srwatson .mpo_sysvmsq_destroy_label = mls_destroy_label, 3371173138Srwatson .mpo_sysvmsq_init_label = mls_init_label, 3372173138Srwatson .mpo_sysvmsq_create = mls_sysvmsq_create, 3373173138Srwatson 3374173138Srwatson .mpo_sysvsem_check_semctl = mls_sysvsem_check_semctl, 3375173138Srwatson .mpo_sysvsem_check_semget = mls_sysvsem_check_semget, 3376173138Srwatson .mpo_sysvsem_check_semop = mls_sysvsem_check_semop, 3377173138Srwatson .mpo_sysvsem_cleanup = mls_sysvsem_cleanup, 3378173138Srwatson .mpo_sysvsem_create = mls_sysvsem_create, 3379173138Srwatson .mpo_sysvsem_destroy_label = mls_destroy_label, 3380173138Srwatson .mpo_sysvsem_init_label = mls_init_label, 3381173138Srwatson 3382173138Srwatson .mpo_sysvshm_check_shmat = mls_sysvshm_check_shmat, 3383173138Srwatson .mpo_sysvshm_check_shmctl = mls_sysvshm_check_shmctl, 3384173138Srwatson .mpo_sysvshm_check_shmget = mls_sysvshm_check_shmget, 3385173138Srwatson .mpo_sysvshm_cleanup = mls_sysvshm_cleanup, 3386173138Srwatson .mpo_sysvshm_create = mls_sysvshm_create, 3387173138Srwatson .mpo_sysvshm_destroy_label = mls_destroy_label, 3388173138Srwatson .mpo_sysvshm_init_label = mls_init_label, 3389173138Srwatson 3390173138Srwatson 3391172955Srwatson .mpo_system_check_acct = mls_system_check_acct, 3392172955Srwatson .mpo_system_check_auditctl = mls_system_check_auditctl, 3393172955Srwatson .mpo_system_check_swapon = mls_system_check_swapon, 3394173138Srwatson 3395173138Srwatson .mpo_vnode_associate_extattr = mls_vnode_associate_extattr, 3396173138Srwatson .mpo_vnode_associate_singlelabel = mls_vnode_associate_singlelabel, 3397172955Srwatson .mpo_vnode_check_access = mls_vnode_check_open, 3398172955Srwatson .mpo_vnode_check_chdir = mls_vnode_check_chdir, 3399172955Srwatson .mpo_vnode_check_chroot = mls_vnode_check_chroot, 3400172955Srwatson .mpo_vnode_check_create = mls_vnode_check_create, 3401172955Srwatson .mpo_vnode_check_deleteacl = mls_vnode_check_deleteacl, 3402172955Srwatson .mpo_vnode_check_deleteextattr = mls_vnode_check_deleteextattr, 3403172955Srwatson .mpo_vnode_check_exec = mls_vnode_check_exec, 3404172955Srwatson .mpo_vnode_check_getacl = mls_vnode_check_getacl, 3405172955Srwatson .mpo_vnode_check_getextattr = mls_vnode_check_getextattr, 3406172955Srwatson .mpo_vnode_check_link = mls_vnode_check_link, 3407172955Srwatson .mpo_vnode_check_listextattr = mls_vnode_check_listextattr, 3408172955Srwatson .mpo_vnode_check_lookup = mls_vnode_check_lookup, 3409172955Srwatson .mpo_vnode_check_mmap = mls_vnode_check_mmap, 3410172955Srwatson .mpo_vnode_check_open = mls_vnode_check_open, 3411172955Srwatson .mpo_vnode_check_poll = mls_vnode_check_poll, 3412172955Srwatson .mpo_vnode_check_read = mls_vnode_check_read, 3413172955Srwatson .mpo_vnode_check_readdir = mls_vnode_check_readdir, 3414172955Srwatson .mpo_vnode_check_readlink = mls_vnode_check_readlink, 3415172955Srwatson .mpo_vnode_check_relabel = mls_vnode_check_relabel, 3416172955Srwatson .mpo_vnode_check_rename_from = mls_vnode_check_rename_from, 3417172955Srwatson .mpo_vnode_check_rename_to = mls_vnode_check_rename_to, 3418172955Srwatson .mpo_vnode_check_revoke = mls_vnode_check_revoke, 3419172955Srwatson .mpo_vnode_check_setacl = mls_vnode_check_setacl, 3420172955Srwatson .mpo_vnode_check_setextattr = mls_vnode_check_setextattr, 3421172955Srwatson .mpo_vnode_check_setflags = mls_vnode_check_setflags, 3422172955Srwatson .mpo_vnode_check_setmode = mls_vnode_check_setmode, 3423172955Srwatson .mpo_vnode_check_setowner = mls_vnode_check_setowner, 3424172955Srwatson .mpo_vnode_check_setutimes = mls_vnode_check_setutimes, 3425172955Srwatson .mpo_vnode_check_stat = mls_vnode_check_stat, 3426172955Srwatson .mpo_vnode_check_unlink = mls_vnode_check_unlink, 3427172955Srwatson .mpo_vnode_check_write = mls_vnode_check_write, 3428173138Srwatson .mpo_vnode_copy_label = mls_copy_label, 3429173138Srwatson .mpo_vnode_create_extattr = mls_vnode_create_extattr, 3430173138Srwatson .mpo_vnode_destroy_label = mls_destroy_label, 3431173138Srwatson .mpo_vnode_externalize_label = mls_externalize_label, 3432173138Srwatson .mpo_vnode_init_label = mls_init_label, 3433173138Srwatson .mpo_vnode_internalize_label = mls_internalize_label, 3434173138Srwatson .mpo_vnode_relabel = mls_vnode_relabel, 3435173138Srwatson .mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr, 3436101099Srwatson}; 3437101099Srwatson 3438172955SrwatsonMAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS", 3439187016Srwatson MPC_LOADTIME_FLAG_NOTLATE, &mls_slot); 3440