1107273Srwatson/*- 2193391Srwatson * Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson 3140879Srwatson * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 4172930Srwatson * Copyright (c) 2006 SPARTA, Inc. 5107273Srwatson * All rights reserved. 6107273Srwatson * 7107273Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 8107273Srwatson * 9107273Srwatson * This software was developed for the FreeBSD Project in part by NAI Labs, 10107273Srwatson * the Security Research Division of Network Associates, Inc. under 11107273Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 12107273Srwatson * CHATS research program. 13107273Srwatson * 14172930Srwatson * This software was enhanced by SPARTA ISSO under SPAWAR contract 15172930Srwatson * N66001-04-C-6019 ("SEFOS"). 16172930Srwatson * 17107273Srwatson * Redistribution and use in source and binary forms, with or without 18107273Srwatson * modification, are permitted provided that the following conditions 19107273Srwatson * are met: 20107273Srwatson * 1. Redistributions of source code must retain the above copyright 21107273Srwatson * notice, this list of conditions and the following disclaimer. 22107273Srwatson * 2. Redistributions in binary form must reproduce the above copyright 23107273Srwatson * notice, this list of conditions and the following disclaimer in the 24107273Srwatson * documentation and/or other materials provided with the distribution. 25107273Srwatson * 26107273Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27107273Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28107273Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29107273Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 30107273Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31107273Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32107273Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33107273Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34107273Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35107273Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36107273Srwatson * SUCH DAMAGE. 37107273Srwatson * 38107273Srwatson * $FreeBSD$ 39107273Srwatson */ 40107273Srwatson 41107273Srwatson/* 42107273Srwatson * Developed by the TrustedBSD Project. 43168951Srwatson * 44107273Srwatson * Low-watermark floating label mandatory integrity policy. 45107273Srwatson */ 46107273Srwatson 47107273Srwatson#include <sys/types.h> 48107273Srwatson#include <sys/param.h> 49107273Srwatson#include <sys/acl.h> 50107273Srwatson#include <sys/conf.h> 51107273Srwatson#include <sys/extattr.h> 52107273Srwatson#include <sys/kernel.h> 53107273Srwatson#include <sys/malloc.h> 54145076Scsjp#include <sys/mman.h> 55107273Srwatson#include <sys/mount.h> 56164033Srwatson#include <sys/priv.h> 57107273Srwatson#include <sys/proc.h> 58116701Srwatson#include <sys/sbuf.h> 59107273Srwatson#include <sys/systm.h> 60107273Srwatson#include <sys/sysproto.h> 61107273Srwatson#include <sys/sysent.h> 62107273Srwatson#include <sys/systm.h> 63107273Srwatson#include <sys/vnode.h> 64107273Srwatson#include <sys/file.h> 65107273Srwatson#include <sys/socket.h> 66107273Srwatson#include <sys/socketvar.h> 67150340Sphk#include <sys/sx.h> 68107273Srwatson#include <sys/pipe.h> 69107273Srwatson#include <sys/sysctl.h> 70107273Srwatson#include <sys/syslog.h> 71107273Srwatson 72107273Srwatson#include <fs/devfs/devfs.h> 73107273Srwatson 74107273Srwatson#include <net/bpfdesc.h> 75107273Srwatson#include <net/if.h> 76107273Srwatson#include <net/if_types.h> 77107273Srwatson#include <net/if_var.h> 78107273Srwatson 79107273Srwatson#include <netinet/in.h> 80122875Srwatson#include <netinet/in_pcb.h> 81107273Srwatson#include <netinet/ip_var.h> 82107273Srwatson 83107273Srwatson#include <vm/vm.h> 84107273Srwatson 85165469Srwatson#include <security/mac/mac_policy.h> 86163606Srwatson#include <security/mac/mac_framework.h> 87107273Srwatson#include <security/mac_lomac/mac_lomac.h> 88107273Srwatson 89107273Srwatsonstruct mac_lomac_proc { 90107273Srwatson struct mac_lomac mac_lomac; 91107273Srwatson struct mtx mtx; 92107273Srwatson}; 93107273Srwatson 94107273SrwatsonSYSCTL_DECL(_security_mac); 95107273Srwatson 96227309Sedstatic SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0, 97107273Srwatson "TrustedBSD mac_lomac policy controls"); 98107273Srwatson 99172955Srwatsonstatic int lomac_label_size = sizeof(struct mac_lomac); 100107273SrwatsonSYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD, 101172955Srwatson &lomac_label_size, 0, "Size of struct mac_lomac"); 102107273Srwatson 103172955Srwatsonstatic int lomac_enabled = 1; 104107273SrwatsonSYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW, 105172955Srwatson &lomac_enabled, 0, "Enforce MAC/LOMAC policy"); 106172955SrwatsonTUNABLE_INT("security.mac.lomac.enabled", &lomac_enabled); 107107273Srwatson 108107273Srwatsonstatic int destroyed_not_inited; 109107273SrwatsonSYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 110107273Srwatson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 111107273Srwatson 112107273Srwatsonstatic int trust_all_interfaces = 0; 113107273SrwatsonSYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 114107273Srwatson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC"); 115107273SrwatsonTUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces); 116107273Srwatson 117107273Srwatsonstatic char trusted_interfaces[128]; 118107273SrwatsonSYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 119107273Srwatson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC"); 120107273SrwatsonTUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces, 121107273Srwatson sizeof(trusted_interfaces)); 122107273Srwatson 123107273Srwatsonstatic int ptys_equal = 0; 124107273SrwatsonSYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW, 125107273Srwatson &ptys_equal, 0, "Label pty devices as lomac/equal on create"); 126107273SrwatsonTUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal); 127107273Srwatson 128107273Srwatsonstatic int revocation_enabled = 1; 129107273SrwatsonSYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW, 130107273Srwatson &revocation_enabled, 0, "Revoke access to objects on relabel"); 131107273SrwatsonTUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled); 132107273Srwatson 133172955Srwatsonstatic int lomac_slot; 134172955Srwatson#define SLOT(l) ((struct mac_lomac *)mac_label_get((l), lomac_slot)) 135172955Srwatson#define SLOT_SET(l, val) mac_label_set((l), lomac_slot, (uintptr_t)(val)) 136107273Srwatson#define PSLOT(l) ((struct mac_lomac_proc *) \ 137172955Srwatson mac_label_get((l), lomac_slot)) 138172955Srwatson#define PSLOT_SET(l, val) mac_label_set((l), lomac_slot, (uintptr_t)(val)) 139107273Srwatson 140227293Sedstatic MALLOC_DEFINE(M_LOMAC, "mac_lomac_label", "MAC/LOMAC labels"); 141107273Srwatson 142107273Srwatsonstatic struct mac_lomac * 143107273Srwatsonlomac_alloc(int flag) 144107273Srwatson{ 145172955Srwatson struct mac_lomac *ml; 146107273Srwatson 147172955Srwatson ml = malloc(sizeof(*ml), M_LOMAC, M_ZERO | flag); 148107273Srwatson 149172955Srwatson return (ml); 150107273Srwatson} 151107273Srwatson 152107273Srwatsonstatic void 153172955Srwatsonlomac_free(struct mac_lomac *ml) 154107273Srwatson{ 155107273Srwatson 156172955Srwatson if (ml != NULL) 157172955Srwatson free(ml, M_LOMAC); 158107273Srwatson else 159107273Srwatson atomic_add_int(&destroyed_not_inited, 1); 160107273Srwatson} 161107273Srwatson 162107273Srwatsonstatic int 163172955Srwatsonlomac_atmostflags(struct mac_lomac *ml, int flags) 164107273Srwatson{ 165107273Srwatson 166172955Srwatson if ((ml->ml_flags & flags) != ml->ml_flags) 167107273Srwatson return (EINVAL); 168107273Srwatson return (0); 169107273Srwatson} 170107273Srwatson 171107273Srwatsonstatic int 172172955Srwatsonlomac_dominate_element(struct mac_lomac_element *a, 173107273Srwatson struct mac_lomac_element *b) 174107273Srwatson{ 175107273Srwatson 176107273Srwatson switch (a->mle_type) { 177107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 178107273Srwatson case MAC_LOMAC_TYPE_HIGH: 179107273Srwatson return (1); 180107273Srwatson 181107273Srwatson case MAC_LOMAC_TYPE_LOW: 182107273Srwatson switch (b->mle_type) { 183107273Srwatson case MAC_LOMAC_TYPE_GRADE: 184107273Srwatson case MAC_LOMAC_TYPE_HIGH: 185107273Srwatson return (0); 186107273Srwatson 187107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 188107273Srwatson case MAC_LOMAC_TYPE_LOW: 189107273Srwatson return (1); 190107273Srwatson 191107273Srwatson default: 192172955Srwatson panic("lomac_dominate_element: b->mle_type invalid"); 193107273Srwatson } 194107273Srwatson 195107273Srwatson case MAC_LOMAC_TYPE_GRADE: 196107273Srwatson switch (b->mle_type) { 197107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 198107273Srwatson case MAC_LOMAC_TYPE_LOW: 199107273Srwatson return (1); 200107273Srwatson 201107273Srwatson case MAC_LOMAC_TYPE_HIGH: 202107273Srwatson return (0); 203107273Srwatson 204107273Srwatson case MAC_LOMAC_TYPE_GRADE: 205107273Srwatson return (a->mle_grade >= b->mle_grade); 206107273Srwatson 207107273Srwatson default: 208172955Srwatson panic("lomac_dominate_element: b->mle_type invalid"); 209107273Srwatson } 210107273Srwatson 211107273Srwatson default: 212172955Srwatson panic("lomac_dominate_element: a->mle_type invalid"); 213107273Srwatson } 214107273Srwatson} 215107273Srwatson 216107273Srwatsonstatic int 217172955Srwatsonlomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb) 218107273Srwatson{ 219107273Srwatson 220172955Srwatson return (lomac_dominate_element(&rangeb->ml_rangehigh, 221107273Srwatson &rangea->ml_rangehigh) && 222172955Srwatson lomac_dominate_element(&rangea->ml_rangelow, 223107273Srwatson &rangeb->ml_rangelow)); 224107273Srwatson} 225107273Srwatson 226107273Srwatsonstatic int 227172955Srwatsonlomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range) 228107273Srwatson{ 229107273Srwatson 230107273Srwatson KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 231172955Srwatson ("lomac_single_in_range: a not single")); 232107273Srwatson KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 233172955Srwatson ("lomac_single_in_range: b not range")); 234107273Srwatson 235172955Srwatson return (lomac_dominate_element(&range->ml_rangehigh, 236172955Srwatson &single->ml_single) && lomac_dominate_element(&single->ml_single, 237107273Srwatson &range->ml_rangelow)); 238107273Srwatson} 239107273Srwatson 240107273Srwatsonstatic int 241172955Srwatsonlomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range) 242107273Srwatson{ 243107273Srwatson 244107273Srwatson KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 245172955Srwatson ("lomac_single_in_range: a not auxsingle")); 246107273Srwatson KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 247172955Srwatson ("lomac_single_in_range: b not range")); 248107273Srwatson 249172955Srwatson return (lomac_dominate_element(&range->ml_rangehigh, 250107273Srwatson &single->ml_auxsingle) && 251172955Srwatson lomac_dominate_element(&single->ml_auxsingle, 252107273Srwatson &range->ml_rangelow)); 253107273Srwatson} 254107273Srwatson 255107273Srwatsonstatic int 256172955Srwatsonlomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b) 257107273Srwatson{ 258107273Srwatson KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 259172955Srwatson ("lomac_dominate_single: a not single")); 260107273Srwatson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 261172955Srwatson ("lomac_dominate_single: b not single")); 262107273Srwatson 263172955Srwatson return (lomac_dominate_element(&a->ml_single, &b->ml_single)); 264107273Srwatson} 265107273Srwatson 266107273Srwatsonstatic int 267172955Srwatsonlomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b) 268107273Srwatson{ 269107273Srwatson KASSERT((~a->ml_flags & 270107273Srwatson (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0, 271172955Srwatson ("lomac_dominate_single: a not subject")); 272107273Srwatson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 273172955Srwatson ("lomac_dominate_single: b not single")); 274107273Srwatson 275172955Srwatson return (lomac_dominate_element(&a->ml_rangehigh, &b->ml_single)); 276107273Srwatson} 277107273Srwatson 278107273Srwatsonstatic int 279172955Srwatsonlomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b) 280107273Srwatson{ 281107273Srwatson 282107273Srwatson if (a->mle_type == MAC_LOMAC_TYPE_EQUAL || 283107273Srwatson b->mle_type == MAC_LOMAC_TYPE_EQUAL) 284107273Srwatson return (1); 285107273Srwatson 286107273Srwatson return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade); 287107273Srwatson} 288107273Srwatson 289107273Srwatsonstatic int 290172955Srwatsonlomac_equal_single(struct mac_lomac *a, struct mac_lomac *b) 291107273Srwatson{ 292107273Srwatson 293107273Srwatson KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 294172955Srwatson ("lomac_equal_single: a not single")); 295107273Srwatson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 296172955Srwatson ("lomac_equal_single: b not single")); 297107273Srwatson 298172955Srwatson return (lomac_equal_element(&a->ml_single, &b->ml_single)); 299107273Srwatson} 300107273Srwatson 301107273Srwatsonstatic int 302172955Srwatsonlomac_contains_equal(struct mac_lomac *ml) 303107273Srwatson{ 304107273Srwatson 305172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) 306172955Srwatson if (ml->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 307107273Srwatson return (1); 308172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) 309172955Srwatson if (ml->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL) 310107273Srwatson return (1); 311107273Srwatson 312172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) { 313172955Srwatson if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL) 314107273Srwatson return (1); 315172955Srwatson if (ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 316107273Srwatson return (1); 317107273Srwatson } 318107273Srwatson 319107273Srwatson return (0); 320107273Srwatson} 321107273Srwatson 322107273Srwatsonstatic int 323172955Srwatsonlomac_subject_privileged(struct mac_lomac *ml) 324107273Srwatson{ 325107273Srwatson 326172955Srwatson KASSERT((ml->ml_flags & MAC_LOMAC_FLAGS_BOTH) == 327107273Srwatson MAC_LOMAC_FLAGS_BOTH, 328172955Srwatson ("lomac_subject_privileged: subject doesn't have both labels")); 329107273Srwatson 330107273Srwatson /* If the single is EQUAL, it's ok. */ 331172955Srwatson if (ml->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 332107273Srwatson return (0); 333107273Srwatson 334107273Srwatson /* If either range endpoint is EQUAL, it's ok. */ 335172955Srwatson if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL || 336172955Srwatson ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 337107273Srwatson return (0); 338107273Srwatson 339107273Srwatson /* If the range is low-high, it's ok. */ 340172955Srwatson if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW && 341172955Srwatson ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH) 342107273Srwatson return (0); 343107273Srwatson 344107273Srwatson /* It's not ok. */ 345107273Srwatson return (EPERM); 346107273Srwatson} 347107273Srwatson 348107273Srwatsonstatic int 349172955Srwatsonlomac_high_single(struct mac_lomac *ml) 350107273Srwatson{ 351107273Srwatson 352172955Srwatson KASSERT((ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 353172955Srwatson ("lomac_high_single: mac_lomac not single")); 354117247Srwatson 355172955Srwatson return (ml->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH); 356107273Srwatson} 357107273Srwatson 358107273Srwatsonstatic int 359172955Srwatsonlomac_valid(struct mac_lomac *ml) 360107273Srwatson{ 361107273Srwatson 362172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 363172955Srwatson switch (ml->ml_single.mle_type) { 364107273Srwatson case MAC_LOMAC_TYPE_GRADE: 365107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 366107273Srwatson case MAC_LOMAC_TYPE_HIGH: 367107273Srwatson case MAC_LOMAC_TYPE_LOW: 368107273Srwatson break; 369107273Srwatson 370107273Srwatson default: 371107273Srwatson return (EINVAL); 372107273Srwatson } 373107273Srwatson } else { 374172955Srwatson if (ml->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF) 375107273Srwatson return (EINVAL); 376107273Srwatson } 377107273Srwatson 378172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) { 379172955Srwatson switch (ml->ml_auxsingle.mle_type) { 380107273Srwatson case MAC_LOMAC_TYPE_GRADE: 381107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 382107273Srwatson case MAC_LOMAC_TYPE_HIGH: 383107273Srwatson case MAC_LOMAC_TYPE_LOW: 384107273Srwatson break; 385107273Srwatson 386107273Srwatson default: 387107273Srwatson return (EINVAL); 388107273Srwatson } 389107273Srwatson } else { 390172955Srwatson if (ml->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF) 391107273Srwatson return (EINVAL); 392107273Srwatson } 393107273Srwatson 394172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) { 395172955Srwatson switch (ml->ml_rangelow.mle_type) { 396107273Srwatson case MAC_LOMAC_TYPE_GRADE: 397107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 398107273Srwatson case MAC_LOMAC_TYPE_HIGH: 399107273Srwatson case MAC_LOMAC_TYPE_LOW: 400107273Srwatson break; 401107273Srwatson 402107273Srwatson default: 403107273Srwatson return (EINVAL); 404107273Srwatson } 405107273Srwatson 406172955Srwatson switch (ml->ml_rangehigh.mle_type) { 407107273Srwatson case MAC_LOMAC_TYPE_GRADE: 408107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 409107273Srwatson case MAC_LOMAC_TYPE_HIGH: 410107273Srwatson case MAC_LOMAC_TYPE_LOW: 411107273Srwatson break; 412107273Srwatson 413107273Srwatson default: 414107273Srwatson return (EINVAL); 415107273Srwatson } 416172955Srwatson if (!lomac_dominate_element(&ml->ml_rangehigh, 417172955Srwatson &ml->ml_rangelow)) 418107273Srwatson return (EINVAL); 419107273Srwatson } else { 420172955Srwatson if (ml->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF || 421172955Srwatson ml->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF) 422107273Srwatson return (EINVAL); 423107273Srwatson } 424107273Srwatson 425107273Srwatson return (0); 426107273Srwatson} 427107273Srwatson 428107273Srwatsonstatic void 429172955Srwatsonlomac_set_range(struct mac_lomac *ml, u_short typelow, u_short gradelow, 430172955Srwatson u_short typehigh, u_short gradehigh) 431107273Srwatson{ 432107273Srwatson 433172955Srwatson ml->ml_rangelow.mle_type = typelow; 434172955Srwatson ml->ml_rangelow.mle_grade = gradelow; 435172955Srwatson ml->ml_rangehigh.mle_type = typehigh; 436172955Srwatson ml->ml_rangehigh.mle_grade = gradehigh; 437172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_RANGE; 438107273Srwatson} 439107273Srwatson 440107273Srwatsonstatic void 441172955Srwatsonlomac_set_single(struct mac_lomac *ml, u_short type, u_short grade) 442107273Srwatson{ 443107273Srwatson 444172955Srwatson ml->ml_single.mle_type = type; 445172955Srwatson ml->ml_single.mle_grade = grade; 446172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 447107273Srwatson} 448107273Srwatson 449107273Srwatsonstatic void 450172955Srwatsonlomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 451107273Srwatson{ 452107273Srwatson 453107273Srwatson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 454172955Srwatson ("lomac_copy_range: labelfrom not range")); 455107273Srwatson 456107273Srwatson labelto->ml_rangelow = labelfrom->ml_rangelow; 457107273Srwatson labelto->ml_rangehigh = labelfrom->ml_rangehigh; 458107273Srwatson labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE; 459107273Srwatson} 460107273Srwatson 461107273Srwatsonstatic void 462172955Srwatsonlomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 463107273Srwatson{ 464107273Srwatson 465107273Srwatson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 466172955Srwatson ("lomac_copy_single: labelfrom not single")); 467107273Srwatson 468107273Srwatson labelto->ml_single = labelfrom->ml_single; 469107273Srwatson labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 470107273Srwatson} 471107273Srwatson 472107273Srwatsonstatic void 473172955Srwatsonlomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 474107273Srwatson{ 475107273Srwatson 476107273Srwatson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 477172955Srwatson ("lomac_copy_auxsingle: labelfrom not auxsingle")); 478107273Srwatson 479107273Srwatson labelto->ml_auxsingle = labelfrom->ml_auxsingle; 480107273Srwatson labelto->ml_flags |= MAC_LOMAC_FLAG_AUX; 481107273Srwatson} 482107273Srwatson 483107273Srwatsonstatic void 484172955Srwatsonlomac_copy(struct mac_lomac *source, struct mac_lomac *dest) 485107273Srwatson{ 486107273Srwatson 487107273Srwatson if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE) 488172955Srwatson lomac_copy_single(source, dest); 489107273Srwatson if (source->ml_flags & MAC_LOMAC_FLAG_AUX) 490172955Srwatson lomac_copy_auxsingle(source, dest); 491107273Srwatson if (source->ml_flags & MAC_LOMAC_FLAG_RANGE) 492172955Srwatson lomac_copy_range(source, dest); 493107273Srwatson} 494107273Srwatson 495172955Srwatsonstatic int lomac_to_string(struct sbuf *sb, struct mac_lomac *ml); 496107273Srwatson 497107273Srwatsonstatic int 498107273Srwatsonmaybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 499168976Srwatson const char *actionname, const char *objname, struct vnode *vp) 500107273Srwatson{ 501116701Srwatson struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb; 502116701Srwatson char *subjlabeltext, *objlabeltext, *subjtext; 503116701Srwatson struct mac_lomac cached_subjlabel; 504116701Srwatson struct mac_lomac_proc *subj; 505107273Srwatson struct vattr va; 506107273Srwatson struct proc *p; 507107273Srwatson pid_t pgid; 508107273Srwatson 509122524Srwatson subj = PSLOT(curthread->td_proc->p_label); 510116701Srwatson 511107273Srwatson p = curthread->td_proc; 512107273Srwatson mtx_lock(&subj->mtx); 513107273Srwatson if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 514107273Srwatson /* 515172955Srwatson * Check to see if the pending demotion would be more or less 516172955Srwatson * severe than this one, and keep the more severe. This can 517172955Srwatson * only happen for a multi-threaded application. 518107273Srwatson */ 519172955Srwatson if (lomac_dominate_single(objlabel, &subj->mac_lomac)) { 520107273Srwatson mtx_unlock(&subj->mtx); 521107273Srwatson return (0); 522107273Srwatson } 523107273Srwatson } 524107273Srwatson bzero(&subj->mac_lomac, sizeof(subj->mac_lomac)); 525107273Srwatson /* 526107273Srwatson * Always demote the single label. 527107273Srwatson */ 528172955Srwatson lomac_copy_single(objlabel, &subj->mac_lomac); 529107273Srwatson /* 530172955Srwatson * Start with the original range, then minimize each side of the 531172955Srwatson * range to the point of not dominating the object. The high side 532172955Srwatson * will always be demoted, of course. 533107273Srwatson */ 534172955Srwatson lomac_copy_range(subjlabel, &subj->mac_lomac); 535172955Srwatson if (!lomac_dominate_element(&objlabel->ml_single, 536107273Srwatson &subj->mac_lomac.ml_rangelow)) 537107273Srwatson subj->mac_lomac.ml_rangelow = objlabel->ml_single; 538107273Srwatson subj->mac_lomac.ml_rangehigh = objlabel->ml_single; 539107273Srwatson subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE; 540170307Sjeff thread_lock(curthread); 541172207Sjeff curthread->td_flags |= TDF_ASTPENDING | TDF_MACPEND; 542170307Sjeff thread_unlock(curthread); 543116701Srwatson 544116701Srwatson /* 545172955Srwatson * Avoid memory allocation while holding a mutex; cache the label. 546116701Srwatson */ 547172955Srwatson lomac_copy_single(&subj->mac_lomac, &cached_subjlabel); 548107273Srwatson mtx_unlock(&subj->mtx); 549116701Srwatson 550116701Srwatson sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 551172955Srwatson lomac_to_string(&subjlabel_sb, subjlabel); 552116701Srwatson sbuf_finish(&subjlabel_sb); 553116701Srwatson subjlabeltext = sbuf_data(&subjlabel_sb); 554116701Srwatson 555116701Srwatson sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND); 556172955Srwatson lomac_to_string(&subjtext_sb, &subj->mac_lomac); 557116701Srwatson sbuf_finish(&subjtext_sb); 558116701Srwatson subjtext = sbuf_data(&subjtext_sb); 559116701Srwatson 560116701Srwatson sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 561172955Srwatson lomac_to_string(&objlabel_sb, objlabel); 562116701Srwatson sbuf_finish(&objlabel_sb); 563116701Srwatson objlabeltext = sbuf_data(&objlabel_sb); 564116701Srwatson 565107273Srwatson pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ 566182371Sattilio if (vp != NULL && VOP_GETATTR(vp, &va, curthread->td_ucred) == 0) { 567107273Srwatson log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 568107273Srwatson " level %s after %s a level-%s %s (inode=%ld, " 569107273Srwatson "mountpount=%s)\n", 570107273Srwatson subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 571107273Srwatson p->p_comm, subjtext, actionname, objlabeltext, objname, 572168976Srwatson va.va_fileid, vp->v_mount->mnt_stat.f_mntonname); 573107273Srwatson } else { 574107273Srwatson log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 575107273Srwatson " level %s after %s a level-%s %s\n", 576107273Srwatson subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 577107273Srwatson p->p_comm, subjtext, actionname, objlabeltext, objname); 578107273Srwatson } 579116701Srwatson 580116701Srwatson sbuf_delete(&subjlabel_sb); 581116701Srwatson sbuf_delete(&subjtext_sb); 582116701Srwatson sbuf_delete(&objlabel_sb); 583107273Srwatson 584107273Srwatson return (0); 585107273Srwatson} 586107273Srwatson 587107273Srwatson/* 588172955Srwatson * Relabel "to" to "from" only if "from" is a valid label (contains at least 589172955Srwatson * a single), as for a relabel operation which may or may not involve a 590172955Srwatson * relevant label. 591107273Srwatson */ 592107279Srwatsonstatic void 593107273Srwatsontry_relabel(struct mac_lomac *from, struct mac_lomac *to) 594107273Srwatson{ 595107273Srwatson 596107273Srwatson if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 597107273Srwatson bzero(to, sizeof(*to)); 598172955Srwatson lomac_copy(from, to); 599107273Srwatson } 600107273Srwatson} 601107273Srwatson 602107273Srwatson/* 603107273Srwatson * Policy module operations. 604107273Srwatson */ 605107273Srwatsonstatic void 606172955Srwatsonlomac_init(struct mac_policy_conf *conf) 607107273Srwatson{ 608107273Srwatson 609107273Srwatson} 610107273Srwatson 611107273Srwatson/* 612107273Srwatson * Label operations. 613107273Srwatson */ 614107273Srwatsonstatic void 615172955Srwatsonlomac_init_label(struct label *label) 616107273Srwatson{ 617107273Srwatson 618132781Skan SLOT_SET(label, lomac_alloc(M_WAITOK)); 619107273Srwatson} 620107273Srwatson 621107273Srwatsonstatic int 622172955Srwatsonlomac_init_label_waitcheck(struct label *label, int flag) 623107273Srwatson{ 624107273Srwatson 625132781Skan SLOT_SET(label, lomac_alloc(flag)); 626107273Srwatson if (SLOT(label) == NULL) 627107273Srwatson return (ENOMEM); 628107273Srwatson 629107273Srwatson return (0); 630107273Srwatson} 631107273Srwatson 632107273Srwatsonstatic void 633172955Srwatsonlomac_destroy_label(struct label *label) 634107273Srwatson{ 635107273Srwatson 636107273Srwatson lomac_free(SLOT(label)); 637132781Skan SLOT_SET(label, NULL); 638107273Srwatson} 639107273Srwatson 640116701Srwatsonstatic int 641172955Srwatsonlomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element) 642107273Srwatson{ 643107273Srwatson 644107273Srwatson switch (element->mle_type) { 645107273Srwatson case MAC_LOMAC_TYPE_HIGH: 646116701Srwatson return (sbuf_printf(sb, "high")); 647107273Srwatson 648107273Srwatson case MAC_LOMAC_TYPE_LOW: 649116701Srwatson return (sbuf_printf(sb, "low")); 650107273Srwatson 651107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 652116701Srwatson return (sbuf_printf(sb, "equal")); 653107273Srwatson 654107273Srwatson case MAC_LOMAC_TYPE_GRADE: 655116701Srwatson return (sbuf_printf(sb, "%d", element->mle_grade)); 656107273Srwatson 657107273Srwatson default: 658172955Srwatson panic("lomac_element_to_string: invalid type (%d)", 659107273Srwatson element->mle_type); 660107273Srwatson } 661107273Srwatson} 662107273Srwatson 663107273Srwatsonstatic int 664172955Srwatsonlomac_to_string(struct sbuf *sb, struct mac_lomac *ml) 665107273Srwatson{ 666107273Srwatson 667172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 668172955Srwatson if (lomac_element_to_string(sb, &ml->ml_single) == -1) 669116701Srwatson return (EINVAL); 670107273Srwatson } 671107273Srwatson 672172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) { 673116701Srwatson if (sbuf_putc(sb, '[') == -1) 674116701Srwatson return (EINVAL); 675107273Srwatson 676172955Srwatson if (lomac_element_to_string(sb, &ml->ml_auxsingle) == -1) 677116701Srwatson return (EINVAL); 678107273Srwatson 679116701Srwatson if (sbuf_putc(sb, ']') == -1) 680116701Srwatson return (EINVAL); 681107273Srwatson } 682107273Srwatson 683172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) { 684116701Srwatson if (sbuf_putc(sb, '(') == -1) 685116701Srwatson return (EINVAL); 686107273Srwatson 687172955Srwatson if (lomac_element_to_string(sb, &ml->ml_rangelow) == -1) 688116701Srwatson return (EINVAL); 689107273Srwatson 690116701Srwatson if (sbuf_putc(sb, '-') == -1) 691116701Srwatson return (EINVAL); 692107273Srwatson 693172955Srwatson if (lomac_element_to_string(sb, &ml->ml_rangehigh) == -1) 694116701Srwatson return (EINVAL); 695107273Srwatson 696122270Srwatson if (sbuf_putc(sb, ')') == -1) 697116701Srwatson return (EINVAL); 698107273Srwatson } 699107273Srwatson 700107273Srwatson return (0); 701107273Srwatson} 702107273Srwatson 703107273Srwatsonstatic int 704172955Srwatsonlomac_externalize_label(struct label *label, char *element_name, 705116701Srwatson struct sbuf *sb, int *claimed) 706107273Srwatson{ 707172955Srwatson struct mac_lomac *ml; 708107273Srwatson 709107273Srwatson if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 710107273Srwatson return (0); 711107273Srwatson 712107273Srwatson (*claimed)++; 713107273Srwatson 714172955Srwatson ml = SLOT(label); 715107273Srwatson 716172955Srwatson return (lomac_to_string(sb, ml)); 717107273Srwatson} 718107273Srwatson 719107273Srwatsonstatic int 720172955Srwatsonlomac_parse_element(struct mac_lomac_element *element, char *string) 721107273Srwatson{ 722107273Srwatson 723172955Srwatson if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { 724107273Srwatson element->mle_type = MAC_LOMAC_TYPE_HIGH; 725107273Srwatson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 726172955Srwatson } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { 727107273Srwatson element->mle_type = MAC_LOMAC_TYPE_LOW; 728107273Srwatson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 729181217Srwatson } else if (strcmp(string, "equal") == 0 || 730181217Srwatson strcmp(string, "eq") == 0) { 731107273Srwatson element->mle_type = MAC_LOMAC_TYPE_EQUAL; 732107273Srwatson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 733107273Srwatson } else { 734107273Srwatson char *p0, *p1; 735107273Srwatson int d; 736107273Srwatson 737107273Srwatson p0 = string; 738107273Srwatson d = strtol(p0, &p1, 10); 739107273Srwatson 740107273Srwatson if (d < 0 || d > 65535) 741107273Srwatson return (EINVAL); 742107273Srwatson element->mle_type = MAC_LOMAC_TYPE_GRADE; 743107273Srwatson element->mle_grade = d; 744107273Srwatson 745107273Srwatson if (p1 == p0 || *p1 != '\0') 746107273Srwatson return (EINVAL); 747107273Srwatson } 748107273Srwatson 749107273Srwatson return (0); 750107273Srwatson} 751107273Srwatson 752107273Srwatson/* 753172955Srwatson * Note: destructively consumes the string, make a local copy before calling 754172955Srwatson * if that's a problem. 755107273Srwatson */ 756107273Srwatsonstatic int 757172955Srwatsonlomac_parse(struct mac_lomac *ml, char *string) 758107273Srwatson{ 759107273Srwatson char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle, 760107273Srwatson *auxsingleend; 761107273Srwatson int error; 762107273Srwatson 763107273Srwatson /* Do we have a range? */ 764107273Srwatson single = string; 765229272Sed range = strchr(string, '('); 766107273Srwatson if (range == single) 767107273Srwatson single = NULL; 768229272Sed auxsingle = strchr(string, '['); 769107273Srwatson if (auxsingle == single) 770107273Srwatson single = NULL; 771107273Srwatson if (range != NULL && auxsingle != NULL) 772107273Srwatson return (EINVAL); 773107273Srwatson rangelow = rangehigh = NULL; 774107273Srwatson if (range != NULL) { 775107273Srwatson /* Nul terminate the end of the single string. */ 776107273Srwatson *range = '\0'; 777107273Srwatson range++; 778107273Srwatson rangelow = range; 779229272Sed rangehigh = strchr(rangelow, '-'); 780107273Srwatson if (rangehigh == NULL) 781107273Srwatson return (EINVAL); 782107273Srwatson rangehigh++; 783107273Srwatson if (*rangelow == '\0' || *rangehigh == '\0') 784107273Srwatson return (EINVAL); 785229272Sed rangeend = strchr(rangehigh, ')'); 786107273Srwatson if (rangeend == NULL) 787107273Srwatson return (EINVAL); 788107273Srwatson if (*(rangeend + 1) != '\0') 789107273Srwatson return (EINVAL); 790107273Srwatson /* Nul terminate the ends of the ranges. */ 791107273Srwatson *(rangehigh - 1) = '\0'; 792107273Srwatson *rangeend = '\0'; 793107273Srwatson } 794107273Srwatson KASSERT((rangelow != NULL && rangehigh != NULL) || 795107273Srwatson (rangelow == NULL && rangehigh == NULL), 796172955Srwatson ("lomac_internalize_label: range mismatch")); 797107273Srwatson if (auxsingle != NULL) { 798107273Srwatson /* Nul terminate the end of the single string. */ 799107273Srwatson *auxsingle = '\0'; 800107273Srwatson auxsingle++; 801229272Sed auxsingleend = strchr(auxsingle, ']'); 802107273Srwatson if (auxsingleend == NULL) 803107273Srwatson return (EINVAL); 804107273Srwatson if (*(auxsingleend + 1) != '\0') 805107273Srwatson return (EINVAL); 806107273Srwatson /* Nul terminate the end of the auxsingle. */ 807107273Srwatson *auxsingleend = '\0'; 808107273Srwatson } 809107273Srwatson 810172955Srwatson bzero(ml, sizeof(*ml)); 811107273Srwatson if (single != NULL) { 812172955Srwatson error = lomac_parse_element(&ml->ml_single, single); 813107273Srwatson if (error) 814107273Srwatson return (error); 815172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 816107273Srwatson } 817107273Srwatson 818107273Srwatson if (auxsingle != NULL) { 819181217Srwatson error = lomac_parse_element(&ml->ml_auxsingle, auxsingle); 820107273Srwatson if (error) 821107273Srwatson return (error); 822172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_AUX; 823107273Srwatson } 824107273Srwatson 825107273Srwatson if (rangelow != NULL) { 826172955Srwatson error = lomac_parse_element(&ml->ml_rangelow, rangelow); 827107273Srwatson if (error) 828107273Srwatson return (error); 829172955Srwatson error = lomac_parse_element(&ml->ml_rangehigh, rangehigh); 830107273Srwatson if (error) 831107273Srwatson return (error); 832172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_RANGE; 833107273Srwatson } 834107273Srwatson 835172955Srwatson error = lomac_valid(ml); 836107273Srwatson if (error) 837107273Srwatson return (error); 838107273Srwatson 839107273Srwatson return (0); 840107273Srwatson} 841107273Srwatson 842107273Srwatsonstatic int 843172955Srwatsonlomac_internalize_label(struct label *label, char *element_name, 844107273Srwatson char *element_data, int *claimed) 845107273Srwatson{ 846172955Srwatson struct mac_lomac *ml, ml_temp; 847107273Srwatson int error; 848107273Srwatson 849107273Srwatson if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 850107273Srwatson return (0); 851107273Srwatson 852107273Srwatson (*claimed)++; 853107273Srwatson 854172955Srwatson error = lomac_parse(&ml_temp, element_data); 855107273Srwatson if (error) 856107273Srwatson return (error); 857107273Srwatson 858172955Srwatson ml = SLOT(label); 859172955Srwatson *ml = ml_temp; 860107273Srwatson 861107273Srwatson return (0); 862107273Srwatson} 863107273Srwatson 864107273Srwatsonstatic void 865172955Srwatsonlomac_copy_label(struct label *src, struct label *dest) 866107273Srwatson{ 867107273Srwatson 868107273Srwatson *SLOT(dest) = *SLOT(src); 869107273Srwatson} 870107273Srwatson 871107273Srwatson/* 872173138Srwatson * Object-specific entry point implementations are sorted alphabetically by 873173138Srwatson * object type name and then by operation. 874107273Srwatson */ 875173138Srwatsonstatic int 876173138Srwatsonlomac_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 877173138Srwatson struct ifnet *ifp, struct label *ifplabel) 878107273Srwatson{ 879173138Srwatson struct mac_lomac *a, *b; 880107273Srwatson 881173138Srwatson if (!lomac_enabled) 882173138Srwatson return (0); 883107273Srwatson 884173138Srwatson a = SLOT(dlabel); 885173138Srwatson b = SLOT(ifplabel); 886107273Srwatson 887173138Srwatson if (lomac_equal_single(a, b)) 888173138Srwatson return (0); 889173138Srwatson return (EACCES); 890107273Srwatson} 891107273Srwatson 892107273Srwatsonstatic void 893173138Srwatsonlomac_bpfdesc_create(struct ucred *cred, struct bpf_d *d, 894173138Srwatson struct label *dlabel) 895107273Srwatson{ 896107273Srwatson struct mac_lomac *source, *dest; 897107273Srwatson 898122524Srwatson source = SLOT(cred->cr_label); 899173138Srwatson dest = SLOT(dlabel); 900107273Srwatson 901172955Srwatson lomac_copy_single(source, dest); 902107273Srwatson} 903107273Srwatson 904107273Srwatsonstatic void 905173138Srwatsonlomac_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 906173138Srwatson struct mbuf *m, struct label *mlabel) 907107273Srwatson{ 908107273Srwatson struct mac_lomac *source, *dest; 909107273Srwatson 910173138Srwatson source = SLOT(dlabel); 911173138Srwatson dest = SLOT(mlabel); 912173138Srwatson 913172955Srwatson lomac_copy_single(source, dest); 914107273Srwatson} 915107273Srwatson 916173138Srwatsonstatic int 917173138Srwatsonlomac_cred_check_relabel(struct ucred *cred, struct label *newlabel) 918107273Srwatson{ 919173138Srwatson struct mac_lomac *subj, *new; 920173138Srwatson int error; 921107273Srwatson 922173138Srwatson subj = SLOT(cred->cr_label); 923173138Srwatson new = SLOT(newlabel); 924107273Srwatson 925173138Srwatson /* 926173138Srwatson * If there is a LOMAC label update for the credential, it may be an 927173138Srwatson * update of the single, range, or both. 928173138Srwatson */ 929173138Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 930173138Srwatson if (error) 931173138Srwatson return (error); 932107273Srwatson 933173138Srwatson /* 934173138Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 935173138Srwatson */ 936173138Srwatson if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 937173138Srwatson /* 938173138Srwatson * Fill in the missing parts from the previous label. 939173138Srwatson */ 940173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 941173138Srwatson lomac_copy_single(subj, new); 942173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 943173138Srwatson lomac_copy_range(subj, new); 944107273Srwatson 945173138Srwatson /* 946173138Srwatson * To change the LOMAC range on a credential, the new range 947173138Srwatson * label must be in the current range. 948173138Srwatson */ 949173138Srwatson if (!lomac_range_in_range(new, subj)) 950173138Srwatson return (EPERM); 951107273Srwatson 952173138Srwatson /* 953173138Srwatson * To change the LOMAC single label on a credential, the new 954173138Srwatson * single label must be in the new range. Implicitly from 955173138Srwatson * the previous check, the new single is in the old range. 956173138Srwatson */ 957173138Srwatson if (!lomac_single_in_range(new, new)) 958173138Srwatson return (EPERM); 959107273Srwatson 960173138Srwatson /* 961173138Srwatson * To have EQUAL in any component of the new credential LOMAC 962173138Srwatson * label, the subject must already have EQUAL in their label. 963173138Srwatson */ 964173138Srwatson if (lomac_contains_equal(new)) { 965173138Srwatson error = lomac_subject_privileged(subj); 966173138Srwatson if (error) 967173138Srwatson return (error); 968173138Srwatson } 969107273Srwatson 970173138Srwatson /* 971173138Srwatson * XXXMAC: Additional consistency tests regarding the single 972173138Srwatson * and range of the new label might be performed here. 973173138Srwatson */ 974173138Srwatson } 975107273Srwatson 976173138Srwatson return (0); 977107273Srwatson} 978107273Srwatson 979107273Srwatsonstatic int 980173138Srwatsonlomac_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 981107273Srwatson{ 982173138Srwatson struct mac_lomac *subj, *obj; 983107273Srwatson 984173138Srwatson if (!lomac_enabled) 985173138Srwatson return (0); 986107273Srwatson 987173138Srwatson subj = SLOT(cr1->cr_label); 988173138Srwatson obj = SLOT(cr2->cr_label); 989107273Srwatson 990173138Srwatson /* XXX: range */ 991173138Srwatson if (!lomac_dominate_single(obj, subj)) 992173138Srwatson return (ESRCH); 993107273Srwatson 994107273Srwatson return (0); 995107273Srwatson} 996184407Srwatson 997107273Srwatsonstatic void 998184407Srwatsonlomac_cred_create_init(struct ucred *cred) 999184407Srwatson{ 1000184407Srwatson struct mac_lomac *dest; 1001184407Srwatson 1002184407Srwatson dest = SLOT(cred->cr_label); 1003184407Srwatson 1004184407Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0); 1005184407Srwatson lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 0); 1006184407Srwatson} 1007184407Srwatson 1008184407Srwatsonstatic void 1009184407Srwatsonlomac_cred_create_swapper(struct ucred *cred) 1010184407Srwatson{ 1011184407Srwatson struct mac_lomac *dest; 1012184407Srwatson 1013184407Srwatson dest = SLOT(cred->cr_label); 1014184407Srwatson 1015184407Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1016184407Srwatson lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 0); 1017184407Srwatson} 1018184407Srwatson 1019184407Srwatsonstatic void 1020173138Srwatsonlomac_cred_relabel(struct ucred *cred, struct label *newlabel) 1021107273Srwatson{ 1022107273Srwatson struct mac_lomac *source, *dest; 1023107273Srwatson 1024173138Srwatson source = SLOT(newlabel); 1025173138Srwatson dest = SLOT(cred->cr_label); 1026107273Srwatson 1027173138Srwatson try_relabel(source, dest); 1028107273Srwatson} 1029107273Srwatson 1030107273Srwatsonstatic void 1031173138Srwatsonlomac_devfs_create_device(struct ucred *cred, struct mount *mp, 1032173138Srwatson struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 1033122875Srwatson{ 1034173138Srwatson struct mac_lomac *ml; 1035231378Sed const char *dn; 1036173138Srwatson int lomac_type; 1037122875Srwatson 1038173138Srwatson ml = SLOT(delabel); 1039231378Sed dn = devtoname(dev); 1040231378Sed if (strcmp(dn, "null") == 0 || 1041231378Sed strcmp(dn, "zero") == 0 || 1042231378Sed strcmp(dn, "random") == 0 || 1043231378Sed strncmp(dn, "fd/", strlen("fd/")) == 0 || 1044231378Sed strncmp(dn, "ttyv", strlen("ttyv")) == 0) 1045173138Srwatson lomac_type = MAC_LOMAC_TYPE_EQUAL; 1046173138Srwatson else if (ptys_equal && 1047231378Sed (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 1048231378Sed strncmp(dn, "pts/", strlen("pts/")) == 0 || 1049231378Sed strncmp(dn, "ptyp", strlen("ptyp")) == 0)) 1050173138Srwatson lomac_type = MAC_LOMAC_TYPE_EQUAL; 1051173138Srwatson else 1052173138Srwatson lomac_type = MAC_LOMAC_TYPE_HIGH; 1053173138Srwatson lomac_set_single(ml, lomac_type, 0); 1054122875Srwatson} 1055122875Srwatson 1056122875Srwatsonstatic void 1057173138Srwatsonlomac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 1058173138Srwatson struct devfs_dirent *de, struct label *delabel) 1059107273Srwatson{ 1060173138Srwatson struct mac_lomac *ml; 1061107273Srwatson 1062173138Srwatson ml = SLOT(delabel); 1063173138Srwatson lomac_set_single(ml, MAC_LOMAC_TYPE_HIGH, 0); 1064107273Srwatson} 1065107273Srwatson 1066107273Srwatsonstatic void 1067173138Srwatsonlomac_devfs_create_symlink(struct ucred *cred, struct mount *mp, 1068173138Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 1069173138Srwatson struct label *delabel) 1070107273Srwatson{ 1071107273Srwatson struct mac_lomac *source, *dest; 1072107273Srwatson 1073122524Srwatson source = SLOT(cred->cr_label); 1074173138Srwatson dest = SLOT(delabel); 1075107273Srwatson 1076172955Srwatson lomac_copy_single(source, dest); 1077107273Srwatson} 1078107273Srwatson 1079107273Srwatsonstatic void 1080173138Srwatsonlomac_devfs_update(struct mount *mp, struct devfs_dirent *de, 1081173138Srwatson struct label *delabel, struct vnode *vp, struct label *vplabel) 1082107273Srwatson{ 1083107273Srwatson struct mac_lomac *source, *dest; 1084107273Srwatson 1085173138Srwatson source = SLOT(vplabel); 1086173138Srwatson dest = SLOT(delabel); 1087107273Srwatson 1088173138Srwatson lomac_copy(source, dest); 1089107273Srwatson} 1090107273Srwatson 1091107273Srwatsonstatic void 1092173138Srwatsonlomac_devfs_vnode_associate(struct mount *mp, struct label *mplabel, 1093173138Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 1094173138Srwatson struct label *vplabel) 1095107273Srwatson{ 1096107273Srwatson struct mac_lomac *source, *dest; 1097107273Srwatson 1098173138Srwatson source = SLOT(delabel); 1099173138Srwatson dest = SLOT(vplabel); 1100107273Srwatson 1101172955Srwatson lomac_copy_single(source, dest); 1102107273Srwatson} 1103107273Srwatson 1104173138Srwatsonstatic int 1105173138Srwatsonlomac_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1106173138Srwatson struct label *ifplabel, struct label *newlabel) 1107107273Srwatson{ 1108173138Srwatson struct mac_lomac *subj, *new; 1109173138Srwatson int error; 1110107273Srwatson 1111173138Srwatson subj = SLOT(cred->cr_label); 1112173138Srwatson new = SLOT(newlabel); 1113107273Srwatson 1114173138Srwatson /* 1115173138Srwatson * If there is a LOMAC label update for the interface, it may be an 1116173138Srwatson * update of the single, range, or both. 1117173138Srwatson */ 1118173138Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1119173138Srwatson if (error) 1120173138Srwatson return (error); 1121107273Srwatson 1122173138Srwatson /* 1123173138Srwatson * Relabling network interfaces requires LOMAC privilege. 1124173138Srwatson */ 1125173138Srwatson error = lomac_subject_privileged(subj); 1126173138Srwatson if (error) 1127173138Srwatson return (error); 1128107273Srwatson 1129173138Srwatson /* 1130173138Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 1131173138Srwatson */ 1132173138Srwatson if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1133173138Srwatson /* 1134173138Srwatson * Fill in the missing parts from the previous label. 1135173138Srwatson */ 1136173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1137173138Srwatson lomac_copy_single(subj, new); 1138173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1139173138Srwatson lomac_copy_range(subj, new); 1140107273Srwatson 1141173138Srwatson /* 1142173138Srwatson * Rely on the traditional superuser status for the LOMAC 1143173138Srwatson * interface relabel requirements. XXXMAC: This will go 1144173138Srwatson * away. 1145173138Srwatson * 1146173138Srwatson * XXXRW: This is also redundant to a higher layer check. 1147173138Srwatson */ 1148173138Srwatson error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0); 1149173138Srwatson if (error) 1150173138Srwatson return (EPERM); 1151107273Srwatson 1152173138Srwatson /* 1153173138Srwatson * XXXMAC: Additional consistency tests regarding the single 1154173138Srwatson * and the range of the new label might be performed here. 1155173138Srwatson */ 1156173138Srwatson } 1157107273Srwatson 1158173138Srwatson return (0); 1159107273Srwatson} 1160107273Srwatson 1161173138Srwatsonstatic int 1162173138Srwatsonlomac_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1163173138Srwatson struct mbuf *m, struct label *mlabel) 1164107273Srwatson{ 1165173138Srwatson struct mac_lomac *p, *i; 1166107273Srwatson 1167173138Srwatson if (!lomac_enabled) 1168173138Srwatson return (0); 1169107273Srwatson 1170173138Srwatson p = SLOT(mlabel); 1171173138Srwatson i = SLOT(ifplabel); 1172107273Srwatson 1173173138Srwatson return (lomac_single_in_range(p, i) ? 0 : EACCES); 1174107273Srwatson} 1175107273Srwatson 1176107273Srwatsonstatic void 1177172955Srwatsonlomac_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1178107273Srwatson{ 1179121816Sbrooks char tifname[IFNAMSIZ], *p, *q; 1180107273Srwatson char tiflist[sizeof(trusted_interfaces)]; 1181107273Srwatson struct mac_lomac *dest; 1182107273Srwatson int len, grade; 1183107273Srwatson 1184168976Srwatson dest = SLOT(ifplabel); 1185107273Srwatson 1186168976Srwatson if (ifp->if_type == IFT_LOOP) { 1187107273Srwatson grade = MAC_LOMAC_TYPE_EQUAL; 1188107273Srwatson goto set; 1189107273Srwatson } 1190107273Srwatson 1191107273Srwatson if (trust_all_interfaces) { 1192107273Srwatson grade = MAC_LOMAC_TYPE_HIGH; 1193107273Srwatson goto set; 1194107273Srwatson } 1195107273Srwatson 1196107273Srwatson grade = MAC_LOMAC_TYPE_LOW; 1197107273Srwatson 1198107273Srwatson if (trusted_interfaces[0] == '\0' || 1199107273Srwatson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1200107273Srwatson goto set; 1201107273Srwatson 1202107273Srwatson bzero(tiflist, sizeof(tiflist)); 1203107273Srwatson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1204107273Srwatson if(*p != ' ' && *p != '\t') 1205107273Srwatson *q = *p; 1206107273Srwatson 1207107273Srwatson for (p = q = tiflist;; p++) { 1208107273Srwatson if (*p == ',' || *p == '\0') { 1209107273Srwatson len = p - q; 1210107273Srwatson if (len < IFNAMSIZ) { 1211107273Srwatson bzero(tifname, sizeof(tifname)); 1212107273Srwatson bcopy(q, tifname, len); 1213168976Srwatson if (strcmp(tifname, ifp->if_xname) == 0) { 1214107273Srwatson grade = MAC_LOMAC_TYPE_HIGH; 1215107273Srwatson break; 1216107273Srwatson } 1217107273Srwatson } 1218107273Srwatson else { 1219107273Srwatson *p = '\0'; 1220107273Srwatson printf("MAC/LOMAC warning: interface name " 1221107273Srwatson "\"%s\" is too long (must be < %d)\n", 1222107273Srwatson q, IFNAMSIZ); 1223107273Srwatson } 1224107273Srwatson if (*p == '\0') 1225107273Srwatson break; 1226107273Srwatson q = p + 1; 1227107273Srwatson } 1228107273Srwatson } 1229107273Srwatsonset: 1230172955Srwatson lomac_set_single(dest, grade, 0); 1231172955Srwatson lomac_set_range(dest, grade, 0, grade, 0); 1232107273Srwatson} 1233107273Srwatson 1234107273Srwatsonstatic void 1235173138Srwatsonlomac_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1236173138Srwatson struct mbuf *m, struct label *mlabel) 1237107273Srwatson{ 1238107273Srwatson struct mac_lomac *source, *dest; 1239107273Srwatson 1240173138Srwatson source = SLOT(ifplabel); 1241173138Srwatson dest = SLOT(mlabel); 1242107273Srwatson 1243172955Srwatson lomac_copy_single(source, dest); 1244107273Srwatson} 1245107273Srwatson 1246107273Srwatsonstatic void 1247173138Srwatsonlomac_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1248173138Srwatson struct label *ifplabel, struct label *newlabel) 1249107273Srwatson{ 1250107273Srwatson struct mac_lomac *source, *dest; 1251107273Srwatson 1252173138Srwatson source = SLOT(newlabel); 1253173138Srwatson dest = SLOT(ifplabel); 1254107273Srwatson 1255173138Srwatson try_relabel(source, dest); 1256107273Srwatson} 1257107273Srwatson 1258173138Srwatsonstatic int 1259173138Srwatsonlomac_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1260173138Srwatson struct mbuf *m, struct label *mlabel) 1261173138Srwatson{ 1262173138Srwatson struct mac_lomac *p, *i; 1263173138Srwatson 1264173138Srwatson if (!lomac_enabled) 1265173138Srwatson return (0); 1266173138Srwatson 1267173138Srwatson p = SLOT(mlabel); 1268173138Srwatson i = SLOT(inplabel); 1269173138Srwatson 1270173138Srwatson return (lomac_equal_single(p, i) ? 0 : EACCES); 1271173138Srwatson} 1272173138Srwatson 1273183980Sbzstatic int 1274183980Sbzlomac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 1275183980Sbz struct label *inplabel) 1276183980Sbz{ 1277183980Sbz struct mac_lomac *subj, *obj; 1278183980Sbz 1279183980Sbz if (!lomac_enabled) 1280183980Sbz return (0); 1281183980Sbz 1282183980Sbz subj = SLOT(cred->cr_label); 1283183980Sbz obj = SLOT(inplabel); 1284183980Sbz 1285183980Sbz if (!lomac_dominate_single(obj, subj)) 1286183980Sbz return (ENOENT); 1287183980Sbz 1288183980Sbz return (0); 1289183980Sbz} 1290183980Sbz 1291107273Srwatsonstatic void 1292173138Srwatsonlomac_inpcb_create(struct socket *so, struct label *solabel, 1293173138Srwatson struct inpcb *inp, struct label *inplabel) 1294107273Srwatson{ 1295107273Srwatson struct mac_lomac *source, *dest; 1296107273Srwatson 1297173138Srwatson source = SLOT(solabel); 1298173138Srwatson dest = SLOT(inplabel); 1299107273Srwatson 1300172955Srwatson lomac_copy_single(source, dest); 1301107273Srwatson} 1302107273Srwatson 1303107273Srwatsonstatic void 1304172955Srwatsonlomac_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1305123607Srwatson struct mbuf *m, struct label *mlabel) 1306123607Srwatson{ 1307123607Srwatson struct mac_lomac *source, *dest; 1308123607Srwatson 1309123607Srwatson source = SLOT(inplabel); 1310123607Srwatson dest = SLOT(mlabel); 1311123607Srwatson 1312172955Srwatson lomac_copy_single(source, dest); 1313123607Srwatson} 1314123607Srwatson 1315123607Srwatsonstatic void 1316173138Srwatsonlomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1317173138Srwatson struct inpcb *inp, struct label *inplabel) 1318107273Srwatson{ 1319107273Srwatson struct mac_lomac *source, *dest; 1320107273Srwatson 1321193391Srwatson SOCK_LOCK_ASSERT(so); 1322193391Srwatson 1323173138Srwatson source = SLOT(solabel); 1324173138Srwatson dest = SLOT(inplabel); 1325107273Srwatson 1326172955Srwatson lomac_copy_single(source, dest); 1327107273Srwatson} 1328107273Srwatson 1329107273Srwatsonstatic void 1330184308Srwatsonlomac_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1331184308Srwatson struct label *q6label) 1332184308Srwatson{ 1333184308Srwatson struct mac_lomac *source, *dest; 1334184308Srwatson 1335184308Srwatson source = SLOT(mlabel); 1336184308Srwatson dest = SLOT(q6label); 1337184308Srwatson 1338184308Srwatson lomac_copy_single(source, dest); 1339184308Srwatson} 1340184308Srwatson 1341184308Srwatsonstatic int 1342184308Srwatsonlomac_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1343184308Srwatson struct label *q6label) 1344184308Srwatson{ 1345184308Srwatson struct mac_lomac *a, *b; 1346184308Srwatson 1347184308Srwatson a = SLOT(q6label); 1348184308Srwatson b = SLOT(mlabel); 1349184308Srwatson 1350184308Srwatson return (lomac_equal_single(a, b)); 1351184308Srwatson} 1352184308Srwatson 1353184308Srwatsonstatic void 1354184308Srwatsonlomac_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1355184308Srwatson struct label *mlabel) 1356184308Srwatson{ 1357184308Srwatson struct mac_lomac *source, *dest; 1358184308Srwatson 1359184308Srwatson source = SLOT(q6label); 1360184308Srwatson dest = SLOT(mlabel); 1361184308Srwatson 1362184308Srwatson /* Just use the head, since we require them all to match. */ 1363184308Srwatson lomac_copy_single(source, dest); 1364184308Srwatson} 1365184308Srwatson 1366184308Srwatsonstatic void 1367184308Srwatsonlomac_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1368184308Srwatson struct label *q6label) 1369184308Srwatson{ 1370184308Srwatson 1371184308Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1372184308Srwatson} 1373184308Srwatson 1374184308Srwatsonstatic void 1375179781Srwatsonlomac_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1376179781Srwatson struct label *qlabel) 1377107273Srwatson{ 1378107273Srwatson struct mac_lomac *source, *dest; 1379107273Srwatson 1380173138Srwatson source = SLOT(mlabel); 1381179781Srwatson dest = SLOT(qlabel); 1382107273Srwatson 1383172955Srwatson lomac_copy_single(source, dest); 1384107273Srwatson} 1385107273Srwatson 1386107273Srwatsonstatic int 1387179781Srwatsonlomac_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1388179781Srwatson struct label *qlabel) 1389107273Srwatson{ 1390107273Srwatson struct mac_lomac *a, *b; 1391107273Srwatson 1392179781Srwatson a = SLOT(qlabel); 1393168976Srwatson b = SLOT(mlabel); 1394107273Srwatson 1395172955Srwatson return (lomac_equal_single(a, b)); 1396107273Srwatson} 1397107273Srwatson 1398107273Srwatsonstatic void 1399179781Srwatsonlomac_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1400179781Srwatson struct label *mlabel) 1401107273Srwatson{ 1402107273Srwatson struct mac_lomac *source, *dest; 1403107273Srwatson 1404179781Srwatson source = SLOT(qlabel); 1405173138Srwatson dest = SLOT(mlabel); 1406107273Srwatson 1407173138Srwatson /* Just use the head, since we require them all to match. */ 1408173138Srwatson lomac_copy_single(source, dest); 1409107273Srwatson} 1410107273Srwatson 1411107273Srwatsonstatic void 1412179781Srwatsonlomac_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1413179781Srwatson struct label *qlabel) 1414107273Srwatson{ 1415107273Srwatson 1416107273Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1417107273Srwatson} 1418107273Srwatson 1419173138Srwatsonstatic int 1420173138Srwatsonlomac_kld_check_load(struct ucred *cred, struct vnode *vp, 1421173138Srwatson struct label *vplabel) 1422122875Srwatson{ 1423173138Srwatson struct mac_lomac *subj, *obj; 1424122875Srwatson 1425173138Srwatson if (!lomac_enabled) 1426173138Srwatson return (0); 1427122875Srwatson 1428173138Srwatson subj = SLOT(cred->cr_label); 1429173138Srwatson obj = SLOT(vplabel); 1430122875Srwatson 1431173138Srwatson if (lomac_subject_privileged(subj)) 1432173138Srwatson return (EPERM); 1433165150Scsjp 1434173138Srwatson if (!lomac_high_single(obj)) 1435173138Srwatson return (EACCES); 1436173138Srwatson 1437173138Srwatson return (0); 1438165150Scsjp} 1439165150Scsjp 1440165150Scsjpstatic void 1441173138Srwatsonlomac_mount_create(struct ucred *cred, struct mount *mp, 1442173138Srwatson struct label *mplabel) 1443165150Scsjp{ 1444165150Scsjp struct mac_lomac *source, *dest; 1445165150Scsjp 1446173138Srwatson source = SLOT(cred->cr_label); 1447173138Srwatson dest = SLOT(mplabel); 1448173138Srwatson lomac_copy_single(source, dest); 1449165150Scsjp} 1450165150Scsjp 1451165150Scsjpstatic void 1452173095Srwatsonlomac_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel, 1453173095Srwatson struct mbuf *m, struct label *mlabel) 1454173095Srwatson{ 1455173095Srwatson struct mac_lomac *dest; 1456173095Srwatson 1457173095Srwatson dest = SLOT(mlabel); 1458173095Srwatson 1459173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1460173095Srwatson} 1461173095Srwatson 1462173095Srwatsonstatic void 1463173095Srwatsonlomac_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1464173095Srwatson struct mbuf *m, struct label *mlabel) 1465173095Srwatson{ 1466173095Srwatson struct mac_lomac *dest; 1467173095Srwatson 1468173095Srwatson dest = SLOT(mlabel); 1469173095Srwatson 1470173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1471173095Srwatson} 1472173095Srwatson 1473173095Srwatsonstatic void 1474173102Srwatsonlomac_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1475173102Srwatson struct mbuf *msend, struct label *msendlabel) 1476173102Srwatson{ 1477173102Srwatson struct mac_lomac *source, *dest; 1478173102Srwatson 1479173102Srwatson source = SLOT(mrecvlabel); 1480173102Srwatson dest = SLOT(msendlabel); 1481173102Srwatson 1482173102Srwatson lomac_copy_single(source, dest); 1483173102Srwatson} 1484173102Srwatson 1485173102Srwatsonstatic void 1486173018Srwatsonlomac_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1487162238Scsjp{ 1488162238Scsjp struct mac_lomac *dest; 1489162238Scsjp 1490168976Srwatson dest = SLOT(mlabel); 1491162238Scsjp 1492162238Scsjp /* XXX: where is the label for the firewall really comming from? */ 1493172955Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1494162238Scsjp} 1495162238Scsjp 1496173095Srwatsonstatic void 1497173138Srwatsonlomac_netinet_fragment(struct mbuf *m, struct label *mlabel, 1498173138Srwatson struct mbuf *frag, struct label *fraglabel) 1499173138Srwatson{ 1500173138Srwatson struct mac_lomac *source, *dest; 1501173138Srwatson 1502173138Srwatson source = SLOT(mlabel); 1503173138Srwatson dest = SLOT(fraglabel); 1504173138Srwatson 1505173138Srwatson lomac_copy_single(source, dest); 1506173138Srwatson} 1507173138Srwatson 1508173138Srwatsonstatic void 1509173102Srwatsonlomac_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1510173102Srwatson struct mbuf *msend, struct label *msendlabel) 1511173102Srwatson{ 1512173102Srwatson struct mac_lomac *source, *dest; 1513173102Srwatson 1514173102Srwatson source = SLOT(mrecvlabel); 1515173102Srwatson dest = SLOT(msendlabel); 1516173102Srwatson 1517173102Srwatson lomac_copy_single(source, dest); 1518173102Srwatson} 1519173102Srwatson 1520173102Srwatsonstatic void 1521173095Srwatsonlomac_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1522173095Srwatson struct mbuf *m, struct label *mlabel) 1523173095Srwatson{ 1524173095Srwatson struct mac_lomac *dest; 1525173095Srwatson 1526173095Srwatson dest = SLOT(mlabel); 1527173095Srwatson 1528173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1529173095Srwatson} 1530173095Srwatson 1531173095Srwatsonstatic void 1532173095Srwatsonlomac_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1533173095Srwatson struct mbuf *m, struct label *mlabel) 1534173095Srwatson{ 1535173095Srwatson struct mac_lomac *dest; 1536173095Srwatson 1537173095Srwatson dest = SLOT(mlabel); 1538173095Srwatson 1539173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1540173095Srwatson} 1541173095Srwatson 1542107273Srwatsonstatic int 1543172955Srwatsonlomac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1544168976Srwatson struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1545107273Srwatson{ 1546107273Srwatson 1547172955Srwatson if (!lomac_enabled) 1548107273Srwatson return (0); 1549107273Srwatson 1550107273Srwatson /* XXX: This will be implemented soon... */ 1551107273Srwatson 1552107273Srwatson return (0); 1553107273Srwatson} 1554107273Srwatson 1555107273Srwatsonstatic int 1556172955Srwatsonlomac_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1557168976Srwatson struct label *pplabel) 1558107273Srwatson{ 1559107273Srwatson struct mac_lomac *subj, *obj; 1560107273Srwatson 1561172955Srwatson if (!lomac_enabled) 1562107273Srwatson return (0); 1563107273Srwatson 1564122524Srwatson subj = SLOT(cred->cr_label); 1565168976Srwatson obj = SLOT(pplabel); 1566107273Srwatson 1567172955Srwatson if (!lomac_dominate_single(obj, subj)) 1568107273Srwatson return (maybe_demote(subj, obj, "reading", "pipe", NULL)); 1569107273Srwatson 1570107273Srwatson return (0); 1571107273Srwatson} 1572107273Srwatson 1573107273Srwatsonstatic int 1574172955Srwatsonlomac_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1575168976Srwatson struct label *pplabel, struct label *newlabel) 1576107273Srwatson{ 1577107273Srwatson struct mac_lomac *subj, *obj, *new; 1578107273Srwatson int error; 1579107273Srwatson 1580107273Srwatson new = SLOT(newlabel); 1581122524Srwatson subj = SLOT(cred->cr_label); 1582168976Srwatson obj = SLOT(pplabel); 1583107273Srwatson 1584107273Srwatson /* 1585172955Srwatson * If there is a LOMAC label update for a pipe, it must be a single 1586172955Srwatson * update. 1587107273Srwatson */ 1588107273Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1589107273Srwatson if (error) 1590107273Srwatson return (error); 1591107273Srwatson 1592107273Srwatson /* 1593107273Srwatson * To perform a relabel of a pipe (LOMAC label or not), LOMAC must 1594107273Srwatson * authorize the relabel. 1595107273Srwatson */ 1596172955Srwatson if (!lomac_single_in_range(obj, subj)) 1597107273Srwatson return (EPERM); 1598107273Srwatson 1599107273Srwatson /* 1600107273Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 1601107273Srwatson */ 1602107273Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1603107273Srwatson /* 1604107273Srwatson * To change the LOMAC label on a pipe, the new pipe label 1605107273Srwatson * must be in the subject range. 1606107273Srwatson */ 1607172955Srwatson if (!lomac_single_in_range(new, subj)) 1608107273Srwatson return (EPERM); 1609107273Srwatson 1610107273Srwatson /* 1611107273Srwatson * To change the LOMAC label on a pipe to be EQUAL, the 1612107273Srwatson * subject must have appropriate privilege. 1613107273Srwatson */ 1614172955Srwatson if (lomac_contains_equal(new)) { 1615172955Srwatson error = lomac_subject_privileged(subj); 1616107273Srwatson if (error) 1617107273Srwatson return (error); 1618107273Srwatson } 1619107273Srwatson } 1620107273Srwatson 1621107273Srwatson return (0); 1622107273Srwatson} 1623107273Srwatson 1624107273Srwatsonstatic int 1625172955Srwatsonlomac_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1626168976Srwatson struct label *pplabel) 1627107273Srwatson{ 1628107273Srwatson struct mac_lomac *subj, *obj; 1629107273Srwatson 1630172955Srwatson if (!lomac_enabled) 1631107273Srwatson return (0); 1632107273Srwatson 1633122524Srwatson subj = SLOT(cred->cr_label); 1634168976Srwatson obj = SLOT(pplabel); 1635107273Srwatson 1636172955Srwatson if (!lomac_subject_dominate(subj, obj)) 1637107273Srwatson return (EACCES); 1638107273Srwatson 1639107273Srwatson return (0); 1640107273Srwatson} 1641107273Srwatson 1642173138Srwatsonstatic void 1643173138Srwatsonlomac_pipe_create(struct ucred *cred, struct pipepair *pp, 1644173138Srwatson struct label *pplabel) 1645107273Srwatson{ 1646173138Srwatson struct mac_lomac *source, *dest; 1647107273Srwatson 1648173138Srwatson source = SLOT(cred->cr_label); 1649173138Srwatson dest = SLOT(pplabel); 1650107273Srwatson 1651173138Srwatson lomac_copy_single(source, dest); 1652107273Srwatson} 1653107273Srwatson 1654173138Srwatsonstatic void 1655173138Srwatsonlomac_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1656173138Srwatson struct label *pplabel, struct label *newlabel) 1657107273Srwatson{ 1658173138Srwatson struct mac_lomac *source, *dest; 1659107273Srwatson 1660173138Srwatson source = SLOT(newlabel); 1661173138Srwatson dest = SLOT(pplabel); 1662107273Srwatson 1663173138Srwatson try_relabel(source, dest); 1664107273Srwatson} 1665107273Srwatson 1666168951Srwatson/* 1667168951Srwatson * Some system privileges are allowed regardless of integrity grade; others 1668168951Srwatson * are allowed only when running with privilege with respect to the LOMAC 1669168951Srwatson * policy as they might otherwise allow bypassing of the integrity policy. 1670168951Srwatson */ 1671107273Srwatsonstatic int 1672172955Srwatsonlomac_priv_check(struct ucred *cred, int priv) 1673168951Srwatson{ 1674168951Srwatson struct mac_lomac *subj; 1675168951Srwatson int error; 1676168951Srwatson 1677172955Srwatson if (!lomac_enabled) 1678168951Srwatson return (0); 1679168951Srwatson 1680168951Srwatson /* 1681168951Srwatson * Exempt only specific privileges from the LOMAC integrity policy. 1682168951Srwatson */ 1683168951Srwatson switch (priv) { 1684168951Srwatson case PRIV_KTRACE: 1685168951Srwatson case PRIV_MSGBUF: 1686168951Srwatson 1687168951Srwatson /* 1688168951Srwatson * Allow processes to manipulate basic process audit properties, and 1689168951Srwatson * to submit audit records. 1690168951Srwatson */ 1691168951Srwatson case PRIV_AUDIT_GETAUDIT: 1692168951Srwatson case PRIV_AUDIT_SETAUDIT: 1693168951Srwatson case PRIV_AUDIT_SUBMIT: 1694168951Srwatson 1695168951Srwatson /* 1696168951Srwatson * Allow processes to manipulate their regular UNIX credentials. 1697168951Srwatson */ 1698168951Srwatson case PRIV_CRED_SETUID: 1699168951Srwatson case PRIV_CRED_SETEUID: 1700168951Srwatson case PRIV_CRED_SETGID: 1701168951Srwatson case PRIV_CRED_SETEGID: 1702168951Srwatson case PRIV_CRED_SETGROUPS: 1703168951Srwatson case PRIV_CRED_SETREUID: 1704168951Srwatson case PRIV_CRED_SETREGID: 1705168951Srwatson case PRIV_CRED_SETRESUID: 1706168951Srwatson case PRIV_CRED_SETRESGID: 1707168951Srwatson 1708168951Srwatson /* 1709168951Srwatson * Allow processes to perform system monitoring. 1710168951Srwatson */ 1711168951Srwatson case PRIV_SEEOTHERGIDS: 1712168951Srwatson case PRIV_SEEOTHERUIDS: 1713168951Srwatson break; 1714168951Srwatson 1715168951Srwatson /* 1716168951Srwatson * Allow access to general process debugging facilities. We 1717168951Srwatson * separately control debugging based on MAC label. 1718168951Srwatson */ 1719168951Srwatson case PRIV_DEBUG_DIFFCRED: 1720168951Srwatson case PRIV_DEBUG_SUGID: 1721168951Srwatson case PRIV_DEBUG_UNPRIV: 1722168951Srwatson 1723168951Srwatson /* 1724168951Srwatson * Allow manipulating jails. 1725168951Srwatson */ 1726168951Srwatson case PRIV_JAIL_ATTACH: 1727168951Srwatson 1728168951Srwatson /* 1729168951Srwatson * Allow privilege with respect to the Partition policy, but not the 1730168951Srwatson * Privs policy. 1731168951Srwatson */ 1732168951Srwatson case PRIV_MAC_PARTITION: 1733168951Srwatson 1734168951Srwatson /* 1735168951Srwatson * Allow privilege with respect to process resource limits and login 1736168951Srwatson * context. 1737168951Srwatson */ 1738168951Srwatson case PRIV_PROC_LIMIT: 1739168951Srwatson case PRIV_PROC_SETLOGIN: 1740168951Srwatson case PRIV_PROC_SETRLIMIT: 1741168951Srwatson 1742168951Srwatson /* 1743168951Srwatson * Allow System V and POSIX IPC privileges. 1744168951Srwatson */ 1745168951Srwatson case PRIV_IPC_READ: 1746168951Srwatson case PRIV_IPC_WRITE: 1747168951Srwatson case PRIV_IPC_ADMIN: 1748168951Srwatson case PRIV_IPC_MSGSIZE: 1749168951Srwatson case PRIV_MQ_ADMIN: 1750168951Srwatson 1751168951Srwatson /* 1752168951Srwatson * Allow certain scheduler manipulations -- possibly this should be 1753168951Srwatson * controlled by more fine-grained policy, as potentially low 1754168951Srwatson * integrity processes can deny CPU to higher integrity ones. 1755168951Srwatson */ 1756168951Srwatson case PRIV_SCHED_DIFFCRED: 1757168951Srwatson case PRIV_SCHED_SETPRIORITY: 1758168951Srwatson case PRIV_SCHED_RTPRIO: 1759168951Srwatson case PRIV_SCHED_SETPOLICY: 1760168951Srwatson case PRIV_SCHED_SET: 1761168951Srwatson case PRIV_SCHED_SETPARAM: 1762168951Srwatson 1763168951Srwatson /* 1764168951Srwatson * More IPC privileges. 1765168951Srwatson */ 1766168951Srwatson case PRIV_SEM_WRITE: 1767168951Srwatson 1768168951Srwatson /* 1769168951Srwatson * Allow signaling privileges subject to integrity policy. 1770168951Srwatson */ 1771168951Srwatson case PRIV_SIGNAL_DIFFCRED: 1772168951Srwatson case PRIV_SIGNAL_SUGID: 1773168951Srwatson 1774168951Srwatson /* 1775168951Srwatson * Allow access to only limited sysctls from lower integrity levels; 1776168951Srwatson * piggy-back on the Jail definition. 1777168951Srwatson */ 1778168951Srwatson case PRIV_SYSCTL_WRITEJAIL: 1779168951Srwatson 1780168951Srwatson /* 1781168951Srwatson * Allow TTY-based privileges, subject to general device access using 1782168951Srwatson * labels on TTY device nodes, but not console privilege. 1783168951Srwatson */ 1784168951Srwatson case PRIV_TTY_DRAINWAIT: 1785168951Srwatson case PRIV_TTY_DTRWAIT: 1786168951Srwatson case PRIV_TTY_EXCLUSIVE: 1787168951Srwatson case PRIV_TTY_STI: 1788168951Srwatson case PRIV_TTY_SETA: 1789168951Srwatson 1790168951Srwatson /* 1791168951Srwatson * Grant most VFS privileges, as almost all are in practice bounded 1792168951Srwatson * by more specific checks using labels. 1793168951Srwatson */ 1794168951Srwatson case PRIV_VFS_READ: 1795168951Srwatson case PRIV_VFS_WRITE: 1796168951Srwatson case PRIV_VFS_ADMIN: 1797168951Srwatson case PRIV_VFS_EXEC: 1798168951Srwatson case PRIV_VFS_LOOKUP: 1799168951Srwatson case PRIV_VFS_CHFLAGS_DEV: 1800168951Srwatson case PRIV_VFS_CHOWN: 1801168951Srwatson case PRIV_VFS_CHROOT: 1802168951Srwatson case PRIV_VFS_RETAINSUGID: 1803168951Srwatson case PRIV_VFS_EXCEEDQUOTA: 1804168951Srwatson case PRIV_VFS_FCHROOT: 1805168951Srwatson case PRIV_VFS_FHOPEN: 1806168951Srwatson case PRIV_VFS_FHSTATFS: 1807168951Srwatson case PRIV_VFS_GENERATION: 1808168951Srwatson case PRIV_VFS_GETFH: 1809168951Srwatson case PRIV_VFS_GETQUOTA: 1810168951Srwatson case PRIV_VFS_LINK: 1811168951Srwatson case PRIV_VFS_MOUNT: 1812168951Srwatson case PRIV_VFS_MOUNT_OWNER: 1813168951Srwatson case PRIV_VFS_MOUNT_PERM: 1814168951Srwatson case PRIV_VFS_MOUNT_SUIDDIR: 1815168951Srwatson case PRIV_VFS_MOUNT_NONUSER: 1816168951Srwatson case PRIV_VFS_SETGID: 1817168951Srwatson case PRIV_VFS_STICKYFILE: 1818168951Srwatson case PRIV_VFS_SYSFLAGS: 1819168951Srwatson case PRIV_VFS_UNMOUNT: 1820168951Srwatson 1821168951Srwatson /* 1822168951Srwatson * Allow VM privileges; it would be nice if these were subject to 1823168951Srwatson * resource limits. 1824168951Srwatson */ 1825168951Srwatson case PRIV_VM_MADV_PROTECT: 1826168951Srwatson case PRIV_VM_MLOCK: 1827168951Srwatson case PRIV_VM_MUNLOCK: 1828194766Skib case PRIV_VM_SWAP_NOQUOTA: 1829194766Skib case PRIV_VM_SWAP_NORLIMIT: 1830168951Srwatson 1831168951Srwatson /* 1832168951Srwatson * Allow some but not all network privileges. In general, dont allow 1833168951Srwatson * reconfiguring the network stack, just normal use. 1834168951Srwatson */ 1835168951Srwatson case PRIV_NETATALK_RESERVEDPORT: 1836168951Srwatson case PRIV_NETINET_RESERVEDPORT: 1837168951Srwatson case PRIV_NETINET_RAW: 1838168951Srwatson case PRIV_NETINET_REUSEPORT: 1839168951Srwatson case PRIV_NETIPX_RESERVEDPORT: 1840168951Srwatson case PRIV_NETIPX_RAW: 1841168951Srwatson break; 1842168951Srwatson 1843168951Srwatson /* 1844168951Srwatson * All remaining system privileges are allow only if the process 1845168951Srwatson * holds privilege with respect to the LOMAC policy. 1846168951Srwatson */ 1847168951Srwatson default: 1848168951Srwatson subj = SLOT(cred->cr_label); 1849172955Srwatson error = lomac_subject_privileged(subj); 1850168951Srwatson if (error) 1851168951Srwatson return (error); 1852168951Srwatson } 1853168951Srwatson return (0); 1854168951Srwatson} 1855168951Srwatson 1856173138Srwatsonstatic int 1857173138Srwatsonlomac_proc_check_debug(struct ucred *cred, struct proc *p) 1858173138Srwatson{ 1859173138Srwatson struct mac_lomac *subj, *obj; 1860168951Srwatson 1861173138Srwatson if (!lomac_enabled) 1862173138Srwatson return (0); 1863173138Srwatson 1864173138Srwatson subj = SLOT(cred->cr_label); 1865173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1866173138Srwatson 1867173138Srwatson /* XXX: range checks */ 1868173138Srwatson if (!lomac_dominate_single(obj, subj)) 1869173138Srwatson return (ESRCH); 1870173138Srwatson if (!lomac_subject_dominate(subj, obj)) 1871173138Srwatson return (EACCES); 1872173138Srwatson 1873173138Srwatson return (0); 1874173138Srwatson} 1875173138Srwatson 1876168951Srwatsonstatic int 1877173138Srwatsonlomac_proc_check_sched(struct ucred *cred, struct proc *p) 1878173138Srwatson{ 1879173138Srwatson struct mac_lomac *subj, *obj; 1880173138Srwatson 1881173138Srwatson if (!lomac_enabled) 1882173138Srwatson return (0); 1883173138Srwatson 1884173138Srwatson subj = SLOT(cred->cr_label); 1885173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1886173138Srwatson 1887173138Srwatson /* XXX: range checks */ 1888173138Srwatson if (!lomac_dominate_single(obj, subj)) 1889173138Srwatson return (ESRCH); 1890173138Srwatson if (!lomac_subject_dominate(subj, obj)) 1891173138Srwatson return (EACCES); 1892173138Srwatson 1893173138Srwatson return (0); 1894173138Srwatson} 1895173138Srwatson 1896173138Srwatsonstatic int 1897173138Srwatsonlomac_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1898173138Srwatson{ 1899173138Srwatson struct mac_lomac *subj, *obj; 1900173138Srwatson 1901173138Srwatson if (!lomac_enabled) 1902173138Srwatson return (0); 1903173138Srwatson 1904173138Srwatson subj = SLOT(cred->cr_label); 1905173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1906173138Srwatson 1907173138Srwatson /* XXX: range checks */ 1908173138Srwatson if (!lomac_dominate_single(obj, subj)) 1909173138Srwatson return (ESRCH); 1910173138Srwatson if (!lomac_subject_dominate(subj, obj)) 1911173138Srwatson return (EACCES); 1912173138Srwatson 1913173138Srwatson return (0); 1914173138Srwatson} 1915173138Srwatson 1916173138Srwatsonstatic void 1917173138Srwatsonlomac_proc_destroy_label(struct label *label) 1918173138Srwatson{ 1919173138Srwatson 1920173138Srwatson mtx_destroy(&PSLOT(label)->mtx); 1921184205Sdes free(PSLOT(label), M_LOMAC); 1922173138Srwatson PSLOT_SET(label, NULL); 1923173138Srwatson} 1924173138Srwatson 1925173138Srwatsonstatic void 1926173138Srwatsonlomac_proc_init_label(struct label *label) 1927173138Srwatson{ 1928173138Srwatson 1929173138Srwatson PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_LOMAC, 1930173138Srwatson M_ZERO | M_WAITOK)); 1931173138Srwatson mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF); 1932173138Srwatson} 1933173138Srwatson 1934173138Srwatsonstatic int 1935173138Srwatsonlomac_socket_check_deliver(struct socket *so, struct label *solabel, 1936173138Srwatson struct mbuf *m, struct label *mlabel) 1937173138Srwatson{ 1938173138Srwatson struct mac_lomac *p, *s; 1939193391Srwatson int error; 1940173138Srwatson 1941173138Srwatson if (!lomac_enabled) 1942173138Srwatson return (0); 1943173138Srwatson 1944173138Srwatson p = SLOT(mlabel); 1945173138Srwatson s = SLOT(solabel); 1946173138Srwatson 1947193391Srwatson SOCK_LOCK(so); 1948193391Srwatson error = lomac_equal_single(p, s) ? 0 : EACCES; 1949193391Srwatson SOCK_UNLOCK(so); 1950193391Srwatson return (error); 1951173138Srwatson} 1952173138Srwatson 1953173138Srwatsonstatic int 1954173138Srwatsonlomac_socket_check_relabel(struct ucred *cred, struct socket *so, 1955173138Srwatson struct label *solabel, struct label *newlabel) 1956173138Srwatson{ 1957173138Srwatson struct mac_lomac *subj, *obj, *new; 1958173138Srwatson int error; 1959173138Srwatson 1960193391Srwatson SOCK_LOCK_ASSERT(so); 1961193391Srwatson 1962173138Srwatson new = SLOT(newlabel); 1963173138Srwatson subj = SLOT(cred->cr_label); 1964173138Srwatson obj = SLOT(solabel); 1965173138Srwatson 1966173138Srwatson /* 1967173138Srwatson * If there is a LOMAC label update for the socket, it may be an 1968173138Srwatson * update of single. 1969173138Srwatson */ 1970173138Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1971173138Srwatson if (error) 1972173138Srwatson return (error); 1973173138Srwatson 1974173138Srwatson /* 1975173138Srwatson * To relabel a socket, the old socket single must be in the subject 1976173138Srwatson * range. 1977173138Srwatson */ 1978173138Srwatson if (!lomac_single_in_range(obj, subj)) 1979173138Srwatson return (EPERM); 1980173138Srwatson 1981173138Srwatson /* 1982173138Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 1983173138Srwatson */ 1984173138Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1985173138Srwatson /* 1986173138Srwatson * To relabel a socket, the new socket single must be in the 1987173138Srwatson * subject range. 1988173138Srwatson */ 1989173138Srwatson if (!lomac_single_in_range(new, subj)) 1990173138Srwatson return (EPERM); 1991173138Srwatson 1992173138Srwatson /* 1993173138Srwatson * To change the LOMAC label on the socket to contain EQUAL, 1994173138Srwatson * the subject must have appropriate privilege. 1995173138Srwatson */ 1996173138Srwatson if (lomac_contains_equal(new)) { 1997173138Srwatson error = lomac_subject_privileged(subj); 1998173138Srwatson if (error) 1999173138Srwatson return (error); 2000173138Srwatson } 2001173138Srwatson } 2002173138Srwatson 2003173138Srwatson return (0); 2004173138Srwatson} 2005173138Srwatson 2006173138Srwatsonstatic int 2007173138Srwatsonlomac_socket_check_visible(struct ucred *cred, struct socket *so, 2008173138Srwatson struct label *solabel) 2009173138Srwatson{ 2010173138Srwatson struct mac_lomac *subj, *obj; 2011173138Srwatson 2012173138Srwatson if (!lomac_enabled) 2013173138Srwatson return (0); 2014173138Srwatson 2015173138Srwatson subj = SLOT(cred->cr_label); 2016173138Srwatson obj = SLOT(solabel); 2017173138Srwatson 2018193391Srwatson SOCK_LOCK(so); 2019193391Srwatson if (!lomac_dominate_single(obj, subj)) { 2020193391Srwatson SOCK_UNLOCK(so); 2021173138Srwatson return (ENOENT); 2022193391Srwatson } 2023193391Srwatson SOCK_UNLOCK(so); 2024173138Srwatson 2025173138Srwatson return (0); 2026173138Srwatson} 2027173138Srwatson 2028173138Srwatsonstatic void 2029173138Srwatsonlomac_socket_create(struct ucred *cred, struct socket *so, 2030173138Srwatson struct label *solabel) 2031173138Srwatson{ 2032173138Srwatson struct mac_lomac *source, *dest; 2033173138Srwatson 2034173138Srwatson source = SLOT(cred->cr_label); 2035173138Srwatson dest = SLOT(solabel); 2036173138Srwatson 2037173138Srwatson lomac_copy_single(source, dest); 2038173138Srwatson} 2039173138Srwatson 2040173138Srwatsonstatic void 2041173138Srwatsonlomac_socket_create_mbuf(struct socket *so, struct label *solabel, 2042173138Srwatson struct mbuf *m, struct label *mlabel) 2043173138Srwatson{ 2044173138Srwatson struct mac_lomac *source, *dest; 2045173138Srwatson 2046173138Srwatson source = SLOT(solabel); 2047173138Srwatson dest = SLOT(mlabel); 2048173138Srwatson 2049193391Srwatson SOCK_LOCK(so); 2050173138Srwatson lomac_copy_single(source, dest); 2051193391Srwatson SOCK_UNLOCK(so); 2052173138Srwatson} 2053173138Srwatson 2054173138Srwatsonstatic void 2055173138Srwatsonlomac_socket_newconn(struct socket *oldso, struct label *oldsolabel, 2056173138Srwatson struct socket *newso, struct label *newsolabel) 2057173138Srwatson{ 2058193391Srwatson struct mac_lomac source, *dest; 2059173138Srwatson 2060193391Srwatson SOCK_LOCK(oldso); 2061193391Srwatson source = *SLOT(oldsolabel); 2062193391Srwatson SOCK_UNLOCK(oldso); 2063193391Srwatson 2064173138Srwatson dest = SLOT(newsolabel); 2065173138Srwatson 2066193391Srwatson SOCK_LOCK(newso); 2067193391Srwatson lomac_copy_single(&source, dest); 2068193391Srwatson SOCK_UNLOCK(newso); 2069173138Srwatson} 2070173138Srwatson 2071173138Srwatsonstatic void 2072173138Srwatsonlomac_socket_relabel(struct ucred *cred, struct socket *so, 2073173138Srwatson struct label *solabel, struct label *newlabel) 2074173138Srwatson{ 2075173138Srwatson struct mac_lomac *source, *dest; 2076173138Srwatson 2077193391Srwatson SOCK_LOCK_ASSERT(so); 2078193391Srwatson 2079173138Srwatson source = SLOT(newlabel); 2080173138Srwatson dest = SLOT(solabel); 2081173138Srwatson 2082173138Srwatson try_relabel(source, dest); 2083173138Srwatson} 2084173138Srwatson 2085173138Srwatsonstatic void 2086173138Srwatsonlomac_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 2087173138Srwatson struct socket *so, struct label *sopeerlabel) 2088173138Srwatson{ 2089173138Srwatson struct mac_lomac *source, *dest; 2090173138Srwatson 2091173138Srwatson source = SLOT(mlabel); 2092173138Srwatson dest = SLOT(sopeerlabel); 2093173138Srwatson 2094193391Srwatson SOCK_LOCK(so); 2095173138Srwatson lomac_copy_single(source, dest); 2096193391Srwatson SOCK_UNLOCK(so); 2097173138Srwatson} 2098173138Srwatson 2099173138Srwatsonstatic void 2100173138Srwatsonlomac_socketpeer_set_from_socket(struct socket *oldso, 2101173138Srwatson struct label *oldsolabel, struct socket *newso, 2102173138Srwatson struct label *newsopeerlabel) 2103173138Srwatson{ 2104193391Srwatson struct mac_lomac source, *dest; 2105173138Srwatson 2106193391Srwatson SOCK_LOCK(oldso); 2107193391Srwatson source = *SLOT(oldsolabel); 2108193391Srwatson SOCK_UNLOCK(oldso); 2109193391Srwatson 2110173138Srwatson dest = SLOT(newsopeerlabel); 2111173138Srwatson 2112193391Srwatson SOCK_LOCK(newso); 2113193391Srwatson lomac_copy_single(&source, dest); 2114193391Srwatson SOCK_UNLOCK(newso); 2115173138Srwatson} 2116173138Srwatson 2117173138Srwatsonstatic void 2118173138Srwatsonlomac_syncache_create(struct label *label, struct inpcb *inp) 2119173138Srwatson{ 2120173138Srwatson struct mac_lomac *source, *dest; 2121173138Srwatson 2122173138Srwatson source = SLOT(inp->inp_label); 2123173138Srwatson dest = SLOT(label); 2124173138Srwatson lomac_copy(source, dest); 2125173138Srwatson} 2126173138Srwatson 2127173138Srwatsonstatic void 2128173138Srwatsonlomac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2129173138Srwatson struct label *mlabel) 2130173138Srwatson{ 2131173138Srwatson struct mac_lomac *source, *dest; 2132173138Srwatson 2133173138Srwatson source = SLOT(sc_label); 2134173138Srwatson dest = SLOT(mlabel); 2135173138Srwatson lomac_copy(source, dest); 2136173138Srwatson} 2137173138Srwatson 2138173138Srwatsonstatic int 2139172955Srwatsonlomac_system_check_acct(struct ucred *cred, struct vnode *vp, 2140168976Srwatson struct label *vplabel) 2141168933Srwatson{ 2142168933Srwatson struct mac_lomac *subj, *obj; 2143168933Srwatson 2144172955Srwatson if (!lomac_enabled) 2145168933Srwatson return (0); 2146168933Srwatson 2147168933Srwatson subj = SLOT(cred->cr_label); 2148168976Srwatson obj = SLOT(vplabel); 2149168933Srwatson 2150172955Srwatson if (lomac_subject_privileged(subj)) 2151168933Srwatson return (EPERM); 2152168933Srwatson 2153172955Srwatson if (!lomac_high_single(obj)) 2154168933Srwatson return (EACCES); 2155168933Srwatson 2156168933Srwatson return (0); 2157168933Srwatson} 2158168933Srwatson 2159168933Srwatsonstatic int 2160172955Srwatsonlomac_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2161168976Srwatson struct label *vplabel) 2162168933Srwatson{ 2163168933Srwatson struct mac_lomac *subj, *obj; 2164168933Srwatson 2165172955Srwatson if (!lomac_enabled) 2166168933Srwatson return (0); 2167168933Srwatson 2168168933Srwatson subj = SLOT(cred->cr_label); 2169168976Srwatson obj = SLOT(vplabel); 2170168933Srwatson 2171172955Srwatson if (lomac_subject_privileged(subj)) 2172168933Srwatson return (EPERM); 2173168933Srwatson 2174172955Srwatson if (!lomac_high_single(obj)) 2175168933Srwatson return (EACCES); 2176168933Srwatson 2177168933Srwatson return (0); 2178168933Srwatson} 2179168933Srwatson 2180168933Srwatsonstatic int 2181172955Srwatsonlomac_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2182168976Srwatson struct label *vplabel) 2183168933Srwatson{ 2184168933Srwatson struct mac_lomac *subj; 2185168933Srwatson 2186172955Srwatson if (!lomac_enabled) 2187168933Srwatson return (0); 2188168933Srwatson 2189168933Srwatson subj = SLOT(cred->cr_label); 2190168933Srwatson 2191172955Srwatson if (lomac_subject_privileged(subj)) 2192168933Srwatson return (EPERM); 2193168933Srwatson 2194168933Srwatson return (0); 2195168933Srwatson} 2196168933Srwatson 2197168933Srwatsonstatic int 2198172955Srwatsonlomac_system_check_swapon(struct ucred *cred, struct vnode *vp, 2199168976Srwatson struct label *vplabel) 2200107273Srwatson{ 2201107273Srwatson struct mac_lomac *subj, *obj; 2202107273Srwatson 2203172955Srwatson if (!lomac_enabled) 2204107273Srwatson return (0); 2205107273Srwatson 2206122524Srwatson subj = SLOT(cred->cr_label); 2207168976Srwatson obj = SLOT(vplabel); 2208107273Srwatson 2209172955Srwatson if (lomac_subject_privileged(subj)) 2210107273Srwatson return (EPERM); 2211107273Srwatson 2212172955Srwatson if (!lomac_high_single(obj)) 2213107273Srwatson return (EACCES); 2214107273Srwatson 2215107273Srwatson return (0); 2216107273Srwatson} 2217107273Srwatson 2218107273Srwatsonstatic int 2219172955Srwatsonlomac_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2220126121Spjd void *arg1, int arg2, struct sysctl_req *req) 2221107273Srwatson{ 2222107273Srwatson struct mac_lomac *subj; 2223107273Srwatson 2224172955Srwatson if (!lomac_enabled) 2225107273Srwatson return (0); 2226107273Srwatson 2227122524Srwatson subj = SLOT(cred->cr_label); 2228107273Srwatson 2229107273Srwatson /* 2230172955Srwatson * Treat sysctl variables without CTLFLAG_ANYBODY flag as lomac/high, 2231172955Srwatson * but also require privilege to change them. 2232107273Srwatson */ 2233126121Spjd if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2234107273Srwatson#ifdef notdef 2235172955Srwatson if (!lomac_subject_dominate_high(subj)) 2236107273Srwatson return (EACCES); 2237107273Srwatson#endif 2238107273Srwatson 2239172955Srwatson if (lomac_subject_privileged(subj)) 2240107273Srwatson return (EPERM); 2241107273Srwatson } 2242107273Srwatson 2243107273Srwatson return (0); 2244107273Srwatson} 2245107273Srwatson 2246173138Srwatsonstatic void 2247173138Srwatsonlomac_thread_userret(struct thread *td) 2248173138Srwatson{ 2249173138Srwatson struct proc *p = td->td_proc; 2250173138Srwatson struct mac_lomac_proc *subj = PSLOT(p->p_label); 2251173138Srwatson struct ucred *newcred, *oldcred; 2252173138Srwatson int dodrop; 2253173138Srwatson 2254173138Srwatson mtx_lock(&subj->mtx); 2255173138Srwatson if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 2256173138Srwatson dodrop = 0; 2257173138Srwatson mtx_unlock(&subj->mtx); 2258173138Srwatson newcred = crget(); 2259173138Srwatson /* 2260184412Srwatson * Prevent a lock order reversal in mac_proc_vm_revoke; 2261184412Srwatson * ideally, the other user of subj->mtx wouldn't be holding 2262184412Srwatson * Giant. 2263173138Srwatson */ 2264173138Srwatson mtx_lock(&Giant); 2265173138Srwatson PROC_LOCK(p); 2266173138Srwatson mtx_lock(&subj->mtx); 2267173138Srwatson /* 2268173138Srwatson * Check if we lost the race while allocating the cred. 2269173138Srwatson */ 2270173138Srwatson if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2271173138Srwatson crfree(newcred); 2272173138Srwatson goto out; 2273173138Srwatson } 2274173138Srwatson oldcred = p->p_ucred; 2275173138Srwatson crcopy(newcred, oldcred); 2276173138Srwatson crhold(newcred); 2277173138Srwatson lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2278173138Srwatson p->p_ucred = newcred; 2279173138Srwatson crfree(oldcred); 2280173138Srwatson dodrop = 1; 2281173138Srwatson out: 2282173138Srwatson mtx_unlock(&subj->mtx); 2283173138Srwatson PROC_UNLOCK(p); 2284173138Srwatson if (dodrop) 2285184412Srwatson mac_proc_vm_revoke(curthread); 2286173138Srwatson mtx_unlock(&Giant); 2287173138Srwatson } else { 2288173138Srwatson mtx_unlock(&subj->mtx); 2289173138Srwatson } 2290173138Srwatson} 2291173138Srwatson 2292107273Srwatsonstatic int 2293173138Srwatsonlomac_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2294173138Srwatson struct vnode *vp, struct label *vplabel) 2295173138Srwatson{ 2296173138Srwatson struct mac_lomac ml_temp, *source, *dest; 2297173138Srwatson int buflen, error; 2298173138Srwatson 2299173138Srwatson source = SLOT(mplabel); 2300173138Srwatson dest = SLOT(vplabel); 2301173138Srwatson 2302173138Srwatson buflen = sizeof(ml_temp); 2303173138Srwatson bzero(&ml_temp, buflen); 2304173138Srwatson 2305173138Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2306173138Srwatson MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&ml_temp, curthread); 2307173138Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 2308173138Srwatson /* Fall back to the mntlabel. */ 2309173138Srwatson lomac_copy_single(source, dest); 2310173138Srwatson return (0); 2311173138Srwatson } else if (error) 2312173138Srwatson return (error); 2313173138Srwatson 2314173138Srwatson if (buflen != sizeof(ml_temp)) { 2315173138Srwatson if (buflen != sizeof(ml_temp) - sizeof(ml_temp.ml_auxsingle)) { 2316173138Srwatson printf("lomac_vnode_associate_extattr: bad size %d\n", 2317173138Srwatson buflen); 2318173138Srwatson return (EPERM); 2319173138Srwatson } 2320173138Srwatson bzero(&ml_temp.ml_auxsingle, sizeof(ml_temp.ml_auxsingle)); 2321173138Srwatson buflen = sizeof(ml_temp); 2322173138Srwatson (void)vn_extattr_set(vp, IO_NODELOCKED, 2323173138Srwatson MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 2324173138Srwatson buflen, (char *)&ml_temp, curthread); 2325173138Srwatson } 2326173138Srwatson if (lomac_valid(&ml_temp) != 0) { 2327173138Srwatson printf("lomac_vnode_associate_extattr: invalid\n"); 2328173138Srwatson return (EPERM); 2329173138Srwatson } 2330173138Srwatson if ((ml_temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != 2331173138Srwatson MAC_LOMAC_FLAG_SINGLE) { 2332173138Srwatson printf("lomac_vnode_associate_extattr: not single\n"); 2333173138Srwatson return (EPERM); 2334173138Srwatson } 2335173138Srwatson 2336173138Srwatson lomac_copy_single(&ml_temp, dest); 2337173138Srwatson return (0); 2338173138Srwatson} 2339173138Srwatson 2340173138Srwatsonstatic void 2341173138Srwatsonlomac_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2342173138Srwatson struct vnode *vp, struct label *vplabel) 2343173138Srwatson{ 2344173138Srwatson struct mac_lomac *source, *dest; 2345173138Srwatson 2346173138Srwatson source = SLOT(mplabel); 2347173138Srwatson dest = SLOT(vplabel); 2348173138Srwatson 2349173138Srwatson lomac_copy_single(source, dest); 2350173138Srwatson} 2351173138Srwatson 2352173138Srwatsonstatic int 2353172955Srwatsonlomac_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2354168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2355107273Srwatson{ 2356107273Srwatson struct mac_lomac *subj, *obj; 2357107273Srwatson 2358172955Srwatson if (!lomac_enabled) 2359107273Srwatson return (0); 2360107273Srwatson 2361122524Srwatson subj = SLOT(cred->cr_label); 2362168976Srwatson obj = SLOT(dvplabel); 2363107273Srwatson 2364172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2365107273Srwatson return (EACCES); 2366107273Srwatson if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2367172955Srwatson !lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2368107273Srwatson return (EACCES); 2369107273Srwatson 2370107273Srwatson return (0); 2371107273Srwatson} 2372107273Srwatson 2373107273Srwatsonstatic int 2374172955Srwatsonlomac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2375168976Srwatson struct label *vplabel, acl_type_t type) 2376107273Srwatson{ 2377107273Srwatson struct mac_lomac *subj, *obj; 2378107273Srwatson 2379172955Srwatson if (!lomac_enabled) 2380107273Srwatson return (0); 2381107273Srwatson 2382122524Srwatson subj = SLOT(cred->cr_label); 2383168976Srwatson obj = SLOT(vplabel); 2384107273Srwatson 2385172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2386107273Srwatson return (EACCES); 2387107273Srwatson 2388107273Srwatson return (0); 2389107273Srwatson} 2390107273Srwatson 2391107273Srwatsonstatic int 2392172955Srwatsonlomac_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2393168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2394107273Srwatson struct componentname *cnp) 2395107273Srwatson{ 2396107273Srwatson struct mac_lomac *subj, *obj; 2397107273Srwatson 2398172955Srwatson if (!lomac_enabled) 2399107273Srwatson return (0); 2400107273Srwatson 2401122524Srwatson subj = SLOT(cred->cr_label); 2402168976Srwatson obj = SLOT(dvplabel); 2403107273Srwatson 2404172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2405107273Srwatson return (EACCES); 2406107273Srwatson 2407168976Srwatson obj = SLOT(vplabel); 2408107273Srwatson 2409172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2410107273Srwatson return (EACCES); 2411107273Srwatson 2412107273Srwatson return (0); 2413107273Srwatson} 2414107273Srwatson 2415107273Srwatsonstatic int 2416172955Srwatsonlomac_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2417168976Srwatson struct label *vplabel, int prot, int flags) 2418107273Srwatson{ 2419107273Srwatson struct mac_lomac *subj, *obj; 2420107273Srwatson 2421107273Srwatson /* 2422107273Srwatson * Rely on the use of open()-time protections to handle 2423107273Srwatson * non-revocation cases. 2424107273Srwatson */ 2425172955Srwatson if (!lomac_enabled) 2426107273Srwatson return (0); 2427107273Srwatson 2428122524Srwatson subj = SLOT(cred->cr_label); 2429168976Srwatson obj = SLOT(vplabel); 2430107273Srwatson 2431145076Scsjp if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2432172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2433107273Srwatson return (EACCES); 2434107273Srwatson } 2435107273Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2436172955Srwatson if (!lomac_dominate_single(obj, subj)) 2437107273Srwatson return (maybe_demote(subj, obj, "mapping", "file", vp)); 2438107273Srwatson } 2439107273Srwatson 2440107273Srwatson return (0); 2441107273Srwatson} 2442107273Srwatson 2443107273Srwatsonstatic void 2444172955Srwatsonlomac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp, 2445168976Srwatson struct label *vplabel, /* XXX vm_prot_t */ int *prot) 2446107273Srwatson{ 2447107273Srwatson struct mac_lomac *subj, *obj; 2448107273Srwatson 2449107273Srwatson /* 2450107273Srwatson * Rely on the use of open()-time protections to handle 2451107273Srwatson * non-revocation cases. 2452107273Srwatson */ 2453172955Srwatson if (!lomac_enabled || !revocation_enabled) 2454107273Srwatson return; 2455107273Srwatson 2456122524Srwatson subj = SLOT(cred->cr_label); 2457168976Srwatson obj = SLOT(vplabel); 2458107273Srwatson 2459172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2460107273Srwatson *prot &= ~VM_PROT_WRITE; 2461107273Srwatson} 2462107273Srwatson 2463107273Srwatsonstatic int 2464172955Srwatsonlomac_vnode_check_open(struct ucred *cred, struct vnode *vp, 2465184413Strasz struct label *vplabel, accmode_t accmode) 2466107273Srwatson{ 2467107273Srwatson struct mac_lomac *subj, *obj; 2468107273Srwatson 2469172955Srwatson if (!lomac_enabled) 2470107273Srwatson return (0); 2471107273Srwatson 2472122524Srwatson subj = SLOT(cred->cr_label); 2473168976Srwatson obj = SLOT(vplabel); 2474107273Srwatson 2475107273Srwatson /* XXX privilege override for admin? */ 2476201438Strasz if (accmode & VMODIFY_PERMS) { 2477172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2478107273Srwatson return (EACCES); 2479107273Srwatson } 2480107273Srwatson 2481107273Srwatson return (0); 2482107273Srwatson} 2483107273Srwatson 2484107273Srwatsonstatic int 2485172955Srwatsonlomac_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2486168976Srwatson struct vnode *vp, struct label *vplabel) 2487107273Srwatson{ 2488107273Srwatson struct mac_lomac *subj, *obj; 2489107273Srwatson 2490172955Srwatson if (!lomac_enabled || !revocation_enabled) 2491107273Srwatson return (0); 2492107273Srwatson 2493122524Srwatson subj = SLOT(active_cred->cr_label); 2494168976Srwatson obj = SLOT(vplabel); 2495107273Srwatson 2496172955Srwatson if (!lomac_dominate_single(obj, subj)) 2497107273Srwatson return (maybe_demote(subj, obj, "reading", "file", vp)); 2498107273Srwatson 2499107273Srwatson return (0); 2500107273Srwatson} 2501107273Srwatson 2502107273Srwatsonstatic int 2503172955Srwatsonlomac_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2504168976Srwatson struct label *vplabel, struct label *newlabel) 2505107273Srwatson{ 2506107273Srwatson struct mac_lomac *old, *new, *subj; 2507107273Srwatson int error; 2508107273Srwatson 2509168976Srwatson old = SLOT(vplabel); 2510107273Srwatson new = SLOT(newlabel); 2511122524Srwatson subj = SLOT(cred->cr_label); 2512107273Srwatson 2513107273Srwatson /* 2514107273Srwatson * If there is a LOMAC label update for the vnode, it must be a 2515107273Srwatson * single label, with an optional explicit auxiliary single. 2516107273Srwatson */ 2517107273Srwatson error = lomac_atmostflags(new, 2518107273Srwatson MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2519107273Srwatson if (error) 2520107273Srwatson return (error); 2521107273Srwatson 2522107273Srwatson /* 2523107273Srwatson * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2524107273Srwatson * authorize the relabel. 2525107273Srwatson */ 2526172955Srwatson if (!lomac_single_in_range(old, subj)) 2527107273Srwatson return (EPERM); 2528107273Srwatson 2529107273Srwatson /* 2530107273Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 2531107273Srwatson */ 2532107273Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2533107273Srwatson /* 2534107273Srwatson * To change the LOMAC label on a vnode, the new vnode label 2535107273Srwatson * must be in the subject range. 2536107273Srwatson */ 2537172955Srwatson if (!lomac_single_in_range(new, subj)) 2538107273Srwatson return (EPERM); 2539107273Srwatson 2540107273Srwatson /* 2541172955Srwatson * To change the LOMAC label on the vnode to be EQUAL, the 2542172955Srwatson * subject must have appropriate privilege. 2543107273Srwatson */ 2544172955Srwatson if (lomac_contains_equal(new)) { 2545172955Srwatson error = lomac_subject_privileged(subj); 2546107273Srwatson if (error) 2547107273Srwatson return (error); 2548107273Srwatson } 2549107273Srwatson } 2550107273Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2551107273Srwatson /* 2552119242Srwatson * Fill in the missing parts from the previous label. 2553119242Srwatson */ 2554119242Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2555172955Srwatson lomac_copy_single(subj, new); 2556119242Srwatson 2557119242Srwatson /* 2558107273Srwatson * To change the auxiliary LOMAC label on a vnode, the new 2559107273Srwatson * vnode label must be in the subject range. 2560107273Srwatson */ 2561172955Srwatson if (!lomac_auxsingle_in_range(new, subj)) 2562107273Srwatson return (EPERM); 2563107273Srwatson 2564107273Srwatson /* 2565107273Srwatson * To change the auxiliary LOMAC label on the vnode to be 2566107273Srwatson * EQUAL, the subject must have appropriate privilege. 2567107273Srwatson */ 2568172955Srwatson if (lomac_contains_equal(new)) { 2569172955Srwatson error = lomac_subject_privileged(subj); 2570107273Srwatson if (error) 2571107273Srwatson return (error); 2572107273Srwatson } 2573107273Srwatson } 2574107273Srwatson 2575107273Srwatson return (0); 2576107273Srwatson} 2577107273Srwatson 2578107273Srwatsonstatic int 2579172955Srwatsonlomac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2580168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2581107273Srwatson struct componentname *cnp) 2582107273Srwatson{ 2583107273Srwatson struct mac_lomac *subj, *obj; 2584107273Srwatson 2585172955Srwatson if (!lomac_enabled) 2586107273Srwatson return (0); 2587107273Srwatson 2588122524Srwatson subj = SLOT(cred->cr_label); 2589168976Srwatson obj = SLOT(dvplabel); 2590107273Srwatson 2591172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2592107273Srwatson return (EACCES); 2593107273Srwatson 2594168976Srwatson obj = SLOT(vplabel); 2595107273Srwatson 2596172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2597107273Srwatson return (EACCES); 2598107273Srwatson 2599107273Srwatson return (0); 2600107273Srwatson} 2601107273Srwatson 2602107273Srwatsonstatic int 2603172955Srwatsonlomac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2604168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2605168976Srwatson int samedir, struct componentname *cnp) 2606107273Srwatson{ 2607107273Srwatson struct mac_lomac *subj, *obj; 2608107273Srwatson 2609172955Srwatson if (!lomac_enabled) 2610107273Srwatson return (0); 2611107273Srwatson 2612122524Srwatson subj = SLOT(cred->cr_label); 2613168976Srwatson obj = SLOT(dvplabel); 2614107273Srwatson 2615172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2616107273Srwatson return (EACCES); 2617107273Srwatson 2618107273Srwatson if (vp != NULL) { 2619168976Srwatson obj = SLOT(vplabel); 2620107273Srwatson 2621172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2622107273Srwatson return (EACCES); 2623107273Srwatson } 2624107273Srwatson 2625107273Srwatson return (0); 2626107273Srwatson} 2627107273Srwatson 2628107273Srwatsonstatic int 2629172955Srwatsonlomac_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2630168976Srwatson struct label *vplabel) 2631107273Srwatson{ 2632107273Srwatson struct mac_lomac *subj, *obj; 2633107273Srwatson 2634172955Srwatson if (!lomac_enabled) 2635107273Srwatson return (0); 2636107273Srwatson 2637122524Srwatson subj = SLOT(cred->cr_label); 2638168976Srwatson obj = SLOT(vplabel); 2639107273Srwatson 2640172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2641107273Srwatson return (EACCES); 2642107273Srwatson 2643107273Srwatson return (0); 2644107273Srwatson} 2645107273Srwatson 2646107273Srwatsonstatic int 2647172955Srwatsonlomac_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2648168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 2649107273Srwatson{ 2650107273Srwatson struct mac_lomac *subj, *obj; 2651107273Srwatson 2652172955Srwatson if (!lomac_enabled) 2653107273Srwatson return (0); 2654107273Srwatson 2655122524Srwatson subj = SLOT(cred->cr_label); 2656168976Srwatson obj = SLOT(vplabel); 2657107273Srwatson 2658172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2659107273Srwatson return (EACCES); 2660107273Srwatson 2661107273Srwatson return (0); 2662107273Srwatson} 2663107273Srwatson 2664107273Srwatsonstatic int 2665172955Srwatsonlomac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2666189533Srwatson struct label *vplabel, int attrnamespace, const char *name) 2667107273Srwatson{ 2668107273Srwatson struct mac_lomac *subj, *obj; 2669107273Srwatson 2670172955Srwatson if (!lomac_enabled) 2671107273Srwatson return (0); 2672107273Srwatson 2673122524Srwatson subj = SLOT(cred->cr_label); 2674168976Srwatson obj = SLOT(vplabel); 2675107273Srwatson 2676172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2677107273Srwatson return (EACCES); 2678107273Srwatson 2679107273Srwatson /* XXX: protect the MAC EA in a special way? */ 2680107273Srwatson 2681107273Srwatson return (0); 2682107273Srwatson} 2683107273Srwatson 2684107273Srwatsonstatic int 2685172955Srwatsonlomac_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2686168976Srwatson struct label *vplabel, u_long flags) 2687107273Srwatson{ 2688107273Srwatson struct mac_lomac *subj, *obj; 2689107273Srwatson 2690172955Srwatson if (!lomac_enabled) 2691107273Srwatson return (0); 2692107273Srwatson 2693122524Srwatson subj = SLOT(cred->cr_label); 2694168976Srwatson obj = SLOT(vplabel); 2695107273Srwatson 2696172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2697107273Srwatson return (EACCES); 2698107273Srwatson 2699107273Srwatson return (0); 2700107273Srwatson} 2701107273Srwatson 2702107273Srwatsonstatic int 2703172955Srwatsonlomac_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 2704168976Srwatson struct label *vplabel, mode_t mode) 2705107273Srwatson{ 2706107273Srwatson struct mac_lomac *subj, *obj; 2707107273Srwatson 2708172955Srwatson if (!lomac_enabled) 2709107273Srwatson return (0); 2710107273Srwatson 2711122524Srwatson subj = SLOT(cred->cr_label); 2712168976Srwatson obj = SLOT(vplabel); 2713107273Srwatson 2714172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2715107273Srwatson return (EACCES); 2716107273Srwatson 2717107273Srwatson return (0); 2718107273Srwatson} 2719107273Srwatson 2720107273Srwatsonstatic int 2721172955Srwatsonlomac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 2722168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 2723107273Srwatson{ 2724107273Srwatson struct mac_lomac *subj, *obj; 2725107273Srwatson 2726172955Srwatson if (!lomac_enabled) 2727107273Srwatson return (0); 2728107273Srwatson 2729122524Srwatson subj = SLOT(cred->cr_label); 2730168976Srwatson obj = SLOT(vplabel); 2731107273Srwatson 2732172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2733107273Srwatson return (EACCES); 2734107273Srwatson 2735107273Srwatson return (0); 2736107273Srwatson} 2737107273Srwatson 2738107273Srwatsonstatic int 2739172955Srwatsonlomac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 2740168976Srwatson struct label *vplabel, struct timespec atime, struct timespec mtime) 2741107273Srwatson{ 2742107273Srwatson struct mac_lomac *subj, *obj; 2743107273Srwatson 2744172955Srwatson if (!lomac_enabled) 2745107273Srwatson return (0); 2746107273Srwatson 2747122524Srwatson subj = SLOT(cred->cr_label); 2748168976Srwatson obj = SLOT(vplabel); 2749107273Srwatson 2750172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2751107273Srwatson return (EACCES); 2752107273Srwatson 2753107273Srwatson return (0); 2754107273Srwatson} 2755107273Srwatson 2756107273Srwatsonstatic int 2757172955Srwatsonlomac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 2758172107Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2759172107Srwatson struct componentname *cnp) 2760172107Srwatson{ 2761172107Srwatson struct mac_lomac *subj, *obj; 2762172107Srwatson 2763172955Srwatson if (!lomac_enabled) 2764172107Srwatson return (0); 2765172107Srwatson 2766172107Srwatson subj = SLOT(cred->cr_label); 2767172107Srwatson obj = SLOT(dvplabel); 2768172107Srwatson 2769172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2770172107Srwatson return (EACCES); 2771172107Srwatson 2772172107Srwatson obj = SLOT(vplabel); 2773172107Srwatson 2774172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2775172107Srwatson return (EACCES); 2776172107Srwatson 2777172107Srwatson return (0); 2778172107Srwatson} 2779172107Srwatson 2780172107Srwatsonstatic int 2781172955Srwatsonlomac_vnode_check_write(struct ucred *active_cred, 2782168976Srwatson struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 2783107273Srwatson{ 2784107273Srwatson struct mac_lomac *subj, *obj; 2785107273Srwatson 2786172955Srwatson if (!lomac_enabled || !revocation_enabled) 2787107273Srwatson return (0); 2788107273Srwatson 2789122524Srwatson subj = SLOT(active_cred->cr_label); 2790168976Srwatson obj = SLOT(vplabel); 2791107273Srwatson 2792172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2793107273Srwatson return (EACCES); 2794107273Srwatson 2795107273Srwatson return (0); 2796107273Srwatson} 2797107273Srwatson 2798173138Srwatsonstatic int 2799173138Srwatsonlomac_vnode_create_extattr(struct ucred *cred, struct mount *mp, 2800173138Srwatson struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 2801173138Srwatson struct vnode *vp, struct label *vplabel, struct componentname *cnp) 2802107273Srwatson{ 2803173138Srwatson struct mac_lomac *source, *dest, *dir, temp; 2804173138Srwatson size_t buflen; 2805173138Srwatson int error; 2806107273Srwatson 2807173138Srwatson buflen = sizeof(temp); 2808173138Srwatson bzero(&temp, buflen); 2809173138Srwatson 2810173138Srwatson source = SLOT(cred->cr_label); 2811173138Srwatson dest = SLOT(vplabel); 2812173138Srwatson dir = SLOT(dvplabel); 2813173138Srwatson if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 2814173138Srwatson lomac_copy_auxsingle(dir, &temp); 2815173138Srwatson lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 2816173138Srwatson dir->ml_auxsingle.mle_grade); 2817107273Srwatson } else { 2818173138Srwatson lomac_copy_single(source, &temp); 2819107273Srwatson } 2820173138Srwatson 2821173138Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2822173138Srwatson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2823173138Srwatson if (error == 0) 2824173138Srwatson lomac_copy(&temp, dest); 2825173138Srwatson return (error); 2826107273Srwatson} 2827107273Srwatson 2828173138Srwatsonstatic void 2829173138Srwatsonlomac_vnode_execve_transition(struct ucred *old, struct ucred *new, 2830173138Srwatson struct vnode *vp, struct label *vplabel, struct label *interpvplabel, 2831173138Srwatson struct image_params *imgp, struct label *execlabel) 2832173138Srwatson{ 2833173138Srwatson struct mac_lomac *source, *dest, *obj, *robj; 2834173138Srwatson 2835173138Srwatson source = SLOT(old->cr_label); 2836173138Srwatson dest = SLOT(new->cr_label); 2837173138Srwatson obj = SLOT(vplabel); 2838173138Srwatson robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2839173138Srwatson 2840173138Srwatson lomac_copy(source, dest); 2841173138Srwatson /* 2842173138Srwatson * If there's an auxiliary label on the real object, respect it and 2843173138Srwatson * assume that this level should be assumed immediately if a higher 2844173138Srwatson * level is currently in place. 2845173138Srwatson */ 2846173138Srwatson if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2847173138Srwatson !lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 2848173138Srwatson && lomac_auxsingle_in_range(robj, dest)) 2849173138Srwatson lomac_set_single(dest, robj->ml_auxsingle.mle_type, 2850173138Srwatson robj->ml_auxsingle.mle_grade); 2851173138Srwatson /* 2852173138Srwatson * Restructuring to use the execve transitioning mechanism instead of 2853173138Srwatson * the normal demotion mechanism here would be difficult, so just 2854173138Srwatson * copy the label over and perform standard demotion. This is also 2855173138Srwatson * non-optimal because it will result in the intermediate label "new" 2856173138Srwatson * being created and immediately recycled. 2857173138Srwatson */ 2858173138Srwatson if (lomac_enabled && revocation_enabled && 2859173138Srwatson !lomac_dominate_single(obj, source)) 2860173138Srwatson (void)maybe_demote(source, obj, "executing", "file", vp); 2861173138Srwatson} 2862173138Srwatson 2863173138Srwatsonstatic int 2864173138Srwatsonlomac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp, 2865173138Srwatson struct label *vplabel, struct label *interpvplabel, 2866173138Srwatson struct image_params *imgp, struct label *execlabel) 2867173138Srwatson{ 2868173138Srwatson struct mac_lomac *subj, *obj, *robj; 2869173138Srwatson 2870173138Srwatson if (!lomac_enabled || !revocation_enabled) 2871173138Srwatson return (0); 2872173138Srwatson 2873173138Srwatson subj = SLOT(old->cr_label); 2874173138Srwatson obj = SLOT(vplabel); 2875173138Srwatson robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2876173138Srwatson 2877173138Srwatson return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2878173138Srwatson !lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 2879173138Srwatson && lomac_auxsingle_in_range(robj, subj)) || 2880173138Srwatson !lomac_dominate_single(obj, subj)); 2881173138Srwatson} 2882173138Srwatson 2883173138Srwatsonstatic void 2884173138Srwatsonlomac_vnode_relabel(struct ucred *cred, struct vnode *vp, 2885173138Srwatson struct label *vplabel, struct label *newlabel) 2886173138Srwatson{ 2887173138Srwatson struct mac_lomac *source, *dest; 2888173138Srwatson 2889173138Srwatson source = SLOT(newlabel); 2890173138Srwatson dest = SLOT(vplabel); 2891173138Srwatson 2892173138Srwatson try_relabel(source, dest); 2893173138Srwatson} 2894173138Srwatson 2895173138Srwatsonstatic int 2896173138Srwatsonlomac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 2897173138Srwatson struct label *vplabel, struct label *intlabel) 2898173138Srwatson{ 2899173138Srwatson struct mac_lomac *source, temp; 2900173138Srwatson size_t buflen; 2901173138Srwatson int error; 2902173138Srwatson 2903173138Srwatson buflen = sizeof(temp); 2904173138Srwatson bzero(&temp, buflen); 2905173138Srwatson 2906173138Srwatson source = SLOT(intlabel); 2907173138Srwatson if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2908173138Srwatson return (0); 2909173138Srwatson 2910173138Srwatson lomac_copy_single(source, &temp); 2911173138Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2912173138Srwatson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2913173138Srwatson return (error); 2914173138Srwatson} 2915173138Srwatson 2916172955Srwatsonstatic struct mac_policy_ops lomac_ops = 2917107273Srwatson{ 2918172955Srwatson .mpo_init = lomac_init, 2919173138Srwatson 2920173138Srwatson .mpo_bpfdesc_check_receive = lomac_bpfdesc_check_receive, 2921173138Srwatson .mpo_bpfdesc_create = lomac_bpfdesc_create, 2922173138Srwatson .mpo_bpfdesc_create_mbuf = lomac_bpfdesc_create_mbuf, 2923173138Srwatson .mpo_bpfdesc_destroy_label = lomac_destroy_label, 2924172955Srwatson .mpo_bpfdesc_init_label = lomac_init_label, 2925173138Srwatson 2926173138Srwatson .mpo_cred_check_relabel = lomac_cred_check_relabel, 2927173138Srwatson .mpo_cred_check_visible = lomac_cred_check_visible, 2928173138Srwatson .mpo_cred_copy_label = lomac_copy_label, 2929184407Srwatson .mpo_cred_create_swapper = lomac_cred_create_swapper, 2930184407Srwatson .mpo_cred_create_init = lomac_cred_create_init, 2931172955Srwatson .mpo_cred_destroy_label = lomac_destroy_label, 2932172955Srwatson .mpo_cred_externalize_label = lomac_externalize_label, 2933173138Srwatson .mpo_cred_init_label = lomac_init_label, 2934172955Srwatson .mpo_cred_internalize_label = lomac_internalize_label, 2935173138Srwatson .mpo_cred_relabel = lomac_cred_relabel, 2936173138Srwatson 2937172955Srwatson .mpo_devfs_create_device = lomac_devfs_create_device, 2938172955Srwatson .mpo_devfs_create_directory = lomac_devfs_create_directory, 2939172955Srwatson .mpo_devfs_create_symlink = lomac_devfs_create_symlink, 2940173138Srwatson .mpo_devfs_destroy_label = lomac_destroy_label, 2941173138Srwatson .mpo_devfs_init_label = lomac_init_label, 2942172955Srwatson .mpo_devfs_update = lomac_devfs_update, 2943172955Srwatson .mpo_devfs_vnode_associate = lomac_devfs_vnode_associate, 2944173138Srwatson 2945173138Srwatson .mpo_ifnet_check_relabel = lomac_ifnet_check_relabel, 2946173138Srwatson .mpo_ifnet_check_transmit = lomac_ifnet_check_transmit, 2947173138Srwatson .mpo_ifnet_copy_label = lomac_copy_label, 2948172955Srwatson .mpo_ifnet_create = lomac_ifnet_create, 2949173138Srwatson .mpo_ifnet_create_mbuf = lomac_ifnet_create_mbuf, 2950173138Srwatson .mpo_ifnet_destroy_label = lomac_destroy_label, 2951173138Srwatson .mpo_ifnet_externalize_label = lomac_externalize_label, 2952173138Srwatson .mpo_ifnet_init_label = lomac_init_label, 2953173138Srwatson .mpo_ifnet_internalize_label = lomac_internalize_label, 2954173138Srwatson .mpo_ifnet_relabel = lomac_ifnet_relabel, 2955173138Srwatson 2956173138Srwatson .mpo_syncache_create = lomac_syncache_create, 2957173138Srwatson .mpo_syncache_destroy_label = lomac_destroy_label, 2958173138Srwatson .mpo_syncache_init_label = lomac_init_label_waitcheck, 2959173138Srwatson 2960173138Srwatson .mpo_inpcb_check_deliver = lomac_inpcb_check_deliver, 2961183980Sbz .mpo_inpcb_check_visible = lomac_inpcb_check_visible, 2962172955Srwatson .mpo_inpcb_create = lomac_inpcb_create, 2963173138Srwatson .mpo_inpcb_create_mbuf = lomac_inpcb_create_mbuf, 2964173138Srwatson .mpo_inpcb_destroy_label = lomac_destroy_label, 2965173138Srwatson .mpo_inpcb_init_label = lomac_init_label_waitcheck, 2966173138Srwatson .mpo_inpcb_sosetlabel = lomac_inpcb_sosetlabel, 2967173138Srwatson 2968184308Srwatson .mpo_ip6q_create = lomac_ip6q_create, 2969184308Srwatson .mpo_ip6q_destroy_label = lomac_destroy_label, 2970184308Srwatson .mpo_ip6q_init_label = lomac_init_label_waitcheck, 2971184308Srwatson .mpo_ip6q_match = lomac_ip6q_match, 2972184308Srwatson .mpo_ip6q_reassemble = lomac_ip6q_reassemble, 2973184308Srwatson .mpo_ip6q_update = lomac_ip6q_update, 2974184308Srwatson 2975172955Srwatson .mpo_ipq_create = lomac_ipq_create, 2976173138Srwatson .mpo_ipq_destroy_label = lomac_destroy_label, 2977173138Srwatson .mpo_ipq_init_label = lomac_init_label_waitcheck, 2978172955Srwatson .mpo_ipq_match = lomac_ipq_match, 2979173138Srwatson .mpo_ipq_reassemble = lomac_ipq_reassemble, 2980172955Srwatson .mpo_ipq_update = lomac_ipq_update, 2981173138Srwatson 2982172955Srwatson .mpo_kld_check_load = lomac_kld_check_load, 2983173138Srwatson 2984173138Srwatson .mpo_mbuf_copy_label = lomac_copy_label, 2985173138Srwatson .mpo_mbuf_destroy_label = lomac_destroy_label, 2986173138Srwatson .mpo_mbuf_init_label = lomac_init_label_waitcheck, 2987173138Srwatson 2988173138Srwatson .mpo_mount_create = lomac_mount_create, 2989173138Srwatson .mpo_mount_destroy_label = lomac_destroy_label, 2990173138Srwatson .mpo_mount_init_label = lomac_init_label, 2991173138Srwatson 2992173138Srwatson .mpo_netatalk_aarp_send = lomac_netatalk_aarp_send, 2993173138Srwatson 2994173138Srwatson .mpo_netinet_arp_send = lomac_netinet_arp_send, 2995173138Srwatson .mpo_netinet_firewall_reply = lomac_netinet_firewall_reply, 2996173138Srwatson .mpo_netinet_firewall_send = lomac_netinet_firewall_send, 2997173138Srwatson .mpo_netinet_fragment = lomac_netinet_fragment, 2998173138Srwatson .mpo_netinet_icmp_reply = lomac_netinet_icmp_reply, 2999173138Srwatson .mpo_netinet_igmp_send = lomac_netinet_igmp_send, 3000173138Srwatson 3001173138Srwatson .mpo_netinet6_nd6_send = lomac_netinet6_nd6_send, 3002173138Srwatson 3003172955Srwatson .mpo_pipe_check_ioctl = lomac_pipe_check_ioctl, 3004172955Srwatson .mpo_pipe_check_read = lomac_pipe_check_read, 3005172955Srwatson .mpo_pipe_check_relabel = lomac_pipe_check_relabel, 3006172955Srwatson .mpo_pipe_check_write = lomac_pipe_check_write, 3007173138Srwatson .mpo_pipe_copy_label = lomac_copy_label, 3008173138Srwatson .mpo_pipe_create = lomac_pipe_create, 3009173138Srwatson .mpo_pipe_destroy_label = lomac_destroy_label, 3010173138Srwatson .mpo_pipe_externalize_label = lomac_externalize_label, 3011173138Srwatson .mpo_pipe_init_label = lomac_init_label, 3012173138Srwatson .mpo_pipe_internalize_label = lomac_internalize_label, 3013173138Srwatson .mpo_pipe_relabel = lomac_pipe_relabel, 3014173138Srwatson 3015173138Srwatson .mpo_priv_check = lomac_priv_check, 3016173138Srwatson 3017172955Srwatson .mpo_proc_check_debug = lomac_proc_check_debug, 3018172955Srwatson .mpo_proc_check_sched = lomac_proc_check_sched, 3019172955Srwatson .mpo_proc_check_signal = lomac_proc_check_signal, 3020173138Srwatson .mpo_proc_destroy_label = lomac_proc_destroy_label, 3021173138Srwatson .mpo_proc_init_label = lomac_proc_init_label, 3022173138Srwatson 3023172955Srwatson .mpo_socket_check_deliver = lomac_socket_check_deliver, 3024172955Srwatson .mpo_socket_check_relabel = lomac_socket_check_relabel, 3025172955Srwatson .mpo_socket_check_visible = lomac_socket_check_visible, 3026173138Srwatson .mpo_socket_copy_label = lomac_copy_label, 3027173138Srwatson .mpo_socket_create = lomac_socket_create, 3028173138Srwatson .mpo_socket_create_mbuf = lomac_socket_create_mbuf, 3029173138Srwatson .mpo_socket_destroy_label = lomac_destroy_label, 3030173138Srwatson .mpo_socket_externalize_label = lomac_externalize_label, 3031173138Srwatson .mpo_socket_init_label = lomac_init_label_waitcheck, 3032173138Srwatson .mpo_socket_internalize_label = lomac_internalize_label, 3033173138Srwatson .mpo_socket_newconn = lomac_socket_newconn, 3034173138Srwatson .mpo_socket_relabel = lomac_socket_relabel, 3035173138Srwatson 3036173138Srwatson .mpo_socketpeer_destroy_label = lomac_destroy_label, 3037173138Srwatson .mpo_socketpeer_externalize_label = lomac_externalize_label, 3038173138Srwatson .mpo_socketpeer_init_label = lomac_init_label_waitcheck, 3039173138Srwatson .mpo_socketpeer_set_from_mbuf = lomac_socketpeer_set_from_mbuf, 3040173138Srwatson .mpo_socketpeer_set_from_socket = lomac_socketpeer_set_from_socket, 3041173138Srwatson 3042173138Srwatson .mpo_syncache_create_mbuf = lomac_syncache_create_mbuf, 3043173138Srwatson 3044172955Srwatson .mpo_system_check_acct = lomac_system_check_acct, 3045172955Srwatson .mpo_system_check_auditctl = lomac_system_check_auditctl, 3046172955Srwatson .mpo_system_check_swapoff = lomac_system_check_swapoff, 3047172955Srwatson .mpo_system_check_swapon = lomac_system_check_swapon, 3048172955Srwatson .mpo_system_check_sysctl = lomac_system_check_sysctl, 3049173138Srwatson 3050173138Srwatson .mpo_thread_userret = lomac_thread_userret, 3051173138Srwatson 3052173138Srwatson .mpo_vnode_associate_extattr = lomac_vnode_associate_extattr, 3053173138Srwatson .mpo_vnode_associate_singlelabel = lomac_vnode_associate_singlelabel, 3054172955Srwatson .mpo_vnode_check_access = lomac_vnode_check_open, 3055172955Srwatson .mpo_vnode_check_create = lomac_vnode_check_create, 3056172955Srwatson .mpo_vnode_check_deleteacl = lomac_vnode_check_deleteacl, 3057172955Srwatson .mpo_vnode_check_link = lomac_vnode_check_link, 3058172955Srwatson .mpo_vnode_check_mmap = lomac_vnode_check_mmap, 3059172955Srwatson .mpo_vnode_check_mmap_downgrade = lomac_vnode_check_mmap_downgrade, 3060172955Srwatson .mpo_vnode_check_open = lomac_vnode_check_open, 3061172955Srwatson .mpo_vnode_check_read = lomac_vnode_check_read, 3062172955Srwatson .mpo_vnode_check_relabel = lomac_vnode_check_relabel, 3063172955Srwatson .mpo_vnode_check_rename_from = lomac_vnode_check_rename_from, 3064172955Srwatson .mpo_vnode_check_rename_to = lomac_vnode_check_rename_to, 3065172955Srwatson .mpo_vnode_check_revoke = lomac_vnode_check_revoke, 3066172955Srwatson .mpo_vnode_check_setacl = lomac_vnode_check_setacl, 3067172955Srwatson .mpo_vnode_check_setextattr = lomac_vnode_check_setextattr, 3068172955Srwatson .mpo_vnode_check_setflags = lomac_vnode_check_setflags, 3069172955Srwatson .mpo_vnode_check_setmode = lomac_vnode_check_setmode, 3070172955Srwatson .mpo_vnode_check_setowner = lomac_vnode_check_setowner, 3071172955Srwatson .mpo_vnode_check_setutimes = lomac_vnode_check_setutimes, 3072172955Srwatson .mpo_vnode_check_unlink = lomac_vnode_check_unlink, 3073172955Srwatson .mpo_vnode_check_write = lomac_vnode_check_write, 3074173138Srwatson .mpo_vnode_copy_label = lomac_copy_label, 3075173138Srwatson .mpo_vnode_create_extattr = lomac_vnode_create_extattr, 3076173138Srwatson .mpo_vnode_destroy_label = lomac_destroy_label, 3077173138Srwatson .mpo_vnode_execve_transition = lomac_vnode_execve_transition, 3078173138Srwatson .mpo_vnode_execve_will_transition = lomac_vnode_execve_will_transition, 3079173138Srwatson .mpo_vnode_externalize_label = lomac_externalize_label, 3080173138Srwatson .mpo_vnode_init_label = lomac_init_label, 3081173138Srwatson .mpo_vnode_internalize_label = lomac_internalize_label, 3082173138Srwatson .mpo_vnode_relabel = lomac_vnode_relabel, 3083173138Srwatson .mpo_vnode_setlabel_extattr = lomac_vnode_setlabel_extattr, 3084107273Srwatson}; 3085107273Srwatson 3086172955SrwatsonMAC_POLICY_SET(&lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC", 3087187016Srwatson MPC_LOADTIME_FLAG_NOTLATE, &lomac_slot); 3088