1107273Srwatson/*- 2193391Srwatson * Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson 3140879Srwatson * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 4172930Srwatson * Copyright (c) 2006 SPARTA, Inc. 5107273Srwatson * All rights reserved. 6107273Srwatson * 7107273Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 8107273Srwatson * 9107273Srwatson * This software was developed for the FreeBSD Project in part by NAI Labs, 10107273Srwatson * the Security Research Division of Network Associates, Inc. under 11107273Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 12107273Srwatson * CHATS research program. 13107273Srwatson * 14172930Srwatson * This software was enhanced by SPARTA ISSO under SPAWAR contract 15172930Srwatson * N66001-04-C-6019 ("SEFOS"). 16172930Srwatson * 17107273Srwatson * Redistribution and use in source and binary forms, with or without 18107273Srwatson * modification, are permitted provided that the following conditions 19107273Srwatson * are met: 20107273Srwatson * 1. Redistributions of source code must retain the above copyright 21107273Srwatson * notice, this list of conditions and the following disclaimer. 22107273Srwatson * 2. Redistributions in binary form must reproduce the above copyright 23107273Srwatson * notice, this list of conditions and the following disclaimer in the 24107273Srwatson * documentation and/or other materials provided with the distribution. 25107273Srwatson * 26107273Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27107273Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28107273Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29107273Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 30107273Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31107273Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32107273Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33107273Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34107273Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35107273Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36107273Srwatson * SUCH DAMAGE. 37107273Srwatson * 38107273Srwatson * $FreeBSD$ 39107273Srwatson */ 40107273Srwatson 41107273Srwatson/* 42107273Srwatson * Developed by the TrustedBSD Project. 43168951Srwatson * 44107273Srwatson * Low-watermark floating label mandatory integrity policy. 45107273Srwatson */ 46107273Srwatson 47107273Srwatson#include <sys/types.h> 48107273Srwatson#include <sys/param.h> 49107273Srwatson#include <sys/acl.h> 50107273Srwatson#include <sys/conf.h> 51107273Srwatson#include <sys/extattr.h> 52107273Srwatson#include <sys/kernel.h> 53107273Srwatson#include <sys/malloc.h> 54145076Scsjp#include <sys/mman.h> 55107273Srwatson#include <sys/mount.h> 56164033Srwatson#include <sys/priv.h> 57107273Srwatson#include <sys/proc.h> 58116701Srwatson#include <sys/sbuf.h> 59107273Srwatson#include <sys/systm.h> 60107273Srwatson#include <sys/sysproto.h> 61107273Srwatson#include <sys/sysent.h> 62107273Srwatson#include <sys/systm.h> 63107273Srwatson#include <sys/vnode.h> 64107273Srwatson#include <sys/file.h> 65107273Srwatson#include <sys/socket.h> 66107273Srwatson#include <sys/socketvar.h> 67150340Sphk#include <sys/sx.h> 68107273Srwatson#include <sys/pipe.h> 69107273Srwatson#include <sys/sysctl.h> 70107273Srwatson#include <sys/syslog.h> 71107273Srwatson 72107273Srwatson#include <fs/devfs/devfs.h> 73107273Srwatson 74107273Srwatson#include <net/bpfdesc.h> 75107273Srwatson#include <net/if.h> 76107273Srwatson#include <net/if_types.h> 77107273Srwatson#include <net/if_var.h> 78107273Srwatson 79107273Srwatson#include <netinet/in.h> 80122875Srwatson#include <netinet/in_pcb.h> 81107273Srwatson#include <netinet/ip_var.h> 82107273Srwatson 83107273Srwatson#include <vm/vm.h> 84107273Srwatson 85165469Srwatson#include <security/mac/mac_policy.h> 86163606Srwatson#include <security/mac/mac_framework.h> 87107273Srwatson#include <security/mac_lomac/mac_lomac.h> 88107273Srwatson 89107273Srwatsonstruct mac_lomac_proc { 90107273Srwatson struct mac_lomac mac_lomac; 91107273Srwatson struct mtx mtx; 92107273Srwatson}; 93107273Srwatson 94107273SrwatsonSYSCTL_DECL(_security_mac); 95107273Srwatson 96227309Sedstatic SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0, 97107273Srwatson "TrustedBSD mac_lomac policy controls"); 98107273Srwatson 99172955Srwatsonstatic int lomac_label_size = sizeof(struct mac_lomac); 100107273SrwatsonSYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD, 101172955Srwatson &lomac_label_size, 0, "Size of struct mac_lomac"); 102107273Srwatson 103172955Srwatsonstatic int lomac_enabled = 1; 104267992ShselaskySYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RWTUN, 105172955Srwatson &lomac_enabled, 0, "Enforce MAC/LOMAC policy"); 106107273Srwatson 107107273Srwatsonstatic int destroyed_not_inited; 108107273SrwatsonSYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 109107273Srwatson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 110107273Srwatson 111107273Srwatsonstatic int trust_all_interfaces = 0; 112267992ShselaskySYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RDTUN, 113107273Srwatson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC"); 114107273Srwatson 115107273Srwatsonstatic char trusted_interfaces[128]; 116267992ShselaskySYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RDTUN, 117107273Srwatson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC"); 118107273Srwatson 119107273Srwatsonstatic int ptys_equal = 0; 120267992ShselaskySYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RWTUN, 121107273Srwatson &ptys_equal, 0, "Label pty devices as lomac/equal on create"); 122107273Srwatson 123107273Srwatsonstatic int revocation_enabled = 1; 124267992ShselaskySYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RWTUN, 125107273Srwatson &revocation_enabled, 0, "Revoke access to objects on relabel"); 126107273Srwatson 127172955Srwatsonstatic int lomac_slot; 128172955Srwatson#define SLOT(l) ((struct mac_lomac *)mac_label_get((l), lomac_slot)) 129172955Srwatson#define SLOT_SET(l, val) mac_label_set((l), lomac_slot, (uintptr_t)(val)) 130107273Srwatson#define PSLOT(l) ((struct mac_lomac_proc *) \ 131172955Srwatson mac_label_get((l), lomac_slot)) 132172955Srwatson#define PSLOT_SET(l, val) mac_label_set((l), lomac_slot, (uintptr_t)(val)) 133107273Srwatson 134227293Sedstatic MALLOC_DEFINE(M_LOMAC, "mac_lomac_label", "MAC/LOMAC labels"); 135107273Srwatson 136107273Srwatsonstatic struct mac_lomac * 137107273Srwatsonlomac_alloc(int flag) 138107273Srwatson{ 139172955Srwatson struct mac_lomac *ml; 140107273Srwatson 141172955Srwatson ml = malloc(sizeof(*ml), M_LOMAC, M_ZERO | flag); 142107273Srwatson 143172955Srwatson return (ml); 144107273Srwatson} 145107273Srwatson 146107273Srwatsonstatic void 147172955Srwatsonlomac_free(struct mac_lomac *ml) 148107273Srwatson{ 149107273Srwatson 150172955Srwatson if (ml != NULL) 151172955Srwatson free(ml, M_LOMAC); 152107273Srwatson else 153107273Srwatson atomic_add_int(&destroyed_not_inited, 1); 154107273Srwatson} 155107273Srwatson 156107273Srwatsonstatic int 157172955Srwatsonlomac_atmostflags(struct mac_lomac *ml, int flags) 158107273Srwatson{ 159107273Srwatson 160172955Srwatson if ((ml->ml_flags & flags) != ml->ml_flags) 161107273Srwatson return (EINVAL); 162107273Srwatson return (0); 163107273Srwatson} 164107273Srwatson 165107273Srwatsonstatic int 166172955Srwatsonlomac_dominate_element(struct mac_lomac_element *a, 167107273Srwatson struct mac_lomac_element *b) 168107273Srwatson{ 169107273Srwatson 170107273Srwatson switch (a->mle_type) { 171107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 172107273Srwatson case MAC_LOMAC_TYPE_HIGH: 173107273Srwatson return (1); 174107273Srwatson 175107273Srwatson case MAC_LOMAC_TYPE_LOW: 176107273Srwatson switch (b->mle_type) { 177107273Srwatson case MAC_LOMAC_TYPE_GRADE: 178107273Srwatson case MAC_LOMAC_TYPE_HIGH: 179107273Srwatson return (0); 180107273Srwatson 181107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 182107273Srwatson case MAC_LOMAC_TYPE_LOW: 183107273Srwatson return (1); 184107273Srwatson 185107273Srwatson default: 186172955Srwatson panic("lomac_dominate_element: b->mle_type invalid"); 187107273Srwatson } 188107273Srwatson 189107273Srwatson case MAC_LOMAC_TYPE_GRADE: 190107273Srwatson switch (b->mle_type) { 191107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 192107273Srwatson case MAC_LOMAC_TYPE_LOW: 193107273Srwatson return (1); 194107273Srwatson 195107273Srwatson case MAC_LOMAC_TYPE_HIGH: 196107273Srwatson return (0); 197107273Srwatson 198107273Srwatson case MAC_LOMAC_TYPE_GRADE: 199107273Srwatson return (a->mle_grade >= b->mle_grade); 200107273Srwatson 201107273Srwatson default: 202172955Srwatson panic("lomac_dominate_element: b->mle_type invalid"); 203107273Srwatson } 204107273Srwatson 205107273Srwatson default: 206172955Srwatson panic("lomac_dominate_element: a->mle_type invalid"); 207107273Srwatson } 208107273Srwatson} 209107273Srwatson 210107273Srwatsonstatic int 211172955Srwatsonlomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb) 212107273Srwatson{ 213107273Srwatson 214172955Srwatson return (lomac_dominate_element(&rangeb->ml_rangehigh, 215107273Srwatson &rangea->ml_rangehigh) && 216172955Srwatson lomac_dominate_element(&rangea->ml_rangelow, 217107273Srwatson &rangeb->ml_rangelow)); 218107273Srwatson} 219107273Srwatson 220107273Srwatsonstatic int 221172955Srwatsonlomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range) 222107273Srwatson{ 223107273Srwatson 224107273Srwatson KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 225172955Srwatson ("lomac_single_in_range: a not single")); 226107273Srwatson KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 227172955Srwatson ("lomac_single_in_range: b not range")); 228107273Srwatson 229172955Srwatson return (lomac_dominate_element(&range->ml_rangehigh, 230172955Srwatson &single->ml_single) && lomac_dominate_element(&single->ml_single, 231107273Srwatson &range->ml_rangelow)); 232107273Srwatson} 233107273Srwatson 234107273Srwatsonstatic int 235172955Srwatsonlomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range) 236107273Srwatson{ 237107273Srwatson 238107273Srwatson KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 239172955Srwatson ("lomac_single_in_range: a not auxsingle")); 240107273Srwatson KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 241172955Srwatson ("lomac_single_in_range: b not range")); 242107273Srwatson 243172955Srwatson return (lomac_dominate_element(&range->ml_rangehigh, 244107273Srwatson &single->ml_auxsingle) && 245172955Srwatson lomac_dominate_element(&single->ml_auxsingle, 246107273Srwatson &range->ml_rangelow)); 247107273Srwatson} 248107273Srwatson 249107273Srwatsonstatic int 250172955Srwatsonlomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b) 251107273Srwatson{ 252107273Srwatson KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 253172955Srwatson ("lomac_dominate_single: a not single")); 254107273Srwatson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 255172955Srwatson ("lomac_dominate_single: b not single")); 256107273Srwatson 257172955Srwatson return (lomac_dominate_element(&a->ml_single, &b->ml_single)); 258107273Srwatson} 259107273Srwatson 260107273Srwatsonstatic int 261172955Srwatsonlomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b) 262107273Srwatson{ 263107273Srwatson KASSERT((~a->ml_flags & 264107273Srwatson (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0, 265172955Srwatson ("lomac_dominate_single: a not subject")); 266107273Srwatson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 267172955Srwatson ("lomac_dominate_single: b not single")); 268107273Srwatson 269172955Srwatson return (lomac_dominate_element(&a->ml_rangehigh, &b->ml_single)); 270107273Srwatson} 271107273Srwatson 272107273Srwatsonstatic int 273172955Srwatsonlomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b) 274107273Srwatson{ 275107273Srwatson 276107273Srwatson if (a->mle_type == MAC_LOMAC_TYPE_EQUAL || 277107273Srwatson b->mle_type == MAC_LOMAC_TYPE_EQUAL) 278107273Srwatson return (1); 279107273Srwatson 280107273Srwatson return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade); 281107273Srwatson} 282107273Srwatson 283107273Srwatsonstatic int 284172955Srwatsonlomac_equal_single(struct mac_lomac *a, struct mac_lomac *b) 285107273Srwatson{ 286107273Srwatson 287107273Srwatson KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 288172955Srwatson ("lomac_equal_single: a not single")); 289107273Srwatson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 290172955Srwatson ("lomac_equal_single: b not single")); 291107273Srwatson 292172955Srwatson return (lomac_equal_element(&a->ml_single, &b->ml_single)); 293107273Srwatson} 294107273Srwatson 295107273Srwatsonstatic int 296172955Srwatsonlomac_contains_equal(struct mac_lomac *ml) 297107273Srwatson{ 298107273Srwatson 299172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) 300172955Srwatson if (ml->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 301107273Srwatson return (1); 302172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) 303172955Srwatson if (ml->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL) 304107273Srwatson return (1); 305107273Srwatson 306172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) { 307172955Srwatson if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL) 308107273Srwatson return (1); 309172955Srwatson if (ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 310107273Srwatson return (1); 311107273Srwatson } 312107273Srwatson 313107273Srwatson return (0); 314107273Srwatson} 315107273Srwatson 316107273Srwatsonstatic int 317172955Srwatsonlomac_subject_privileged(struct mac_lomac *ml) 318107273Srwatson{ 319107273Srwatson 320172955Srwatson KASSERT((ml->ml_flags & MAC_LOMAC_FLAGS_BOTH) == 321107273Srwatson MAC_LOMAC_FLAGS_BOTH, 322172955Srwatson ("lomac_subject_privileged: subject doesn't have both labels")); 323107273Srwatson 324107273Srwatson /* If the single is EQUAL, it's ok. */ 325172955Srwatson if (ml->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 326107273Srwatson return (0); 327107273Srwatson 328107273Srwatson /* If either range endpoint is EQUAL, it's ok. */ 329172955Srwatson if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL || 330172955Srwatson ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 331107273Srwatson return (0); 332107273Srwatson 333107273Srwatson /* If the range is low-high, it's ok. */ 334172955Srwatson if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW && 335172955Srwatson ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH) 336107273Srwatson return (0); 337107273Srwatson 338107273Srwatson /* It's not ok. */ 339107273Srwatson return (EPERM); 340107273Srwatson} 341107273Srwatson 342107273Srwatsonstatic int 343172955Srwatsonlomac_high_single(struct mac_lomac *ml) 344107273Srwatson{ 345107273Srwatson 346172955Srwatson KASSERT((ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 347172955Srwatson ("lomac_high_single: mac_lomac not single")); 348117247Srwatson 349172955Srwatson return (ml->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH); 350107273Srwatson} 351107273Srwatson 352107273Srwatsonstatic int 353172955Srwatsonlomac_valid(struct mac_lomac *ml) 354107273Srwatson{ 355107273Srwatson 356172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 357172955Srwatson switch (ml->ml_single.mle_type) { 358107273Srwatson case MAC_LOMAC_TYPE_GRADE: 359107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 360107273Srwatson case MAC_LOMAC_TYPE_HIGH: 361107273Srwatson case MAC_LOMAC_TYPE_LOW: 362107273Srwatson break; 363107273Srwatson 364107273Srwatson default: 365107273Srwatson return (EINVAL); 366107273Srwatson } 367107273Srwatson } else { 368172955Srwatson if (ml->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF) 369107273Srwatson return (EINVAL); 370107273Srwatson } 371107273Srwatson 372172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) { 373172955Srwatson switch (ml->ml_auxsingle.mle_type) { 374107273Srwatson case MAC_LOMAC_TYPE_GRADE: 375107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 376107273Srwatson case MAC_LOMAC_TYPE_HIGH: 377107273Srwatson case MAC_LOMAC_TYPE_LOW: 378107273Srwatson break; 379107273Srwatson 380107273Srwatson default: 381107273Srwatson return (EINVAL); 382107273Srwatson } 383107273Srwatson } else { 384172955Srwatson if (ml->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF) 385107273Srwatson return (EINVAL); 386107273Srwatson } 387107273Srwatson 388172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) { 389172955Srwatson switch (ml->ml_rangelow.mle_type) { 390107273Srwatson case MAC_LOMAC_TYPE_GRADE: 391107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 392107273Srwatson case MAC_LOMAC_TYPE_HIGH: 393107273Srwatson case MAC_LOMAC_TYPE_LOW: 394107273Srwatson break; 395107273Srwatson 396107273Srwatson default: 397107273Srwatson return (EINVAL); 398107273Srwatson } 399107273Srwatson 400172955Srwatson switch (ml->ml_rangehigh.mle_type) { 401107273Srwatson case MAC_LOMAC_TYPE_GRADE: 402107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 403107273Srwatson case MAC_LOMAC_TYPE_HIGH: 404107273Srwatson case MAC_LOMAC_TYPE_LOW: 405107273Srwatson break; 406107273Srwatson 407107273Srwatson default: 408107273Srwatson return (EINVAL); 409107273Srwatson } 410172955Srwatson if (!lomac_dominate_element(&ml->ml_rangehigh, 411172955Srwatson &ml->ml_rangelow)) 412107273Srwatson return (EINVAL); 413107273Srwatson } else { 414172955Srwatson if (ml->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF || 415172955Srwatson ml->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF) 416107273Srwatson return (EINVAL); 417107273Srwatson } 418107273Srwatson 419107273Srwatson return (0); 420107273Srwatson} 421107273Srwatson 422107273Srwatsonstatic void 423172955Srwatsonlomac_set_range(struct mac_lomac *ml, u_short typelow, u_short gradelow, 424172955Srwatson u_short typehigh, u_short gradehigh) 425107273Srwatson{ 426107273Srwatson 427172955Srwatson ml->ml_rangelow.mle_type = typelow; 428172955Srwatson ml->ml_rangelow.mle_grade = gradelow; 429172955Srwatson ml->ml_rangehigh.mle_type = typehigh; 430172955Srwatson ml->ml_rangehigh.mle_grade = gradehigh; 431172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_RANGE; 432107273Srwatson} 433107273Srwatson 434107273Srwatsonstatic void 435172955Srwatsonlomac_set_single(struct mac_lomac *ml, u_short type, u_short grade) 436107273Srwatson{ 437107273Srwatson 438172955Srwatson ml->ml_single.mle_type = type; 439172955Srwatson ml->ml_single.mle_grade = grade; 440172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 441107273Srwatson} 442107273Srwatson 443107273Srwatsonstatic void 444172955Srwatsonlomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 445107273Srwatson{ 446107273Srwatson 447107273Srwatson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 448172955Srwatson ("lomac_copy_range: labelfrom not range")); 449107273Srwatson 450107273Srwatson labelto->ml_rangelow = labelfrom->ml_rangelow; 451107273Srwatson labelto->ml_rangehigh = labelfrom->ml_rangehigh; 452107273Srwatson labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE; 453107273Srwatson} 454107273Srwatson 455107273Srwatsonstatic void 456172955Srwatsonlomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 457107273Srwatson{ 458107273Srwatson 459107273Srwatson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 460172955Srwatson ("lomac_copy_single: labelfrom not single")); 461107273Srwatson 462107273Srwatson labelto->ml_single = labelfrom->ml_single; 463107273Srwatson labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 464107273Srwatson} 465107273Srwatson 466107273Srwatsonstatic void 467172955Srwatsonlomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 468107273Srwatson{ 469107273Srwatson 470107273Srwatson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 471172955Srwatson ("lomac_copy_auxsingle: labelfrom not auxsingle")); 472107273Srwatson 473107273Srwatson labelto->ml_auxsingle = labelfrom->ml_auxsingle; 474107273Srwatson labelto->ml_flags |= MAC_LOMAC_FLAG_AUX; 475107273Srwatson} 476107273Srwatson 477107273Srwatsonstatic void 478172955Srwatsonlomac_copy(struct mac_lomac *source, struct mac_lomac *dest) 479107273Srwatson{ 480107273Srwatson 481107273Srwatson if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE) 482172955Srwatson lomac_copy_single(source, dest); 483107273Srwatson if (source->ml_flags & MAC_LOMAC_FLAG_AUX) 484172955Srwatson lomac_copy_auxsingle(source, dest); 485107273Srwatson if (source->ml_flags & MAC_LOMAC_FLAG_RANGE) 486172955Srwatson lomac_copy_range(source, dest); 487107273Srwatson} 488107273Srwatson 489172955Srwatsonstatic int lomac_to_string(struct sbuf *sb, struct mac_lomac *ml); 490107273Srwatson 491107273Srwatsonstatic int 492107273Srwatsonmaybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 493168976Srwatson const char *actionname, const char *objname, struct vnode *vp) 494107273Srwatson{ 495116701Srwatson struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb; 496116701Srwatson char *subjlabeltext, *objlabeltext, *subjtext; 497116701Srwatson struct mac_lomac cached_subjlabel; 498116701Srwatson struct mac_lomac_proc *subj; 499107273Srwatson struct vattr va; 500107273Srwatson struct proc *p; 501107273Srwatson pid_t pgid; 502107273Srwatson 503122524Srwatson subj = PSLOT(curthread->td_proc->p_label); 504116701Srwatson 505107273Srwatson p = curthread->td_proc; 506107273Srwatson mtx_lock(&subj->mtx); 507107273Srwatson if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 508107273Srwatson /* 509172955Srwatson * Check to see if the pending demotion would be more or less 510172955Srwatson * severe than this one, and keep the more severe. This can 511172955Srwatson * only happen for a multi-threaded application. 512107273Srwatson */ 513172955Srwatson if (lomac_dominate_single(objlabel, &subj->mac_lomac)) { 514107273Srwatson mtx_unlock(&subj->mtx); 515107273Srwatson return (0); 516107273Srwatson } 517107273Srwatson } 518107273Srwatson bzero(&subj->mac_lomac, sizeof(subj->mac_lomac)); 519107273Srwatson /* 520107273Srwatson * Always demote the single label. 521107273Srwatson */ 522172955Srwatson lomac_copy_single(objlabel, &subj->mac_lomac); 523107273Srwatson /* 524172955Srwatson * Start with the original range, then minimize each side of the 525172955Srwatson * range to the point of not dominating the object. The high side 526172955Srwatson * will always be demoted, of course. 527107273Srwatson */ 528172955Srwatson lomac_copy_range(subjlabel, &subj->mac_lomac); 529172955Srwatson if (!lomac_dominate_element(&objlabel->ml_single, 530107273Srwatson &subj->mac_lomac.ml_rangelow)) 531107273Srwatson subj->mac_lomac.ml_rangelow = objlabel->ml_single; 532107273Srwatson subj->mac_lomac.ml_rangehigh = objlabel->ml_single; 533107273Srwatson subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE; 534170307Sjeff thread_lock(curthread); 535172207Sjeff curthread->td_flags |= TDF_ASTPENDING | TDF_MACPEND; 536170307Sjeff thread_unlock(curthread); 537116701Srwatson 538116701Srwatson /* 539172955Srwatson * Avoid memory allocation while holding a mutex; cache the label. 540116701Srwatson */ 541172955Srwatson lomac_copy_single(&subj->mac_lomac, &cached_subjlabel); 542107273Srwatson mtx_unlock(&subj->mtx); 543116701Srwatson 544116701Srwatson sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 545172955Srwatson lomac_to_string(&subjlabel_sb, subjlabel); 546116701Srwatson sbuf_finish(&subjlabel_sb); 547116701Srwatson subjlabeltext = sbuf_data(&subjlabel_sb); 548116701Srwatson 549116701Srwatson sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND); 550172955Srwatson lomac_to_string(&subjtext_sb, &subj->mac_lomac); 551116701Srwatson sbuf_finish(&subjtext_sb); 552116701Srwatson subjtext = sbuf_data(&subjtext_sb); 553116701Srwatson 554116701Srwatson sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 555172955Srwatson lomac_to_string(&objlabel_sb, objlabel); 556116701Srwatson sbuf_finish(&objlabel_sb); 557116701Srwatson objlabeltext = sbuf_data(&objlabel_sb); 558116701Srwatson 559107273Srwatson pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ 560182371Sattilio if (vp != NULL && VOP_GETATTR(vp, &va, curthread->td_ucred) == 0) { 561107273Srwatson log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 562275856Sgleb " level %s after %s a level-%s %s (inode=%ju, " 563107273Srwatson "mountpount=%s)\n", 564107273Srwatson subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 565107273Srwatson p->p_comm, subjtext, actionname, objlabeltext, objname, 566275856Sgleb (uintmax_t)va.va_fileid, vp->v_mount->mnt_stat.f_mntonname); 567107273Srwatson } else { 568107273Srwatson log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 569107273Srwatson " level %s after %s a level-%s %s\n", 570107273Srwatson subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 571107273Srwatson p->p_comm, subjtext, actionname, objlabeltext, objname); 572107273Srwatson } 573116701Srwatson 574116701Srwatson sbuf_delete(&subjlabel_sb); 575116701Srwatson sbuf_delete(&subjtext_sb); 576116701Srwatson sbuf_delete(&objlabel_sb); 577107273Srwatson 578107273Srwatson return (0); 579107273Srwatson} 580107273Srwatson 581107273Srwatson/* 582172955Srwatson * Relabel "to" to "from" only if "from" is a valid label (contains at least 583172955Srwatson * a single), as for a relabel operation which may or may not involve a 584172955Srwatson * relevant label. 585107273Srwatson */ 586107279Srwatsonstatic void 587107273Srwatsontry_relabel(struct mac_lomac *from, struct mac_lomac *to) 588107273Srwatson{ 589107273Srwatson 590107273Srwatson if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 591107273Srwatson bzero(to, sizeof(*to)); 592172955Srwatson lomac_copy(from, to); 593107273Srwatson } 594107273Srwatson} 595107273Srwatson 596107273Srwatson/* 597107273Srwatson * Policy module operations. 598107273Srwatson */ 599107273Srwatsonstatic void 600172955Srwatsonlomac_init(struct mac_policy_conf *conf) 601107273Srwatson{ 602107273Srwatson 603107273Srwatson} 604107273Srwatson 605107273Srwatson/* 606107273Srwatson * Label operations. 607107273Srwatson */ 608107273Srwatsonstatic void 609172955Srwatsonlomac_init_label(struct label *label) 610107273Srwatson{ 611107273Srwatson 612132781Skan SLOT_SET(label, lomac_alloc(M_WAITOK)); 613107273Srwatson} 614107273Srwatson 615107273Srwatsonstatic int 616172955Srwatsonlomac_init_label_waitcheck(struct label *label, int flag) 617107273Srwatson{ 618107273Srwatson 619132781Skan SLOT_SET(label, lomac_alloc(flag)); 620107273Srwatson if (SLOT(label) == NULL) 621107273Srwatson return (ENOMEM); 622107273Srwatson 623107273Srwatson return (0); 624107273Srwatson} 625107273Srwatson 626107273Srwatsonstatic void 627172955Srwatsonlomac_destroy_label(struct label *label) 628107273Srwatson{ 629107273Srwatson 630107273Srwatson lomac_free(SLOT(label)); 631132781Skan SLOT_SET(label, NULL); 632107273Srwatson} 633107273Srwatson 634116701Srwatsonstatic int 635172955Srwatsonlomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element) 636107273Srwatson{ 637107273Srwatson 638107273Srwatson switch (element->mle_type) { 639107273Srwatson case MAC_LOMAC_TYPE_HIGH: 640116701Srwatson return (sbuf_printf(sb, "high")); 641107273Srwatson 642107273Srwatson case MAC_LOMAC_TYPE_LOW: 643116701Srwatson return (sbuf_printf(sb, "low")); 644107273Srwatson 645107273Srwatson case MAC_LOMAC_TYPE_EQUAL: 646116701Srwatson return (sbuf_printf(sb, "equal")); 647107273Srwatson 648107273Srwatson case MAC_LOMAC_TYPE_GRADE: 649116701Srwatson return (sbuf_printf(sb, "%d", element->mle_grade)); 650107273Srwatson 651107273Srwatson default: 652172955Srwatson panic("lomac_element_to_string: invalid type (%d)", 653107273Srwatson element->mle_type); 654107273Srwatson } 655107273Srwatson} 656107273Srwatson 657107273Srwatsonstatic int 658172955Srwatsonlomac_to_string(struct sbuf *sb, struct mac_lomac *ml) 659107273Srwatson{ 660107273Srwatson 661172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 662172955Srwatson if (lomac_element_to_string(sb, &ml->ml_single) == -1) 663116701Srwatson return (EINVAL); 664107273Srwatson } 665107273Srwatson 666172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) { 667116701Srwatson if (sbuf_putc(sb, '[') == -1) 668116701Srwatson return (EINVAL); 669107273Srwatson 670172955Srwatson if (lomac_element_to_string(sb, &ml->ml_auxsingle) == -1) 671116701Srwatson return (EINVAL); 672107273Srwatson 673116701Srwatson if (sbuf_putc(sb, ']') == -1) 674116701Srwatson return (EINVAL); 675107273Srwatson } 676107273Srwatson 677172955Srwatson if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) { 678116701Srwatson if (sbuf_putc(sb, '(') == -1) 679116701Srwatson return (EINVAL); 680107273Srwatson 681172955Srwatson if (lomac_element_to_string(sb, &ml->ml_rangelow) == -1) 682116701Srwatson return (EINVAL); 683107273Srwatson 684116701Srwatson if (sbuf_putc(sb, '-') == -1) 685116701Srwatson return (EINVAL); 686107273Srwatson 687172955Srwatson if (lomac_element_to_string(sb, &ml->ml_rangehigh) == -1) 688116701Srwatson return (EINVAL); 689107273Srwatson 690122270Srwatson if (sbuf_putc(sb, ')') == -1) 691116701Srwatson return (EINVAL); 692107273Srwatson } 693107273Srwatson 694107273Srwatson return (0); 695107273Srwatson} 696107273Srwatson 697107273Srwatsonstatic int 698172955Srwatsonlomac_externalize_label(struct label *label, char *element_name, 699116701Srwatson struct sbuf *sb, int *claimed) 700107273Srwatson{ 701172955Srwatson struct mac_lomac *ml; 702107273Srwatson 703107273Srwatson if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 704107273Srwatson return (0); 705107273Srwatson 706107273Srwatson (*claimed)++; 707107273Srwatson 708172955Srwatson ml = SLOT(label); 709107273Srwatson 710172955Srwatson return (lomac_to_string(sb, ml)); 711107273Srwatson} 712107273Srwatson 713107273Srwatsonstatic int 714172955Srwatsonlomac_parse_element(struct mac_lomac_element *element, char *string) 715107273Srwatson{ 716107273Srwatson 717172955Srwatson if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { 718107273Srwatson element->mle_type = MAC_LOMAC_TYPE_HIGH; 719107273Srwatson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 720172955Srwatson } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { 721107273Srwatson element->mle_type = MAC_LOMAC_TYPE_LOW; 722107273Srwatson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 723181217Srwatson } else if (strcmp(string, "equal") == 0 || 724181217Srwatson strcmp(string, "eq") == 0) { 725107273Srwatson element->mle_type = MAC_LOMAC_TYPE_EQUAL; 726107273Srwatson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 727107273Srwatson } else { 728107273Srwatson char *p0, *p1; 729107273Srwatson int d; 730107273Srwatson 731107273Srwatson p0 = string; 732107273Srwatson d = strtol(p0, &p1, 10); 733107273Srwatson 734107273Srwatson if (d < 0 || d > 65535) 735107273Srwatson return (EINVAL); 736107273Srwatson element->mle_type = MAC_LOMAC_TYPE_GRADE; 737107273Srwatson element->mle_grade = d; 738107273Srwatson 739107273Srwatson if (p1 == p0 || *p1 != '\0') 740107273Srwatson return (EINVAL); 741107273Srwatson } 742107273Srwatson 743107273Srwatson return (0); 744107273Srwatson} 745107273Srwatson 746107273Srwatson/* 747172955Srwatson * Note: destructively consumes the string, make a local copy before calling 748172955Srwatson * if that's a problem. 749107273Srwatson */ 750107273Srwatsonstatic int 751172955Srwatsonlomac_parse(struct mac_lomac *ml, char *string) 752107273Srwatson{ 753107273Srwatson char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle, 754107273Srwatson *auxsingleend; 755107273Srwatson int error; 756107273Srwatson 757107273Srwatson /* Do we have a range? */ 758107273Srwatson single = string; 759229272Sed range = strchr(string, '('); 760107273Srwatson if (range == single) 761107273Srwatson single = NULL; 762229272Sed auxsingle = strchr(string, '['); 763107273Srwatson if (auxsingle == single) 764107273Srwatson single = NULL; 765107273Srwatson if (range != NULL && auxsingle != NULL) 766107273Srwatson return (EINVAL); 767107273Srwatson rangelow = rangehigh = NULL; 768107273Srwatson if (range != NULL) { 769107273Srwatson /* Nul terminate the end of the single string. */ 770107273Srwatson *range = '\0'; 771107273Srwatson range++; 772107273Srwatson rangelow = range; 773229272Sed rangehigh = strchr(rangelow, '-'); 774107273Srwatson if (rangehigh == NULL) 775107273Srwatson return (EINVAL); 776107273Srwatson rangehigh++; 777107273Srwatson if (*rangelow == '\0' || *rangehigh == '\0') 778107273Srwatson return (EINVAL); 779229272Sed rangeend = strchr(rangehigh, ')'); 780107273Srwatson if (rangeend == NULL) 781107273Srwatson return (EINVAL); 782107273Srwatson if (*(rangeend + 1) != '\0') 783107273Srwatson return (EINVAL); 784107273Srwatson /* Nul terminate the ends of the ranges. */ 785107273Srwatson *(rangehigh - 1) = '\0'; 786107273Srwatson *rangeend = '\0'; 787107273Srwatson } 788107273Srwatson KASSERT((rangelow != NULL && rangehigh != NULL) || 789107273Srwatson (rangelow == NULL && rangehigh == NULL), 790172955Srwatson ("lomac_internalize_label: range mismatch")); 791107273Srwatson if (auxsingle != NULL) { 792107273Srwatson /* Nul terminate the end of the single string. */ 793107273Srwatson *auxsingle = '\0'; 794107273Srwatson auxsingle++; 795229272Sed auxsingleend = strchr(auxsingle, ']'); 796107273Srwatson if (auxsingleend == NULL) 797107273Srwatson return (EINVAL); 798107273Srwatson if (*(auxsingleend + 1) != '\0') 799107273Srwatson return (EINVAL); 800107273Srwatson /* Nul terminate the end of the auxsingle. */ 801107273Srwatson *auxsingleend = '\0'; 802107273Srwatson } 803107273Srwatson 804172955Srwatson bzero(ml, sizeof(*ml)); 805107273Srwatson if (single != NULL) { 806172955Srwatson error = lomac_parse_element(&ml->ml_single, single); 807107273Srwatson if (error) 808107273Srwatson return (error); 809172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 810107273Srwatson } 811107273Srwatson 812107273Srwatson if (auxsingle != NULL) { 813181217Srwatson error = lomac_parse_element(&ml->ml_auxsingle, auxsingle); 814107273Srwatson if (error) 815107273Srwatson return (error); 816172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_AUX; 817107273Srwatson } 818107273Srwatson 819107273Srwatson if (rangelow != NULL) { 820172955Srwatson error = lomac_parse_element(&ml->ml_rangelow, rangelow); 821107273Srwatson if (error) 822107273Srwatson return (error); 823172955Srwatson error = lomac_parse_element(&ml->ml_rangehigh, rangehigh); 824107273Srwatson if (error) 825107273Srwatson return (error); 826172955Srwatson ml->ml_flags |= MAC_LOMAC_FLAG_RANGE; 827107273Srwatson } 828107273Srwatson 829172955Srwatson error = lomac_valid(ml); 830107273Srwatson if (error) 831107273Srwatson return (error); 832107273Srwatson 833107273Srwatson return (0); 834107273Srwatson} 835107273Srwatson 836107273Srwatsonstatic int 837172955Srwatsonlomac_internalize_label(struct label *label, char *element_name, 838107273Srwatson char *element_data, int *claimed) 839107273Srwatson{ 840172955Srwatson struct mac_lomac *ml, ml_temp; 841107273Srwatson int error; 842107273Srwatson 843107273Srwatson if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 844107273Srwatson return (0); 845107273Srwatson 846107273Srwatson (*claimed)++; 847107273Srwatson 848172955Srwatson error = lomac_parse(&ml_temp, element_data); 849107273Srwatson if (error) 850107273Srwatson return (error); 851107273Srwatson 852172955Srwatson ml = SLOT(label); 853172955Srwatson *ml = ml_temp; 854107273Srwatson 855107273Srwatson return (0); 856107273Srwatson} 857107273Srwatson 858107273Srwatsonstatic void 859172955Srwatsonlomac_copy_label(struct label *src, struct label *dest) 860107273Srwatson{ 861107273Srwatson 862107273Srwatson *SLOT(dest) = *SLOT(src); 863107273Srwatson} 864107273Srwatson 865107273Srwatson/* 866173138Srwatson * Object-specific entry point implementations are sorted alphabetically by 867173138Srwatson * object type name and then by operation. 868107273Srwatson */ 869173138Srwatsonstatic int 870173138Srwatsonlomac_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 871173138Srwatson struct ifnet *ifp, struct label *ifplabel) 872107273Srwatson{ 873173138Srwatson struct mac_lomac *a, *b; 874107273Srwatson 875173138Srwatson if (!lomac_enabled) 876173138Srwatson return (0); 877107273Srwatson 878173138Srwatson a = SLOT(dlabel); 879173138Srwatson b = SLOT(ifplabel); 880107273Srwatson 881173138Srwatson if (lomac_equal_single(a, b)) 882173138Srwatson return (0); 883173138Srwatson return (EACCES); 884107273Srwatson} 885107273Srwatson 886107273Srwatsonstatic void 887173138Srwatsonlomac_bpfdesc_create(struct ucred *cred, struct bpf_d *d, 888173138Srwatson struct label *dlabel) 889107273Srwatson{ 890107273Srwatson struct mac_lomac *source, *dest; 891107273Srwatson 892122524Srwatson source = SLOT(cred->cr_label); 893173138Srwatson dest = SLOT(dlabel); 894107273Srwatson 895172955Srwatson lomac_copy_single(source, dest); 896107273Srwatson} 897107273Srwatson 898107273Srwatsonstatic void 899173138Srwatsonlomac_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 900173138Srwatson struct mbuf *m, struct label *mlabel) 901107273Srwatson{ 902107273Srwatson struct mac_lomac *source, *dest; 903107273Srwatson 904173138Srwatson source = SLOT(dlabel); 905173138Srwatson dest = SLOT(mlabel); 906173138Srwatson 907172955Srwatson lomac_copy_single(source, dest); 908107273Srwatson} 909107273Srwatson 910173138Srwatsonstatic int 911173138Srwatsonlomac_cred_check_relabel(struct ucred *cred, struct label *newlabel) 912107273Srwatson{ 913173138Srwatson struct mac_lomac *subj, *new; 914173138Srwatson int error; 915107273Srwatson 916173138Srwatson subj = SLOT(cred->cr_label); 917173138Srwatson new = SLOT(newlabel); 918107273Srwatson 919173138Srwatson /* 920173138Srwatson * If there is a LOMAC label update for the credential, it may be an 921173138Srwatson * update of the single, range, or both. 922173138Srwatson */ 923173138Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 924173138Srwatson if (error) 925173138Srwatson return (error); 926107273Srwatson 927173138Srwatson /* 928173138Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 929173138Srwatson */ 930173138Srwatson if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 931173138Srwatson /* 932173138Srwatson * Fill in the missing parts from the previous label. 933173138Srwatson */ 934173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 935173138Srwatson lomac_copy_single(subj, new); 936173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 937173138Srwatson lomac_copy_range(subj, new); 938107273Srwatson 939173138Srwatson /* 940173138Srwatson * To change the LOMAC range on a credential, the new range 941173138Srwatson * label must be in the current range. 942173138Srwatson */ 943173138Srwatson if (!lomac_range_in_range(new, subj)) 944173138Srwatson return (EPERM); 945107273Srwatson 946173138Srwatson /* 947173138Srwatson * To change the LOMAC single label on a credential, the new 948173138Srwatson * single label must be in the new range. Implicitly from 949173138Srwatson * the previous check, the new single is in the old range. 950173138Srwatson */ 951173138Srwatson if (!lomac_single_in_range(new, new)) 952173138Srwatson return (EPERM); 953107273Srwatson 954173138Srwatson /* 955173138Srwatson * To have EQUAL in any component of the new credential LOMAC 956173138Srwatson * label, the subject must already have EQUAL in their label. 957173138Srwatson */ 958173138Srwatson if (lomac_contains_equal(new)) { 959173138Srwatson error = lomac_subject_privileged(subj); 960173138Srwatson if (error) 961173138Srwatson return (error); 962173138Srwatson } 963107273Srwatson 964173138Srwatson /* 965173138Srwatson * XXXMAC: Additional consistency tests regarding the single 966173138Srwatson * and range of the new label might be performed here. 967173138Srwatson */ 968173138Srwatson } 969107273Srwatson 970173138Srwatson return (0); 971107273Srwatson} 972107273Srwatson 973107273Srwatsonstatic int 974173138Srwatsonlomac_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 975107273Srwatson{ 976173138Srwatson struct mac_lomac *subj, *obj; 977107273Srwatson 978173138Srwatson if (!lomac_enabled) 979173138Srwatson return (0); 980107273Srwatson 981173138Srwatson subj = SLOT(cr1->cr_label); 982173138Srwatson obj = SLOT(cr2->cr_label); 983107273Srwatson 984173138Srwatson /* XXX: range */ 985173138Srwatson if (!lomac_dominate_single(obj, subj)) 986173138Srwatson return (ESRCH); 987107273Srwatson 988107273Srwatson return (0); 989107273Srwatson} 990184407Srwatson 991107273Srwatsonstatic void 992184407Srwatsonlomac_cred_create_init(struct ucred *cred) 993184407Srwatson{ 994184407Srwatson struct mac_lomac *dest; 995184407Srwatson 996184407Srwatson dest = SLOT(cred->cr_label); 997184407Srwatson 998184407Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0); 999184407Srwatson lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 0); 1000184407Srwatson} 1001184407Srwatson 1002184407Srwatsonstatic void 1003184407Srwatsonlomac_cred_create_swapper(struct ucred *cred) 1004184407Srwatson{ 1005184407Srwatson struct mac_lomac *dest; 1006184407Srwatson 1007184407Srwatson dest = SLOT(cred->cr_label); 1008184407Srwatson 1009184407Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1010184407Srwatson lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 0); 1011184407Srwatson} 1012184407Srwatson 1013184407Srwatsonstatic void 1014173138Srwatsonlomac_cred_relabel(struct ucred *cred, struct label *newlabel) 1015107273Srwatson{ 1016107273Srwatson struct mac_lomac *source, *dest; 1017107273Srwatson 1018173138Srwatson source = SLOT(newlabel); 1019173138Srwatson dest = SLOT(cred->cr_label); 1020107273Srwatson 1021173138Srwatson try_relabel(source, dest); 1022107273Srwatson} 1023107273Srwatson 1024107273Srwatsonstatic void 1025173138Srwatsonlomac_devfs_create_device(struct ucred *cred, struct mount *mp, 1026173138Srwatson struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 1027122875Srwatson{ 1028173138Srwatson struct mac_lomac *ml; 1029231378Sed const char *dn; 1030173138Srwatson int lomac_type; 1031122875Srwatson 1032173138Srwatson ml = SLOT(delabel); 1033231378Sed dn = devtoname(dev); 1034231378Sed if (strcmp(dn, "null") == 0 || 1035231378Sed strcmp(dn, "zero") == 0 || 1036231378Sed strcmp(dn, "random") == 0 || 1037231378Sed strncmp(dn, "fd/", strlen("fd/")) == 0 || 1038231378Sed strncmp(dn, "ttyv", strlen("ttyv")) == 0) 1039173138Srwatson lomac_type = MAC_LOMAC_TYPE_EQUAL; 1040173138Srwatson else if (ptys_equal && 1041231378Sed (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 1042231378Sed strncmp(dn, "pts/", strlen("pts/")) == 0 || 1043231378Sed strncmp(dn, "ptyp", strlen("ptyp")) == 0)) 1044173138Srwatson lomac_type = MAC_LOMAC_TYPE_EQUAL; 1045173138Srwatson else 1046173138Srwatson lomac_type = MAC_LOMAC_TYPE_HIGH; 1047173138Srwatson lomac_set_single(ml, lomac_type, 0); 1048122875Srwatson} 1049122875Srwatson 1050122875Srwatsonstatic void 1051173138Srwatsonlomac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 1052173138Srwatson struct devfs_dirent *de, struct label *delabel) 1053107273Srwatson{ 1054173138Srwatson struct mac_lomac *ml; 1055107273Srwatson 1056173138Srwatson ml = SLOT(delabel); 1057173138Srwatson lomac_set_single(ml, MAC_LOMAC_TYPE_HIGH, 0); 1058107273Srwatson} 1059107273Srwatson 1060107273Srwatsonstatic void 1061173138Srwatsonlomac_devfs_create_symlink(struct ucred *cred, struct mount *mp, 1062173138Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 1063173138Srwatson struct label *delabel) 1064107273Srwatson{ 1065107273Srwatson struct mac_lomac *source, *dest; 1066107273Srwatson 1067122524Srwatson source = SLOT(cred->cr_label); 1068173138Srwatson dest = SLOT(delabel); 1069107273Srwatson 1070172955Srwatson lomac_copy_single(source, dest); 1071107273Srwatson} 1072107273Srwatson 1073107273Srwatsonstatic void 1074173138Srwatsonlomac_devfs_update(struct mount *mp, struct devfs_dirent *de, 1075173138Srwatson struct label *delabel, struct vnode *vp, struct label *vplabel) 1076107273Srwatson{ 1077107273Srwatson struct mac_lomac *source, *dest; 1078107273Srwatson 1079173138Srwatson source = SLOT(vplabel); 1080173138Srwatson dest = SLOT(delabel); 1081107273Srwatson 1082173138Srwatson lomac_copy(source, dest); 1083107273Srwatson} 1084107273Srwatson 1085107273Srwatsonstatic void 1086173138Srwatsonlomac_devfs_vnode_associate(struct mount *mp, struct label *mplabel, 1087173138Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 1088173138Srwatson struct label *vplabel) 1089107273Srwatson{ 1090107273Srwatson struct mac_lomac *source, *dest; 1091107273Srwatson 1092173138Srwatson source = SLOT(delabel); 1093173138Srwatson dest = SLOT(vplabel); 1094107273Srwatson 1095172955Srwatson lomac_copy_single(source, dest); 1096107273Srwatson} 1097107273Srwatson 1098173138Srwatsonstatic int 1099173138Srwatsonlomac_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1100173138Srwatson struct label *ifplabel, struct label *newlabel) 1101107273Srwatson{ 1102173138Srwatson struct mac_lomac *subj, *new; 1103173138Srwatson int error; 1104107273Srwatson 1105173138Srwatson subj = SLOT(cred->cr_label); 1106173138Srwatson new = SLOT(newlabel); 1107107273Srwatson 1108173138Srwatson /* 1109173138Srwatson * If there is a LOMAC label update for the interface, it may be an 1110173138Srwatson * update of the single, range, or both. 1111173138Srwatson */ 1112173138Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1113173138Srwatson if (error) 1114173138Srwatson return (error); 1115107273Srwatson 1116173138Srwatson /* 1117173138Srwatson * Relabling network interfaces requires LOMAC privilege. 1118173138Srwatson */ 1119173138Srwatson error = lomac_subject_privileged(subj); 1120173138Srwatson if (error) 1121173138Srwatson return (error); 1122107273Srwatson 1123173138Srwatson /* 1124173138Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 1125173138Srwatson */ 1126173138Srwatson if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1127173138Srwatson /* 1128173138Srwatson * Fill in the missing parts from the previous label. 1129173138Srwatson */ 1130173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1131173138Srwatson lomac_copy_single(subj, new); 1132173138Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1133173138Srwatson lomac_copy_range(subj, new); 1134107273Srwatson 1135173138Srwatson /* 1136173138Srwatson * Rely on the traditional superuser status for the LOMAC 1137173138Srwatson * interface relabel requirements. XXXMAC: This will go 1138173138Srwatson * away. 1139173138Srwatson * 1140173138Srwatson * XXXRW: This is also redundant to a higher layer check. 1141173138Srwatson */ 1142173138Srwatson error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0); 1143173138Srwatson if (error) 1144173138Srwatson return (EPERM); 1145107273Srwatson 1146173138Srwatson /* 1147173138Srwatson * XXXMAC: Additional consistency tests regarding the single 1148173138Srwatson * and the range of the new label might be performed here. 1149173138Srwatson */ 1150173138Srwatson } 1151107273Srwatson 1152173138Srwatson return (0); 1153107273Srwatson} 1154107273Srwatson 1155173138Srwatsonstatic int 1156173138Srwatsonlomac_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1157173138Srwatson struct mbuf *m, struct label *mlabel) 1158107273Srwatson{ 1159173138Srwatson struct mac_lomac *p, *i; 1160107273Srwatson 1161173138Srwatson if (!lomac_enabled) 1162173138Srwatson return (0); 1163107273Srwatson 1164173138Srwatson p = SLOT(mlabel); 1165173138Srwatson i = SLOT(ifplabel); 1166107273Srwatson 1167173138Srwatson return (lomac_single_in_range(p, i) ? 0 : EACCES); 1168107273Srwatson} 1169107273Srwatson 1170107273Srwatsonstatic void 1171172955Srwatsonlomac_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1172107273Srwatson{ 1173121816Sbrooks char tifname[IFNAMSIZ], *p, *q; 1174107273Srwatson char tiflist[sizeof(trusted_interfaces)]; 1175107273Srwatson struct mac_lomac *dest; 1176107273Srwatson int len, grade; 1177107273Srwatson 1178168976Srwatson dest = SLOT(ifplabel); 1179107273Srwatson 1180168976Srwatson if (ifp->if_type == IFT_LOOP) { 1181107273Srwatson grade = MAC_LOMAC_TYPE_EQUAL; 1182107273Srwatson goto set; 1183107273Srwatson } 1184107273Srwatson 1185107273Srwatson if (trust_all_interfaces) { 1186107273Srwatson grade = MAC_LOMAC_TYPE_HIGH; 1187107273Srwatson goto set; 1188107273Srwatson } 1189107273Srwatson 1190107273Srwatson grade = MAC_LOMAC_TYPE_LOW; 1191107273Srwatson 1192107273Srwatson if (trusted_interfaces[0] == '\0' || 1193107273Srwatson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1194107273Srwatson goto set; 1195107273Srwatson 1196107273Srwatson bzero(tiflist, sizeof(tiflist)); 1197107273Srwatson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1198107273Srwatson if(*p != ' ' && *p != '\t') 1199107273Srwatson *q = *p; 1200107273Srwatson 1201107273Srwatson for (p = q = tiflist;; p++) { 1202107273Srwatson if (*p == ',' || *p == '\0') { 1203107273Srwatson len = p - q; 1204107273Srwatson if (len < IFNAMSIZ) { 1205107273Srwatson bzero(tifname, sizeof(tifname)); 1206107273Srwatson bcopy(q, tifname, len); 1207168976Srwatson if (strcmp(tifname, ifp->if_xname) == 0) { 1208107273Srwatson grade = MAC_LOMAC_TYPE_HIGH; 1209107273Srwatson break; 1210107273Srwatson } 1211107273Srwatson } 1212107273Srwatson else { 1213107273Srwatson *p = '\0'; 1214107273Srwatson printf("MAC/LOMAC warning: interface name " 1215107273Srwatson "\"%s\" is too long (must be < %d)\n", 1216107273Srwatson q, IFNAMSIZ); 1217107273Srwatson } 1218107273Srwatson if (*p == '\0') 1219107273Srwatson break; 1220107273Srwatson q = p + 1; 1221107273Srwatson } 1222107273Srwatson } 1223107273Srwatsonset: 1224172955Srwatson lomac_set_single(dest, grade, 0); 1225172955Srwatson lomac_set_range(dest, grade, 0, grade, 0); 1226107273Srwatson} 1227107273Srwatson 1228107273Srwatsonstatic void 1229173138Srwatsonlomac_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1230173138Srwatson struct mbuf *m, struct label *mlabel) 1231107273Srwatson{ 1232107273Srwatson struct mac_lomac *source, *dest; 1233107273Srwatson 1234173138Srwatson source = SLOT(ifplabel); 1235173138Srwatson dest = SLOT(mlabel); 1236107273Srwatson 1237172955Srwatson lomac_copy_single(source, dest); 1238107273Srwatson} 1239107273Srwatson 1240107273Srwatsonstatic void 1241173138Srwatsonlomac_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1242173138Srwatson struct label *ifplabel, struct label *newlabel) 1243107273Srwatson{ 1244107273Srwatson struct mac_lomac *source, *dest; 1245107273Srwatson 1246173138Srwatson source = SLOT(newlabel); 1247173138Srwatson dest = SLOT(ifplabel); 1248107273Srwatson 1249173138Srwatson try_relabel(source, dest); 1250107273Srwatson} 1251107273Srwatson 1252173138Srwatsonstatic int 1253173138Srwatsonlomac_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1254173138Srwatson struct mbuf *m, struct label *mlabel) 1255173138Srwatson{ 1256173138Srwatson struct mac_lomac *p, *i; 1257173138Srwatson 1258173138Srwatson if (!lomac_enabled) 1259173138Srwatson return (0); 1260173138Srwatson 1261173138Srwatson p = SLOT(mlabel); 1262173138Srwatson i = SLOT(inplabel); 1263173138Srwatson 1264173138Srwatson return (lomac_equal_single(p, i) ? 0 : EACCES); 1265173138Srwatson} 1266173138Srwatson 1267183980Sbzstatic int 1268183980Sbzlomac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 1269183980Sbz struct label *inplabel) 1270183980Sbz{ 1271183980Sbz struct mac_lomac *subj, *obj; 1272183980Sbz 1273183980Sbz if (!lomac_enabled) 1274183980Sbz return (0); 1275183980Sbz 1276183980Sbz subj = SLOT(cred->cr_label); 1277183980Sbz obj = SLOT(inplabel); 1278183980Sbz 1279183980Sbz if (!lomac_dominate_single(obj, subj)) 1280183980Sbz return (ENOENT); 1281183980Sbz 1282183980Sbz return (0); 1283183980Sbz} 1284183980Sbz 1285107273Srwatsonstatic void 1286173138Srwatsonlomac_inpcb_create(struct socket *so, struct label *solabel, 1287173138Srwatson struct inpcb *inp, struct label *inplabel) 1288107273Srwatson{ 1289107273Srwatson struct mac_lomac *source, *dest; 1290107273Srwatson 1291173138Srwatson source = SLOT(solabel); 1292173138Srwatson dest = SLOT(inplabel); 1293107273Srwatson 1294172955Srwatson lomac_copy_single(source, dest); 1295107273Srwatson} 1296107273Srwatson 1297107273Srwatsonstatic void 1298172955Srwatsonlomac_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1299123607Srwatson struct mbuf *m, struct label *mlabel) 1300123607Srwatson{ 1301123607Srwatson struct mac_lomac *source, *dest; 1302123607Srwatson 1303123607Srwatson source = SLOT(inplabel); 1304123607Srwatson dest = SLOT(mlabel); 1305123607Srwatson 1306172955Srwatson lomac_copy_single(source, dest); 1307123607Srwatson} 1308123607Srwatson 1309123607Srwatsonstatic void 1310173138Srwatsonlomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1311173138Srwatson struct inpcb *inp, struct label *inplabel) 1312107273Srwatson{ 1313107273Srwatson struct mac_lomac *source, *dest; 1314107273Srwatson 1315193391Srwatson SOCK_LOCK_ASSERT(so); 1316193391Srwatson 1317173138Srwatson source = SLOT(solabel); 1318173138Srwatson dest = SLOT(inplabel); 1319107273Srwatson 1320172955Srwatson lomac_copy_single(source, dest); 1321107273Srwatson} 1322107273Srwatson 1323107273Srwatsonstatic void 1324184308Srwatsonlomac_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1325184308Srwatson struct label *q6label) 1326184308Srwatson{ 1327184308Srwatson struct mac_lomac *source, *dest; 1328184308Srwatson 1329184308Srwatson source = SLOT(mlabel); 1330184308Srwatson dest = SLOT(q6label); 1331184308Srwatson 1332184308Srwatson lomac_copy_single(source, dest); 1333184308Srwatson} 1334184308Srwatson 1335184308Srwatsonstatic int 1336184308Srwatsonlomac_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1337184308Srwatson struct label *q6label) 1338184308Srwatson{ 1339184308Srwatson struct mac_lomac *a, *b; 1340184308Srwatson 1341184308Srwatson a = SLOT(q6label); 1342184308Srwatson b = SLOT(mlabel); 1343184308Srwatson 1344184308Srwatson return (lomac_equal_single(a, b)); 1345184308Srwatson} 1346184308Srwatson 1347184308Srwatsonstatic void 1348184308Srwatsonlomac_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1349184308Srwatson struct label *mlabel) 1350184308Srwatson{ 1351184308Srwatson struct mac_lomac *source, *dest; 1352184308Srwatson 1353184308Srwatson source = SLOT(q6label); 1354184308Srwatson dest = SLOT(mlabel); 1355184308Srwatson 1356184308Srwatson /* Just use the head, since we require them all to match. */ 1357184308Srwatson lomac_copy_single(source, dest); 1358184308Srwatson} 1359184308Srwatson 1360184308Srwatsonstatic void 1361184308Srwatsonlomac_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1362184308Srwatson struct label *q6label) 1363184308Srwatson{ 1364184308Srwatson 1365184308Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1366184308Srwatson} 1367184308Srwatson 1368184308Srwatsonstatic void 1369179781Srwatsonlomac_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1370179781Srwatson struct label *qlabel) 1371107273Srwatson{ 1372107273Srwatson struct mac_lomac *source, *dest; 1373107273Srwatson 1374173138Srwatson source = SLOT(mlabel); 1375179781Srwatson dest = SLOT(qlabel); 1376107273Srwatson 1377172955Srwatson lomac_copy_single(source, dest); 1378107273Srwatson} 1379107273Srwatson 1380107273Srwatsonstatic int 1381179781Srwatsonlomac_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1382179781Srwatson struct label *qlabel) 1383107273Srwatson{ 1384107273Srwatson struct mac_lomac *a, *b; 1385107273Srwatson 1386179781Srwatson a = SLOT(qlabel); 1387168976Srwatson b = SLOT(mlabel); 1388107273Srwatson 1389172955Srwatson return (lomac_equal_single(a, b)); 1390107273Srwatson} 1391107273Srwatson 1392107273Srwatsonstatic void 1393179781Srwatsonlomac_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1394179781Srwatson struct label *mlabel) 1395107273Srwatson{ 1396107273Srwatson struct mac_lomac *source, *dest; 1397107273Srwatson 1398179781Srwatson source = SLOT(qlabel); 1399173138Srwatson dest = SLOT(mlabel); 1400107273Srwatson 1401173138Srwatson /* Just use the head, since we require them all to match. */ 1402173138Srwatson lomac_copy_single(source, dest); 1403107273Srwatson} 1404107273Srwatson 1405107273Srwatsonstatic void 1406179781Srwatsonlomac_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1407179781Srwatson struct label *qlabel) 1408107273Srwatson{ 1409107273Srwatson 1410107273Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1411107273Srwatson} 1412107273Srwatson 1413173138Srwatsonstatic int 1414173138Srwatsonlomac_kld_check_load(struct ucred *cred, struct vnode *vp, 1415173138Srwatson struct label *vplabel) 1416122875Srwatson{ 1417173138Srwatson struct mac_lomac *subj, *obj; 1418122875Srwatson 1419173138Srwatson if (!lomac_enabled) 1420173138Srwatson return (0); 1421122875Srwatson 1422173138Srwatson subj = SLOT(cred->cr_label); 1423173138Srwatson obj = SLOT(vplabel); 1424122875Srwatson 1425173138Srwatson if (lomac_subject_privileged(subj)) 1426173138Srwatson return (EPERM); 1427165150Scsjp 1428173138Srwatson if (!lomac_high_single(obj)) 1429173138Srwatson return (EACCES); 1430173138Srwatson 1431173138Srwatson return (0); 1432165150Scsjp} 1433165150Scsjp 1434165150Scsjpstatic void 1435173138Srwatsonlomac_mount_create(struct ucred *cred, struct mount *mp, 1436173138Srwatson struct label *mplabel) 1437165150Scsjp{ 1438165150Scsjp struct mac_lomac *source, *dest; 1439165150Scsjp 1440173138Srwatson source = SLOT(cred->cr_label); 1441173138Srwatson dest = SLOT(mplabel); 1442173138Srwatson lomac_copy_single(source, dest); 1443165150Scsjp} 1444165150Scsjp 1445165150Scsjpstatic void 1446173095Srwatsonlomac_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1447173095Srwatson struct mbuf *m, struct label *mlabel) 1448173095Srwatson{ 1449173095Srwatson struct mac_lomac *dest; 1450173095Srwatson 1451173095Srwatson dest = SLOT(mlabel); 1452173095Srwatson 1453173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1454173095Srwatson} 1455173095Srwatson 1456173095Srwatsonstatic void 1457173102Srwatsonlomac_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1458173102Srwatson struct mbuf *msend, struct label *msendlabel) 1459173102Srwatson{ 1460173102Srwatson struct mac_lomac *source, *dest; 1461173102Srwatson 1462173102Srwatson source = SLOT(mrecvlabel); 1463173102Srwatson dest = SLOT(msendlabel); 1464173102Srwatson 1465173102Srwatson lomac_copy_single(source, dest); 1466173102Srwatson} 1467173102Srwatson 1468173102Srwatsonstatic void 1469173018Srwatsonlomac_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1470162238Scsjp{ 1471162238Scsjp struct mac_lomac *dest; 1472162238Scsjp 1473168976Srwatson dest = SLOT(mlabel); 1474162238Scsjp 1475299187Spfg /* XXX: where is the label for the firewall really coming from? */ 1476172955Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1477162238Scsjp} 1478162238Scsjp 1479173095Srwatsonstatic void 1480173138Srwatsonlomac_netinet_fragment(struct mbuf *m, struct label *mlabel, 1481173138Srwatson struct mbuf *frag, struct label *fraglabel) 1482173138Srwatson{ 1483173138Srwatson struct mac_lomac *source, *dest; 1484173138Srwatson 1485173138Srwatson source = SLOT(mlabel); 1486173138Srwatson dest = SLOT(fraglabel); 1487173138Srwatson 1488173138Srwatson lomac_copy_single(source, dest); 1489173138Srwatson} 1490173138Srwatson 1491173138Srwatsonstatic void 1492173102Srwatsonlomac_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1493173102Srwatson struct mbuf *msend, struct label *msendlabel) 1494173102Srwatson{ 1495173102Srwatson struct mac_lomac *source, *dest; 1496173102Srwatson 1497173102Srwatson source = SLOT(mrecvlabel); 1498173102Srwatson dest = SLOT(msendlabel); 1499173102Srwatson 1500173102Srwatson lomac_copy_single(source, dest); 1501173102Srwatson} 1502173102Srwatson 1503173102Srwatsonstatic void 1504173095Srwatsonlomac_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1505173095Srwatson struct mbuf *m, struct label *mlabel) 1506173095Srwatson{ 1507173095Srwatson struct mac_lomac *dest; 1508173095Srwatson 1509173095Srwatson dest = SLOT(mlabel); 1510173095Srwatson 1511173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1512173095Srwatson} 1513173095Srwatson 1514173095Srwatsonstatic void 1515173095Srwatsonlomac_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1516173095Srwatson struct mbuf *m, struct label *mlabel) 1517173095Srwatson{ 1518173095Srwatson struct mac_lomac *dest; 1519173095Srwatson 1520173095Srwatson dest = SLOT(mlabel); 1521173095Srwatson 1522173095Srwatson lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1523173095Srwatson} 1524173095Srwatson 1525107273Srwatsonstatic int 1526172955Srwatsonlomac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1527168976Srwatson struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1528107273Srwatson{ 1529107273Srwatson 1530172955Srwatson if (!lomac_enabled) 1531107273Srwatson return (0); 1532107273Srwatson 1533107273Srwatson /* XXX: This will be implemented soon... */ 1534107273Srwatson 1535107273Srwatson return (0); 1536107273Srwatson} 1537107273Srwatson 1538107273Srwatsonstatic int 1539172955Srwatsonlomac_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1540168976Srwatson struct label *pplabel) 1541107273Srwatson{ 1542107273Srwatson struct mac_lomac *subj, *obj; 1543107273Srwatson 1544172955Srwatson if (!lomac_enabled) 1545107273Srwatson return (0); 1546107273Srwatson 1547122524Srwatson subj = SLOT(cred->cr_label); 1548168976Srwatson obj = SLOT(pplabel); 1549107273Srwatson 1550172955Srwatson if (!lomac_dominate_single(obj, subj)) 1551107273Srwatson return (maybe_demote(subj, obj, "reading", "pipe", NULL)); 1552107273Srwatson 1553107273Srwatson return (0); 1554107273Srwatson} 1555107273Srwatson 1556107273Srwatsonstatic int 1557172955Srwatsonlomac_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1558168976Srwatson struct label *pplabel, struct label *newlabel) 1559107273Srwatson{ 1560107273Srwatson struct mac_lomac *subj, *obj, *new; 1561107273Srwatson int error; 1562107273Srwatson 1563107273Srwatson new = SLOT(newlabel); 1564122524Srwatson subj = SLOT(cred->cr_label); 1565168976Srwatson obj = SLOT(pplabel); 1566107273Srwatson 1567107273Srwatson /* 1568172955Srwatson * If there is a LOMAC label update for a pipe, it must be a single 1569172955Srwatson * update. 1570107273Srwatson */ 1571107273Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1572107273Srwatson if (error) 1573107273Srwatson return (error); 1574107273Srwatson 1575107273Srwatson /* 1576107273Srwatson * To perform a relabel of a pipe (LOMAC label or not), LOMAC must 1577107273Srwatson * authorize the relabel. 1578107273Srwatson */ 1579172955Srwatson if (!lomac_single_in_range(obj, subj)) 1580107273Srwatson return (EPERM); 1581107273Srwatson 1582107273Srwatson /* 1583107273Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 1584107273Srwatson */ 1585107273Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1586107273Srwatson /* 1587107273Srwatson * To change the LOMAC label on a pipe, the new pipe label 1588107273Srwatson * must be in the subject range. 1589107273Srwatson */ 1590172955Srwatson if (!lomac_single_in_range(new, subj)) 1591107273Srwatson return (EPERM); 1592107273Srwatson 1593107273Srwatson /* 1594107273Srwatson * To change the LOMAC label on a pipe to be EQUAL, the 1595107273Srwatson * subject must have appropriate privilege. 1596107273Srwatson */ 1597172955Srwatson if (lomac_contains_equal(new)) { 1598172955Srwatson error = lomac_subject_privileged(subj); 1599107273Srwatson if (error) 1600107273Srwatson return (error); 1601107273Srwatson } 1602107273Srwatson } 1603107273Srwatson 1604107273Srwatson return (0); 1605107273Srwatson} 1606107273Srwatson 1607107273Srwatsonstatic int 1608172955Srwatsonlomac_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1609168976Srwatson struct label *pplabel) 1610107273Srwatson{ 1611107273Srwatson struct mac_lomac *subj, *obj; 1612107273Srwatson 1613172955Srwatson if (!lomac_enabled) 1614107273Srwatson return (0); 1615107273Srwatson 1616122524Srwatson subj = SLOT(cred->cr_label); 1617168976Srwatson obj = SLOT(pplabel); 1618107273Srwatson 1619172955Srwatson if (!lomac_subject_dominate(subj, obj)) 1620107273Srwatson return (EACCES); 1621107273Srwatson 1622107273Srwatson return (0); 1623107273Srwatson} 1624107273Srwatson 1625173138Srwatsonstatic void 1626173138Srwatsonlomac_pipe_create(struct ucred *cred, struct pipepair *pp, 1627173138Srwatson struct label *pplabel) 1628107273Srwatson{ 1629173138Srwatson struct mac_lomac *source, *dest; 1630107273Srwatson 1631173138Srwatson source = SLOT(cred->cr_label); 1632173138Srwatson dest = SLOT(pplabel); 1633107273Srwatson 1634173138Srwatson lomac_copy_single(source, dest); 1635107273Srwatson} 1636107273Srwatson 1637173138Srwatsonstatic void 1638173138Srwatsonlomac_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1639173138Srwatson struct label *pplabel, struct label *newlabel) 1640107273Srwatson{ 1641173138Srwatson struct mac_lomac *source, *dest; 1642107273Srwatson 1643173138Srwatson source = SLOT(newlabel); 1644173138Srwatson dest = SLOT(pplabel); 1645107273Srwatson 1646173138Srwatson try_relabel(source, dest); 1647107273Srwatson} 1648107273Srwatson 1649168951Srwatson/* 1650168951Srwatson * Some system privileges are allowed regardless of integrity grade; others 1651168951Srwatson * are allowed only when running with privilege with respect to the LOMAC 1652168951Srwatson * policy as they might otherwise allow bypassing of the integrity policy. 1653168951Srwatson */ 1654107273Srwatsonstatic int 1655172955Srwatsonlomac_priv_check(struct ucred *cred, int priv) 1656168951Srwatson{ 1657168951Srwatson struct mac_lomac *subj; 1658168951Srwatson int error; 1659168951Srwatson 1660172955Srwatson if (!lomac_enabled) 1661168951Srwatson return (0); 1662168951Srwatson 1663168951Srwatson /* 1664168951Srwatson * Exempt only specific privileges from the LOMAC integrity policy. 1665168951Srwatson */ 1666168951Srwatson switch (priv) { 1667168951Srwatson case PRIV_KTRACE: 1668168951Srwatson case PRIV_MSGBUF: 1669168951Srwatson 1670168951Srwatson /* 1671168951Srwatson * Allow processes to manipulate basic process audit properties, and 1672168951Srwatson * to submit audit records. 1673168951Srwatson */ 1674168951Srwatson case PRIV_AUDIT_GETAUDIT: 1675168951Srwatson case PRIV_AUDIT_SETAUDIT: 1676168951Srwatson case PRIV_AUDIT_SUBMIT: 1677168951Srwatson 1678168951Srwatson /* 1679168951Srwatson * Allow processes to manipulate their regular UNIX credentials. 1680168951Srwatson */ 1681168951Srwatson case PRIV_CRED_SETUID: 1682168951Srwatson case PRIV_CRED_SETEUID: 1683168951Srwatson case PRIV_CRED_SETGID: 1684168951Srwatson case PRIV_CRED_SETEGID: 1685168951Srwatson case PRIV_CRED_SETGROUPS: 1686168951Srwatson case PRIV_CRED_SETREUID: 1687168951Srwatson case PRIV_CRED_SETREGID: 1688168951Srwatson case PRIV_CRED_SETRESUID: 1689168951Srwatson case PRIV_CRED_SETRESGID: 1690168951Srwatson 1691168951Srwatson /* 1692168951Srwatson * Allow processes to perform system monitoring. 1693168951Srwatson */ 1694168951Srwatson case PRIV_SEEOTHERGIDS: 1695168951Srwatson case PRIV_SEEOTHERUIDS: 1696168951Srwatson break; 1697168951Srwatson 1698168951Srwatson /* 1699168951Srwatson * Allow access to general process debugging facilities. We 1700168951Srwatson * separately control debugging based on MAC label. 1701168951Srwatson */ 1702168951Srwatson case PRIV_DEBUG_DIFFCRED: 1703168951Srwatson case PRIV_DEBUG_SUGID: 1704168951Srwatson case PRIV_DEBUG_UNPRIV: 1705168951Srwatson 1706168951Srwatson /* 1707168951Srwatson * Allow manipulating jails. 1708168951Srwatson */ 1709168951Srwatson case PRIV_JAIL_ATTACH: 1710168951Srwatson 1711168951Srwatson /* 1712168951Srwatson * Allow privilege with respect to the Partition policy, but not the 1713168951Srwatson * Privs policy. 1714168951Srwatson */ 1715168951Srwatson case PRIV_MAC_PARTITION: 1716168951Srwatson 1717168951Srwatson /* 1718168951Srwatson * Allow privilege with respect to process resource limits and login 1719168951Srwatson * context. 1720168951Srwatson */ 1721168951Srwatson case PRIV_PROC_LIMIT: 1722168951Srwatson case PRIV_PROC_SETLOGIN: 1723168951Srwatson case PRIV_PROC_SETRLIMIT: 1724168951Srwatson 1725168951Srwatson /* 1726168951Srwatson * Allow System V and POSIX IPC privileges. 1727168951Srwatson */ 1728168951Srwatson case PRIV_IPC_READ: 1729168951Srwatson case PRIV_IPC_WRITE: 1730168951Srwatson case PRIV_IPC_ADMIN: 1731168951Srwatson case PRIV_IPC_MSGSIZE: 1732168951Srwatson case PRIV_MQ_ADMIN: 1733168951Srwatson 1734168951Srwatson /* 1735168951Srwatson * Allow certain scheduler manipulations -- possibly this should be 1736168951Srwatson * controlled by more fine-grained policy, as potentially low 1737168951Srwatson * integrity processes can deny CPU to higher integrity ones. 1738168951Srwatson */ 1739168951Srwatson case PRIV_SCHED_DIFFCRED: 1740168951Srwatson case PRIV_SCHED_SETPRIORITY: 1741168951Srwatson case PRIV_SCHED_RTPRIO: 1742168951Srwatson case PRIV_SCHED_SETPOLICY: 1743168951Srwatson case PRIV_SCHED_SET: 1744168951Srwatson case PRIV_SCHED_SETPARAM: 1745168951Srwatson 1746168951Srwatson /* 1747168951Srwatson * More IPC privileges. 1748168951Srwatson */ 1749168951Srwatson case PRIV_SEM_WRITE: 1750168951Srwatson 1751168951Srwatson /* 1752168951Srwatson * Allow signaling privileges subject to integrity policy. 1753168951Srwatson */ 1754168951Srwatson case PRIV_SIGNAL_DIFFCRED: 1755168951Srwatson case PRIV_SIGNAL_SUGID: 1756168951Srwatson 1757168951Srwatson /* 1758168951Srwatson * Allow access to only limited sysctls from lower integrity levels; 1759168951Srwatson * piggy-back on the Jail definition. 1760168951Srwatson */ 1761168951Srwatson case PRIV_SYSCTL_WRITEJAIL: 1762168951Srwatson 1763168951Srwatson /* 1764168951Srwatson * Allow TTY-based privileges, subject to general device access using 1765168951Srwatson * labels on TTY device nodes, but not console privilege. 1766168951Srwatson */ 1767168951Srwatson case PRIV_TTY_DRAINWAIT: 1768168951Srwatson case PRIV_TTY_DTRWAIT: 1769168951Srwatson case PRIV_TTY_EXCLUSIVE: 1770168951Srwatson case PRIV_TTY_STI: 1771168951Srwatson case PRIV_TTY_SETA: 1772168951Srwatson 1773168951Srwatson /* 1774168951Srwatson * Grant most VFS privileges, as almost all are in practice bounded 1775168951Srwatson * by more specific checks using labels. 1776168951Srwatson */ 1777168951Srwatson case PRIV_VFS_READ: 1778168951Srwatson case PRIV_VFS_WRITE: 1779168951Srwatson case PRIV_VFS_ADMIN: 1780168951Srwatson case PRIV_VFS_EXEC: 1781168951Srwatson case PRIV_VFS_LOOKUP: 1782168951Srwatson case PRIV_VFS_CHFLAGS_DEV: 1783168951Srwatson case PRIV_VFS_CHOWN: 1784168951Srwatson case PRIV_VFS_CHROOT: 1785168951Srwatson case PRIV_VFS_RETAINSUGID: 1786168951Srwatson case PRIV_VFS_EXCEEDQUOTA: 1787168951Srwatson case PRIV_VFS_FCHROOT: 1788168951Srwatson case PRIV_VFS_FHOPEN: 1789168951Srwatson case PRIV_VFS_FHSTATFS: 1790168951Srwatson case PRIV_VFS_GENERATION: 1791168951Srwatson case PRIV_VFS_GETFH: 1792168951Srwatson case PRIV_VFS_GETQUOTA: 1793168951Srwatson case PRIV_VFS_LINK: 1794168951Srwatson case PRIV_VFS_MOUNT: 1795168951Srwatson case PRIV_VFS_MOUNT_OWNER: 1796168951Srwatson case PRIV_VFS_MOUNT_PERM: 1797168951Srwatson case PRIV_VFS_MOUNT_SUIDDIR: 1798168951Srwatson case PRIV_VFS_MOUNT_NONUSER: 1799168951Srwatson case PRIV_VFS_SETGID: 1800168951Srwatson case PRIV_VFS_STICKYFILE: 1801168951Srwatson case PRIV_VFS_SYSFLAGS: 1802168951Srwatson case PRIV_VFS_UNMOUNT: 1803168951Srwatson 1804168951Srwatson /* 1805168951Srwatson * Allow VM privileges; it would be nice if these were subject to 1806168951Srwatson * resource limits. 1807168951Srwatson */ 1808168951Srwatson case PRIV_VM_MADV_PROTECT: 1809168951Srwatson case PRIV_VM_MLOCK: 1810168951Srwatson case PRIV_VM_MUNLOCK: 1811194766Skib case PRIV_VM_SWAP_NOQUOTA: 1812194766Skib case PRIV_VM_SWAP_NORLIMIT: 1813168951Srwatson 1814168951Srwatson /* 1815168951Srwatson * Allow some but not all network privileges. In general, dont allow 1816168951Srwatson * reconfiguring the network stack, just normal use. 1817168951Srwatson */ 1818168951Srwatson case PRIV_NETINET_RESERVEDPORT: 1819168951Srwatson case PRIV_NETINET_RAW: 1820168951Srwatson case PRIV_NETINET_REUSEPORT: 1821168951Srwatson break; 1822168951Srwatson 1823168951Srwatson /* 1824168951Srwatson * All remaining system privileges are allow only if the process 1825168951Srwatson * holds privilege with respect to the LOMAC policy. 1826168951Srwatson */ 1827168951Srwatson default: 1828168951Srwatson subj = SLOT(cred->cr_label); 1829172955Srwatson error = lomac_subject_privileged(subj); 1830168951Srwatson if (error) 1831168951Srwatson return (error); 1832168951Srwatson } 1833168951Srwatson return (0); 1834168951Srwatson} 1835168951Srwatson 1836173138Srwatsonstatic int 1837173138Srwatsonlomac_proc_check_debug(struct ucred *cred, struct proc *p) 1838173138Srwatson{ 1839173138Srwatson struct mac_lomac *subj, *obj; 1840168951Srwatson 1841173138Srwatson if (!lomac_enabled) 1842173138Srwatson return (0); 1843173138Srwatson 1844173138Srwatson subj = SLOT(cred->cr_label); 1845173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1846173138Srwatson 1847173138Srwatson /* XXX: range checks */ 1848173138Srwatson if (!lomac_dominate_single(obj, subj)) 1849173138Srwatson return (ESRCH); 1850173138Srwatson if (!lomac_subject_dominate(subj, obj)) 1851173138Srwatson return (EACCES); 1852173138Srwatson 1853173138Srwatson return (0); 1854173138Srwatson} 1855173138Srwatson 1856168951Srwatsonstatic int 1857173138Srwatsonlomac_proc_check_sched(struct ucred *cred, struct proc *p) 1858173138Srwatson{ 1859173138Srwatson struct mac_lomac *subj, *obj; 1860173138Srwatson 1861173138Srwatson if (!lomac_enabled) 1862173138Srwatson return (0); 1863173138Srwatson 1864173138Srwatson subj = SLOT(cred->cr_label); 1865173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1866173138Srwatson 1867173138Srwatson /* XXX: range checks */ 1868173138Srwatson if (!lomac_dominate_single(obj, subj)) 1869173138Srwatson return (ESRCH); 1870173138Srwatson if (!lomac_subject_dominate(subj, obj)) 1871173138Srwatson return (EACCES); 1872173138Srwatson 1873173138Srwatson return (0); 1874173138Srwatson} 1875173138Srwatson 1876173138Srwatsonstatic int 1877173138Srwatsonlomac_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1878173138Srwatson{ 1879173138Srwatson struct mac_lomac *subj, *obj; 1880173138Srwatson 1881173138Srwatson if (!lomac_enabled) 1882173138Srwatson return (0); 1883173138Srwatson 1884173138Srwatson subj = SLOT(cred->cr_label); 1885173138Srwatson obj = SLOT(p->p_ucred->cr_label); 1886173138Srwatson 1887173138Srwatson /* XXX: range checks */ 1888173138Srwatson if (!lomac_dominate_single(obj, subj)) 1889173138Srwatson return (ESRCH); 1890173138Srwatson if (!lomac_subject_dominate(subj, obj)) 1891173138Srwatson return (EACCES); 1892173138Srwatson 1893173138Srwatson return (0); 1894173138Srwatson} 1895173138Srwatson 1896173138Srwatsonstatic void 1897173138Srwatsonlomac_proc_destroy_label(struct label *label) 1898173138Srwatson{ 1899173138Srwatson 1900173138Srwatson mtx_destroy(&PSLOT(label)->mtx); 1901184205Sdes free(PSLOT(label), M_LOMAC); 1902173138Srwatson PSLOT_SET(label, NULL); 1903173138Srwatson} 1904173138Srwatson 1905173138Srwatsonstatic void 1906173138Srwatsonlomac_proc_init_label(struct label *label) 1907173138Srwatson{ 1908173138Srwatson 1909173138Srwatson PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_LOMAC, 1910173138Srwatson M_ZERO | M_WAITOK)); 1911173138Srwatson mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF); 1912173138Srwatson} 1913173138Srwatson 1914173138Srwatsonstatic int 1915173138Srwatsonlomac_socket_check_deliver(struct socket *so, struct label *solabel, 1916173138Srwatson struct mbuf *m, struct label *mlabel) 1917173138Srwatson{ 1918173138Srwatson struct mac_lomac *p, *s; 1919193391Srwatson int error; 1920173138Srwatson 1921173138Srwatson if (!lomac_enabled) 1922173138Srwatson return (0); 1923173138Srwatson 1924173138Srwatson p = SLOT(mlabel); 1925173138Srwatson s = SLOT(solabel); 1926173138Srwatson 1927193391Srwatson SOCK_LOCK(so); 1928193391Srwatson error = lomac_equal_single(p, s) ? 0 : EACCES; 1929193391Srwatson SOCK_UNLOCK(so); 1930193391Srwatson return (error); 1931173138Srwatson} 1932173138Srwatson 1933173138Srwatsonstatic int 1934173138Srwatsonlomac_socket_check_relabel(struct ucred *cred, struct socket *so, 1935173138Srwatson struct label *solabel, struct label *newlabel) 1936173138Srwatson{ 1937173138Srwatson struct mac_lomac *subj, *obj, *new; 1938173138Srwatson int error; 1939173138Srwatson 1940193391Srwatson SOCK_LOCK_ASSERT(so); 1941193391Srwatson 1942173138Srwatson new = SLOT(newlabel); 1943173138Srwatson subj = SLOT(cred->cr_label); 1944173138Srwatson obj = SLOT(solabel); 1945173138Srwatson 1946173138Srwatson /* 1947173138Srwatson * If there is a LOMAC label update for the socket, it may be an 1948173138Srwatson * update of single. 1949173138Srwatson */ 1950173138Srwatson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1951173138Srwatson if (error) 1952173138Srwatson return (error); 1953173138Srwatson 1954173138Srwatson /* 1955173138Srwatson * To relabel a socket, the old socket single must be in the subject 1956173138Srwatson * range. 1957173138Srwatson */ 1958173138Srwatson if (!lomac_single_in_range(obj, subj)) 1959173138Srwatson return (EPERM); 1960173138Srwatson 1961173138Srwatson /* 1962173138Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 1963173138Srwatson */ 1964173138Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1965173138Srwatson /* 1966173138Srwatson * To relabel a socket, the new socket single must be in the 1967173138Srwatson * subject range. 1968173138Srwatson */ 1969173138Srwatson if (!lomac_single_in_range(new, subj)) 1970173138Srwatson return (EPERM); 1971173138Srwatson 1972173138Srwatson /* 1973173138Srwatson * To change the LOMAC label on the socket to contain EQUAL, 1974173138Srwatson * the subject must have appropriate privilege. 1975173138Srwatson */ 1976173138Srwatson if (lomac_contains_equal(new)) { 1977173138Srwatson error = lomac_subject_privileged(subj); 1978173138Srwatson if (error) 1979173138Srwatson return (error); 1980173138Srwatson } 1981173138Srwatson } 1982173138Srwatson 1983173138Srwatson return (0); 1984173138Srwatson} 1985173138Srwatson 1986173138Srwatsonstatic int 1987173138Srwatsonlomac_socket_check_visible(struct ucred *cred, struct socket *so, 1988173138Srwatson struct label *solabel) 1989173138Srwatson{ 1990173138Srwatson struct mac_lomac *subj, *obj; 1991173138Srwatson 1992173138Srwatson if (!lomac_enabled) 1993173138Srwatson return (0); 1994173138Srwatson 1995173138Srwatson subj = SLOT(cred->cr_label); 1996173138Srwatson obj = SLOT(solabel); 1997173138Srwatson 1998193391Srwatson SOCK_LOCK(so); 1999193391Srwatson if (!lomac_dominate_single(obj, subj)) { 2000193391Srwatson SOCK_UNLOCK(so); 2001173138Srwatson return (ENOENT); 2002193391Srwatson } 2003193391Srwatson SOCK_UNLOCK(so); 2004173138Srwatson 2005173138Srwatson return (0); 2006173138Srwatson} 2007173138Srwatson 2008173138Srwatsonstatic void 2009173138Srwatsonlomac_socket_create(struct ucred *cred, struct socket *so, 2010173138Srwatson struct label *solabel) 2011173138Srwatson{ 2012173138Srwatson struct mac_lomac *source, *dest; 2013173138Srwatson 2014173138Srwatson source = SLOT(cred->cr_label); 2015173138Srwatson dest = SLOT(solabel); 2016173138Srwatson 2017173138Srwatson lomac_copy_single(source, dest); 2018173138Srwatson} 2019173138Srwatson 2020173138Srwatsonstatic void 2021173138Srwatsonlomac_socket_create_mbuf(struct socket *so, struct label *solabel, 2022173138Srwatson struct mbuf *m, struct label *mlabel) 2023173138Srwatson{ 2024173138Srwatson struct mac_lomac *source, *dest; 2025173138Srwatson 2026173138Srwatson source = SLOT(solabel); 2027173138Srwatson dest = SLOT(mlabel); 2028173138Srwatson 2029193391Srwatson SOCK_LOCK(so); 2030173138Srwatson lomac_copy_single(source, dest); 2031193391Srwatson SOCK_UNLOCK(so); 2032173138Srwatson} 2033173138Srwatson 2034173138Srwatsonstatic void 2035173138Srwatsonlomac_socket_newconn(struct socket *oldso, struct label *oldsolabel, 2036173138Srwatson struct socket *newso, struct label *newsolabel) 2037173138Srwatson{ 2038193391Srwatson struct mac_lomac source, *dest; 2039173138Srwatson 2040193391Srwatson SOCK_LOCK(oldso); 2041193391Srwatson source = *SLOT(oldsolabel); 2042193391Srwatson SOCK_UNLOCK(oldso); 2043193391Srwatson 2044173138Srwatson dest = SLOT(newsolabel); 2045173138Srwatson 2046193391Srwatson SOCK_LOCK(newso); 2047193391Srwatson lomac_copy_single(&source, dest); 2048193391Srwatson SOCK_UNLOCK(newso); 2049173138Srwatson} 2050173138Srwatson 2051173138Srwatsonstatic void 2052173138Srwatsonlomac_socket_relabel(struct ucred *cred, struct socket *so, 2053173138Srwatson struct label *solabel, struct label *newlabel) 2054173138Srwatson{ 2055173138Srwatson struct mac_lomac *source, *dest; 2056173138Srwatson 2057193391Srwatson SOCK_LOCK_ASSERT(so); 2058193391Srwatson 2059173138Srwatson source = SLOT(newlabel); 2060173138Srwatson dest = SLOT(solabel); 2061173138Srwatson 2062173138Srwatson try_relabel(source, dest); 2063173138Srwatson} 2064173138Srwatson 2065173138Srwatsonstatic void 2066173138Srwatsonlomac_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 2067173138Srwatson struct socket *so, struct label *sopeerlabel) 2068173138Srwatson{ 2069173138Srwatson struct mac_lomac *source, *dest; 2070173138Srwatson 2071173138Srwatson source = SLOT(mlabel); 2072173138Srwatson dest = SLOT(sopeerlabel); 2073173138Srwatson 2074193391Srwatson SOCK_LOCK(so); 2075173138Srwatson lomac_copy_single(source, dest); 2076193391Srwatson SOCK_UNLOCK(so); 2077173138Srwatson} 2078173138Srwatson 2079173138Srwatsonstatic void 2080173138Srwatsonlomac_socketpeer_set_from_socket(struct socket *oldso, 2081173138Srwatson struct label *oldsolabel, struct socket *newso, 2082173138Srwatson struct label *newsopeerlabel) 2083173138Srwatson{ 2084193391Srwatson struct mac_lomac source, *dest; 2085173138Srwatson 2086193391Srwatson SOCK_LOCK(oldso); 2087193391Srwatson source = *SLOT(oldsolabel); 2088193391Srwatson SOCK_UNLOCK(oldso); 2089193391Srwatson 2090173138Srwatson dest = SLOT(newsopeerlabel); 2091173138Srwatson 2092193391Srwatson SOCK_LOCK(newso); 2093193391Srwatson lomac_copy_single(&source, dest); 2094193391Srwatson SOCK_UNLOCK(newso); 2095173138Srwatson} 2096173138Srwatson 2097173138Srwatsonstatic void 2098173138Srwatsonlomac_syncache_create(struct label *label, struct inpcb *inp) 2099173138Srwatson{ 2100173138Srwatson struct mac_lomac *source, *dest; 2101173138Srwatson 2102173138Srwatson source = SLOT(inp->inp_label); 2103173138Srwatson dest = SLOT(label); 2104173138Srwatson lomac_copy(source, dest); 2105173138Srwatson} 2106173138Srwatson 2107173138Srwatsonstatic void 2108173138Srwatsonlomac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2109173138Srwatson struct label *mlabel) 2110173138Srwatson{ 2111173138Srwatson struct mac_lomac *source, *dest; 2112173138Srwatson 2113173138Srwatson source = SLOT(sc_label); 2114173138Srwatson dest = SLOT(mlabel); 2115173138Srwatson lomac_copy(source, dest); 2116173138Srwatson} 2117173138Srwatson 2118173138Srwatsonstatic int 2119172955Srwatsonlomac_system_check_acct(struct ucred *cred, struct vnode *vp, 2120168976Srwatson struct label *vplabel) 2121168933Srwatson{ 2122168933Srwatson struct mac_lomac *subj, *obj; 2123168933Srwatson 2124172955Srwatson if (!lomac_enabled) 2125168933Srwatson return (0); 2126168933Srwatson 2127168933Srwatson subj = SLOT(cred->cr_label); 2128168976Srwatson obj = SLOT(vplabel); 2129168933Srwatson 2130172955Srwatson if (lomac_subject_privileged(subj)) 2131168933Srwatson return (EPERM); 2132168933Srwatson 2133172955Srwatson if (!lomac_high_single(obj)) 2134168933Srwatson return (EACCES); 2135168933Srwatson 2136168933Srwatson return (0); 2137168933Srwatson} 2138168933Srwatson 2139168933Srwatsonstatic int 2140172955Srwatsonlomac_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2141168976Srwatson struct label *vplabel) 2142168933Srwatson{ 2143168933Srwatson struct mac_lomac *subj, *obj; 2144168933Srwatson 2145172955Srwatson if (!lomac_enabled) 2146168933Srwatson return (0); 2147168933Srwatson 2148168933Srwatson subj = SLOT(cred->cr_label); 2149168976Srwatson obj = SLOT(vplabel); 2150168933Srwatson 2151172955Srwatson if (lomac_subject_privileged(subj)) 2152168933Srwatson return (EPERM); 2153168933Srwatson 2154172955Srwatson if (!lomac_high_single(obj)) 2155168933Srwatson return (EACCES); 2156168933Srwatson 2157168933Srwatson return (0); 2158168933Srwatson} 2159168933Srwatson 2160168933Srwatsonstatic int 2161172955Srwatsonlomac_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2162168976Srwatson struct label *vplabel) 2163168933Srwatson{ 2164168933Srwatson struct mac_lomac *subj; 2165168933Srwatson 2166172955Srwatson if (!lomac_enabled) 2167168933Srwatson return (0); 2168168933Srwatson 2169168933Srwatson subj = SLOT(cred->cr_label); 2170168933Srwatson 2171172955Srwatson if (lomac_subject_privileged(subj)) 2172168933Srwatson return (EPERM); 2173168933Srwatson 2174168933Srwatson return (0); 2175168933Srwatson} 2176168933Srwatson 2177168933Srwatsonstatic int 2178172955Srwatsonlomac_system_check_swapon(struct ucred *cred, struct vnode *vp, 2179168976Srwatson struct label *vplabel) 2180107273Srwatson{ 2181107273Srwatson struct mac_lomac *subj, *obj; 2182107273Srwatson 2183172955Srwatson if (!lomac_enabled) 2184107273Srwatson return (0); 2185107273Srwatson 2186122524Srwatson subj = SLOT(cred->cr_label); 2187168976Srwatson obj = SLOT(vplabel); 2188107273Srwatson 2189172955Srwatson if (lomac_subject_privileged(subj)) 2190107273Srwatson return (EPERM); 2191107273Srwatson 2192172955Srwatson if (!lomac_high_single(obj)) 2193107273Srwatson return (EACCES); 2194107273Srwatson 2195107273Srwatson return (0); 2196107273Srwatson} 2197107273Srwatson 2198107273Srwatsonstatic int 2199172955Srwatsonlomac_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2200126121Spjd void *arg1, int arg2, struct sysctl_req *req) 2201107273Srwatson{ 2202107273Srwatson struct mac_lomac *subj; 2203107273Srwatson 2204172955Srwatson if (!lomac_enabled) 2205107273Srwatson return (0); 2206107273Srwatson 2207122524Srwatson subj = SLOT(cred->cr_label); 2208107273Srwatson 2209107273Srwatson /* 2210172955Srwatson * Treat sysctl variables without CTLFLAG_ANYBODY flag as lomac/high, 2211172955Srwatson * but also require privilege to change them. 2212107273Srwatson */ 2213126121Spjd if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2214107273Srwatson#ifdef notdef 2215172955Srwatson if (!lomac_subject_dominate_high(subj)) 2216107273Srwatson return (EACCES); 2217107273Srwatson#endif 2218107273Srwatson 2219172955Srwatson if (lomac_subject_privileged(subj)) 2220107273Srwatson return (EPERM); 2221107273Srwatson } 2222107273Srwatson 2223107273Srwatson return (0); 2224107273Srwatson} 2225107273Srwatson 2226173138Srwatsonstatic void 2227173138Srwatsonlomac_thread_userret(struct thread *td) 2228173138Srwatson{ 2229173138Srwatson struct proc *p = td->td_proc; 2230173138Srwatson struct mac_lomac_proc *subj = PSLOT(p->p_label); 2231173138Srwatson struct ucred *newcred, *oldcred; 2232173138Srwatson int dodrop; 2233173138Srwatson 2234173138Srwatson mtx_lock(&subj->mtx); 2235173138Srwatson if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 2236173138Srwatson dodrop = 0; 2237173138Srwatson mtx_unlock(&subj->mtx); 2238173138Srwatson newcred = crget(); 2239173138Srwatson /* 2240184412Srwatson * Prevent a lock order reversal in mac_proc_vm_revoke; 2241184412Srwatson * ideally, the other user of subj->mtx wouldn't be holding 2242184412Srwatson * Giant. 2243173138Srwatson */ 2244173138Srwatson mtx_lock(&Giant); 2245173138Srwatson PROC_LOCK(p); 2246173138Srwatson mtx_lock(&subj->mtx); 2247173138Srwatson /* 2248173138Srwatson * Check if we lost the race while allocating the cred. 2249173138Srwatson */ 2250173138Srwatson if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2251173138Srwatson crfree(newcred); 2252173138Srwatson goto out; 2253173138Srwatson } 2254173138Srwatson oldcred = p->p_ucred; 2255173138Srwatson crcopy(newcred, oldcred); 2256173138Srwatson crhold(newcred); 2257173138Srwatson lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2258280130Smjg proc_set_cred(p, newcred); 2259173138Srwatson crfree(oldcred); 2260173138Srwatson dodrop = 1; 2261173138Srwatson out: 2262173138Srwatson mtx_unlock(&subj->mtx); 2263173138Srwatson PROC_UNLOCK(p); 2264173138Srwatson if (dodrop) 2265184412Srwatson mac_proc_vm_revoke(curthread); 2266173138Srwatson mtx_unlock(&Giant); 2267173138Srwatson } else { 2268173138Srwatson mtx_unlock(&subj->mtx); 2269173138Srwatson } 2270173138Srwatson} 2271173138Srwatson 2272107273Srwatsonstatic int 2273173138Srwatsonlomac_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2274173138Srwatson struct vnode *vp, struct label *vplabel) 2275173138Srwatson{ 2276173138Srwatson struct mac_lomac ml_temp, *source, *dest; 2277173138Srwatson int buflen, error; 2278173138Srwatson 2279173138Srwatson source = SLOT(mplabel); 2280173138Srwatson dest = SLOT(vplabel); 2281173138Srwatson 2282173138Srwatson buflen = sizeof(ml_temp); 2283173138Srwatson bzero(&ml_temp, buflen); 2284173138Srwatson 2285173138Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2286173138Srwatson MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&ml_temp, curthread); 2287173138Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 2288173138Srwatson /* Fall back to the mntlabel. */ 2289173138Srwatson lomac_copy_single(source, dest); 2290173138Srwatson return (0); 2291173138Srwatson } else if (error) 2292173138Srwatson return (error); 2293173138Srwatson 2294173138Srwatson if (buflen != sizeof(ml_temp)) { 2295173138Srwatson if (buflen != sizeof(ml_temp) - sizeof(ml_temp.ml_auxsingle)) { 2296173138Srwatson printf("lomac_vnode_associate_extattr: bad size %d\n", 2297173138Srwatson buflen); 2298173138Srwatson return (EPERM); 2299173138Srwatson } 2300173138Srwatson bzero(&ml_temp.ml_auxsingle, sizeof(ml_temp.ml_auxsingle)); 2301173138Srwatson buflen = sizeof(ml_temp); 2302173138Srwatson (void)vn_extattr_set(vp, IO_NODELOCKED, 2303173138Srwatson MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 2304173138Srwatson buflen, (char *)&ml_temp, curthread); 2305173138Srwatson } 2306173138Srwatson if (lomac_valid(&ml_temp) != 0) { 2307173138Srwatson printf("lomac_vnode_associate_extattr: invalid\n"); 2308173138Srwatson return (EPERM); 2309173138Srwatson } 2310173138Srwatson if ((ml_temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != 2311173138Srwatson MAC_LOMAC_FLAG_SINGLE) { 2312173138Srwatson printf("lomac_vnode_associate_extattr: not single\n"); 2313173138Srwatson return (EPERM); 2314173138Srwatson } 2315173138Srwatson 2316173138Srwatson lomac_copy_single(&ml_temp, dest); 2317173138Srwatson return (0); 2318173138Srwatson} 2319173138Srwatson 2320173138Srwatsonstatic void 2321173138Srwatsonlomac_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2322173138Srwatson struct vnode *vp, struct label *vplabel) 2323173138Srwatson{ 2324173138Srwatson struct mac_lomac *source, *dest; 2325173138Srwatson 2326173138Srwatson source = SLOT(mplabel); 2327173138Srwatson dest = SLOT(vplabel); 2328173138Srwatson 2329173138Srwatson lomac_copy_single(source, dest); 2330173138Srwatson} 2331173138Srwatson 2332173138Srwatsonstatic int 2333172955Srwatsonlomac_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2334168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2335107273Srwatson{ 2336107273Srwatson struct mac_lomac *subj, *obj; 2337107273Srwatson 2338172955Srwatson if (!lomac_enabled) 2339107273Srwatson return (0); 2340107273Srwatson 2341122524Srwatson subj = SLOT(cred->cr_label); 2342168976Srwatson obj = SLOT(dvplabel); 2343107273Srwatson 2344172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2345107273Srwatson return (EACCES); 2346107273Srwatson if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2347172955Srwatson !lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2348107273Srwatson return (EACCES); 2349107273Srwatson 2350107273Srwatson return (0); 2351107273Srwatson} 2352107273Srwatson 2353107273Srwatsonstatic int 2354172955Srwatsonlomac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2355168976Srwatson struct label *vplabel, acl_type_t type) 2356107273Srwatson{ 2357107273Srwatson struct mac_lomac *subj, *obj; 2358107273Srwatson 2359172955Srwatson if (!lomac_enabled) 2360107273Srwatson return (0); 2361107273Srwatson 2362122524Srwatson subj = SLOT(cred->cr_label); 2363168976Srwatson obj = SLOT(vplabel); 2364107273Srwatson 2365172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2366107273Srwatson return (EACCES); 2367107273Srwatson 2368107273Srwatson return (0); 2369107273Srwatson} 2370107273Srwatson 2371107273Srwatsonstatic int 2372172955Srwatsonlomac_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2373168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2374107273Srwatson struct componentname *cnp) 2375107273Srwatson{ 2376107273Srwatson struct mac_lomac *subj, *obj; 2377107273Srwatson 2378172955Srwatson if (!lomac_enabled) 2379107273Srwatson return (0); 2380107273Srwatson 2381122524Srwatson subj = SLOT(cred->cr_label); 2382168976Srwatson obj = SLOT(dvplabel); 2383107273Srwatson 2384172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2385107273Srwatson return (EACCES); 2386107273Srwatson 2387168976Srwatson obj = SLOT(vplabel); 2388107273Srwatson 2389172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2390107273Srwatson return (EACCES); 2391107273Srwatson 2392107273Srwatson return (0); 2393107273Srwatson} 2394107273Srwatson 2395107273Srwatsonstatic int 2396172955Srwatsonlomac_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2397168976Srwatson struct label *vplabel, int prot, int flags) 2398107273Srwatson{ 2399107273Srwatson struct mac_lomac *subj, *obj; 2400107273Srwatson 2401107273Srwatson /* 2402107273Srwatson * Rely on the use of open()-time protections to handle 2403107273Srwatson * non-revocation cases. 2404107273Srwatson */ 2405172955Srwatson if (!lomac_enabled) 2406107273Srwatson return (0); 2407107273Srwatson 2408122524Srwatson subj = SLOT(cred->cr_label); 2409168976Srwatson obj = SLOT(vplabel); 2410107273Srwatson 2411145076Scsjp if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2412172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2413107273Srwatson return (EACCES); 2414107273Srwatson } 2415107273Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2416172955Srwatson if (!lomac_dominate_single(obj, subj)) 2417107273Srwatson return (maybe_demote(subj, obj, "mapping", "file", vp)); 2418107273Srwatson } 2419107273Srwatson 2420107273Srwatson return (0); 2421107273Srwatson} 2422107273Srwatson 2423107273Srwatsonstatic void 2424172955Srwatsonlomac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp, 2425168976Srwatson struct label *vplabel, /* XXX vm_prot_t */ int *prot) 2426107273Srwatson{ 2427107273Srwatson struct mac_lomac *subj, *obj; 2428107273Srwatson 2429107273Srwatson /* 2430107273Srwatson * Rely on the use of open()-time protections to handle 2431107273Srwatson * non-revocation cases. 2432107273Srwatson */ 2433172955Srwatson if (!lomac_enabled || !revocation_enabled) 2434107273Srwatson return; 2435107273Srwatson 2436122524Srwatson subj = SLOT(cred->cr_label); 2437168976Srwatson obj = SLOT(vplabel); 2438107273Srwatson 2439172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2440107273Srwatson *prot &= ~VM_PROT_WRITE; 2441107273Srwatson} 2442107273Srwatson 2443107273Srwatsonstatic int 2444172955Srwatsonlomac_vnode_check_open(struct ucred *cred, struct vnode *vp, 2445184413Strasz struct label *vplabel, accmode_t accmode) 2446107273Srwatson{ 2447107273Srwatson struct mac_lomac *subj, *obj; 2448107273Srwatson 2449172955Srwatson if (!lomac_enabled) 2450107273Srwatson return (0); 2451107273Srwatson 2452122524Srwatson subj = SLOT(cred->cr_label); 2453168976Srwatson obj = SLOT(vplabel); 2454107273Srwatson 2455107273Srwatson /* XXX privilege override for admin? */ 2456201438Strasz if (accmode & VMODIFY_PERMS) { 2457172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2458107273Srwatson return (EACCES); 2459107273Srwatson } 2460107273Srwatson 2461107273Srwatson return (0); 2462107273Srwatson} 2463107273Srwatson 2464107273Srwatsonstatic int 2465172955Srwatsonlomac_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2466168976Srwatson struct vnode *vp, struct label *vplabel) 2467107273Srwatson{ 2468107273Srwatson struct mac_lomac *subj, *obj; 2469107273Srwatson 2470172955Srwatson if (!lomac_enabled || !revocation_enabled) 2471107273Srwatson return (0); 2472107273Srwatson 2473122524Srwatson subj = SLOT(active_cred->cr_label); 2474168976Srwatson obj = SLOT(vplabel); 2475107273Srwatson 2476172955Srwatson if (!lomac_dominate_single(obj, subj)) 2477107273Srwatson return (maybe_demote(subj, obj, "reading", "file", vp)); 2478107273Srwatson 2479107273Srwatson return (0); 2480107273Srwatson} 2481107273Srwatson 2482107273Srwatsonstatic int 2483172955Srwatsonlomac_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2484168976Srwatson struct label *vplabel, struct label *newlabel) 2485107273Srwatson{ 2486107273Srwatson struct mac_lomac *old, *new, *subj; 2487107273Srwatson int error; 2488107273Srwatson 2489168976Srwatson old = SLOT(vplabel); 2490107273Srwatson new = SLOT(newlabel); 2491122524Srwatson subj = SLOT(cred->cr_label); 2492107273Srwatson 2493107273Srwatson /* 2494107273Srwatson * If there is a LOMAC label update for the vnode, it must be a 2495107273Srwatson * single label, with an optional explicit auxiliary single. 2496107273Srwatson */ 2497107273Srwatson error = lomac_atmostflags(new, 2498107273Srwatson MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2499107273Srwatson if (error) 2500107273Srwatson return (error); 2501107273Srwatson 2502107273Srwatson /* 2503107273Srwatson * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2504107273Srwatson * authorize the relabel. 2505107273Srwatson */ 2506172955Srwatson if (!lomac_single_in_range(old, subj)) 2507107273Srwatson return (EPERM); 2508107273Srwatson 2509107273Srwatson /* 2510107273Srwatson * If the LOMAC label is to be changed, authorize as appropriate. 2511107273Srwatson */ 2512107273Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2513107273Srwatson /* 2514107273Srwatson * To change the LOMAC label on a vnode, the new vnode label 2515107273Srwatson * must be in the subject range. 2516107273Srwatson */ 2517172955Srwatson if (!lomac_single_in_range(new, subj)) 2518107273Srwatson return (EPERM); 2519107273Srwatson 2520107273Srwatson /* 2521172955Srwatson * To change the LOMAC label on the vnode to be EQUAL, the 2522172955Srwatson * subject must have appropriate privilege. 2523107273Srwatson */ 2524172955Srwatson if (lomac_contains_equal(new)) { 2525172955Srwatson error = lomac_subject_privileged(subj); 2526107273Srwatson if (error) 2527107273Srwatson return (error); 2528107273Srwatson } 2529107273Srwatson } 2530107273Srwatson if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2531107273Srwatson /* 2532119242Srwatson * Fill in the missing parts from the previous label. 2533119242Srwatson */ 2534119242Srwatson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2535172955Srwatson lomac_copy_single(subj, new); 2536119242Srwatson 2537119242Srwatson /* 2538107273Srwatson * To change the auxiliary LOMAC label on a vnode, the new 2539107273Srwatson * vnode label must be in the subject range. 2540107273Srwatson */ 2541172955Srwatson if (!lomac_auxsingle_in_range(new, subj)) 2542107273Srwatson return (EPERM); 2543107273Srwatson 2544107273Srwatson /* 2545107273Srwatson * To change the auxiliary LOMAC label on the vnode to be 2546107273Srwatson * EQUAL, the subject must have appropriate privilege. 2547107273Srwatson */ 2548172955Srwatson if (lomac_contains_equal(new)) { 2549172955Srwatson error = lomac_subject_privileged(subj); 2550107273Srwatson if (error) 2551107273Srwatson return (error); 2552107273Srwatson } 2553107273Srwatson } 2554107273Srwatson 2555107273Srwatson return (0); 2556107273Srwatson} 2557107273Srwatson 2558107273Srwatsonstatic int 2559172955Srwatsonlomac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2560168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2561107273Srwatson struct componentname *cnp) 2562107273Srwatson{ 2563107273Srwatson struct mac_lomac *subj, *obj; 2564107273Srwatson 2565172955Srwatson if (!lomac_enabled) 2566107273Srwatson return (0); 2567107273Srwatson 2568122524Srwatson subj = SLOT(cred->cr_label); 2569168976Srwatson obj = SLOT(dvplabel); 2570107273Srwatson 2571172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2572107273Srwatson return (EACCES); 2573107273Srwatson 2574168976Srwatson obj = SLOT(vplabel); 2575107273Srwatson 2576172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2577107273Srwatson return (EACCES); 2578107273Srwatson 2579107273Srwatson return (0); 2580107273Srwatson} 2581107273Srwatson 2582107273Srwatsonstatic int 2583172955Srwatsonlomac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2584168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2585168976Srwatson int samedir, struct componentname *cnp) 2586107273Srwatson{ 2587107273Srwatson struct mac_lomac *subj, *obj; 2588107273Srwatson 2589172955Srwatson if (!lomac_enabled) 2590107273Srwatson return (0); 2591107273Srwatson 2592122524Srwatson subj = SLOT(cred->cr_label); 2593168976Srwatson obj = SLOT(dvplabel); 2594107273Srwatson 2595172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2596107273Srwatson return (EACCES); 2597107273Srwatson 2598107273Srwatson if (vp != NULL) { 2599168976Srwatson obj = SLOT(vplabel); 2600107273Srwatson 2601172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2602107273Srwatson return (EACCES); 2603107273Srwatson } 2604107273Srwatson 2605107273Srwatson return (0); 2606107273Srwatson} 2607107273Srwatson 2608107273Srwatsonstatic int 2609172955Srwatsonlomac_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2610168976Srwatson struct label *vplabel) 2611107273Srwatson{ 2612107273Srwatson struct mac_lomac *subj, *obj; 2613107273Srwatson 2614172955Srwatson if (!lomac_enabled) 2615107273Srwatson return (0); 2616107273Srwatson 2617122524Srwatson subj = SLOT(cred->cr_label); 2618168976Srwatson obj = SLOT(vplabel); 2619107273Srwatson 2620172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2621107273Srwatson return (EACCES); 2622107273Srwatson 2623107273Srwatson return (0); 2624107273Srwatson} 2625107273Srwatson 2626107273Srwatsonstatic int 2627172955Srwatsonlomac_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2628168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 2629107273Srwatson{ 2630107273Srwatson struct mac_lomac *subj, *obj; 2631107273Srwatson 2632172955Srwatson if (!lomac_enabled) 2633107273Srwatson return (0); 2634107273Srwatson 2635122524Srwatson subj = SLOT(cred->cr_label); 2636168976Srwatson obj = SLOT(vplabel); 2637107273Srwatson 2638172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2639107273Srwatson return (EACCES); 2640107273Srwatson 2641107273Srwatson return (0); 2642107273Srwatson} 2643107273Srwatson 2644107273Srwatsonstatic int 2645172955Srwatsonlomac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2646189533Srwatson struct label *vplabel, int attrnamespace, const char *name) 2647107273Srwatson{ 2648107273Srwatson struct mac_lomac *subj, *obj; 2649107273Srwatson 2650172955Srwatson if (!lomac_enabled) 2651107273Srwatson return (0); 2652107273Srwatson 2653122524Srwatson subj = SLOT(cred->cr_label); 2654168976Srwatson obj = SLOT(vplabel); 2655107273Srwatson 2656172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2657107273Srwatson return (EACCES); 2658107273Srwatson 2659107273Srwatson /* XXX: protect the MAC EA in a special way? */ 2660107273Srwatson 2661107273Srwatson return (0); 2662107273Srwatson} 2663107273Srwatson 2664107273Srwatsonstatic int 2665172955Srwatsonlomac_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2666168976Srwatson struct label *vplabel, u_long flags) 2667107273Srwatson{ 2668107273Srwatson struct mac_lomac *subj, *obj; 2669107273Srwatson 2670172955Srwatson if (!lomac_enabled) 2671107273Srwatson return (0); 2672107273Srwatson 2673122524Srwatson subj = SLOT(cred->cr_label); 2674168976Srwatson obj = SLOT(vplabel); 2675107273Srwatson 2676172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2677107273Srwatson return (EACCES); 2678107273Srwatson 2679107273Srwatson return (0); 2680107273Srwatson} 2681107273Srwatson 2682107273Srwatsonstatic int 2683172955Srwatsonlomac_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 2684168976Srwatson struct label *vplabel, mode_t mode) 2685107273Srwatson{ 2686107273Srwatson struct mac_lomac *subj, *obj; 2687107273Srwatson 2688172955Srwatson if (!lomac_enabled) 2689107273Srwatson return (0); 2690107273Srwatson 2691122524Srwatson subj = SLOT(cred->cr_label); 2692168976Srwatson obj = SLOT(vplabel); 2693107273Srwatson 2694172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2695107273Srwatson return (EACCES); 2696107273Srwatson 2697107273Srwatson return (0); 2698107273Srwatson} 2699107273Srwatson 2700107273Srwatsonstatic int 2701172955Srwatsonlomac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 2702168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 2703107273Srwatson{ 2704107273Srwatson struct mac_lomac *subj, *obj; 2705107273Srwatson 2706172955Srwatson if (!lomac_enabled) 2707107273Srwatson return (0); 2708107273Srwatson 2709122524Srwatson subj = SLOT(cred->cr_label); 2710168976Srwatson obj = SLOT(vplabel); 2711107273Srwatson 2712172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2713107273Srwatson return (EACCES); 2714107273Srwatson 2715107273Srwatson return (0); 2716107273Srwatson} 2717107273Srwatson 2718107273Srwatsonstatic int 2719172955Srwatsonlomac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 2720168976Srwatson struct label *vplabel, struct timespec atime, struct timespec mtime) 2721107273Srwatson{ 2722107273Srwatson struct mac_lomac *subj, *obj; 2723107273Srwatson 2724172955Srwatson if (!lomac_enabled) 2725107273Srwatson return (0); 2726107273Srwatson 2727122524Srwatson subj = SLOT(cred->cr_label); 2728168976Srwatson obj = SLOT(vplabel); 2729107273Srwatson 2730172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2731107273Srwatson return (EACCES); 2732107273Srwatson 2733107273Srwatson return (0); 2734107273Srwatson} 2735107273Srwatson 2736107273Srwatsonstatic int 2737172955Srwatsonlomac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 2738172107Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2739172107Srwatson struct componentname *cnp) 2740172107Srwatson{ 2741172107Srwatson struct mac_lomac *subj, *obj; 2742172107Srwatson 2743172955Srwatson if (!lomac_enabled) 2744172107Srwatson return (0); 2745172107Srwatson 2746172107Srwatson subj = SLOT(cred->cr_label); 2747172107Srwatson obj = SLOT(dvplabel); 2748172107Srwatson 2749172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2750172107Srwatson return (EACCES); 2751172107Srwatson 2752172107Srwatson obj = SLOT(vplabel); 2753172107Srwatson 2754172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2755172107Srwatson return (EACCES); 2756172107Srwatson 2757172107Srwatson return (0); 2758172107Srwatson} 2759172107Srwatson 2760172107Srwatsonstatic int 2761172955Srwatsonlomac_vnode_check_write(struct ucred *active_cred, 2762168976Srwatson struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 2763107273Srwatson{ 2764107273Srwatson struct mac_lomac *subj, *obj; 2765107273Srwatson 2766172955Srwatson if (!lomac_enabled || !revocation_enabled) 2767107273Srwatson return (0); 2768107273Srwatson 2769122524Srwatson subj = SLOT(active_cred->cr_label); 2770168976Srwatson obj = SLOT(vplabel); 2771107273Srwatson 2772172955Srwatson if (!lomac_subject_dominate(subj, obj)) 2773107273Srwatson return (EACCES); 2774107273Srwatson 2775107273Srwatson return (0); 2776107273Srwatson} 2777107273Srwatson 2778173138Srwatsonstatic int 2779173138Srwatsonlomac_vnode_create_extattr(struct ucred *cred, struct mount *mp, 2780173138Srwatson struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 2781173138Srwatson struct vnode *vp, struct label *vplabel, struct componentname *cnp) 2782107273Srwatson{ 2783173138Srwatson struct mac_lomac *source, *dest, *dir, temp; 2784173138Srwatson size_t buflen; 2785173138Srwatson int error; 2786107273Srwatson 2787173138Srwatson buflen = sizeof(temp); 2788173138Srwatson bzero(&temp, buflen); 2789173138Srwatson 2790173138Srwatson source = SLOT(cred->cr_label); 2791173138Srwatson dest = SLOT(vplabel); 2792173138Srwatson dir = SLOT(dvplabel); 2793173138Srwatson if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 2794173138Srwatson lomac_copy_auxsingle(dir, &temp); 2795173138Srwatson lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 2796173138Srwatson dir->ml_auxsingle.mle_grade); 2797107273Srwatson } else { 2798173138Srwatson lomac_copy_single(source, &temp); 2799107273Srwatson } 2800173138Srwatson 2801173138Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2802173138Srwatson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2803173138Srwatson if (error == 0) 2804173138Srwatson lomac_copy(&temp, dest); 2805173138Srwatson return (error); 2806107273Srwatson} 2807107273Srwatson 2808173138Srwatsonstatic void 2809173138Srwatsonlomac_vnode_execve_transition(struct ucred *old, struct ucred *new, 2810173138Srwatson struct vnode *vp, struct label *vplabel, struct label *interpvplabel, 2811173138Srwatson struct image_params *imgp, struct label *execlabel) 2812173138Srwatson{ 2813173138Srwatson struct mac_lomac *source, *dest, *obj, *robj; 2814173138Srwatson 2815173138Srwatson source = SLOT(old->cr_label); 2816173138Srwatson dest = SLOT(new->cr_label); 2817173138Srwatson obj = SLOT(vplabel); 2818173138Srwatson robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2819173138Srwatson 2820173138Srwatson lomac_copy(source, dest); 2821173138Srwatson /* 2822173138Srwatson * If there's an auxiliary label on the real object, respect it and 2823173138Srwatson * assume that this level should be assumed immediately if a higher 2824173138Srwatson * level is currently in place. 2825173138Srwatson */ 2826173138Srwatson if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2827173138Srwatson !lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 2828173138Srwatson && lomac_auxsingle_in_range(robj, dest)) 2829173138Srwatson lomac_set_single(dest, robj->ml_auxsingle.mle_type, 2830173138Srwatson robj->ml_auxsingle.mle_grade); 2831173138Srwatson /* 2832173138Srwatson * Restructuring to use the execve transitioning mechanism instead of 2833173138Srwatson * the normal demotion mechanism here would be difficult, so just 2834173138Srwatson * copy the label over and perform standard demotion. This is also 2835173138Srwatson * non-optimal because it will result in the intermediate label "new" 2836173138Srwatson * being created and immediately recycled. 2837173138Srwatson */ 2838173138Srwatson if (lomac_enabled && revocation_enabled && 2839173138Srwatson !lomac_dominate_single(obj, source)) 2840173138Srwatson (void)maybe_demote(source, obj, "executing", "file", vp); 2841173138Srwatson} 2842173138Srwatson 2843173138Srwatsonstatic int 2844173138Srwatsonlomac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp, 2845173138Srwatson struct label *vplabel, struct label *interpvplabel, 2846173138Srwatson struct image_params *imgp, struct label *execlabel) 2847173138Srwatson{ 2848173138Srwatson struct mac_lomac *subj, *obj, *robj; 2849173138Srwatson 2850173138Srwatson if (!lomac_enabled || !revocation_enabled) 2851173138Srwatson return (0); 2852173138Srwatson 2853173138Srwatson subj = SLOT(old->cr_label); 2854173138Srwatson obj = SLOT(vplabel); 2855173138Srwatson robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2856173138Srwatson 2857173138Srwatson return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2858173138Srwatson !lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 2859173138Srwatson && lomac_auxsingle_in_range(robj, subj)) || 2860173138Srwatson !lomac_dominate_single(obj, subj)); 2861173138Srwatson} 2862173138Srwatson 2863173138Srwatsonstatic void 2864173138Srwatsonlomac_vnode_relabel(struct ucred *cred, struct vnode *vp, 2865173138Srwatson struct label *vplabel, struct label *newlabel) 2866173138Srwatson{ 2867173138Srwatson struct mac_lomac *source, *dest; 2868173138Srwatson 2869173138Srwatson source = SLOT(newlabel); 2870173138Srwatson dest = SLOT(vplabel); 2871173138Srwatson 2872173138Srwatson try_relabel(source, dest); 2873173138Srwatson} 2874173138Srwatson 2875173138Srwatsonstatic int 2876173138Srwatsonlomac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 2877173138Srwatson struct label *vplabel, struct label *intlabel) 2878173138Srwatson{ 2879173138Srwatson struct mac_lomac *source, temp; 2880173138Srwatson size_t buflen; 2881173138Srwatson int error; 2882173138Srwatson 2883173138Srwatson buflen = sizeof(temp); 2884173138Srwatson bzero(&temp, buflen); 2885173138Srwatson 2886173138Srwatson source = SLOT(intlabel); 2887173138Srwatson if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2888173138Srwatson return (0); 2889173138Srwatson 2890173138Srwatson lomac_copy_single(source, &temp); 2891173138Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2892173138Srwatson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2893173138Srwatson return (error); 2894173138Srwatson} 2895173138Srwatson 2896172955Srwatsonstatic struct mac_policy_ops lomac_ops = 2897107273Srwatson{ 2898172955Srwatson .mpo_init = lomac_init, 2899173138Srwatson 2900173138Srwatson .mpo_bpfdesc_check_receive = lomac_bpfdesc_check_receive, 2901173138Srwatson .mpo_bpfdesc_create = lomac_bpfdesc_create, 2902173138Srwatson .mpo_bpfdesc_create_mbuf = lomac_bpfdesc_create_mbuf, 2903173138Srwatson .mpo_bpfdesc_destroy_label = lomac_destroy_label, 2904172955Srwatson .mpo_bpfdesc_init_label = lomac_init_label, 2905173138Srwatson 2906173138Srwatson .mpo_cred_check_relabel = lomac_cred_check_relabel, 2907173138Srwatson .mpo_cred_check_visible = lomac_cred_check_visible, 2908173138Srwatson .mpo_cred_copy_label = lomac_copy_label, 2909184407Srwatson .mpo_cred_create_swapper = lomac_cred_create_swapper, 2910184407Srwatson .mpo_cred_create_init = lomac_cred_create_init, 2911172955Srwatson .mpo_cred_destroy_label = lomac_destroy_label, 2912172955Srwatson .mpo_cred_externalize_label = lomac_externalize_label, 2913173138Srwatson .mpo_cred_init_label = lomac_init_label, 2914172955Srwatson .mpo_cred_internalize_label = lomac_internalize_label, 2915173138Srwatson .mpo_cred_relabel = lomac_cred_relabel, 2916173138Srwatson 2917172955Srwatson .mpo_devfs_create_device = lomac_devfs_create_device, 2918172955Srwatson .mpo_devfs_create_directory = lomac_devfs_create_directory, 2919172955Srwatson .mpo_devfs_create_symlink = lomac_devfs_create_symlink, 2920173138Srwatson .mpo_devfs_destroy_label = lomac_destroy_label, 2921173138Srwatson .mpo_devfs_init_label = lomac_init_label, 2922172955Srwatson .mpo_devfs_update = lomac_devfs_update, 2923172955Srwatson .mpo_devfs_vnode_associate = lomac_devfs_vnode_associate, 2924173138Srwatson 2925173138Srwatson .mpo_ifnet_check_relabel = lomac_ifnet_check_relabel, 2926173138Srwatson .mpo_ifnet_check_transmit = lomac_ifnet_check_transmit, 2927173138Srwatson .mpo_ifnet_copy_label = lomac_copy_label, 2928172955Srwatson .mpo_ifnet_create = lomac_ifnet_create, 2929173138Srwatson .mpo_ifnet_create_mbuf = lomac_ifnet_create_mbuf, 2930173138Srwatson .mpo_ifnet_destroy_label = lomac_destroy_label, 2931173138Srwatson .mpo_ifnet_externalize_label = lomac_externalize_label, 2932173138Srwatson .mpo_ifnet_init_label = lomac_init_label, 2933173138Srwatson .mpo_ifnet_internalize_label = lomac_internalize_label, 2934173138Srwatson .mpo_ifnet_relabel = lomac_ifnet_relabel, 2935173138Srwatson 2936173138Srwatson .mpo_syncache_create = lomac_syncache_create, 2937173138Srwatson .mpo_syncache_destroy_label = lomac_destroy_label, 2938173138Srwatson .mpo_syncache_init_label = lomac_init_label_waitcheck, 2939173138Srwatson 2940173138Srwatson .mpo_inpcb_check_deliver = lomac_inpcb_check_deliver, 2941183980Sbz .mpo_inpcb_check_visible = lomac_inpcb_check_visible, 2942172955Srwatson .mpo_inpcb_create = lomac_inpcb_create, 2943173138Srwatson .mpo_inpcb_create_mbuf = lomac_inpcb_create_mbuf, 2944173138Srwatson .mpo_inpcb_destroy_label = lomac_destroy_label, 2945173138Srwatson .mpo_inpcb_init_label = lomac_init_label_waitcheck, 2946173138Srwatson .mpo_inpcb_sosetlabel = lomac_inpcb_sosetlabel, 2947173138Srwatson 2948184308Srwatson .mpo_ip6q_create = lomac_ip6q_create, 2949184308Srwatson .mpo_ip6q_destroy_label = lomac_destroy_label, 2950184308Srwatson .mpo_ip6q_init_label = lomac_init_label_waitcheck, 2951184308Srwatson .mpo_ip6q_match = lomac_ip6q_match, 2952184308Srwatson .mpo_ip6q_reassemble = lomac_ip6q_reassemble, 2953184308Srwatson .mpo_ip6q_update = lomac_ip6q_update, 2954184308Srwatson 2955172955Srwatson .mpo_ipq_create = lomac_ipq_create, 2956173138Srwatson .mpo_ipq_destroy_label = lomac_destroy_label, 2957173138Srwatson .mpo_ipq_init_label = lomac_init_label_waitcheck, 2958172955Srwatson .mpo_ipq_match = lomac_ipq_match, 2959173138Srwatson .mpo_ipq_reassemble = lomac_ipq_reassemble, 2960172955Srwatson .mpo_ipq_update = lomac_ipq_update, 2961173138Srwatson 2962172955Srwatson .mpo_kld_check_load = lomac_kld_check_load, 2963173138Srwatson 2964173138Srwatson .mpo_mbuf_copy_label = lomac_copy_label, 2965173138Srwatson .mpo_mbuf_destroy_label = lomac_destroy_label, 2966173138Srwatson .mpo_mbuf_init_label = lomac_init_label_waitcheck, 2967173138Srwatson 2968173138Srwatson .mpo_mount_create = lomac_mount_create, 2969173138Srwatson .mpo_mount_destroy_label = lomac_destroy_label, 2970173138Srwatson .mpo_mount_init_label = lomac_init_label, 2971173138Srwatson 2972173138Srwatson .mpo_netinet_arp_send = lomac_netinet_arp_send, 2973173138Srwatson .mpo_netinet_firewall_reply = lomac_netinet_firewall_reply, 2974173138Srwatson .mpo_netinet_firewall_send = lomac_netinet_firewall_send, 2975173138Srwatson .mpo_netinet_fragment = lomac_netinet_fragment, 2976173138Srwatson .mpo_netinet_icmp_reply = lomac_netinet_icmp_reply, 2977173138Srwatson .mpo_netinet_igmp_send = lomac_netinet_igmp_send, 2978173138Srwatson 2979173138Srwatson .mpo_netinet6_nd6_send = lomac_netinet6_nd6_send, 2980173138Srwatson 2981172955Srwatson .mpo_pipe_check_ioctl = lomac_pipe_check_ioctl, 2982172955Srwatson .mpo_pipe_check_read = lomac_pipe_check_read, 2983172955Srwatson .mpo_pipe_check_relabel = lomac_pipe_check_relabel, 2984172955Srwatson .mpo_pipe_check_write = lomac_pipe_check_write, 2985173138Srwatson .mpo_pipe_copy_label = lomac_copy_label, 2986173138Srwatson .mpo_pipe_create = lomac_pipe_create, 2987173138Srwatson .mpo_pipe_destroy_label = lomac_destroy_label, 2988173138Srwatson .mpo_pipe_externalize_label = lomac_externalize_label, 2989173138Srwatson .mpo_pipe_init_label = lomac_init_label, 2990173138Srwatson .mpo_pipe_internalize_label = lomac_internalize_label, 2991173138Srwatson .mpo_pipe_relabel = lomac_pipe_relabel, 2992173138Srwatson 2993173138Srwatson .mpo_priv_check = lomac_priv_check, 2994173138Srwatson 2995172955Srwatson .mpo_proc_check_debug = lomac_proc_check_debug, 2996172955Srwatson .mpo_proc_check_sched = lomac_proc_check_sched, 2997172955Srwatson .mpo_proc_check_signal = lomac_proc_check_signal, 2998173138Srwatson .mpo_proc_destroy_label = lomac_proc_destroy_label, 2999173138Srwatson .mpo_proc_init_label = lomac_proc_init_label, 3000173138Srwatson 3001172955Srwatson .mpo_socket_check_deliver = lomac_socket_check_deliver, 3002172955Srwatson .mpo_socket_check_relabel = lomac_socket_check_relabel, 3003172955Srwatson .mpo_socket_check_visible = lomac_socket_check_visible, 3004173138Srwatson .mpo_socket_copy_label = lomac_copy_label, 3005173138Srwatson .mpo_socket_create = lomac_socket_create, 3006173138Srwatson .mpo_socket_create_mbuf = lomac_socket_create_mbuf, 3007173138Srwatson .mpo_socket_destroy_label = lomac_destroy_label, 3008173138Srwatson .mpo_socket_externalize_label = lomac_externalize_label, 3009173138Srwatson .mpo_socket_init_label = lomac_init_label_waitcheck, 3010173138Srwatson .mpo_socket_internalize_label = lomac_internalize_label, 3011173138Srwatson .mpo_socket_newconn = lomac_socket_newconn, 3012173138Srwatson .mpo_socket_relabel = lomac_socket_relabel, 3013173138Srwatson 3014173138Srwatson .mpo_socketpeer_destroy_label = lomac_destroy_label, 3015173138Srwatson .mpo_socketpeer_externalize_label = lomac_externalize_label, 3016173138Srwatson .mpo_socketpeer_init_label = lomac_init_label_waitcheck, 3017173138Srwatson .mpo_socketpeer_set_from_mbuf = lomac_socketpeer_set_from_mbuf, 3018173138Srwatson .mpo_socketpeer_set_from_socket = lomac_socketpeer_set_from_socket, 3019173138Srwatson 3020173138Srwatson .mpo_syncache_create_mbuf = lomac_syncache_create_mbuf, 3021173138Srwatson 3022172955Srwatson .mpo_system_check_acct = lomac_system_check_acct, 3023172955Srwatson .mpo_system_check_auditctl = lomac_system_check_auditctl, 3024172955Srwatson .mpo_system_check_swapoff = lomac_system_check_swapoff, 3025172955Srwatson .mpo_system_check_swapon = lomac_system_check_swapon, 3026172955Srwatson .mpo_system_check_sysctl = lomac_system_check_sysctl, 3027173138Srwatson 3028173138Srwatson .mpo_thread_userret = lomac_thread_userret, 3029173138Srwatson 3030173138Srwatson .mpo_vnode_associate_extattr = lomac_vnode_associate_extattr, 3031173138Srwatson .mpo_vnode_associate_singlelabel = lomac_vnode_associate_singlelabel, 3032172955Srwatson .mpo_vnode_check_access = lomac_vnode_check_open, 3033172955Srwatson .mpo_vnode_check_create = lomac_vnode_check_create, 3034172955Srwatson .mpo_vnode_check_deleteacl = lomac_vnode_check_deleteacl, 3035172955Srwatson .mpo_vnode_check_link = lomac_vnode_check_link, 3036172955Srwatson .mpo_vnode_check_mmap = lomac_vnode_check_mmap, 3037172955Srwatson .mpo_vnode_check_mmap_downgrade = lomac_vnode_check_mmap_downgrade, 3038172955Srwatson .mpo_vnode_check_open = lomac_vnode_check_open, 3039172955Srwatson .mpo_vnode_check_read = lomac_vnode_check_read, 3040172955Srwatson .mpo_vnode_check_relabel = lomac_vnode_check_relabel, 3041172955Srwatson .mpo_vnode_check_rename_from = lomac_vnode_check_rename_from, 3042172955Srwatson .mpo_vnode_check_rename_to = lomac_vnode_check_rename_to, 3043172955Srwatson .mpo_vnode_check_revoke = lomac_vnode_check_revoke, 3044172955Srwatson .mpo_vnode_check_setacl = lomac_vnode_check_setacl, 3045172955Srwatson .mpo_vnode_check_setextattr = lomac_vnode_check_setextattr, 3046172955Srwatson .mpo_vnode_check_setflags = lomac_vnode_check_setflags, 3047172955Srwatson .mpo_vnode_check_setmode = lomac_vnode_check_setmode, 3048172955Srwatson .mpo_vnode_check_setowner = lomac_vnode_check_setowner, 3049172955Srwatson .mpo_vnode_check_setutimes = lomac_vnode_check_setutimes, 3050172955Srwatson .mpo_vnode_check_unlink = lomac_vnode_check_unlink, 3051172955Srwatson .mpo_vnode_check_write = lomac_vnode_check_write, 3052173138Srwatson .mpo_vnode_copy_label = lomac_copy_label, 3053173138Srwatson .mpo_vnode_create_extattr = lomac_vnode_create_extattr, 3054173138Srwatson .mpo_vnode_destroy_label = lomac_destroy_label, 3055173138Srwatson .mpo_vnode_execve_transition = lomac_vnode_execve_transition, 3056173138Srwatson .mpo_vnode_execve_will_transition = lomac_vnode_execve_will_transition, 3057173138Srwatson .mpo_vnode_externalize_label = lomac_externalize_label, 3058173138Srwatson .mpo_vnode_init_label = lomac_init_label, 3059173138Srwatson .mpo_vnode_internalize_label = lomac_internalize_label, 3060173138Srwatson .mpo_vnode_relabel = lomac_vnode_relabel, 3061173138Srwatson .mpo_vnode_setlabel_extattr = lomac_vnode_setlabel_extattr, 3062107273Srwatson}; 3063107273Srwatson 3064172955SrwatsonMAC_POLICY_SET(&lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC", 3065187016Srwatson MPC_LOADTIME_FLAG_NOTLATE, &lomac_slot); 3066