mac_lomac.c revision 187016
1107273Srwatson/*- 2184308Srwatson * Copyright (c) 1999-2002, 2007-2008 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: head/sys/security/mac_lomac/mac_lomac.c 187016 2009-01-10 10:58:41Z rwatson $ 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 96107273SrwatsonSYSCTL_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 140172955SrwatsonMALLOC_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; 765107273Srwatson range = index(string, '('); 766107273Srwatson if (range == single) 767107273Srwatson single = NULL; 768107273Srwatson auxsingle = index(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; 779107273Srwatson rangehigh = index(rangelow, '-'); 780107273Srwatson if (rangehigh == NULL) 781107273Srwatson return (EINVAL); 782107273Srwatson rangehigh++; 783107273Srwatson if (*rangelow == '\0' || *rangehigh == '\0') 784107273Srwatson return (EINVAL); 785107273Srwatson rangeend = index(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++; 801107273Srwatson auxsingleend = index(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; 1035173138Srwatson int lomac_type; 1036122875Srwatson 1037173138Srwatson ml = SLOT(delabel); 1038173138Srwatson if (strcmp(dev->si_name, "null") == 0 || 1039173138Srwatson strcmp(dev->si_name, "zero") == 0 || 1040173138Srwatson strcmp(dev->si_name, "random") == 0 || 1041173138Srwatson strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 || 1042173138Srwatson strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0) 1043173138Srwatson lomac_type = MAC_LOMAC_TYPE_EQUAL; 1044173138Srwatson else if (ptys_equal && 1045173138Srwatson (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 1046173138Srwatson strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 1047173138Srwatson lomac_type = MAC_LOMAC_TYPE_EQUAL; 1048173138Srwatson else 1049173138Srwatson lomac_type = MAC_LOMAC_TYPE_HIGH; 1050173138Srwatson lomac_set_single(ml, lomac_type, 0); 1051122875Srwatson} 1052122875Srwatson 1053122875Srwatsonstatic void 1054173138Srwatsonlomac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 1055173138Srwatson struct devfs_dirent *de, struct label *delabel) 1056107273Srwatson{ 1057173138Srwatson struct mac_lomac *ml; 1058107273Srwatson 1059173138Srwatson ml = SLOT(delabel); 1060173138Srwatson lomac_set_single(ml, MAC_LOMAC_TYPE_HIGH, 0); 1061107273Srwatson} 1062107273Srwatson 1063107273Srwatsonstatic void 1064173138Srwatsonlomac_devfs_create_symlink(struct ucred *cred, struct mount *mp, 1065173138Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 1066173138Srwatson struct label *delabel) 1067107273Srwatson{ 1068107273Srwatson struct mac_lomac *source, *dest; 1069107273Srwatson 1070122524Srwatson source = SLOT(cred->cr_label); 1071173138Srwatson dest = SLOT(delabel); 1072107273Srwatson 1073172955Srwatson lomac_copy_single(source, dest); 1074107273Srwatson} 1075107273Srwatson 1076107273Srwatsonstatic void 1077173138Srwatsonlomac_devfs_update(struct mount *mp, struct devfs_dirent *de, 1078173138Srwatson struct label *delabel, struct vnode *vp, struct label *vplabel) 1079107273Srwatson{ 1080107273Srwatson struct mac_lomac *source, *dest; 1081107273Srwatson 1082173138Srwatson source = SLOT(vplabel); 1083173138Srwatson dest = SLOT(delabel); 1084107273Srwatson 1085173138Srwatson lomac_copy(source, dest); 1086107273Srwatson} 1087107273Srwatson 1088107273Srwatsonstatic void 1089173138Srwatsonlomac_devfs_vnode_associate(struct mount *mp, struct label *mplabel, 1090173138Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 1091173138Srwatson struct label *vplabel) 1092107273Srwatson{ 1093107273Srwatson struct mac_lomac *source, *dest; 1094107273Srwatson 1095173138Srwatson source = SLOT(delabel); 1096173138Srwatson dest = SLOT(vplabel); 1097107273Srwatson 1098172955Srwatson lomac_copy_single(source, dest); 1099107273Srwatson} 1100107273Srwatson 1101173138Srwatsonstatic int 1102173138Srwatsonlomac_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1103173138Srwatson struct label *ifplabel, struct label *newlabel) 1104107273Srwatson{ 1105173138Srwatson struct mac_lomac *subj, *new; 1106173138Srwatson int error; 1107107273Srwatson 1108173138Srwatson subj = SLOT(cred->cr_label); 1109173138Srwatson new = SLOT(newlabel); 1110107273Srwatson 1111173138Srwatson /* 1112173138Srwatson * If there is a LOMAC label update for the interface, it may be an 1113173138Srwatson * update of the single, range, or both. 1114173138Srwatson */ 1115173138Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1116173138Srwatson if (error) 1117173138Srwatson return (error); 1118107273Srwatson 1119173138Srwatson /* 1120173138Srwatson * Relabling network interfaces requires LOMAC privilege. 1121173138Srwatson */ 1122173138Srwatson error = lomac_subject_privileged(subj); 1123173138Srwatson if (error) 1124173138Srwatson return (error); 1125107273Srwatson 1126173138Srwatson /* 1127173138Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 1128173138Srwatson */ 1129173138Srwatson if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1130173138Srwatson /* 1131173138Srwatson * Fill in the missing parts from the previous label. 1132173138Srwatson */ 1133173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1134173138Srwatson lomac_copy_single(subj, new); 1135173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1136173138Srwatson lomac_copy_range(subj, new); 1137107273Srwatson 1138173138Srwatson /* 1139173138Srwatson * Rely on the traditional superuser status for the LOMAC 1140173138Srwatson * interface relabel requirements. XXXMAC: This will go 1141173138Srwatson * away. 1142173138Srwatson * 1143173138Srwatson * XXXRW: This is also redundant to a higher layer check. 1144173138Srwatson */ 1145173138Srwatson error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0); 1146173138Srwatson if (error) 1147173138Srwatson return (EPERM); 1148107273Srwatson 1149173138Srwatson /* 1150173138Srwatson * XXXMAC: Additional consistency tests regarding the single 1151173138Srwatson * and the range of the new label might be performed here. 1152173138Srwatson */ 1153173138Srwatson } 1154107273Srwatson 1155173138Srwatson return (0); 1156107273Srwatson} 1157107273Srwatson 1158173138Srwatsonstatic int 1159173138Srwatsonlomac_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1160173138Srwatson struct mbuf *m, struct label *mlabel) 1161107273Srwatson{ 1162173138Srwatson struct mac_lomac *p, *i; 1163107273Srwatson 1164173138Srwatson if (!lomac_enabled) 1165173138Srwatson return (0); 1166107273Srwatson 1167173138Srwatson p = SLOT(mlabel); 1168173138Srwatson i = SLOT(ifplabel); 1169107273Srwatson 1170173138Srwatson return (lomac_single_in_range(p, i) ? 0 : EACCES); 1171107273Srwatson} 1172107273Srwatson 1173107273Srwatsonstatic void 1174172955Srwatsonlomac_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1175107273Srwatson{ 1176121816Sbrooks char tifname[IFNAMSIZ], *p, *q; 1177107273Srwatson char tiflist[sizeof(trusted_interfaces)]; 1178107273Srwatson struct mac_lomac *dest; 1179107273Srwatson int len, grade; 1180107273Srwatson 1181168976Srwatson dest = SLOT(ifplabel); 1182107273Srwatson 1183168976Srwatson if (ifp->if_type == IFT_LOOP) { 1184107273Srwatson grade = MAC_LOMAC_TYPE_EQUAL; 1185107273Srwatson goto set; 1186107273Srwatson } 1187107273Srwatson 1188107273Srwatson if (trust_all_interfaces) { 1189107273Srwatson grade = MAC_LOMAC_TYPE_HIGH; 1190107273Srwatson goto set; 1191107273Srwatson } 1192107273Srwatson 1193107273Srwatson grade = MAC_LOMAC_TYPE_LOW; 1194107273Srwatson 1195107273Srwatson if (trusted_interfaces[0] == '\0' || 1196107273Srwatson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1197107273Srwatson goto set; 1198107273Srwatson 1199107273Srwatson bzero(tiflist, sizeof(tiflist)); 1200107273Srwatson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1201107273Srwatson if(*p != ' ' && *p != '\t') 1202107273Srwatson *q = *p; 1203107273Srwatson 1204107273Srwatson for (p = q = tiflist;; p++) { 1205107273Srwatson if (*p == ',' || *p == '\0') { 1206107273Srwatson len = p - q; 1207107273Srwatson if (len < IFNAMSIZ) { 1208107273Srwatson bzero(tifname, sizeof(tifname)); 1209107273Srwatson bcopy(q, tifname, len); 1210168976Srwatson if (strcmp(tifname, ifp->if_xname) == 0) { 1211107273Srwatson grade = MAC_LOMAC_TYPE_HIGH; 1212107273Srwatson break; 1213107273Srwatson } 1214107273Srwatson } 1215107273Srwatson else { 1216107273Srwatson *p = '\0'; 1217107273Srwatson printf("MAC/LOMAC warning: interface name " 1218107273Srwatson "\"%s\" is too long (must be < %d)\n", 1219107273Srwatson q, IFNAMSIZ); 1220107273Srwatson } 1221107273Srwatson if (*p == '\0') 1222107273Srwatson break; 1223107273Srwatson q = p + 1; 1224107273Srwatson } 1225107273Srwatson } 1226107273Srwatsonset: 1227172955Srwatson lomac_set_single(dest, grade, 0); 1228172955Srwatson lomac_set_range(dest, grade, 0, grade, 0); 1229107273Srwatson} 1230107273Srwatson 1231107273Srwatsonstatic void 1232173138Srwatsonlomac_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1233173138Srwatson struct mbuf *m, struct label *mlabel) 1234107273Srwatson{ 1235107273Srwatson struct mac_lomac *source, *dest; 1236107273Srwatson 1237173138Srwatson source = SLOT(ifplabel); 1238173138Srwatson dest = SLOT(mlabel); 1239107273Srwatson 1240172955Srwatson lomac_copy_single(source, dest); 1241107273Srwatson} 1242107273Srwatson 1243107273Srwatsonstatic void 1244173138Srwatsonlomac_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1245173138Srwatson struct label *ifplabel, struct label *newlabel) 1246107273Srwatson{ 1247107273Srwatson struct mac_lomac *source, *dest; 1248107273Srwatson 1249173138Srwatson source = SLOT(newlabel); 1250173138Srwatson dest = SLOT(ifplabel); 1251107273Srwatson 1252173138Srwatson try_relabel(source, dest); 1253107273Srwatson} 1254107273Srwatson 1255173138Srwatsonstatic int 1256173138Srwatsonlomac_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1257173138Srwatson struct mbuf *m, struct label *mlabel) 1258173138Srwatson{ 1259173138Srwatson struct mac_lomac *p, *i; 1260173138Srwatson 1261173138Srwatson if (!lomac_enabled) 1262173138Srwatson return (0); 1263173138Srwatson 1264173138Srwatson p = SLOT(mlabel); 1265173138Srwatson i = SLOT(inplabel); 1266173138Srwatson 1267173138Srwatson return (lomac_equal_single(p, i) ? 0 : EACCES); 1268173138Srwatson} 1269173138Srwatson 1270183980Sbzstatic int 1271183980Sbzlomac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 1272183980Sbz struct label *inplabel) 1273183980Sbz{ 1274183980Sbz struct mac_lomac *subj, *obj; 1275183980Sbz 1276183980Sbz if (!lomac_enabled) 1277183980Sbz return (0); 1278183980Sbz 1279183980Sbz subj = SLOT(cred->cr_label); 1280183980Sbz obj = SLOT(inplabel); 1281183980Sbz 1282183980Sbz if (!lomac_dominate_single(obj, subj)) 1283183980Sbz return (ENOENT); 1284183980Sbz 1285183980Sbz return (0); 1286183980Sbz} 1287183980Sbz 1288107273Srwatsonstatic void 1289173138Srwatsonlomac_inpcb_create(struct socket *so, struct label *solabel, 1290173138Srwatson struct inpcb *inp, struct label *inplabel) 1291107273Srwatson{ 1292107273Srwatson struct mac_lomac *source, *dest; 1293107273Srwatson 1294173138Srwatson source = SLOT(solabel); 1295173138Srwatson dest = SLOT(inplabel); 1296107273Srwatson 1297172955Srwatson lomac_copy_single(source, dest); 1298107273Srwatson} 1299107273Srwatson 1300107273Srwatsonstatic void 1301172955Srwatsonlomac_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1302123607Srwatson struct mbuf *m, struct label *mlabel) 1303123607Srwatson{ 1304123607Srwatson struct mac_lomac *source, *dest; 1305123607Srwatson 1306123607Srwatson source = SLOT(inplabel); 1307123607Srwatson dest = SLOT(mlabel); 1308123607Srwatson 1309172955Srwatson lomac_copy_single(source, dest); 1310123607Srwatson} 1311123607Srwatson 1312123607Srwatsonstatic void 1313173138Srwatsonlomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1314173138Srwatson struct inpcb *inp, struct label *inplabel) 1315107273Srwatson{ 1316107273Srwatson struct mac_lomac *source, *dest; 1317107273Srwatson 1318173138Srwatson source = SLOT(solabel); 1319173138Srwatson dest = SLOT(inplabel); 1320107273Srwatson 1321172955Srwatson lomac_copy_single(source, dest); 1322107273Srwatson} 1323107273Srwatson 1324107273Srwatsonstatic void 1325184308Srwatsonlomac_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1326184308Srwatson struct label *q6label) 1327184308Srwatson{ 1328184308Srwatson struct mac_lomac *source, *dest; 1329184308Srwatson 1330184308Srwatson source = SLOT(mlabel); 1331184308Srwatson dest = SLOT(q6label); 1332184308Srwatson 1333184308Srwatson lomac_copy_single(source, dest); 1334184308Srwatson} 1335184308Srwatson 1336184308Srwatsonstatic int 1337184308Srwatsonlomac_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1338184308Srwatson struct label *q6label) 1339184308Srwatson{ 1340184308Srwatson struct mac_lomac *a, *b; 1341184308Srwatson 1342184308Srwatson a = SLOT(q6label); 1343184308Srwatson b = SLOT(mlabel); 1344184308Srwatson 1345184308Srwatson return (lomac_equal_single(a, b)); 1346184308Srwatson} 1347184308Srwatson 1348184308Srwatsonstatic void 1349184308Srwatsonlomac_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1350184308Srwatson struct label *mlabel) 1351184308Srwatson{ 1352184308Srwatson struct mac_lomac *source, *dest; 1353184308Srwatson 1354184308Srwatson source = SLOT(q6label); 1355184308Srwatson dest = SLOT(mlabel); 1356184308Srwatson 1357184308Srwatson /* Just use the head, since we require them all to match. */ 1358184308Srwatson lomac_copy_single(source, dest); 1359184308Srwatson} 1360184308Srwatson 1361184308Srwatsonstatic void 1362184308Srwatsonlomac_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1363184308Srwatson struct label *q6label) 1364184308Srwatson{ 1365184308Srwatson 1366184308Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1367184308Srwatson} 1368184308Srwatson 1369184308Srwatsonstatic void 1370179781Srwatsonlomac_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1371179781Srwatson struct label *qlabel) 1372107273Srwatson{ 1373107273Srwatson struct mac_lomac *source, *dest; 1374107273Srwatson 1375173138Srwatson source = SLOT(mlabel); 1376179781Srwatson dest = SLOT(qlabel); 1377107273Srwatson 1378172955Srwatson lomac_copy_single(source, dest); 1379107273Srwatson} 1380107273Srwatson 1381107273Srwatsonstatic int 1382179781Srwatsonlomac_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1383179781Srwatson struct label *qlabel) 1384107273Srwatson{ 1385107273Srwatson struct mac_lomac *a, *b; 1386107273Srwatson 1387179781Srwatson a = SLOT(qlabel); 1388168976Srwatson b = SLOT(mlabel); 1389107273Srwatson 1390172955Srwatson return (lomac_equal_single(a, b)); 1391107273Srwatson} 1392107273Srwatson 1393107273Srwatsonstatic void 1394179781Srwatsonlomac_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1395179781Srwatson struct label *mlabel) 1396107273Srwatson{ 1397107273Srwatson struct mac_lomac *source, *dest; 1398107273Srwatson 1399179781Srwatson source = SLOT(qlabel); 1400173138Srwatson dest = SLOT(mlabel); 1401107273Srwatson 1402173138Srwatson /* Just use the head, since we require them all to match. */ 1403173138Srwatson lomac_copy_single(source, dest); 1404107273Srwatson} 1405107273Srwatson 1406107273Srwatsonstatic void 1407179781Srwatsonlomac_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1408179781Srwatson struct label *qlabel) 1409107273Srwatson{ 1410107273Srwatson 1411107273Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1412107273Srwatson} 1413107273Srwatson 1414173138Srwatsonstatic int 1415173138Srwatsonlomac_kld_check_load(struct ucred *cred, struct vnode *vp, 1416173138Srwatson struct label *vplabel) 1417122875Srwatson{ 1418173138Srwatson struct mac_lomac *subj, *obj; 1419122875Srwatson 1420173138Srwatson if (!lomac_enabled) 1421173138Srwatson return (0); 1422122875Srwatson 1423173138Srwatson subj = SLOT(cred->cr_label); 1424173138Srwatson obj = SLOT(vplabel); 1425122875Srwatson 1426173138Srwatson if (lomac_subject_privileged(subj)) 1427173138Srwatson return (EPERM); 1428165150Scsjp 1429173138Srwatson if (!lomac_high_single(obj)) 1430173138Srwatson return (EACCES); 1431173138Srwatson 1432173138Srwatson return (0); 1433165150Scsjp} 1434165150Scsjp 1435165150Scsjpstatic void 1436173138Srwatsonlomac_mount_create(struct ucred *cred, struct mount *mp, 1437173138Srwatson struct label *mplabel) 1438165150Scsjp{ 1439165150Scsjp struct mac_lomac *source, *dest; 1440165150Scsjp 1441173138Srwatson source = SLOT(cred->cr_label); 1442173138Srwatson dest = SLOT(mplabel); 1443173138Srwatson lomac_copy_single(source, dest); 1444165150Scsjp} 1445165150Scsjp 1446165150Scsjpstatic void 1447173095Srwatsonlomac_netatalk_aarp_send(struct ifnet *ifp, struct label *ifplabel, 1448173095Srwatson struct mbuf *m, struct label *mlabel) 1449173095Srwatson{ 1450173095Srwatson struct mac_lomac *dest; 1451173095Srwatson 1452173095Srwatson dest = SLOT(mlabel); 1453173095Srwatson 1454173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1455173095Srwatson} 1456173095Srwatson 1457173095Srwatsonstatic void 1458173095Srwatsonlomac_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1459173095Srwatson struct mbuf *m, struct label *mlabel) 1460173095Srwatson{ 1461173095Srwatson struct mac_lomac *dest; 1462173095Srwatson 1463173095Srwatson dest = SLOT(mlabel); 1464173095Srwatson 1465173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1466173095Srwatson} 1467173095Srwatson 1468173095Srwatsonstatic void 1469173102Srwatsonlomac_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1470173102Srwatson struct mbuf *msend, struct label *msendlabel) 1471173102Srwatson{ 1472173102Srwatson struct mac_lomac *source, *dest; 1473173102Srwatson 1474173102Srwatson source = SLOT(mrecvlabel); 1475173102Srwatson dest = SLOT(msendlabel); 1476173102Srwatson 1477173102Srwatson lomac_copy_single(source, dest); 1478173102Srwatson} 1479173102Srwatson 1480173102Srwatsonstatic void 1481173018Srwatsonlomac_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1482162238Scsjp{ 1483162238Scsjp struct mac_lomac *dest; 1484162238Scsjp 1485168976Srwatson dest = SLOT(mlabel); 1486162238Scsjp 1487162238Scsjp /* XXX: where is the label for the firewall really comming from? */ 1488172955Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1489162238Scsjp} 1490162238Scsjp 1491173095Srwatsonstatic void 1492173138Srwatsonlomac_netinet_fragment(struct mbuf *m, struct label *mlabel, 1493173138Srwatson struct mbuf *frag, struct label *fraglabel) 1494173138Srwatson{ 1495173138Srwatson struct mac_lomac *source, *dest; 1496173138Srwatson 1497173138Srwatson source = SLOT(mlabel); 1498173138Srwatson dest = SLOT(fraglabel); 1499173138Srwatson 1500173138Srwatson lomac_copy_single(source, dest); 1501173138Srwatson} 1502173138Srwatson 1503173138Srwatsonstatic void 1504173102Srwatsonlomac_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1505173102Srwatson struct mbuf *msend, struct label *msendlabel) 1506173102Srwatson{ 1507173102Srwatson struct mac_lomac *source, *dest; 1508173102Srwatson 1509173102Srwatson source = SLOT(mrecvlabel); 1510173102Srwatson dest = SLOT(msendlabel); 1511173102Srwatson 1512173102Srwatson lomac_copy_single(source, dest); 1513173102Srwatson} 1514173102Srwatson 1515173102Srwatsonstatic void 1516173095Srwatsonlomac_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1517173095Srwatson struct mbuf *m, struct label *mlabel) 1518173095Srwatson{ 1519173095Srwatson struct mac_lomac *dest; 1520173095Srwatson 1521173095Srwatson dest = SLOT(mlabel); 1522173095Srwatson 1523173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1524173095Srwatson} 1525173095Srwatson 1526173095Srwatsonstatic void 1527173095Srwatsonlomac_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1528173095Srwatson struct mbuf *m, struct label *mlabel) 1529173095Srwatson{ 1530173095Srwatson struct mac_lomac *dest; 1531173095Srwatson 1532173095Srwatson dest = SLOT(mlabel); 1533173095Srwatson 1534173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1535173095Srwatson} 1536173095Srwatson 1537107273Srwatsonstatic int 1538172955Srwatsonlomac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1539168976Srwatson struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1540107273Srwatson{ 1541107273Srwatson 1542172955Srwatson if (!lomac_enabled) 1543107273Srwatson return (0); 1544107273Srwatson 1545107273Srwatson /* XXX: This will be implemented soon... */ 1546107273Srwatson 1547107273Srwatson return (0); 1548107273Srwatson} 1549107273Srwatson 1550107273Srwatsonstatic int 1551172955Srwatsonlomac_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1552168976Srwatson struct label *pplabel) 1553107273Srwatson{ 1554107273Srwatson struct mac_lomac *subj, *obj; 1555107273Srwatson 1556172955Srwatson if (!lomac_enabled) 1557107273Srwatson return (0); 1558107273Srwatson 1559122524Srwatson subj = SLOT(cred->cr_label); 1560168976Srwatson obj = SLOT(pplabel); 1561107273Srwatson 1562172955Srwatson if (!lomac_dominate_single(obj, subj)) 1563107273Srwatson return (maybe_demote(subj, obj, "reading", "pipe", NULL)); 1564107273Srwatson 1565107273Srwatson return (0); 1566107273Srwatson} 1567107273Srwatson 1568107273Srwatsonstatic int 1569172955Srwatsonlomac_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1570168976Srwatson struct label *pplabel, struct label *newlabel) 1571107273Srwatson{ 1572107273Srwatson struct mac_lomac *subj, *obj, *new; 1573107273Srwatson int error; 1574107273Srwatson 1575107273Srwatson new = SLOT(newlabel); 1576122524Srwatson subj = SLOT(cred->cr_label); 1577168976Srwatson obj = SLOT(pplabel); 1578107273Srwatson 1579107273Srwatson /* 1580172955Srwatson * If there is a LOMAC label update for a pipe, it must be a single 1581172955Srwatson * update. 1582107273Srwatson */ 1583107273Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1584107273Srwatson if (error) 1585107273Srwatson return (error); 1586107273Srwatson 1587107273Srwatson /* 1588107273Srwatson * To perform a relabel of a pipe (LOMAC label or not), LOMAC must 1589107273Srwatson * authorize the relabel. 1590107273Srwatson */ 1591172955Srwatson if (!lomac_single_in_range(obj, subj)) 1592107273Srwatson return (EPERM); 1593107273Srwatson 1594107273Srwatson /* 1595107273Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 1596107273Srwatson */ 1597107273Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1598107273Srwatson /* 1599107273Srwatson * To change the LOMAC label on a pipe, the new pipe label 1600107273Srwatson * must be in the subject range. 1601107273Srwatson */ 1602172955Srwatson if (!lomac_single_in_range(new, subj)) 1603107273Srwatson return (EPERM); 1604107273Srwatson 1605107273Srwatson /* 1606107273Srwatson * To change the LOMAC label on a pipe to be EQUAL, the 1607107273Srwatson * subject must have appropriate privilege. 1608107273Srwatson */ 1609172955Srwatson if (lomac_contains_equal(new)) { 1610172955Srwatson error = lomac_subject_privileged(subj); 1611107273Srwatson if (error) 1612107273Srwatson return (error); 1613107273Srwatson } 1614107273Srwatson } 1615107273Srwatson 1616107273Srwatson return (0); 1617107273Srwatson} 1618107273Srwatson 1619107273Srwatsonstatic int 1620172955Srwatsonlomac_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1621168976Srwatson struct label *pplabel) 1622107273Srwatson{ 1623107273Srwatson struct mac_lomac *subj, *obj; 1624107273Srwatson 1625172955Srwatson if (!lomac_enabled) 1626107273Srwatson return (0); 1627107273Srwatson 1628122524Srwatson subj = SLOT(cred->cr_label); 1629168976Srwatson obj = SLOT(pplabel); 1630107273Srwatson 1631172955Srwatson if (!lomac_subject_dominate(subj, obj)) 1632107273Srwatson return (EACCES); 1633107273Srwatson 1634107273Srwatson return (0); 1635107273Srwatson} 1636107273Srwatson 1637173138Srwatsonstatic void 1638173138Srwatsonlomac_pipe_create(struct ucred *cred, struct pipepair *pp, 1639173138Srwatson struct label *pplabel) 1640107273Srwatson{ 1641173138Srwatson struct mac_lomac *source, *dest; 1642107273Srwatson 1643173138Srwatson source = SLOT(cred->cr_label); 1644173138Srwatson dest = SLOT(pplabel); 1645107273Srwatson 1646173138Srwatson lomac_copy_single(source, dest); 1647107273Srwatson} 1648107273Srwatson 1649173138Srwatsonstatic void 1650173138Srwatsonlomac_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1651173138Srwatson struct label *pplabel, struct label *newlabel) 1652107273Srwatson{ 1653173138Srwatson struct mac_lomac *source, *dest; 1654107273Srwatson 1655173138Srwatson source = SLOT(newlabel); 1656173138Srwatson dest = SLOT(pplabel); 1657107273Srwatson 1658173138Srwatson try_relabel(source, dest); 1659107273Srwatson} 1660107273Srwatson 1661168951Srwatson/* 1662168951Srwatson * Some system privileges are allowed regardless of integrity grade; others 1663168951Srwatson * are allowed only when running with privilege with respect to the LOMAC 1664168951Srwatson * policy as they might otherwise allow bypassing of the integrity policy. 1665168951Srwatson */ 1666107273Srwatsonstatic int 1667172955Srwatsonlomac_priv_check(struct ucred *cred, int priv) 1668168951Srwatson{ 1669168951Srwatson struct mac_lomac *subj; 1670168951Srwatson int error; 1671168951Srwatson 1672172955Srwatson if (!lomac_enabled) 1673168951Srwatson return (0); 1674168951Srwatson 1675168951Srwatson /* 1676168951Srwatson * Exempt only specific privileges from the LOMAC integrity policy. 1677168951Srwatson */ 1678168951Srwatson switch (priv) { 1679168951Srwatson case PRIV_KTRACE: 1680168951Srwatson case PRIV_MSGBUF: 1681168951Srwatson 1682168951Srwatson /* 1683168951Srwatson * Allow processes to manipulate basic process audit properties, and 1684168951Srwatson * to submit audit records. 1685168951Srwatson */ 1686168951Srwatson case PRIV_AUDIT_GETAUDIT: 1687168951Srwatson case PRIV_AUDIT_SETAUDIT: 1688168951Srwatson case PRIV_AUDIT_SUBMIT: 1689168951Srwatson 1690168951Srwatson /* 1691168951Srwatson * Allow processes to manipulate their regular UNIX credentials. 1692168951Srwatson */ 1693168951Srwatson case PRIV_CRED_SETUID: 1694168951Srwatson case PRIV_CRED_SETEUID: 1695168951Srwatson case PRIV_CRED_SETGID: 1696168951Srwatson case PRIV_CRED_SETEGID: 1697168951Srwatson case PRIV_CRED_SETGROUPS: 1698168951Srwatson case PRIV_CRED_SETREUID: 1699168951Srwatson case PRIV_CRED_SETREGID: 1700168951Srwatson case PRIV_CRED_SETRESUID: 1701168951Srwatson case PRIV_CRED_SETRESGID: 1702168951Srwatson 1703168951Srwatson /* 1704168951Srwatson * Allow processes to perform system monitoring. 1705168951Srwatson */ 1706168951Srwatson case PRIV_SEEOTHERGIDS: 1707168951Srwatson case PRIV_SEEOTHERUIDS: 1708168951Srwatson break; 1709168951Srwatson 1710168951Srwatson /* 1711168951Srwatson * Allow access to general process debugging facilities. We 1712168951Srwatson * separately control debugging based on MAC label. 1713168951Srwatson */ 1714168951Srwatson case PRIV_DEBUG_DIFFCRED: 1715168951Srwatson case PRIV_DEBUG_SUGID: 1716168951Srwatson case PRIV_DEBUG_UNPRIV: 1717168951Srwatson 1718168951Srwatson /* 1719168951Srwatson * Allow manipulating jails. 1720168951Srwatson */ 1721168951Srwatson case PRIV_JAIL_ATTACH: 1722168951Srwatson 1723168951Srwatson /* 1724168951Srwatson * Allow privilege with respect to the Partition policy, but not the 1725168951Srwatson * Privs policy. 1726168951Srwatson */ 1727168951Srwatson case PRIV_MAC_PARTITION: 1728168951Srwatson 1729168951Srwatson /* 1730168951Srwatson * Allow privilege with respect to process resource limits and login 1731168951Srwatson * context. 1732168951Srwatson */ 1733168951Srwatson case PRIV_PROC_LIMIT: 1734168951Srwatson case PRIV_PROC_SETLOGIN: 1735168951Srwatson case PRIV_PROC_SETRLIMIT: 1736168951Srwatson 1737168951Srwatson /* 1738168951Srwatson * Allow System V and POSIX IPC privileges. 1739168951Srwatson */ 1740168951Srwatson case PRIV_IPC_READ: 1741168951Srwatson case PRIV_IPC_WRITE: 1742168951Srwatson case PRIV_IPC_ADMIN: 1743168951Srwatson case PRIV_IPC_MSGSIZE: 1744168951Srwatson case PRIV_MQ_ADMIN: 1745168951Srwatson 1746168951Srwatson /* 1747168951Srwatson * Allow certain scheduler manipulations -- possibly this should be 1748168951Srwatson * controlled by more fine-grained policy, as potentially low 1749168951Srwatson * integrity processes can deny CPU to higher integrity ones. 1750168951Srwatson */ 1751168951Srwatson case PRIV_SCHED_DIFFCRED: 1752168951Srwatson case PRIV_SCHED_SETPRIORITY: 1753168951Srwatson case PRIV_SCHED_RTPRIO: 1754168951Srwatson case PRIV_SCHED_SETPOLICY: 1755168951Srwatson case PRIV_SCHED_SET: 1756168951Srwatson case PRIV_SCHED_SETPARAM: 1757168951Srwatson 1758168951Srwatson /* 1759168951Srwatson * More IPC privileges. 1760168951Srwatson */ 1761168951Srwatson case PRIV_SEM_WRITE: 1762168951Srwatson 1763168951Srwatson /* 1764168951Srwatson * Allow signaling privileges subject to integrity policy. 1765168951Srwatson */ 1766168951Srwatson case PRIV_SIGNAL_DIFFCRED: 1767168951Srwatson case PRIV_SIGNAL_SUGID: 1768168951Srwatson 1769168951Srwatson /* 1770168951Srwatson * Allow access to only limited sysctls from lower integrity levels; 1771168951Srwatson * piggy-back on the Jail definition. 1772168951Srwatson */ 1773168951Srwatson case PRIV_SYSCTL_WRITEJAIL: 1774168951Srwatson 1775168951Srwatson /* 1776168951Srwatson * Allow TTY-based privileges, subject to general device access using 1777168951Srwatson * labels on TTY device nodes, but not console privilege. 1778168951Srwatson */ 1779168951Srwatson case PRIV_TTY_DRAINWAIT: 1780168951Srwatson case PRIV_TTY_DTRWAIT: 1781168951Srwatson case PRIV_TTY_EXCLUSIVE: 1782168951Srwatson case PRIV_TTY_PRISON: 1783168951Srwatson case PRIV_TTY_STI: 1784168951Srwatson case PRIV_TTY_SETA: 1785168951Srwatson 1786168951Srwatson /* 1787168951Srwatson * Grant most VFS privileges, as almost all are in practice bounded 1788168951Srwatson * by more specific checks using labels. 1789168951Srwatson */ 1790168951Srwatson case PRIV_VFS_READ: 1791168951Srwatson case PRIV_VFS_WRITE: 1792168951Srwatson case PRIV_VFS_ADMIN: 1793168951Srwatson case PRIV_VFS_EXEC: 1794168951Srwatson case PRIV_VFS_LOOKUP: 1795168951Srwatson case PRIV_VFS_CHFLAGS_DEV: 1796168951Srwatson case PRIV_VFS_CHOWN: 1797168951Srwatson case PRIV_VFS_CHROOT: 1798168951Srwatson case PRIV_VFS_RETAINSUGID: 1799168951Srwatson case PRIV_VFS_EXCEEDQUOTA: 1800168951Srwatson case PRIV_VFS_FCHROOT: 1801168951Srwatson case PRIV_VFS_FHOPEN: 1802168951Srwatson case PRIV_VFS_FHSTATFS: 1803168951Srwatson case PRIV_VFS_GENERATION: 1804168951Srwatson case PRIV_VFS_GETFH: 1805168951Srwatson case PRIV_VFS_GETQUOTA: 1806168951Srwatson case PRIV_VFS_LINK: 1807168951Srwatson case PRIV_VFS_MOUNT: 1808168951Srwatson case PRIV_VFS_MOUNT_OWNER: 1809168951Srwatson case PRIV_VFS_MOUNT_PERM: 1810168951Srwatson case PRIV_VFS_MOUNT_SUIDDIR: 1811168951Srwatson case PRIV_VFS_MOUNT_NONUSER: 1812168951Srwatson case PRIV_VFS_SETGID: 1813168951Srwatson case PRIV_VFS_STICKYFILE: 1814168951Srwatson case PRIV_VFS_SYSFLAGS: 1815168951Srwatson case PRIV_VFS_UNMOUNT: 1816168951Srwatson 1817168951Srwatson /* 1818168951Srwatson * Allow VM privileges; it would be nice if these were subject to 1819168951Srwatson * resource limits. 1820168951Srwatson */ 1821168951Srwatson case PRIV_VM_MADV_PROTECT: 1822168951Srwatson case PRIV_VM_MLOCK: 1823168951Srwatson case PRIV_VM_MUNLOCK: 1824168951Srwatson 1825168951Srwatson /* 1826168951Srwatson * Allow some but not all network privileges. In general, dont allow 1827168951Srwatson * reconfiguring the network stack, just normal use. 1828168951Srwatson */ 1829168951Srwatson case PRIV_NETATALK_RESERVEDPORT: 1830168951Srwatson case PRIV_NETINET_RESERVEDPORT: 1831168951Srwatson case PRIV_NETINET_RAW: 1832168951Srwatson case PRIV_NETINET_REUSEPORT: 1833168951Srwatson case PRIV_NETIPX_RESERVEDPORT: 1834168951Srwatson case PRIV_NETIPX_RAW: 1835168951Srwatson break; 1836168951Srwatson 1837168951Srwatson /* 1838168951Srwatson * All remaining system privileges are allow only if the process 1839168951Srwatson * holds privilege with respect to the LOMAC policy. 1840168951Srwatson */ 1841168951Srwatson default: 1842168951Srwatson subj = SLOT(cred->cr_label); 1843172955Srwatson error = lomac_subject_privileged(subj); 1844168951Srwatson if (error) 1845168951Srwatson return (error); 1846168951Srwatson } 1847168951Srwatson return (0); 1848168951Srwatson} 1849168951Srwatson 1850173138Srwatsonstatic int 1851173138Srwatsonlomac_proc_check_debug(struct ucred *cred, struct proc *p) 1852173138Srwatson{ 1853173138Srwatson struct mac_lomac *subj, *obj; 1854168951Srwatson 1855173138Srwatson if (!lomac_enabled) 1856173138Srwatson return (0); 1857173138Srwatson 1858173138Srwatson subj = SLOT(cred->cr_label); 1859173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1860173138Srwatson 1861173138Srwatson /* XXX: range checks */ 1862173138Srwatson if (!lomac_dominate_single(obj, subj)) 1863173138Srwatson return (ESRCH); 1864173138Srwatson if (!lomac_subject_dominate(subj, obj)) 1865173138Srwatson return (EACCES); 1866173138Srwatson 1867173138Srwatson return (0); 1868173138Srwatson} 1869173138Srwatson 1870168951Srwatsonstatic int 1871173138Srwatsonlomac_proc_check_sched(struct ucred *cred, struct proc *p) 1872173138Srwatson{ 1873173138Srwatson struct mac_lomac *subj, *obj; 1874173138Srwatson 1875173138Srwatson if (!lomac_enabled) 1876173138Srwatson return (0); 1877173138Srwatson 1878173138Srwatson subj = SLOT(cred->cr_label); 1879173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1880173138Srwatson 1881173138Srwatson /* XXX: range checks */ 1882173138Srwatson if (!lomac_dominate_single(obj, subj)) 1883173138Srwatson return (ESRCH); 1884173138Srwatson if (!lomac_subject_dominate(subj, obj)) 1885173138Srwatson return (EACCES); 1886173138Srwatson 1887173138Srwatson return (0); 1888173138Srwatson} 1889173138Srwatson 1890173138Srwatsonstatic int 1891173138Srwatsonlomac_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1892173138Srwatson{ 1893173138Srwatson struct mac_lomac *subj, *obj; 1894173138Srwatson 1895173138Srwatson if (!lomac_enabled) 1896173138Srwatson return (0); 1897173138Srwatson 1898173138Srwatson subj = SLOT(cred->cr_label); 1899173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1900173138Srwatson 1901173138Srwatson /* XXX: range checks */ 1902173138Srwatson if (!lomac_dominate_single(obj, subj)) 1903173138Srwatson return (ESRCH); 1904173138Srwatson if (!lomac_subject_dominate(subj, obj)) 1905173138Srwatson return (EACCES); 1906173138Srwatson 1907173138Srwatson return (0); 1908173138Srwatson} 1909173138Srwatson 1910173138Srwatsonstatic void 1911173138Srwatsonlomac_proc_destroy_label(struct label *label) 1912173138Srwatson{ 1913173138Srwatson 1914173138Srwatson mtx_destroy(&PSLOT(label)->mtx); 1915184205Sdes free(PSLOT(label), M_LOMAC); 1916173138Srwatson PSLOT_SET(label, NULL); 1917173138Srwatson} 1918173138Srwatson 1919173138Srwatsonstatic void 1920173138Srwatsonlomac_proc_init_label(struct label *label) 1921173138Srwatson{ 1922173138Srwatson 1923173138Srwatson PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_LOMAC, 1924173138Srwatson M_ZERO | M_WAITOK)); 1925173138Srwatson mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF); 1926173138Srwatson} 1927173138Srwatson 1928173138Srwatsonstatic int 1929173138Srwatsonlomac_socket_check_deliver(struct socket *so, struct label *solabel, 1930173138Srwatson struct mbuf *m, struct label *mlabel) 1931173138Srwatson{ 1932173138Srwatson struct mac_lomac *p, *s; 1933173138Srwatson 1934173138Srwatson if (!lomac_enabled) 1935173138Srwatson return (0); 1936173138Srwatson 1937173138Srwatson p = SLOT(mlabel); 1938173138Srwatson s = SLOT(solabel); 1939173138Srwatson 1940173138Srwatson return (lomac_equal_single(p, s) ? 0 : EACCES); 1941173138Srwatson} 1942173138Srwatson 1943173138Srwatsonstatic int 1944173138Srwatsonlomac_socket_check_relabel(struct ucred *cred, struct socket *so, 1945173138Srwatson struct label *solabel, struct label *newlabel) 1946173138Srwatson{ 1947173138Srwatson struct mac_lomac *subj, *obj, *new; 1948173138Srwatson int error; 1949173138Srwatson 1950173138Srwatson new = SLOT(newlabel); 1951173138Srwatson subj = SLOT(cred->cr_label); 1952173138Srwatson obj = SLOT(solabel); 1953173138Srwatson 1954173138Srwatson /* 1955173138Srwatson * If there is a LOMAC label update for the socket, it may be an 1956173138Srwatson * update of single. 1957173138Srwatson */ 1958173138Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1959173138Srwatson if (error) 1960173138Srwatson return (error); 1961173138Srwatson 1962173138Srwatson /* 1963173138Srwatson * To relabel a socket, the old socket single must be in the subject 1964173138Srwatson * range. 1965173138Srwatson */ 1966173138Srwatson if (!lomac_single_in_range(obj, subj)) 1967173138Srwatson return (EPERM); 1968173138Srwatson 1969173138Srwatson /* 1970173138Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 1971173138Srwatson */ 1972173138Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1973173138Srwatson /* 1974173138Srwatson * To relabel a socket, the new socket single must be in the 1975173138Srwatson * subject range. 1976173138Srwatson */ 1977173138Srwatson if (!lomac_single_in_range(new, subj)) 1978173138Srwatson return (EPERM); 1979173138Srwatson 1980173138Srwatson /* 1981173138Srwatson * To change the LOMAC label on the socket to contain EQUAL, 1982173138Srwatson * the subject must have appropriate privilege. 1983173138Srwatson */ 1984173138Srwatson if (lomac_contains_equal(new)) { 1985173138Srwatson error = lomac_subject_privileged(subj); 1986173138Srwatson if (error) 1987173138Srwatson return (error); 1988173138Srwatson } 1989173138Srwatson } 1990173138Srwatson 1991173138Srwatson return (0); 1992173138Srwatson} 1993173138Srwatson 1994173138Srwatsonstatic int 1995173138Srwatsonlomac_socket_check_visible(struct ucred *cred, struct socket *so, 1996173138Srwatson struct label *solabel) 1997173138Srwatson{ 1998173138Srwatson struct mac_lomac *subj, *obj; 1999173138Srwatson 2000173138Srwatson if (!lomac_enabled) 2001173138Srwatson return (0); 2002173138Srwatson 2003173138Srwatson subj = SLOT(cred->cr_label); 2004173138Srwatson obj = SLOT(solabel); 2005173138Srwatson 2006173138Srwatson if (!lomac_dominate_single(obj, subj)) 2007173138Srwatson return (ENOENT); 2008173138Srwatson 2009173138Srwatson return (0); 2010173138Srwatson} 2011173138Srwatson 2012173138Srwatsonstatic void 2013173138Srwatsonlomac_socket_create(struct ucred *cred, struct socket *so, 2014173138Srwatson struct label *solabel) 2015173138Srwatson{ 2016173138Srwatson struct mac_lomac *source, *dest; 2017173138Srwatson 2018173138Srwatson source = SLOT(cred->cr_label); 2019173138Srwatson dest = SLOT(solabel); 2020173138Srwatson 2021173138Srwatson lomac_copy_single(source, dest); 2022173138Srwatson} 2023173138Srwatson 2024173138Srwatsonstatic void 2025173138Srwatsonlomac_socket_create_mbuf(struct socket *so, struct label *solabel, 2026173138Srwatson struct mbuf *m, struct label *mlabel) 2027173138Srwatson{ 2028173138Srwatson struct mac_lomac *source, *dest; 2029173138Srwatson 2030173138Srwatson source = SLOT(solabel); 2031173138Srwatson dest = SLOT(mlabel); 2032173138Srwatson 2033173138Srwatson lomac_copy_single(source, dest); 2034173138Srwatson} 2035173138Srwatson 2036173138Srwatsonstatic void 2037173138Srwatsonlomac_socket_newconn(struct socket *oldso, struct label *oldsolabel, 2038173138Srwatson struct socket *newso, struct label *newsolabel) 2039173138Srwatson{ 2040173138Srwatson struct mac_lomac *source, *dest; 2041173138Srwatson 2042173138Srwatson source = SLOT(oldsolabel); 2043173138Srwatson dest = SLOT(newsolabel); 2044173138Srwatson 2045173138Srwatson lomac_copy_single(source, dest); 2046173138Srwatson} 2047173138Srwatson 2048173138Srwatsonstatic void 2049173138Srwatsonlomac_socket_relabel(struct ucred *cred, struct socket *so, 2050173138Srwatson struct label *solabel, struct label *newlabel) 2051173138Srwatson{ 2052173138Srwatson struct mac_lomac *source, *dest; 2053173138Srwatson 2054173138Srwatson source = SLOT(newlabel); 2055173138Srwatson dest = SLOT(solabel); 2056173138Srwatson 2057173138Srwatson try_relabel(source, dest); 2058173138Srwatson} 2059173138Srwatson 2060173138Srwatsonstatic void 2061173138Srwatsonlomac_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 2062173138Srwatson struct socket *so, struct label *sopeerlabel) 2063173138Srwatson{ 2064173138Srwatson struct mac_lomac *source, *dest; 2065173138Srwatson 2066173138Srwatson source = SLOT(mlabel); 2067173138Srwatson dest = SLOT(sopeerlabel); 2068173138Srwatson 2069173138Srwatson lomac_copy_single(source, dest); 2070173138Srwatson} 2071173138Srwatson 2072173138Srwatsonstatic void 2073173138Srwatsonlomac_socketpeer_set_from_socket(struct socket *oldso, 2074173138Srwatson struct label *oldsolabel, struct socket *newso, 2075173138Srwatson struct label *newsopeerlabel) 2076173138Srwatson{ 2077173138Srwatson struct mac_lomac *source, *dest; 2078173138Srwatson 2079173138Srwatson source = SLOT(oldsolabel); 2080173138Srwatson dest = SLOT(newsopeerlabel); 2081173138Srwatson 2082173138Srwatson lomac_copy_single(source, dest); 2083173138Srwatson} 2084173138Srwatson 2085173138Srwatsonstatic void 2086173138Srwatsonlomac_syncache_create(struct label *label, struct inpcb *inp) 2087173138Srwatson{ 2088173138Srwatson struct mac_lomac *source, *dest; 2089173138Srwatson 2090173138Srwatson source = SLOT(inp->inp_label); 2091173138Srwatson dest = SLOT(label); 2092173138Srwatson lomac_copy(source, dest); 2093173138Srwatson} 2094173138Srwatson 2095173138Srwatsonstatic void 2096173138Srwatsonlomac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2097173138Srwatson struct label *mlabel) 2098173138Srwatson{ 2099173138Srwatson struct mac_lomac *source, *dest; 2100173138Srwatson 2101173138Srwatson source = SLOT(sc_label); 2102173138Srwatson dest = SLOT(mlabel); 2103173138Srwatson lomac_copy(source, dest); 2104173138Srwatson} 2105173138Srwatson 2106173138Srwatsonstatic int 2107172955Srwatsonlomac_system_check_acct(struct ucred *cred, struct vnode *vp, 2108168976Srwatson struct label *vplabel) 2109168933Srwatson{ 2110168933Srwatson struct mac_lomac *subj, *obj; 2111168933Srwatson 2112172955Srwatson if (!lomac_enabled) 2113168933Srwatson return (0); 2114168933Srwatson 2115168933Srwatson subj = SLOT(cred->cr_label); 2116168976Srwatson obj = SLOT(vplabel); 2117168933Srwatson 2118172955Srwatson if (lomac_subject_privileged(subj)) 2119168933Srwatson return (EPERM); 2120168933Srwatson 2121172955Srwatson if (!lomac_high_single(obj)) 2122168933Srwatson return (EACCES); 2123168933Srwatson 2124168933Srwatson return (0); 2125168933Srwatson} 2126168933Srwatson 2127168933Srwatsonstatic int 2128172955Srwatsonlomac_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2129168976Srwatson struct label *vplabel) 2130168933Srwatson{ 2131168933Srwatson struct mac_lomac *subj, *obj; 2132168933Srwatson 2133172955Srwatson if (!lomac_enabled) 2134168933Srwatson return (0); 2135168933Srwatson 2136168933Srwatson subj = SLOT(cred->cr_label); 2137168976Srwatson obj = SLOT(vplabel); 2138168933Srwatson 2139172955Srwatson if (lomac_subject_privileged(subj)) 2140168933Srwatson return (EPERM); 2141168933Srwatson 2142172955Srwatson if (!lomac_high_single(obj)) 2143168933Srwatson return (EACCES); 2144168933Srwatson 2145168933Srwatson return (0); 2146168933Srwatson} 2147168933Srwatson 2148168933Srwatsonstatic int 2149172955Srwatsonlomac_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2150168976Srwatson struct label *vplabel) 2151168933Srwatson{ 2152168933Srwatson struct mac_lomac *subj; 2153168933Srwatson 2154172955Srwatson if (!lomac_enabled) 2155168933Srwatson return (0); 2156168933Srwatson 2157168933Srwatson subj = SLOT(cred->cr_label); 2158168933Srwatson 2159172955Srwatson if (lomac_subject_privileged(subj)) 2160168933Srwatson return (EPERM); 2161168933Srwatson 2162168933Srwatson return (0); 2163168933Srwatson} 2164168933Srwatson 2165168933Srwatsonstatic int 2166172955Srwatsonlomac_system_check_swapon(struct ucred *cred, struct vnode *vp, 2167168976Srwatson struct label *vplabel) 2168107273Srwatson{ 2169107273Srwatson struct mac_lomac *subj, *obj; 2170107273Srwatson 2171172955Srwatson if (!lomac_enabled) 2172107273Srwatson return (0); 2173107273Srwatson 2174122524Srwatson subj = SLOT(cred->cr_label); 2175168976Srwatson obj = SLOT(vplabel); 2176107273Srwatson 2177172955Srwatson if (lomac_subject_privileged(subj)) 2178107273Srwatson return (EPERM); 2179107273Srwatson 2180172955Srwatson if (!lomac_high_single(obj)) 2181107273Srwatson return (EACCES); 2182107273Srwatson 2183107273Srwatson return (0); 2184107273Srwatson} 2185107273Srwatson 2186107273Srwatsonstatic int 2187172955Srwatsonlomac_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2188126121Spjd void *arg1, int arg2, struct sysctl_req *req) 2189107273Srwatson{ 2190107273Srwatson struct mac_lomac *subj; 2191107273Srwatson 2192172955Srwatson if (!lomac_enabled) 2193107273Srwatson return (0); 2194107273Srwatson 2195122524Srwatson subj = SLOT(cred->cr_label); 2196107273Srwatson 2197107273Srwatson /* 2198172955Srwatson * Treat sysctl variables without CTLFLAG_ANYBODY flag as lomac/high, 2199172955Srwatson * but also require privilege to change them. 2200107273Srwatson */ 2201126121Spjd if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2202107273Srwatson#ifdef notdef 2203172955Srwatson if (!lomac_subject_dominate_high(subj)) 2204107273Srwatson return (EACCES); 2205107273Srwatson#endif 2206107273Srwatson 2207172955Srwatson if (lomac_subject_privileged(subj)) 2208107273Srwatson return (EPERM); 2209107273Srwatson } 2210107273Srwatson 2211107273Srwatson return (0); 2212107273Srwatson} 2213107273Srwatson 2214173138Srwatsonstatic void 2215173138Srwatsonlomac_thread_userret(struct thread *td) 2216173138Srwatson{ 2217173138Srwatson struct proc *p = td->td_proc; 2218173138Srwatson struct mac_lomac_proc *subj = PSLOT(p->p_label); 2219173138Srwatson struct ucred *newcred, *oldcred; 2220173138Srwatson int dodrop; 2221173138Srwatson 2222173138Srwatson mtx_lock(&subj->mtx); 2223173138Srwatson if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 2224173138Srwatson dodrop = 0; 2225173138Srwatson mtx_unlock(&subj->mtx); 2226173138Srwatson newcred = crget(); 2227173138Srwatson /* 2228184412Srwatson * Prevent a lock order reversal in mac_proc_vm_revoke; 2229184412Srwatson * ideally, the other user of subj->mtx wouldn't be holding 2230184412Srwatson * Giant. 2231173138Srwatson */ 2232173138Srwatson mtx_lock(&Giant); 2233173138Srwatson PROC_LOCK(p); 2234173138Srwatson mtx_lock(&subj->mtx); 2235173138Srwatson /* 2236173138Srwatson * Check if we lost the race while allocating the cred. 2237173138Srwatson */ 2238173138Srwatson if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2239173138Srwatson crfree(newcred); 2240173138Srwatson goto out; 2241173138Srwatson } 2242173138Srwatson oldcred = p->p_ucred; 2243173138Srwatson crcopy(newcred, oldcred); 2244173138Srwatson crhold(newcred); 2245173138Srwatson lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2246173138Srwatson p->p_ucred = newcred; 2247173138Srwatson crfree(oldcred); 2248173138Srwatson dodrop = 1; 2249173138Srwatson out: 2250173138Srwatson mtx_unlock(&subj->mtx); 2251173138Srwatson PROC_UNLOCK(p); 2252173138Srwatson if (dodrop) 2253184412Srwatson mac_proc_vm_revoke(curthread); 2254173138Srwatson mtx_unlock(&Giant); 2255173138Srwatson } else { 2256173138Srwatson mtx_unlock(&subj->mtx); 2257173138Srwatson } 2258173138Srwatson} 2259173138Srwatson 2260107273Srwatsonstatic int 2261173138Srwatsonlomac_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2262173138Srwatson struct vnode *vp, struct label *vplabel) 2263173138Srwatson{ 2264173138Srwatson struct mac_lomac ml_temp, *source, *dest; 2265173138Srwatson int buflen, error; 2266173138Srwatson 2267173138Srwatson source = SLOT(mplabel); 2268173138Srwatson dest = SLOT(vplabel); 2269173138Srwatson 2270173138Srwatson buflen = sizeof(ml_temp); 2271173138Srwatson bzero(&ml_temp, buflen); 2272173138Srwatson 2273173138Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2274173138Srwatson MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&ml_temp, curthread); 2275173138Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 2276173138Srwatson /* Fall back to the mntlabel. */ 2277173138Srwatson lomac_copy_single(source, dest); 2278173138Srwatson return (0); 2279173138Srwatson } else if (error) 2280173138Srwatson return (error); 2281173138Srwatson 2282173138Srwatson if (buflen != sizeof(ml_temp)) { 2283173138Srwatson if (buflen != sizeof(ml_temp) - sizeof(ml_temp.ml_auxsingle)) { 2284173138Srwatson printf("lomac_vnode_associate_extattr: bad size %d\n", 2285173138Srwatson buflen); 2286173138Srwatson return (EPERM); 2287173138Srwatson } 2288173138Srwatson bzero(&ml_temp.ml_auxsingle, sizeof(ml_temp.ml_auxsingle)); 2289173138Srwatson buflen = sizeof(ml_temp); 2290173138Srwatson (void)vn_extattr_set(vp, IO_NODELOCKED, 2291173138Srwatson MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 2292173138Srwatson buflen, (char *)&ml_temp, curthread); 2293173138Srwatson } 2294173138Srwatson if (lomac_valid(&ml_temp) != 0) { 2295173138Srwatson printf("lomac_vnode_associate_extattr: invalid\n"); 2296173138Srwatson return (EPERM); 2297173138Srwatson } 2298173138Srwatson if ((ml_temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != 2299173138Srwatson MAC_LOMAC_FLAG_SINGLE) { 2300173138Srwatson printf("lomac_vnode_associate_extattr: not single\n"); 2301173138Srwatson return (EPERM); 2302173138Srwatson } 2303173138Srwatson 2304173138Srwatson lomac_copy_single(&ml_temp, dest); 2305173138Srwatson return (0); 2306173138Srwatson} 2307173138Srwatson 2308173138Srwatsonstatic void 2309173138Srwatsonlomac_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2310173138Srwatson struct vnode *vp, struct label *vplabel) 2311173138Srwatson{ 2312173138Srwatson struct mac_lomac *source, *dest; 2313173138Srwatson 2314173138Srwatson source = SLOT(mplabel); 2315173138Srwatson dest = SLOT(vplabel); 2316173138Srwatson 2317173138Srwatson lomac_copy_single(source, dest); 2318173138Srwatson} 2319173138Srwatson 2320173138Srwatsonstatic int 2321172955Srwatsonlomac_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2322168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2323107273Srwatson{ 2324107273Srwatson struct mac_lomac *subj, *obj; 2325107273Srwatson 2326172955Srwatson if (!lomac_enabled) 2327107273Srwatson return (0); 2328107273Srwatson 2329122524Srwatson subj = SLOT(cred->cr_label); 2330168976Srwatson obj = SLOT(dvplabel); 2331107273Srwatson 2332172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2333107273Srwatson return (EACCES); 2334107273Srwatson if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2335172955Srwatson !lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2336107273Srwatson return (EACCES); 2337107273Srwatson 2338107273Srwatson return (0); 2339107273Srwatson} 2340107273Srwatson 2341107273Srwatsonstatic int 2342172955Srwatsonlomac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2343168976Srwatson struct label *vplabel, acl_type_t type) 2344107273Srwatson{ 2345107273Srwatson struct mac_lomac *subj, *obj; 2346107273Srwatson 2347172955Srwatson if (!lomac_enabled) 2348107273Srwatson return (0); 2349107273Srwatson 2350122524Srwatson subj = SLOT(cred->cr_label); 2351168976Srwatson obj = SLOT(vplabel); 2352107273Srwatson 2353172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2354107273Srwatson return (EACCES); 2355107273Srwatson 2356107273Srwatson return (0); 2357107273Srwatson} 2358107273Srwatson 2359107273Srwatsonstatic int 2360172955Srwatsonlomac_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2361168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2362107273Srwatson struct componentname *cnp) 2363107273Srwatson{ 2364107273Srwatson struct mac_lomac *subj, *obj; 2365107273Srwatson 2366172955Srwatson if (!lomac_enabled) 2367107273Srwatson return (0); 2368107273Srwatson 2369122524Srwatson subj = SLOT(cred->cr_label); 2370168976Srwatson obj = SLOT(dvplabel); 2371107273Srwatson 2372172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2373107273Srwatson return (EACCES); 2374107273Srwatson 2375168976Srwatson obj = SLOT(vplabel); 2376107273Srwatson 2377172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2378107273Srwatson return (EACCES); 2379107273Srwatson 2380107273Srwatson return (0); 2381107273Srwatson} 2382107273Srwatson 2383107273Srwatsonstatic int 2384172955Srwatsonlomac_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2385168976Srwatson struct label *vplabel, int prot, int flags) 2386107273Srwatson{ 2387107273Srwatson struct mac_lomac *subj, *obj; 2388107273Srwatson 2389107273Srwatson /* 2390107273Srwatson * Rely on the use of open()-time protections to handle 2391107273Srwatson * non-revocation cases. 2392107273Srwatson */ 2393172955Srwatson if (!lomac_enabled) 2394107273Srwatson return (0); 2395107273Srwatson 2396122524Srwatson subj = SLOT(cred->cr_label); 2397168976Srwatson obj = SLOT(vplabel); 2398107273Srwatson 2399145076Scsjp if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2400172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2401107273Srwatson return (EACCES); 2402107273Srwatson } 2403107273Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2404172955Srwatson if (!lomac_dominate_single(obj, subj)) 2405107273Srwatson return (maybe_demote(subj, obj, "mapping", "file", vp)); 2406107273Srwatson } 2407107273Srwatson 2408107273Srwatson return (0); 2409107273Srwatson} 2410107273Srwatson 2411107273Srwatsonstatic void 2412172955Srwatsonlomac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp, 2413168976Srwatson struct label *vplabel, /* XXX vm_prot_t */ int *prot) 2414107273Srwatson{ 2415107273Srwatson struct mac_lomac *subj, *obj; 2416107273Srwatson 2417107273Srwatson /* 2418107273Srwatson * Rely on the use of open()-time protections to handle 2419107273Srwatson * non-revocation cases. 2420107273Srwatson */ 2421172955Srwatson if (!lomac_enabled || !revocation_enabled) 2422107273Srwatson return; 2423107273Srwatson 2424122524Srwatson subj = SLOT(cred->cr_label); 2425168976Srwatson obj = SLOT(vplabel); 2426107273Srwatson 2427172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2428107273Srwatson *prot &= ~VM_PROT_WRITE; 2429107273Srwatson} 2430107273Srwatson 2431107273Srwatsonstatic int 2432172955Srwatsonlomac_vnode_check_open(struct ucred *cred, struct vnode *vp, 2433184413Strasz struct label *vplabel, accmode_t accmode) 2434107273Srwatson{ 2435107273Srwatson struct mac_lomac *subj, *obj; 2436107273Srwatson 2437172955Srwatson if (!lomac_enabled) 2438107273Srwatson return (0); 2439107273Srwatson 2440122524Srwatson subj = SLOT(cred->cr_label); 2441168976Srwatson obj = SLOT(vplabel); 2442107273Srwatson 2443107273Srwatson /* XXX privilege override for admin? */ 2444184413Strasz if (accmode & (VWRITE | VAPPEND | VADMIN)) { 2445172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2446107273Srwatson return (EACCES); 2447107273Srwatson } 2448107273Srwatson 2449107273Srwatson return (0); 2450107273Srwatson} 2451107273Srwatson 2452107273Srwatsonstatic int 2453172955Srwatsonlomac_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2454168976Srwatson struct vnode *vp, struct label *vplabel) 2455107273Srwatson{ 2456107273Srwatson struct mac_lomac *subj, *obj; 2457107273Srwatson 2458172955Srwatson if (!lomac_enabled || !revocation_enabled) 2459107273Srwatson return (0); 2460107273Srwatson 2461122524Srwatson subj = SLOT(active_cred->cr_label); 2462168976Srwatson obj = SLOT(vplabel); 2463107273Srwatson 2464172955Srwatson if (!lomac_dominate_single(obj, subj)) 2465107273Srwatson return (maybe_demote(subj, obj, "reading", "file", vp)); 2466107273Srwatson 2467107273Srwatson return (0); 2468107273Srwatson} 2469107273Srwatson 2470107273Srwatsonstatic int 2471172955Srwatsonlomac_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2472168976Srwatson struct label *vplabel, struct label *newlabel) 2473107273Srwatson{ 2474107273Srwatson struct mac_lomac *old, *new, *subj; 2475107273Srwatson int error; 2476107273Srwatson 2477168976Srwatson old = SLOT(vplabel); 2478107273Srwatson new = SLOT(newlabel); 2479122524Srwatson subj = SLOT(cred->cr_label); 2480107273Srwatson 2481107273Srwatson /* 2482107273Srwatson * If there is a LOMAC label update for the vnode, it must be a 2483107273Srwatson * single label, with an optional explicit auxiliary single. 2484107273Srwatson */ 2485107273Srwatson error = lomac_atmostflags(new, 2486107273Srwatson MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2487107273Srwatson if (error) 2488107273Srwatson return (error); 2489107273Srwatson 2490107273Srwatson /* 2491107273Srwatson * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2492107273Srwatson * authorize the relabel. 2493107273Srwatson */ 2494172955Srwatson if (!lomac_single_in_range(old, subj)) 2495107273Srwatson return (EPERM); 2496107273Srwatson 2497107273Srwatson /* 2498107273Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 2499107273Srwatson */ 2500107273Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2501107273Srwatson /* 2502107273Srwatson * To change the LOMAC label on a vnode, the new vnode label 2503107273Srwatson * must be in the subject range. 2504107273Srwatson */ 2505172955Srwatson if (!lomac_single_in_range(new, subj)) 2506107273Srwatson return (EPERM); 2507107273Srwatson 2508107273Srwatson /* 2509172955Srwatson * To change the LOMAC label on the vnode to be EQUAL, the 2510172955Srwatson * subject must have appropriate privilege. 2511107273Srwatson */ 2512172955Srwatson if (lomac_contains_equal(new)) { 2513172955Srwatson error = lomac_subject_privileged(subj); 2514107273Srwatson if (error) 2515107273Srwatson return (error); 2516107273Srwatson } 2517107273Srwatson } 2518107273Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2519107273Srwatson /* 2520119242Srwatson * Fill in the missing parts from the previous label. 2521119242Srwatson */ 2522119242Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2523172955Srwatson lomac_copy_single(subj, new); 2524119242Srwatson 2525119242Srwatson /* 2526107273Srwatson * To change the auxiliary LOMAC label on a vnode, the new 2527107273Srwatson * vnode label must be in the subject range. 2528107273Srwatson */ 2529172955Srwatson if (!lomac_auxsingle_in_range(new, subj)) 2530107273Srwatson return (EPERM); 2531107273Srwatson 2532107273Srwatson /* 2533107273Srwatson * To change the auxiliary LOMAC label on the vnode to be 2534107273Srwatson * EQUAL, the subject must have appropriate privilege. 2535107273Srwatson */ 2536172955Srwatson if (lomac_contains_equal(new)) { 2537172955Srwatson error = lomac_subject_privileged(subj); 2538107273Srwatson if (error) 2539107273Srwatson return (error); 2540107273Srwatson } 2541107273Srwatson } 2542107273Srwatson 2543107273Srwatson return (0); 2544107273Srwatson} 2545107273Srwatson 2546107273Srwatsonstatic int 2547172955Srwatsonlomac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2548168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2549107273Srwatson struct componentname *cnp) 2550107273Srwatson{ 2551107273Srwatson struct mac_lomac *subj, *obj; 2552107273Srwatson 2553172955Srwatson if (!lomac_enabled) 2554107273Srwatson return (0); 2555107273Srwatson 2556122524Srwatson subj = SLOT(cred->cr_label); 2557168976Srwatson obj = SLOT(dvplabel); 2558107273Srwatson 2559172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2560107273Srwatson return (EACCES); 2561107273Srwatson 2562168976Srwatson obj = SLOT(vplabel); 2563107273Srwatson 2564172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2565107273Srwatson return (EACCES); 2566107273Srwatson 2567107273Srwatson return (0); 2568107273Srwatson} 2569107273Srwatson 2570107273Srwatsonstatic int 2571172955Srwatsonlomac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2572168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2573168976Srwatson int samedir, struct componentname *cnp) 2574107273Srwatson{ 2575107273Srwatson struct mac_lomac *subj, *obj; 2576107273Srwatson 2577172955Srwatson if (!lomac_enabled) 2578107273Srwatson return (0); 2579107273Srwatson 2580122524Srwatson subj = SLOT(cred->cr_label); 2581168976Srwatson obj = SLOT(dvplabel); 2582107273Srwatson 2583172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2584107273Srwatson return (EACCES); 2585107273Srwatson 2586107273Srwatson if (vp != NULL) { 2587168976Srwatson obj = SLOT(vplabel); 2588107273Srwatson 2589172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2590107273Srwatson return (EACCES); 2591107273Srwatson } 2592107273Srwatson 2593107273Srwatson return (0); 2594107273Srwatson} 2595107273Srwatson 2596107273Srwatsonstatic int 2597172955Srwatsonlomac_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2598168976Srwatson struct label *vplabel) 2599107273Srwatson{ 2600107273Srwatson struct mac_lomac *subj, *obj; 2601107273Srwatson 2602172955Srwatson if (!lomac_enabled) 2603107273Srwatson return (0); 2604107273Srwatson 2605122524Srwatson subj = SLOT(cred->cr_label); 2606168976Srwatson obj = SLOT(vplabel); 2607107273Srwatson 2608172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2609107273Srwatson return (EACCES); 2610107273Srwatson 2611107273Srwatson return (0); 2612107273Srwatson} 2613107273Srwatson 2614107273Srwatsonstatic int 2615172955Srwatsonlomac_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2616168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 2617107273Srwatson{ 2618107273Srwatson struct mac_lomac *subj, *obj; 2619107273Srwatson 2620172955Srwatson if (!lomac_enabled) 2621107273Srwatson return (0); 2622107273Srwatson 2623122524Srwatson subj = SLOT(cred->cr_label); 2624168976Srwatson obj = SLOT(vplabel); 2625107273Srwatson 2626172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2627107273Srwatson return (EACCES); 2628107273Srwatson 2629107273Srwatson return (0); 2630107273Srwatson} 2631107273Srwatson 2632107273Srwatsonstatic int 2633172955Srwatsonlomac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2634168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 2635107273Srwatson struct uio *uio) 2636107273Srwatson{ 2637107273Srwatson struct mac_lomac *subj, *obj; 2638107273Srwatson 2639172955Srwatson if (!lomac_enabled) 2640107273Srwatson return (0); 2641107273Srwatson 2642122524Srwatson subj = SLOT(cred->cr_label); 2643168976Srwatson obj = SLOT(vplabel); 2644107273Srwatson 2645172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2646107273Srwatson return (EACCES); 2647107273Srwatson 2648107273Srwatson /* XXX: protect the MAC EA in a special way? */ 2649107273Srwatson 2650107273Srwatson return (0); 2651107273Srwatson} 2652107273Srwatson 2653107273Srwatsonstatic int 2654172955Srwatsonlomac_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2655168976Srwatson struct label *vplabel, u_long flags) 2656107273Srwatson{ 2657107273Srwatson struct mac_lomac *subj, *obj; 2658107273Srwatson 2659172955Srwatson if (!lomac_enabled) 2660107273Srwatson return (0); 2661107273Srwatson 2662122524Srwatson subj = SLOT(cred->cr_label); 2663168976Srwatson obj = SLOT(vplabel); 2664107273Srwatson 2665172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2666107273Srwatson return (EACCES); 2667107273Srwatson 2668107273Srwatson return (0); 2669107273Srwatson} 2670107273Srwatson 2671107273Srwatsonstatic int 2672172955Srwatsonlomac_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 2673168976Srwatson struct label *vplabel, mode_t mode) 2674107273Srwatson{ 2675107273Srwatson struct mac_lomac *subj, *obj; 2676107273Srwatson 2677172955Srwatson if (!lomac_enabled) 2678107273Srwatson return (0); 2679107273Srwatson 2680122524Srwatson subj = SLOT(cred->cr_label); 2681168976Srwatson obj = SLOT(vplabel); 2682107273Srwatson 2683172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2684107273Srwatson return (EACCES); 2685107273Srwatson 2686107273Srwatson return (0); 2687107273Srwatson} 2688107273Srwatson 2689107273Srwatsonstatic int 2690172955Srwatsonlomac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 2691168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 2692107273Srwatson{ 2693107273Srwatson struct mac_lomac *subj, *obj; 2694107273Srwatson 2695172955Srwatson if (!lomac_enabled) 2696107273Srwatson return (0); 2697107273Srwatson 2698122524Srwatson subj = SLOT(cred->cr_label); 2699168976Srwatson obj = SLOT(vplabel); 2700107273Srwatson 2701172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2702107273Srwatson return (EACCES); 2703107273Srwatson 2704107273Srwatson return (0); 2705107273Srwatson} 2706107273Srwatson 2707107273Srwatsonstatic int 2708172955Srwatsonlomac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 2709168976Srwatson struct label *vplabel, struct timespec atime, struct timespec mtime) 2710107273Srwatson{ 2711107273Srwatson struct mac_lomac *subj, *obj; 2712107273Srwatson 2713172955Srwatson if (!lomac_enabled) 2714107273Srwatson return (0); 2715107273Srwatson 2716122524Srwatson subj = SLOT(cred->cr_label); 2717168976Srwatson obj = SLOT(vplabel); 2718107273Srwatson 2719172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2720107273Srwatson return (EACCES); 2721107273Srwatson 2722107273Srwatson return (0); 2723107273Srwatson} 2724107273Srwatson 2725107273Srwatsonstatic int 2726172955Srwatsonlomac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 2727172107Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2728172107Srwatson struct componentname *cnp) 2729172107Srwatson{ 2730172107Srwatson struct mac_lomac *subj, *obj; 2731172107Srwatson 2732172955Srwatson if (!lomac_enabled) 2733172107Srwatson return (0); 2734172107Srwatson 2735172107Srwatson subj = SLOT(cred->cr_label); 2736172107Srwatson obj = SLOT(dvplabel); 2737172107Srwatson 2738172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2739172107Srwatson return (EACCES); 2740172107Srwatson 2741172107Srwatson obj = SLOT(vplabel); 2742172107Srwatson 2743172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2744172107Srwatson return (EACCES); 2745172107Srwatson 2746172107Srwatson return (0); 2747172107Srwatson} 2748172107Srwatson 2749172107Srwatsonstatic int 2750172955Srwatsonlomac_vnode_check_write(struct ucred *active_cred, 2751168976Srwatson struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 2752107273Srwatson{ 2753107273Srwatson struct mac_lomac *subj, *obj; 2754107273Srwatson 2755172955Srwatson if (!lomac_enabled || !revocation_enabled) 2756107273Srwatson return (0); 2757107273Srwatson 2758122524Srwatson subj = SLOT(active_cred->cr_label); 2759168976Srwatson obj = SLOT(vplabel); 2760107273Srwatson 2761172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2762107273Srwatson return (EACCES); 2763107273Srwatson 2764107273Srwatson return (0); 2765107273Srwatson} 2766107273Srwatson 2767173138Srwatsonstatic int 2768173138Srwatsonlomac_vnode_create_extattr(struct ucred *cred, struct mount *mp, 2769173138Srwatson struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 2770173138Srwatson struct vnode *vp, struct label *vplabel, struct componentname *cnp) 2771107273Srwatson{ 2772173138Srwatson struct mac_lomac *source, *dest, *dir, temp; 2773173138Srwatson size_t buflen; 2774173138Srwatson int error; 2775107273Srwatson 2776173138Srwatson buflen = sizeof(temp); 2777173138Srwatson bzero(&temp, buflen); 2778173138Srwatson 2779173138Srwatson source = SLOT(cred->cr_label); 2780173138Srwatson dest = SLOT(vplabel); 2781173138Srwatson dir = SLOT(dvplabel); 2782173138Srwatson if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 2783173138Srwatson lomac_copy_auxsingle(dir, &temp); 2784173138Srwatson lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 2785173138Srwatson dir->ml_auxsingle.mle_grade); 2786107273Srwatson } else { 2787173138Srwatson lomac_copy_single(source, &temp); 2788107273Srwatson } 2789173138Srwatson 2790173138Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2791173138Srwatson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2792173138Srwatson if (error == 0) 2793173138Srwatson lomac_copy(&temp, dest); 2794173138Srwatson return (error); 2795107273Srwatson} 2796107273Srwatson 2797173138Srwatsonstatic void 2798173138Srwatsonlomac_vnode_execve_transition(struct ucred *old, struct ucred *new, 2799173138Srwatson struct vnode *vp, struct label *vplabel, struct label *interpvplabel, 2800173138Srwatson struct image_params *imgp, struct label *execlabel) 2801173138Srwatson{ 2802173138Srwatson struct mac_lomac *source, *dest, *obj, *robj; 2803173138Srwatson 2804173138Srwatson source = SLOT(old->cr_label); 2805173138Srwatson dest = SLOT(new->cr_label); 2806173138Srwatson obj = SLOT(vplabel); 2807173138Srwatson robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2808173138Srwatson 2809173138Srwatson lomac_copy(source, dest); 2810173138Srwatson /* 2811173138Srwatson * If there's an auxiliary label on the real object, respect it and 2812173138Srwatson * assume that this level should be assumed immediately if a higher 2813173138Srwatson * level is currently in place. 2814173138Srwatson */ 2815173138Srwatson if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2816173138Srwatson !lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 2817173138Srwatson && lomac_auxsingle_in_range(robj, dest)) 2818173138Srwatson lomac_set_single(dest, robj->ml_auxsingle.mle_type, 2819173138Srwatson robj->ml_auxsingle.mle_grade); 2820173138Srwatson /* 2821173138Srwatson * Restructuring to use the execve transitioning mechanism instead of 2822173138Srwatson * the normal demotion mechanism here would be difficult, so just 2823173138Srwatson * copy the label over and perform standard demotion. This is also 2824173138Srwatson * non-optimal because it will result in the intermediate label "new" 2825173138Srwatson * being created and immediately recycled. 2826173138Srwatson */ 2827173138Srwatson if (lomac_enabled && revocation_enabled && 2828173138Srwatson !lomac_dominate_single(obj, source)) 2829173138Srwatson (void)maybe_demote(source, obj, "executing", "file", vp); 2830173138Srwatson} 2831173138Srwatson 2832173138Srwatsonstatic int 2833173138Srwatsonlomac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp, 2834173138Srwatson struct label *vplabel, struct label *interpvplabel, 2835173138Srwatson struct image_params *imgp, struct label *execlabel) 2836173138Srwatson{ 2837173138Srwatson struct mac_lomac *subj, *obj, *robj; 2838173138Srwatson 2839173138Srwatson if (!lomac_enabled || !revocation_enabled) 2840173138Srwatson return (0); 2841173138Srwatson 2842173138Srwatson subj = SLOT(old->cr_label); 2843173138Srwatson obj = SLOT(vplabel); 2844173138Srwatson robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2845173138Srwatson 2846173138Srwatson return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2847173138Srwatson !lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 2848173138Srwatson && lomac_auxsingle_in_range(robj, subj)) || 2849173138Srwatson !lomac_dominate_single(obj, subj)); 2850173138Srwatson} 2851173138Srwatson 2852173138Srwatsonstatic void 2853173138Srwatsonlomac_vnode_relabel(struct ucred *cred, struct vnode *vp, 2854173138Srwatson struct label *vplabel, struct label *newlabel) 2855173138Srwatson{ 2856173138Srwatson struct mac_lomac *source, *dest; 2857173138Srwatson 2858173138Srwatson source = SLOT(newlabel); 2859173138Srwatson dest = SLOT(vplabel); 2860173138Srwatson 2861173138Srwatson try_relabel(source, dest); 2862173138Srwatson} 2863173138Srwatson 2864173138Srwatsonstatic int 2865173138Srwatsonlomac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 2866173138Srwatson struct label *vplabel, struct label *intlabel) 2867173138Srwatson{ 2868173138Srwatson struct mac_lomac *source, temp; 2869173138Srwatson size_t buflen; 2870173138Srwatson int error; 2871173138Srwatson 2872173138Srwatson buflen = sizeof(temp); 2873173138Srwatson bzero(&temp, buflen); 2874173138Srwatson 2875173138Srwatson source = SLOT(intlabel); 2876173138Srwatson if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2877173138Srwatson return (0); 2878173138Srwatson 2879173138Srwatson lomac_copy_single(source, &temp); 2880173138Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2881173138Srwatson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2882173138Srwatson return (error); 2883173138Srwatson} 2884173138Srwatson 2885172955Srwatsonstatic struct mac_policy_ops lomac_ops = 2886107273Srwatson{ 2887172955Srwatson .mpo_init = lomac_init, 2888173138Srwatson 2889173138Srwatson .mpo_bpfdesc_check_receive = lomac_bpfdesc_check_receive, 2890173138Srwatson .mpo_bpfdesc_create = lomac_bpfdesc_create, 2891173138Srwatson .mpo_bpfdesc_create_mbuf = lomac_bpfdesc_create_mbuf, 2892173138Srwatson .mpo_bpfdesc_destroy_label = lomac_destroy_label, 2893172955Srwatson .mpo_bpfdesc_init_label = lomac_init_label, 2894173138Srwatson 2895173138Srwatson .mpo_cred_check_relabel = lomac_cred_check_relabel, 2896173138Srwatson .mpo_cred_check_visible = lomac_cred_check_visible, 2897173138Srwatson .mpo_cred_copy_label = lomac_copy_label, 2898184407Srwatson .mpo_cred_create_swapper = lomac_cred_create_swapper, 2899184407Srwatson .mpo_cred_create_init = lomac_cred_create_init, 2900172955Srwatson .mpo_cred_destroy_label = lomac_destroy_label, 2901172955Srwatson .mpo_cred_externalize_label = lomac_externalize_label, 2902173138Srwatson .mpo_cred_init_label = lomac_init_label, 2903172955Srwatson .mpo_cred_internalize_label = lomac_internalize_label, 2904173138Srwatson .mpo_cred_relabel = lomac_cred_relabel, 2905173138Srwatson 2906172955Srwatson .mpo_devfs_create_device = lomac_devfs_create_device, 2907172955Srwatson .mpo_devfs_create_directory = lomac_devfs_create_directory, 2908172955Srwatson .mpo_devfs_create_symlink = lomac_devfs_create_symlink, 2909173138Srwatson .mpo_devfs_destroy_label = lomac_destroy_label, 2910173138Srwatson .mpo_devfs_init_label = lomac_init_label, 2911172955Srwatson .mpo_devfs_update = lomac_devfs_update, 2912172955Srwatson .mpo_devfs_vnode_associate = lomac_devfs_vnode_associate, 2913173138Srwatson 2914173138Srwatson .mpo_ifnet_check_relabel = lomac_ifnet_check_relabel, 2915173138Srwatson .mpo_ifnet_check_transmit = lomac_ifnet_check_transmit, 2916173138Srwatson .mpo_ifnet_copy_label = lomac_copy_label, 2917172955Srwatson .mpo_ifnet_create = lomac_ifnet_create, 2918173138Srwatson .mpo_ifnet_create_mbuf = lomac_ifnet_create_mbuf, 2919173138Srwatson .mpo_ifnet_destroy_label = lomac_destroy_label, 2920173138Srwatson .mpo_ifnet_externalize_label = lomac_externalize_label, 2921173138Srwatson .mpo_ifnet_init_label = lomac_init_label, 2922173138Srwatson .mpo_ifnet_internalize_label = lomac_internalize_label, 2923173138Srwatson .mpo_ifnet_relabel = lomac_ifnet_relabel, 2924173138Srwatson 2925173138Srwatson .mpo_syncache_create = lomac_syncache_create, 2926173138Srwatson .mpo_syncache_destroy_label = lomac_destroy_label, 2927173138Srwatson .mpo_syncache_init_label = lomac_init_label_waitcheck, 2928173138Srwatson 2929173138Srwatson .mpo_inpcb_check_deliver = lomac_inpcb_check_deliver, 2930183980Sbz .mpo_inpcb_check_visible = lomac_inpcb_check_visible, 2931172955Srwatson .mpo_inpcb_create = lomac_inpcb_create, 2932173138Srwatson .mpo_inpcb_create_mbuf = lomac_inpcb_create_mbuf, 2933173138Srwatson .mpo_inpcb_destroy_label = lomac_destroy_label, 2934173138Srwatson .mpo_inpcb_init_label = lomac_init_label_waitcheck, 2935173138Srwatson .mpo_inpcb_sosetlabel = lomac_inpcb_sosetlabel, 2936173138Srwatson 2937184308Srwatson .mpo_ip6q_create = lomac_ip6q_create, 2938184308Srwatson .mpo_ip6q_destroy_label = lomac_destroy_label, 2939184308Srwatson .mpo_ip6q_init_label = lomac_init_label_waitcheck, 2940184308Srwatson .mpo_ip6q_match = lomac_ip6q_match, 2941184308Srwatson .mpo_ip6q_reassemble = lomac_ip6q_reassemble, 2942184308Srwatson .mpo_ip6q_update = lomac_ip6q_update, 2943184308Srwatson 2944172955Srwatson .mpo_ipq_create = lomac_ipq_create, 2945173138Srwatson .mpo_ipq_destroy_label = lomac_destroy_label, 2946173138Srwatson .mpo_ipq_init_label = lomac_init_label_waitcheck, 2947172955Srwatson .mpo_ipq_match = lomac_ipq_match, 2948173138Srwatson .mpo_ipq_reassemble = lomac_ipq_reassemble, 2949172955Srwatson .mpo_ipq_update = lomac_ipq_update, 2950173138Srwatson 2951172955Srwatson .mpo_kld_check_load = lomac_kld_check_load, 2952173138Srwatson 2953173138Srwatson .mpo_mbuf_copy_label = lomac_copy_label, 2954173138Srwatson .mpo_mbuf_destroy_label = lomac_destroy_label, 2955173138Srwatson .mpo_mbuf_init_label = lomac_init_label_waitcheck, 2956173138Srwatson 2957173138Srwatson .mpo_mount_create = lomac_mount_create, 2958173138Srwatson .mpo_mount_destroy_label = lomac_destroy_label, 2959173138Srwatson .mpo_mount_init_label = lomac_init_label, 2960173138Srwatson 2961173138Srwatson .mpo_netatalk_aarp_send = lomac_netatalk_aarp_send, 2962173138Srwatson 2963173138Srwatson .mpo_netinet_arp_send = lomac_netinet_arp_send, 2964173138Srwatson .mpo_netinet_firewall_reply = lomac_netinet_firewall_reply, 2965173138Srwatson .mpo_netinet_firewall_send = lomac_netinet_firewall_send, 2966173138Srwatson .mpo_netinet_fragment = lomac_netinet_fragment, 2967173138Srwatson .mpo_netinet_icmp_reply = lomac_netinet_icmp_reply, 2968173138Srwatson .mpo_netinet_igmp_send = lomac_netinet_igmp_send, 2969173138Srwatson 2970173138Srwatson .mpo_netinet6_nd6_send = lomac_netinet6_nd6_send, 2971173138Srwatson 2972172955Srwatson .mpo_pipe_check_ioctl = lomac_pipe_check_ioctl, 2973172955Srwatson .mpo_pipe_check_read = lomac_pipe_check_read, 2974172955Srwatson .mpo_pipe_check_relabel = lomac_pipe_check_relabel, 2975172955Srwatson .mpo_pipe_check_write = lomac_pipe_check_write, 2976173138Srwatson .mpo_pipe_copy_label = lomac_copy_label, 2977173138Srwatson .mpo_pipe_create = lomac_pipe_create, 2978173138Srwatson .mpo_pipe_destroy_label = lomac_destroy_label, 2979173138Srwatson .mpo_pipe_externalize_label = lomac_externalize_label, 2980173138Srwatson .mpo_pipe_init_label = lomac_init_label, 2981173138Srwatson .mpo_pipe_internalize_label = lomac_internalize_label, 2982173138Srwatson .mpo_pipe_relabel = lomac_pipe_relabel, 2983173138Srwatson 2984173138Srwatson .mpo_priv_check = lomac_priv_check, 2985173138Srwatson 2986172955Srwatson .mpo_proc_check_debug = lomac_proc_check_debug, 2987172955Srwatson .mpo_proc_check_sched = lomac_proc_check_sched, 2988172955Srwatson .mpo_proc_check_signal = lomac_proc_check_signal, 2989173138Srwatson .mpo_proc_destroy_label = lomac_proc_destroy_label, 2990173138Srwatson .mpo_proc_init_label = lomac_proc_init_label, 2991173138Srwatson 2992172955Srwatson .mpo_socket_check_deliver = lomac_socket_check_deliver, 2993172955Srwatson .mpo_socket_check_relabel = lomac_socket_check_relabel, 2994172955Srwatson .mpo_socket_check_visible = lomac_socket_check_visible, 2995173138Srwatson .mpo_socket_copy_label = lomac_copy_label, 2996173138Srwatson .mpo_socket_create = lomac_socket_create, 2997173138Srwatson .mpo_socket_create_mbuf = lomac_socket_create_mbuf, 2998173138Srwatson .mpo_socket_destroy_label = lomac_destroy_label, 2999173138Srwatson .mpo_socket_externalize_label = lomac_externalize_label, 3000173138Srwatson .mpo_socket_init_label = lomac_init_label_waitcheck, 3001173138Srwatson .mpo_socket_internalize_label = lomac_internalize_label, 3002173138Srwatson .mpo_socket_newconn = lomac_socket_newconn, 3003173138Srwatson .mpo_socket_relabel = lomac_socket_relabel, 3004173138Srwatson 3005173138Srwatson .mpo_socketpeer_destroy_label = lomac_destroy_label, 3006173138Srwatson .mpo_socketpeer_externalize_label = lomac_externalize_label, 3007173138Srwatson .mpo_socketpeer_init_label = lomac_init_label_waitcheck, 3008173138Srwatson .mpo_socketpeer_set_from_mbuf = lomac_socketpeer_set_from_mbuf, 3009173138Srwatson .mpo_socketpeer_set_from_socket = lomac_socketpeer_set_from_socket, 3010173138Srwatson 3011173138Srwatson .mpo_syncache_create_mbuf = lomac_syncache_create_mbuf, 3012173138Srwatson 3013172955Srwatson .mpo_system_check_acct = lomac_system_check_acct, 3014172955Srwatson .mpo_system_check_auditctl = lomac_system_check_auditctl, 3015172955Srwatson .mpo_system_check_swapoff = lomac_system_check_swapoff, 3016172955Srwatson .mpo_system_check_swapon = lomac_system_check_swapon, 3017172955Srwatson .mpo_system_check_sysctl = lomac_system_check_sysctl, 3018173138Srwatson 3019173138Srwatson .mpo_thread_userret = lomac_thread_userret, 3020173138Srwatson 3021173138Srwatson .mpo_vnode_associate_extattr = lomac_vnode_associate_extattr, 3022173138Srwatson .mpo_vnode_associate_singlelabel = lomac_vnode_associate_singlelabel, 3023172955Srwatson .mpo_vnode_check_access = lomac_vnode_check_open, 3024172955Srwatson .mpo_vnode_check_create = lomac_vnode_check_create, 3025172955Srwatson .mpo_vnode_check_deleteacl = lomac_vnode_check_deleteacl, 3026172955Srwatson .mpo_vnode_check_link = lomac_vnode_check_link, 3027172955Srwatson .mpo_vnode_check_mmap = lomac_vnode_check_mmap, 3028172955Srwatson .mpo_vnode_check_mmap_downgrade = lomac_vnode_check_mmap_downgrade, 3029172955Srwatson .mpo_vnode_check_open = lomac_vnode_check_open, 3030172955Srwatson .mpo_vnode_check_read = lomac_vnode_check_read, 3031172955Srwatson .mpo_vnode_check_relabel = lomac_vnode_check_relabel, 3032172955Srwatson .mpo_vnode_check_rename_from = lomac_vnode_check_rename_from, 3033172955Srwatson .mpo_vnode_check_rename_to = lomac_vnode_check_rename_to, 3034172955Srwatson .mpo_vnode_check_revoke = lomac_vnode_check_revoke, 3035172955Srwatson .mpo_vnode_check_setacl = lomac_vnode_check_setacl, 3036172955Srwatson .mpo_vnode_check_setextattr = lomac_vnode_check_setextattr, 3037172955Srwatson .mpo_vnode_check_setflags = lomac_vnode_check_setflags, 3038172955Srwatson .mpo_vnode_check_setmode = lomac_vnode_check_setmode, 3039172955Srwatson .mpo_vnode_check_setowner = lomac_vnode_check_setowner, 3040172955Srwatson .mpo_vnode_check_setutimes = lomac_vnode_check_setutimes, 3041172955Srwatson .mpo_vnode_check_unlink = lomac_vnode_check_unlink, 3042172955Srwatson .mpo_vnode_check_write = lomac_vnode_check_write, 3043173138Srwatson .mpo_vnode_copy_label = lomac_copy_label, 3044173138Srwatson .mpo_vnode_create_extattr = lomac_vnode_create_extattr, 3045173138Srwatson .mpo_vnode_destroy_label = lomac_destroy_label, 3046173138Srwatson .mpo_vnode_execve_transition = lomac_vnode_execve_transition, 3047173138Srwatson .mpo_vnode_execve_will_transition = lomac_vnode_execve_will_transition, 3048173138Srwatson .mpo_vnode_externalize_label = lomac_externalize_label, 3049173138Srwatson .mpo_vnode_init_label = lomac_init_label, 3050173138Srwatson .mpo_vnode_internalize_label = lomac_internalize_label, 3051173138Srwatson .mpo_vnode_relabel = lomac_vnode_relabel, 3052173138Srwatson .mpo_vnode_setlabel_extattr = lomac_vnode_setlabel_extattr, 3053107273Srwatson}; 3054107273Srwatson 3055172955SrwatsonMAC_POLICY_SET(&lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC", 3056187016Srwatson MPC_LOADTIME_FLAG_NOTLATE, &lomac_slot); 3057