1db2661ceSRobert Watson /*- 218717f69SRobert Watson * Copyright (c) 1999-2002, 2007 Robert N. M. Watson 3c77cf2b1SRobert Watson * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 4db2661ceSRobert Watson * All rights reserved. 5db2661ceSRobert Watson * 6db2661ceSRobert Watson * This software was developed by Robert Watson for the TrustedBSD Project. 7db2661ceSRobert Watson * 8db2661ceSRobert Watson * This software was developed for the FreeBSD Project in part by NAI Labs, 9db2661ceSRobert Watson * the Security Research Division of Network Associates, Inc. under 10db2661ceSRobert Watson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 11db2661ceSRobert Watson * CHATS research program. 12db2661ceSRobert Watson * 13db2661ceSRobert Watson * Redistribution and use in source and binary forms, with or without 14db2661ceSRobert Watson * modification, are permitted provided that the following conditions 15db2661ceSRobert Watson * are met: 16db2661ceSRobert Watson * 1. Redistributions of source code must retain the above copyright 17db2661ceSRobert Watson * notice, this list of conditions and the following disclaimer. 18db2661ceSRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 19db2661ceSRobert Watson * notice, this list of conditions and the following disclaimer in the 20db2661ceSRobert Watson * documentation and/or other materials provided with the distribution. 21db2661ceSRobert Watson * 22db2661ceSRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23db2661ceSRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24db2661ceSRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25db2661ceSRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26db2661ceSRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27db2661ceSRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28db2661ceSRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29db2661ceSRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30db2661ceSRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31db2661ceSRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32db2661ceSRobert Watson * SUCH DAMAGE. 33db2661ceSRobert Watson * 34db2661ceSRobert Watson * $FreeBSD$ 35db2661ceSRobert Watson */ 36db2661ceSRobert Watson 37db2661ceSRobert Watson /* 38db2661ceSRobert Watson * Developed by the TrustedBSD Project. 39c14d15aeSRobert Watson * 40db2661ceSRobert Watson * Low-watermark floating label mandatory integrity policy. 41db2661ceSRobert Watson */ 42db2661ceSRobert Watson 43db2661ceSRobert Watson #include <sys/types.h> 44db2661ceSRobert Watson #include <sys/param.h> 45db2661ceSRobert Watson #include <sys/acl.h> 46db2661ceSRobert Watson #include <sys/conf.h> 47db2661ceSRobert Watson #include <sys/extattr.h> 48db2661ceSRobert Watson #include <sys/kernel.h> 49db2661ceSRobert Watson #include <sys/malloc.h> 50c92163dcSChristian S.J. Peron #include <sys/mman.h> 51db2661ceSRobert Watson #include <sys/mount.h> 52acd3428bSRobert Watson #include <sys/priv.h> 53db2661ceSRobert Watson #include <sys/proc.h> 54f51e5803SRobert Watson #include <sys/sbuf.h> 55db2661ceSRobert Watson #include <sys/systm.h> 56db2661ceSRobert Watson #include <sys/sysproto.h> 57db2661ceSRobert Watson #include <sys/sysent.h> 58db2661ceSRobert Watson #include <sys/systm.h> 59db2661ceSRobert Watson #include <sys/vnode.h> 60db2661ceSRobert Watson #include <sys/file.h> 61db2661ceSRobert Watson #include <sys/socket.h> 62db2661ceSRobert Watson #include <sys/socketvar.h> 6336422989SPoul-Henning Kamp #include <sys/sx.h> 64db2661ceSRobert Watson #include <sys/pipe.h> 65db2661ceSRobert Watson #include <sys/sysctl.h> 66db2661ceSRobert Watson #include <sys/syslog.h> 67db2661ceSRobert Watson 68db2661ceSRobert Watson #include <fs/devfs/devfs.h> 69db2661ceSRobert Watson 70db2661ceSRobert Watson #include <net/bpfdesc.h> 71db2661ceSRobert Watson #include <net/if.h> 72db2661ceSRobert Watson #include <net/if_types.h> 73db2661ceSRobert Watson #include <net/if_var.h> 74db2661ceSRobert Watson 75db2661ceSRobert Watson #include <netinet/in.h> 76a557af22SRobert Watson #include <netinet/in_pcb.h> 77db2661ceSRobert Watson #include <netinet/ip_var.h> 78db2661ceSRobert Watson 79db2661ceSRobert Watson #include <vm/vm.h> 80db2661ceSRobert Watson 810efd6615SRobert Watson #include <security/mac/mac_policy.h> 82aed55708SRobert Watson #include <security/mac/mac_framework.h> 83db2661ceSRobert Watson #include <security/mac_lomac/mac_lomac.h> 84db2661ceSRobert Watson 85db2661ceSRobert Watson struct mac_lomac_proc { 86db2661ceSRobert Watson struct mac_lomac mac_lomac; 87db2661ceSRobert Watson struct mtx mtx; 88db2661ceSRobert Watson }; 89db2661ceSRobert Watson 90db2661ceSRobert Watson SYSCTL_DECL(_security_mac); 91db2661ceSRobert Watson 92db2661ceSRobert Watson SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0, 93db2661ceSRobert Watson "TrustedBSD mac_lomac policy controls"); 94db2661ceSRobert Watson 95db2661ceSRobert Watson static int mac_lomac_label_size = sizeof(struct mac_lomac); 96db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD, 97db2661ceSRobert Watson &mac_lomac_label_size, 0, "Size of struct mac_lomac"); 98db2661ceSRobert Watson 99eba0370dSRobert Watson static int mac_lomac_enabled = 1; 100db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW, 101db2661ceSRobert Watson &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy"); 102db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled); 103db2661ceSRobert Watson 104db2661ceSRobert Watson static int destroyed_not_inited; 105db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 106db2661ceSRobert Watson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 107db2661ceSRobert Watson 108db2661ceSRobert Watson static int trust_all_interfaces = 0; 109db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 110db2661ceSRobert Watson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC"); 111db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces); 112db2661ceSRobert Watson 113db2661ceSRobert Watson static char trusted_interfaces[128]; 114db2661ceSRobert Watson SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 115db2661ceSRobert Watson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC"); 116db2661ceSRobert Watson TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces, 117db2661ceSRobert Watson sizeof(trusted_interfaces)); 118db2661ceSRobert Watson 119db2661ceSRobert Watson static int ptys_equal = 0; 120db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW, 121db2661ceSRobert Watson &ptys_equal, 0, "Label pty devices as lomac/equal on create"); 122db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal); 123db2661ceSRobert Watson 124db2661ceSRobert Watson static int revocation_enabled = 1; 125db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW, 126db2661ceSRobert Watson &revocation_enabled, 0, "Revoke access to objects on relabel"); 127db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled); 128db2661ceSRobert Watson 129db2661ceSRobert Watson static int mac_lomac_slot; 1300142affcSRobert Watson #define SLOT(l) ((struct mac_lomac *)mac_label_get((l), mac_lomac_slot)) 1310142affcSRobert Watson #define SLOT_SET(l, val) mac_label_set((l), mac_lomac_slot, (uintptr_t)(val)) 132db2661ceSRobert Watson #define PSLOT(l) ((struct mac_lomac_proc *) \ 1330142affcSRobert Watson mac_label_get((l), mac_lomac_slot)) 1340142affcSRobert Watson #define PSLOT_SET(l, val) mac_label_set((l), mac_lomac_slot, (uintptr_t)(val)) 135db2661ceSRobert Watson 1365bb84bc8SRobert Watson MALLOC_DEFINE(M_MACLOMAC, "mac_lomac_label", "MAC/LOMAC labels"); 137db2661ceSRobert Watson 138db2661ceSRobert Watson static struct mac_lomac * 139db2661ceSRobert Watson lomac_alloc(int flag) 140db2661ceSRobert Watson { 141db2661ceSRobert Watson struct mac_lomac *mac_lomac; 142db2661ceSRobert Watson 143db2661ceSRobert Watson mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag); 144db2661ceSRobert Watson 145db2661ceSRobert Watson return (mac_lomac); 146db2661ceSRobert Watson } 147db2661ceSRobert Watson 148db2661ceSRobert Watson static void 149db2661ceSRobert Watson lomac_free(struct mac_lomac *mac_lomac) 150db2661ceSRobert Watson { 151db2661ceSRobert Watson 152db2661ceSRobert Watson if (mac_lomac != NULL) 153db2661ceSRobert Watson free(mac_lomac, M_MACLOMAC); 154db2661ceSRobert Watson else 155db2661ceSRobert Watson atomic_add_int(&destroyed_not_inited, 1); 156db2661ceSRobert Watson } 157db2661ceSRobert Watson 158db2661ceSRobert Watson static int 159db2661ceSRobert Watson lomac_atmostflags(struct mac_lomac *mac_lomac, int flags) 160db2661ceSRobert Watson { 161db2661ceSRobert Watson 162db2661ceSRobert Watson if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags) 163db2661ceSRobert Watson return (EINVAL); 164db2661ceSRobert Watson return (0); 165db2661ceSRobert Watson } 166db2661ceSRobert Watson 167db2661ceSRobert Watson static int 168db2661ceSRobert Watson mac_lomac_dominate_element(struct mac_lomac_element *a, 169db2661ceSRobert Watson struct mac_lomac_element *b) 170db2661ceSRobert Watson { 171db2661ceSRobert Watson 172db2661ceSRobert Watson switch (a->mle_type) { 173db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 174db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 175db2661ceSRobert Watson return (1); 176db2661ceSRobert Watson 177db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 178db2661ceSRobert Watson switch (b->mle_type) { 179db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 180db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 181db2661ceSRobert Watson return (0); 182db2661ceSRobert Watson 183db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 184db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 185db2661ceSRobert Watson return (1); 186db2661ceSRobert Watson 187db2661ceSRobert Watson default: 188db2661ceSRobert Watson panic("mac_lomac_dominate_element: b->mle_type invalid"); 189db2661ceSRobert Watson } 190db2661ceSRobert Watson 191db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 192db2661ceSRobert Watson switch (b->mle_type) { 193db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 194db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 195db2661ceSRobert Watson return (1); 196db2661ceSRobert Watson 197db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 198db2661ceSRobert Watson return (0); 199db2661ceSRobert Watson 200db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 201db2661ceSRobert Watson return (a->mle_grade >= b->mle_grade); 202db2661ceSRobert Watson 203db2661ceSRobert Watson default: 204db2661ceSRobert Watson panic("mac_lomac_dominate_element: b->mle_type invalid"); 205db2661ceSRobert Watson } 206db2661ceSRobert Watson 207db2661ceSRobert Watson default: 208db2661ceSRobert Watson panic("mac_lomac_dominate_element: a->mle_type invalid"); 209db2661ceSRobert Watson } 210db2661ceSRobert Watson } 211db2661ceSRobert Watson 212db2661ceSRobert Watson static int 213db2661ceSRobert Watson mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb) 214db2661ceSRobert Watson { 215db2661ceSRobert Watson 216db2661ceSRobert Watson return (mac_lomac_dominate_element(&rangeb->ml_rangehigh, 217db2661ceSRobert Watson &rangea->ml_rangehigh) && 218db2661ceSRobert Watson mac_lomac_dominate_element(&rangea->ml_rangelow, 219db2661ceSRobert Watson &rangeb->ml_rangelow)); 220db2661ceSRobert Watson } 221db2661ceSRobert Watson 222db2661ceSRobert Watson static int 223db2661ceSRobert Watson mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range) 224db2661ceSRobert Watson { 225db2661ceSRobert Watson 226db2661ceSRobert Watson KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 227db2661ceSRobert Watson ("mac_lomac_single_in_range: a not single")); 228db2661ceSRobert Watson KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 229db2661ceSRobert Watson ("mac_lomac_single_in_range: b not range")); 230db2661ceSRobert Watson 231db2661ceSRobert Watson return (mac_lomac_dominate_element(&range->ml_rangehigh, 232db2661ceSRobert Watson &single->ml_single) && 233db2661ceSRobert Watson mac_lomac_dominate_element(&single->ml_single, 234db2661ceSRobert Watson &range->ml_rangelow)); 235db2661ceSRobert Watson } 236db2661ceSRobert Watson 237db2661ceSRobert Watson static int 238db2661ceSRobert Watson mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range) 239db2661ceSRobert Watson { 240db2661ceSRobert Watson 241db2661ceSRobert Watson KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 242db2661ceSRobert Watson ("mac_lomac_single_in_range: a not auxsingle")); 243db2661ceSRobert Watson KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 244db2661ceSRobert Watson ("mac_lomac_single_in_range: b not range")); 245db2661ceSRobert Watson 246db2661ceSRobert Watson return (mac_lomac_dominate_element(&range->ml_rangehigh, 247db2661ceSRobert Watson &single->ml_auxsingle) && 248db2661ceSRobert Watson mac_lomac_dominate_element(&single->ml_auxsingle, 249db2661ceSRobert Watson &range->ml_rangelow)); 250db2661ceSRobert Watson } 251db2661ceSRobert Watson 252db2661ceSRobert Watson static int 253db2661ceSRobert Watson mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b) 254db2661ceSRobert Watson { 255db2661ceSRobert Watson KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 256db2661ceSRobert Watson ("mac_lomac_dominate_single: a not single")); 257db2661ceSRobert Watson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 258db2661ceSRobert Watson ("mac_lomac_dominate_single: b not single")); 259db2661ceSRobert Watson 260db2661ceSRobert Watson return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single)); 261db2661ceSRobert Watson } 262db2661ceSRobert Watson 263db2661ceSRobert Watson static int 264db2661ceSRobert Watson mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b) 265db2661ceSRobert Watson { 266db2661ceSRobert Watson KASSERT((~a->ml_flags & 267db2661ceSRobert Watson (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0, 268db2661ceSRobert Watson ("mac_lomac_dominate_single: a not subject")); 269db2661ceSRobert Watson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 270db2661ceSRobert Watson ("mac_lomac_dominate_single: b not single")); 271db2661ceSRobert Watson 272db2661ceSRobert Watson return (mac_lomac_dominate_element(&a->ml_rangehigh, 273db2661ceSRobert Watson &b->ml_single)); 274db2661ceSRobert Watson } 275db2661ceSRobert Watson 276db2661ceSRobert Watson static int 277db2661ceSRobert Watson mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b) 278db2661ceSRobert Watson { 279db2661ceSRobert Watson 280db2661ceSRobert Watson if (a->mle_type == MAC_LOMAC_TYPE_EQUAL || 281db2661ceSRobert Watson b->mle_type == MAC_LOMAC_TYPE_EQUAL) 282db2661ceSRobert Watson return (1); 283db2661ceSRobert Watson 284db2661ceSRobert Watson return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade); 285db2661ceSRobert Watson } 286db2661ceSRobert Watson 287db2661ceSRobert Watson static int 288db2661ceSRobert Watson mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b) 289db2661ceSRobert Watson { 290db2661ceSRobert Watson 291db2661ceSRobert Watson KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 292db2661ceSRobert Watson ("mac_lomac_equal_single: a not single")); 293db2661ceSRobert Watson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 294db2661ceSRobert Watson ("mac_lomac_equal_single: b not single")); 295db2661ceSRobert Watson 296db2661ceSRobert Watson return (mac_lomac_equal_element(&a->ml_single, &b->ml_single)); 297db2661ceSRobert Watson } 298db2661ceSRobert Watson 299db2661ceSRobert Watson static int 300db2661ceSRobert Watson mac_lomac_contains_equal(struct mac_lomac *mac_lomac) 301db2661ceSRobert Watson { 302db2661ceSRobert Watson 303db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) 304db2661ceSRobert Watson if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 305db2661ceSRobert Watson return (1); 306db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) 307db2661ceSRobert Watson if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL) 308db2661ceSRobert Watson return (1); 309db2661ceSRobert Watson 310db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 311db2661ceSRobert Watson if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL) 312db2661ceSRobert Watson return (1); 313db2661ceSRobert Watson if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 314db2661ceSRobert Watson return (1); 315db2661ceSRobert Watson } 316db2661ceSRobert Watson 317db2661ceSRobert Watson return (0); 318db2661ceSRobert Watson } 319db2661ceSRobert Watson 320db2661ceSRobert Watson static int 321db2661ceSRobert Watson mac_lomac_subject_privileged(struct mac_lomac *mac_lomac) 322db2661ceSRobert Watson { 323db2661ceSRobert Watson 324db2661ceSRobert Watson KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) == 325db2661ceSRobert Watson MAC_LOMAC_FLAGS_BOTH, 326db2661ceSRobert Watson ("mac_lomac_subject_privileged: subject doesn't have both labels")); 327db2661ceSRobert Watson 328db2661ceSRobert Watson /* If the single is EQUAL, it's ok. */ 329db2661ceSRobert Watson if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 330db2661ceSRobert Watson return (0); 331db2661ceSRobert Watson 332db2661ceSRobert Watson /* If either range endpoint is EQUAL, it's ok. */ 333db2661ceSRobert Watson if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL || 334db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 335db2661ceSRobert Watson return (0); 336db2661ceSRobert Watson 337db2661ceSRobert Watson /* If the range is low-high, it's ok. */ 338db2661ceSRobert Watson if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW && 339db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH) 340db2661ceSRobert Watson return (0); 341db2661ceSRobert Watson 342db2661ceSRobert Watson /* It's not ok. */ 343db2661ceSRobert Watson return (EPERM); 344db2661ceSRobert Watson } 345db2661ceSRobert Watson 346db2661ceSRobert Watson static int 347db2661ceSRobert Watson mac_lomac_high_single(struct mac_lomac *mac_lomac) 348db2661ceSRobert Watson { 349db2661ceSRobert Watson 350db2661ceSRobert Watson KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 351db2661ceSRobert Watson ("mac_lomac_high_single: mac_lomac not single")); 352db2661ceSRobert Watson 353db2661ceSRobert Watson return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH); 354db2661ceSRobert Watson } 355db2661ceSRobert Watson 356db2661ceSRobert Watson static int 357db2661ceSRobert Watson mac_lomac_valid(struct mac_lomac *mac_lomac) 358db2661ceSRobert Watson { 359db2661ceSRobert Watson 360db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 361db2661ceSRobert Watson switch (mac_lomac->ml_single.mle_type) { 362db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 363db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 364db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 365db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 366db2661ceSRobert Watson break; 367db2661ceSRobert Watson 368db2661ceSRobert Watson default: 369db2661ceSRobert Watson return (EINVAL); 370db2661ceSRobert Watson } 371db2661ceSRobert Watson } else { 372db2661ceSRobert Watson if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF) 373db2661ceSRobert Watson return (EINVAL); 374db2661ceSRobert Watson } 375db2661ceSRobert Watson 376db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { 377db2661ceSRobert Watson switch (mac_lomac->ml_auxsingle.mle_type) { 378db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 379db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 380db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 381db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 382db2661ceSRobert Watson break; 383db2661ceSRobert Watson 384db2661ceSRobert Watson default: 385db2661ceSRobert Watson return (EINVAL); 386db2661ceSRobert Watson } 387db2661ceSRobert Watson } else { 388db2661ceSRobert Watson if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF) 389db2661ceSRobert Watson return (EINVAL); 390db2661ceSRobert Watson } 391db2661ceSRobert Watson 392db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 393db2661ceSRobert Watson switch (mac_lomac->ml_rangelow.mle_type) { 394db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 395db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 396db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 397db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 398db2661ceSRobert Watson break; 399db2661ceSRobert Watson 400db2661ceSRobert Watson default: 401db2661ceSRobert Watson return (EINVAL); 402db2661ceSRobert Watson } 403db2661ceSRobert Watson 404db2661ceSRobert Watson switch (mac_lomac->ml_rangehigh.mle_type) { 405db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 406db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 407db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 408db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 409db2661ceSRobert Watson break; 410db2661ceSRobert Watson 411db2661ceSRobert Watson default: 412db2661ceSRobert Watson return (EINVAL); 413db2661ceSRobert Watson } 414db2661ceSRobert Watson if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh, 415db2661ceSRobert Watson &mac_lomac->ml_rangelow)) 416db2661ceSRobert Watson return (EINVAL); 417db2661ceSRobert Watson } else { 418db2661ceSRobert Watson if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF || 419db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF) 420db2661ceSRobert Watson return (EINVAL); 421db2661ceSRobert Watson } 422db2661ceSRobert Watson 423db2661ceSRobert Watson return (0); 424db2661ceSRobert Watson } 425db2661ceSRobert Watson 426db2661ceSRobert Watson static void 427db2661ceSRobert Watson mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow, 428db2661ceSRobert Watson u_short gradelow, u_short typehigh, u_short gradehigh) 429db2661ceSRobert Watson { 430db2661ceSRobert Watson 431db2661ceSRobert Watson mac_lomac->ml_rangelow.mle_type = typelow; 432db2661ceSRobert Watson mac_lomac->ml_rangelow.mle_grade = gradelow; 433db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_type = typehigh; 434db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_grade = gradehigh; 435db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE; 436db2661ceSRobert Watson } 437db2661ceSRobert Watson 438db2661ceSRobert Watson static void 439db2661ceSRobert Watson mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade) 440db2661ceSRobert Watson { 441db2661ceSRobert Watson 442db2661ceSRobert Watson mac_lomac->ml_single.mle_type = type; 443db2661ceSRobert Watson mac_lomac->ml_single.mle_grade = grade; 444db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 445db2661ceSRobert Watson } 446db2661ceSRobert Watson 447db2661ceSRobert Watson static void 448db2661ceSRobert Watson mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 449db2661ceSRobert Watson { 450db2661ceSRobert Watson 451db2661ceSRobert Watson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 452db2661ceSRobert Watson ("mac_lomac_copy_range: labelfrom not range")); 453db2661ceSRobert Watson 454db2661ceSRobert Watson labelto->ml_rangelow = labelfrom->ml_rangelow; 455db2661ceSRobert Watson labelto->ml_rangehigh = labelfrom->ml_rangehigh; 456db2661ceSRobert Watson labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE; 457db2661ceSRobert Watson } 458db2661ceSRobert Watson 459db2661ceSRobert Watson static void 460db2661ceSRobert Watson mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 461db2661ceSRobert Watson { 462db2661ceSRobert Watson 463db2661ceSRobert Watson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 464db2661ceSRobert Watson ("mac_lomac_copy_single: labelfrom not single")); 465db2661ceSRobert Watson 466db2661ceSRobert Watson labelto->ml_single = labelfrom->ml_single; 467db2661ceSRobert Watson labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 468db2661ceSRobert Watson } 469db2661ceSRobert Watson 470db2661ceSRobert Watson static void 471db2661ceSRobert Watson mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 472db2661ceSRobert Watson { 473db2661ceSRobert Watson 474db2661ceSRobert Watson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 475db2661ceSRobert Watson ("mac_lomac_copy_auxsingle: labelfrom not auxsingle")); 476db2661ceSRobert Watson 477db2661ceSRobert Watson labelto->ml_auxsingle = labelfrom->ml_auxsingle; 478db2661ceSRobert Watson labelto->ml_flags |= MAC_LOMAC_FLAG_AUX; 479db2661ceSRobert Watson } 480db2661ceSRobert Watson 481db2661ceSRobert Watson static void 482db2661ceSRobert Watson mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest) 483db2661ceSRobert Watson { 484db2661ceSRobert Watson 485db2661ceSRobert Watson if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE) 486db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 487db2661ceSRobert Watson if (source->ml_flags & MAC_LOMAC_FLAG_AUX) 488db2661ceSRobert Watson mac_lomac_copy_auxsingle(source, dest); 489db2661ceSRobert Watson if (source->ml_flags & MAC_LOMAC_FLAG_RANGE) 490db2661ceSRobert Watson mac_lomac_copy_range(source, dest); 491db2661ceSRobert Watson } 492db2661ceSRobert Watson 493f51e5803SRobert Watson static int mac_lomac_to_string(struct sbuf *sb, 494f51e5803SRobert Watson struct mac_lomac *mac_lomac); 495db2661ceSRobert Watson 496db2661ceSRobert Watson static int 497db2661ceSRobert Watson maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 49878007886SRobert Watson const char *actionname, const char *objname, struct vnode *vp) 499db2661ceSRobert Watson { 500f51e5803SRobert Watson struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb; 501f51e5803SRobert Watson char *subjlabeltext, *objlabeltext, *subjtext; 502f51e5803SRobert Watson struct mac_lomac cached_subjlabel; 503f51e5803SRobert Watson struct mac_lomac_proc *subj; 504db2661ceSRobert Watson struct vattr va; 505db2661ceSRobert Watson struct proc *p; 506db2661ceSRobert Watson pid_t pgid; 507db2661ceSRobert Watson 508eca8a663SRobert Watson subj = PSLOT(curthread->td_proc->p_label); 509f51e5803SRobert Watson 510db2661ceSRobert Watson p = curthread->td_proc; 511db2661ceSRobert Watson mtx_lock(&subj->mtx); 512db2661ceSRobert Watson if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 513db2661ceSRobert Watson /* 514db2661ceSRobert Watson * Check to see if the pending demotion would be more or 515db2661ceSRobert Watson * less severe than this one, and keep the more severe. 516db2661ceSRobert Watson * This can only happen for a multi-threaded application. 517db2661ceSRobert Watson */ 518db2661ceSRobert Watson if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) { 519db2661ceSRobert Watson mtx_unlock(&subj->mtx); 520db2661ceSRobert Watson return (0); 521db2661ceSRobert Watson } 522db2661ceSRobert Watson } 523db2661ceSRobert Watson bzero(&subj->mac_lomac, sizeof(subj->mac_lomac)); 524db2661ceSRobert Watson /* 525db2661ceSRobert Watson * Always demote the single label. 526db2661ceSRobert Watson */ 527db2661ceSRobert Watson mac_lomac_copy_single(objlabel, &subj->mac_lomac); 528db2661ceSRobert Watson /* 529db2661ceSRobert Watson * Start with the original range, then minimize each side of 530db2661ceSRobert Watson * the range to the point of not dominating the object. The 531db2661ceSRobert Watson * high side will always be demoted, of course. 532db2661ceSRobert Watson */ 533db2661ceSRobert Watson mac_lomac_copy_range(subjlabel, &subj->mac_lomac); 534db2661ceSRobert Watson if (!mac_lomac_dominate_element(&objlabel->ml_single, 535db2661ceSRobert Watson &subj->mac_lomac.ml_rangelow)) 536db2661ceSRobert Watson subj->mac_lomac.ml_rangelow = objlabel->ml_single; 537db2661ceSRobert Watson subj->mac_lomac.ml_rangehigh = objlabel->ml_single; 538db2661ceSRobert Watson subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE; 539db2661ceSRobert Watson mtx_lock_spin(&sched_lock); 5404a338afdSJulian Elischer curthread->td_flags |= TDF_ASTPENDING; 541db2661ceSRobert Watson curthread->td_proc->p_sflag |= PS_MACPEND; 542db2661ceSRobert Watson mtx_unlock_spin(&sched_lock); 543f51e5803SRobert Watson 544f51e5803SRobert Watson /* 545f51e5803SRobert Watson * Avoid memory allocation while holding a mutex; cache the 546f51e5803SRobert Watson * label. 547f51e5803SRobert Watson */ 548f51e5803SRobert Watson mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel); 549db2661ceSRobert Watson mtx_unlock(&subj->mtx); 550f51e5803SRobert Watson 551f51e5803SRobert Watson sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 552f51e5803SRobert Watson mac_lomac_to_string(&subjlabel_sb, subjlabel); 553f51e5803SRobert Watson sbuf_finish(&subjlabel_sb); 554f51e5803SRobert Watson subjlabeltext = sbuf_data(&subjlabel_sb); 555f51e5803SRobert Watson 556f51e5803SRobert Watson sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND); 557f51e5803SRobert Watson mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac); 558f51e5803SRobert Watson sbuf_finish(&subjtext_sb); 559f51e5803SRobert Watson subjtext = sbuf_data(&subjtext_sb); 560f51e5803SRobert Watson 561f51e5803SRobert Watson sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 562f51e5803SRobert Watson mac_lomac_to_string(&objlabel_sb, objlabel); 563f51e5803SRobert Watson sbuf_finish(&objlabel_sb); 564f51e5803SRobert Watson objlabeltext = sbuf_data(&objlabel_sb); 565f51e5803SRobert Watson 566db2661ceSRobert Watson pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ 56778007886SRobert Watson if (vp != NULL && VOP_GETATTR(vp, &va, curthread->td_ucred, 568db2661ceSRobert Watson curthread) == 0) { 569db2661ceSRobert Watson log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 570db2661ceSRobert Watson " level %s after %s a level-%s %s (inode=%ld, " 571db2661ceSRobert Watson "mountpount=%s)\n", 572db2661ceSRobert Watson subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 573db2661ceSRobert Watson p->p_comm, subjtext, actionname, objlabeltext, objname, 57478007886SRobert Watson va.va_fileid, vp->v_mount->mnt_stat.f_mntonname); 575db2661ceSRobert Watson } else { 576db2661ceSRobert Watson log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 577db2661ceSRobert Watson " level %s after %s a level-%s %s\n", 578db2661ceSRobert Watson subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 579db2661ceSRobert Watson p->p_comm, subjtext, actionname, objlabeltext, objname); 580db2661ceSRobert Watson } 581db2661ceSRobert Watson 582f51e5803SRobert Watson sbuf_delete(&subjlabel_sb); 583f51e5803SRobert Watson sbuf_delete(&subjtext_sb); 584f51e5803SRobert Watson sbuf_delete(&objlabel_sb); 585f51e5803SRobert Watson 586db2661ceSRobert Watson return (0); 587db2661ceSRobert Watson } 588db2661ceSRobert Watson 589db2661ceSRobert Watson /* 590db2661ceSRobert Watson * Relabel "to" to "from" only if "from" is a valid label (contains 591db2661ceSRobert Watson * at least a single), as for a relabel operation which may or may 592db2661ceSRobert Watson * not involve a relevant label. 593db2661ceSRobert Watson */ 5947496ed81SRobert Watson static void 595db2661ceSRobert Watson try_relabel(struct mac_lomac *from, struct mac_lomac *to) 596db2661ceSRobert Watson { 597db2661ceSRobert Watson 598db2661ceSRobert Watson if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 599db2661ceSRobert Watson bzero(to, sizeof(*to)); 600db2661ceSRobert Watson mac_lomac_copy(from, to); 601db2661ceSRobert Watson } 602db2661ceSRobert Watson } 603db2661ceSRobert Watson 604db2661ceSRobert Watson /* 605db2661ceSRobert Watson * Policy module operations. 606db2661ceSRobert Watson */ 607db2661ceSRobert Watson static void 608db2661ceSRobert Watson mac_lomac_init(struct mac_policy_conf *conf) 609db2661ceSRobert Watson { 610db2661ceSRobert Watson 611db2661ceSRobert Watson } 612db2661ceSRobert Watson 613db2661ceSRobert Watson /* 614db2661ceSRobert Watson * Label operations. 615db2661ceSRobert Watson */ 616db2661ceSRobert Watson static void 617db2661ceSRobert Watson mac_lomac_init_label(struct label *label) 618db2661ceSRobert Watson { 619db2661ceSRobert Watson 6201477f588SAlexander Kabaev SLOT_SET(label, lomac_alloc(M_WAITOK)); 621db2661ceSRobert Watson } 622db2661ceSRobert Watson 623db2661ceSRobert Watson static int 624db2661ceSRobert Watson mac_lomac_init_label_waitcheck(struct label *label, int flag) 625db2661ceSRobert Watson { 626db2661ceSRobert Watson 6271477f588SAlexander Kabaev SLOT_SET(label, lomac_alloc(flag)); 628db2661ceSRobert Watson if (SLOT(label) == NULL) 629db2661ceSRobert Watson return (ENOMEM); 630db2661ceSRobert Watson 631db2661ceSRobert Watson return (0); 632db2661ceSRobert Watson } 633db2661ceSRobert Watson 634db2661ceSRobert Watson static void 635db2661ceSRobert Watson mac_lomac_init_proc_label(struct label *label) 636db2661ceSRobert Watson { 637db2661ceSRobert Watson 6381477f588SAlexander Kabaev PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_MACLOMAC, 6391477f588SAlexander Kabaev M_ZERO | M_WAITOK)); 640db2661ceSRobert Watson mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF); 641db2661ceSRobert Watson } 642db2661ceSRobert Watson 643db2661ceSRobert Watson static void 644db2661ceSRobert Watson mac_lomac_destroy_label(struct label *label) 645db2661ceSRobert Watson { 646db2661ceSRobert Watson 647db2661ceSRobert Watson lomac_free(SLOT(label)); 6481477f588SAlexander Kabaev SLOT_SET(label, NULL); 649db2661ceSRobert Watson } 650db2661ceSRobert Watson 651db2661ceSRobert Watson static void 652db2661ceSRobert Watson mac_lomac_destroy_proc_label(struct label *label) 653db2661ceSRobert Watson { 654db2661ceSRobert Watson 655db2661ceSRobert Watson mtx_destroy(&PSLOT(label)->mtx); 656db2661ceSRobert Watson FREE(PSLOT(label), M_MACLOMAC); 6571477f588SAlexander Kabaev PSLOT_SET(label, NULL); 658db2661ceSRobert Watson } 659db2661ceSRobert Watson 660f51e5803SRobert Watson static int 661f51e5803SRobert Watson mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element) 662db2661ceSRobert Watson { 663db2661ceSRobert Watson 664db2661ceSRobert Watson switch (element->mle_type) { 665db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 666f51e5803SRobert Watson return (sbuf_printf(sb, "high")); 667db2661ceSRobert Watson 668db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 669f51e5803SRobert Watson return (sbuf_printf(sb, "low")); 670db2661ceSRobert Watson 671db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 672f51e5803SRobert Watson return (sbuf_printf(sb, "equal")); 673db2661ceSRobert Watson 674db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 675f51e5803SRobert Watson return (sbuf_printf(sb, "%d", element->mle_grade)); 676db2661ceSRobert Watson 677db2661ceSRobert Watson default: 678db2661ceSRobert Watson panic("mac_lomac_element_to_string: invalid type (%d)", 679db2661ceSRobert Watson element->mle_type); 680db2661ceSRobert Watson } 681db2661ceSRobert Watson } 682db2661ceSRobert Watson 683db2661ceSRobert Watson static int 684f51e5803SRobert Watson mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac) 685db2661ceSRobert Watson { 686db2661ceSRobert Watson 687db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 688f51e5803SRobert Watson if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single) 689f51e5803SRobert Watson == -1) 690f51e5803SRobert Watson return (EINVAL); 691db2661ceSRobert Watson } 692db2661ceSRobert Watson 693db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { 694f51e5803SRobert Watson if (sbuf_putc(sb, '[') == -1) 695f51e5803SRobert Watson return (EINVAL); 696db2661ceSRobert Watson 697f51e5803SRobert Watson if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle) 698f51e5803SRobert Watson == -1) 699f51e5803SRobert Watson return (EINVAL); 700db2661ceSRobert Watson 701f51e5803SRobert Watson if (sbuf_putc(sb, ']') == -1) 702f51e5803SRobert Watson return (EINVAL); 703db2661ceSRobert Watson } 704db2661ceSRobert Watson 705db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 706f51e5803SRobert Watson if (sbuf_putc(sb, '(') == -1) 707f51e5803SRobert Watson return (EINVAL); 708db2661ceSRobert Watson 709f51e5803SRobert Watson if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow) 710f51e5803SRobert Watson == -1) 711f51e5803SRobert Watson return (EINVAL); 712db2661ceSRobert Watson 713f51e5803SRobert Watson if (sbuf_putc(sb, '-') == -1) 714f51e5803SRobert Watson return (EINVAL); 715db2661ceSRobert Watson 716f51e5803SRobert Watson if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh) 717f51e5803SRobert Watson == -1) 718f51e5803SRobert Watson return (EINVAL); 719db2661ceSRobert Watson 7208a4b86b9SRobert Watson if (sbuf_putc(sb, ')') == -1) 721f51e5803SRobert Watson return (EINVAL); 722db2661ceSRobert Watson } 723db2661ceSRobert Watson 724db2661ceSRobert Watson return (0); 725db2661ceSRobert Watson } 726db2661ceSRobert Watson 727db2661ceSRobert Watson static int 728db2661ceSRobert Watson mac_lomac_externalize_label(struct label *label, char *element_name, 729f51e5803SRobert Watson struct sbuf *sb, int *claimed) 730db2661ceSRobert Watson { 731db2661ceSRobert Watson struct mac_lomac *mac_lomac; 732db2661ceSRobert Watson 733db2661ceSRobert Watson if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 734db2661ceSRobert Watson return (0); 735db2661ceSRobert Watson 736db2661ceSRobert Watson (*claimed)++; 737db2661ceSRobert Watson 738db2661ceSRobert Watson mac_lomac = SLOT(label); 739db2661ceSRobert Watson 740f51e5803SRobert Watson return (mac_lomac_to_string(sb, mac_lomac)); 741db2661ceSRobert Watson } 742db2661ceSRobert Watson 743db2661ceSRobert Watson static int 744db2661ceSRobert Watson mac_lomac_parse_element(struct mac_lomac_element *element, char *string) 745db2661ceSRobert Watson { 746db2661ceSRobert Watson 747db2661ceSRobert Watson if (strcmp(string, "high") == 0 || 748db2661ceSRobert Watson strcmp(string, "hi") == 0) { 749db2661ceSRobert Watson element->mle_type = MAC_LOMAC_TYPE_HIGH; 750db2661ceSRobert Watson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 751db2661ceSRobert Watson } else if (strcmp(string, "low") == 0 || 752db2661ceSRobert Watson strcmp(string, "lo") == 0) { 753db2661ceSRobert Watson element->mle_type = MAC_LOMAC_TYPE_LOW; 754db2661ceSRobert Watson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 755db2661ceSRobert Watson } else if (strcmp(string, "equal") == 0 || 756db2661ceSRobert Watson strcmp(string, "eq") == 0) { 757db2661ceSRobert Watson element->mle_type = MAC_LOMAC_TYPE_EQUAL; 758db2661ceSRobert Watson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 759db2661ceSRobert Watson } else { 760db2661ceSRobert Watson char *p0, *p1; 761db2661ceSRobert Watson int d; 762db2661ceSRobert Watson 763db2661ceSRobert Watson p0 = string; 764db2661ceSRobert Watson d = strtol(p0, &p1, 10); 765db2661ceSRobert Watson 766db2661ceSRobert Watson if (d < 0 || d > 65535) 767db2661ceSRobert Watson return (EINVAL); 768db2661ceSRobert Watson element->mle_type = MAC_LOMAC_TYPE_GRADE; 769db2661ceSRobert Watson element->mle_grade = d; 770db2661ceSRobert Watson 771db2661ceSRobert Watson if (p1 == p0 || *p1 != '\0') 772db2661ceSRobert Watson return (EINVAL); 773db2661ceSRobert Watson } 774db2661ceSRobert Watson 775db2661ceSRobert Watson return (0); 776db2661ceSRobert Watson } 777db2661ceSRobert Watson 778db2661ceSRobert Watson /* 779db2661ceSRobert Watson * Note: destructively consumes the string, make a local copy before 780db2661ceSRobert Watson * calling if that's a problem. 781db2661ceSRobert Watson */ 782db2661ceSRobert Watson static int 783db2661ceSRobert Watson mac_lomac_parse(struct mac_lomac *mac_lomac, char *string) 784db2661ceSRobert Watson { 785db2661ceSRobert Watson char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle, 786db2661ceSRobert Watson *auxsingleend; 787db2661ceSRobert Watson int error; 788db2661ceSRobert Watson 789db2661ceSRobert Watson /* Do we have a range? */ 790db2661ceSRobert Watson single = string; 791db2661ceSRobert Watson range = index(string, '('); 792db2661ceSRobert Watson if (range == single) 793db2661ceSRobert Watson single = NULL; 794db2661ceSRobert Watson auxsingle = index(string, '['); 795db2661ceSRobert Watson if (auxsingle == single) 796db2661ceSRobert Watson single = NULL; 797db2661ceSRobert Watson if (range != NULL && auxsingle != NULL) 798db2661ceSRobert Watson return (EINVAL); 799db2661ceSRobert Watson rangelow = rangehigh = NULL; 800db2661ceSRobert Watson if (range != NULL) { 801db2661ceSRobert Watson /* Nul terminate the end of the single string. */ 802db2661ceSRobert Watson *range = '\0'; 803db2661ceSRobert Watson range++; 804db2661ceSRobert Watson rangelow = range; 805db2661ceSRobert Watson rangehigh = index(rangelow, '-'); 806db2661ceSRobert Watson if (rangehigh == NULL) 807db2661ceSRobert Watson return (EINVAL); 808db2661ceSRobert Watson rangehigh++; 809db2661ceSRobert Watson if (*rangelow == '\0' || *rangehigh == '\0') 810db2661ceSRobert Watson return (EINVAL); 811db2661ceSRobert Watson rangeend = index(rangehigh, ')'); 812db2661ceSRobert Watson if (rangeend == NULL) 813db2661ceSRobert Watson return (EINVAL); 814db2661ceSRobert Watson if (*(rangeend + 1) != '\0') 815db2661ceSRobert Watson return (EINVAL); 816db2661ceSRobert Watson /* Nul terminate the ends of the ranges. */ 817db2661ceSRobert Watson *(rangehigh - 1) = '\0'; 818db2661ceSRobert Watson *rangeend = '\0'; 819db2661ceSRobert Watson } 820db2661ceSRobert Watson KASSERT((rangelow != NULL && rangehigh != NULL) || 821db2661ceSRobert Watson (rangelow == NULL && rangehigh == NULL), 822db2661ceSRobert Watson ("mac_lomac_internalize_label: range mismatch")); 823db2661ceSRobert Watson if (auxsingle != NULL) { 824db2661ceSRobert Watson /* Nul terminate the end of the single string. */ 825db2661ceSRobert Watson *auxsingle = '\0'; 826db2661ceSRobert Watson auxsingle++; 827db2661ceSRobert Watson auxsingleend = index(auxsingle, ']'); 828db2661ceSRobert Watson if (auxsingleend == NULL) 829db2661ceSRobert Watson return (EINVAL); 830db2661ceSRobert Watson if (*(auxsingleend + 1) != '\0') 831db2661ceSRobert Watson return (EINVAL); 832db2661ceSRobert Watson /* Nul terminate the end of the auxsingle. */ 833db2661ceSRobert Watson *auxsingleend = '\0'; 834db2661ceSRobert Watson } 835db2661ceSRobert Watson 836db2661ceSRobert Watson bzero(mac_lomac, sizeof(*mac_lomac)); 837db2661ceSRobert Watson if (single != NULL) { 838db2661ceSRobert Watson error = mac_lomac_parse_element(&mac_lomac->ml_single, single); 839db2661ceSRobert Watson if (error) 840db2661ceSRobert Watson return (error); 841db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 842db2661ceSRobert Watson } 843db2661ceSRobert Watson 844db2661ceSRobert Watson if (auxsingle != NULL) { 845db2661ceSRobert Watson error = mac_lomac_parse_element(&mac_lomac->ml_auxsingle, 846db2661ceSRobert Watson auxsingle); 847db2661ceSRobert Watson if (error) 848db2661ceSRobert Watson return (error); 849db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_AUX; 850db2661ceSRobert Watson } 851db2661ceSRobert Watson 852db2661ceSRobert Watson if (rangelow != NULL) { 853db2661ceSRobert Watson error = mac_lomac_parse_element(&mac_lomac->ml_rangelow, 854db2661ceSRobert Watson rangelow); 855db2661ceSRobert Watson if (error) 856db2661ceSRobert Watson return (error); 857db2661ceSRobert Watson error = mac_lomac_parse_element(&mac_lomac->ml_rangehigh, 858db2661ceSRobert Watson rangehigh); 859db2661ceSRobert Watson if (error) 860db2661ceSRobert Watson return (error); 861db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE; 862db2661ceSRobert Watson } 863db2661ceSRobert Watson 864db2661ceSRobert Watson error = mac_lomac_valid(mac_lomac); 865db2661ceSRobert Watson if (error) 866db2661ceSRobert Watson return (error); 867db2661ceSRobert Watson 868db2661ceSRobert Watson return (0); 869db2661ceSRobert Watson } 870db2661ceSRobert Watson 871db2661ceSRobert Watson static int 872db2661ceSRobert Watson mac_lomac_internalize_label(struct label *label, char *element_name, 873db2661ceSRobert Watson char *element_data, int *claimed) 874db2661ceSRobert Watson { 875db2661ceSRobert Watson struct mac_lomac *mac_lomac, mac_lomac_temp; 876db2661ceSRobert Watson int error; 877db2661ceSRobert Watson 878db2661ceSRobert Watson if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 879db2661ceSRobert Watson return (0); 880db2661ceSRobert Watson 881db2661ceSRobert Watson (*claimed)++; 882db2661ceSRobert Watson 883db2661ceSRobert Watson error = mac_lomac_parse(&mac_lomac_temp, element_data); 884db2661ceSRobert Watson if (error) 885db2661ceSRobert Watson return (error); 886db2661ceSRobert Watson 887db2661ceSRobert Watson mac_lomac = SLOT(label); 888db2661ceSRobert Watson *mac_lomac = mac_lomac_temp; 889db2661ceSRobert Watson 890db2661ceSRobert Watson return (0); 891db2661ceSRobert Watson } 892db2661ceSRobert Watson 893db2661ceSRobert Watson static void 894db2661ceSRobert Watson mac_lomac_copy_label(struct label *src, struct label *dest) 895db2661ceSRobert Watson { 896db2661ceSRobert Watson 897db2661ceSRobert Watson *SLOT(dest) = *SLOT(src); 898db2661ceSRobert Watson } 899db2661ceSRobert Watson 900db2661ceSRobert Watson /* 901db2661ceSRobert Watson * Labeling event operations: file system objects, and things that look 902db2661ceSRobert Watson * a lot like file system objects. 903db2661ceSRobert Watson */ 904db2661ceSRobert Watson static void 905d26dd2d9SRobert Watson mac_lomac_create_devfs_device(struct ucred *cred, struct mount *mp, 90678007886SRobert Watson struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 907db2661ceSRobert Watson { 908db2661ceSRobert Watson struct mac_lomac *mac_lomac; 909db2661ceSRobert Watson int lomac_type; 910db2661ceSRobert Watson 91178007886SRobert Watson mac_lomac = SLOT(delabel); 912db2661ceSRobert Watson if (strcmp(dev->si_name, "null") == 0 || 913db2661ceSRobert Watson strcmp(dev->si_name, "zero") == 0 || 914db2661ceSRobert Watson strcmp(dev->si_name, "random") == 0 || 915db2661ceSRobert Watson strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 || 916db2661ceSRobert Watson strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0) 917db2661ceSRobert Watson lomac_type = MAC_LOMAC_TYPE_EQUAL; 918db2661ceSRobert Watson else if (ptys_equal && 919db2661ceSRobert Watson (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 920db2661ceSRobert Watson strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 921db2661ceSRobert Watson lomac_type = MAC_LOMAC_TYPE_EQUAL; 922db2661ceSRobert Watson else 923db2661ceSRobert Watson lomac_type = MAC_LOMAC_TYPE_HIGH; 924db2661ceSRobert Watson mac_lomac_set_single(mac_lomac, lomac_type, 0); 925db2661ceSRobert Watson } 926db2661ceSRobert Watson 927db2661ceSRobert Watson static void 928990b4b2dSRobert Watson mac_lomac_create_devfs_directory(struct mount *mp, char *dirname, 92978007886SRobert Watson int dirnamelen, struct devfs_dirent *de, struct label *delabel) 930db2661ceSRobert Watson { 931db2661ceSRobert Watson struct mac_lomac *mac_lomac; 932db2661ceSRobert Watson 93378007886SRobert Watson mac_lomac = SLOT(delabel); 934db2661ceSRobert Watson mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0); 935db2661ceSRobert Watson } 936db2661ceSRobert Watson 937db2661ceSRobert Watson static void 938990b4b2dSRobert Watson mac_lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 939990b4b2dSRobert Watson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 940990b4b2dSRobert Watson struct label *delabel) 941db2661ceSRobert Watson { 942db2661ceSRobert Watson struct mac_lomac *source, *dest; 943db2661ceSRobert Watson 944eca8a663SRobert Watson source = SLOT(cred->cr_label); 945db2661ceSRobert Watson dest = SLOT(delabel); 946db2661ceSRobert Watson 947db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 948db2661ceSRobert Watson } 949db2661ceSRobert Watson 950db2661ceSRobert Watson static void 951db2661ceSRobert Watson mac_lomac_create_mount(struct ucred *cred, struct mount *mp, 95278007886SRobert Watson struct label *mplabel) 953db2661ceSRobert Watson { 954db2661ceSRobert Watson struct mac_lomac *source, *dest; 955db2661ceSRobert Watson 956eca8a663SRobert Watson source = SLOT(cred->cr_label); 95778007886SRobert Watson dest = SLOT(mplabel); 958db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 959db2661ceSRobert Watson } 960db2661ceSRobert Watson 961db2661ceSRobert Watson static void 962db2661ceSRobert Watson mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp, 96378007886SRobert Watson struct label *vplabel, struct label *newlabel) 964db2661ceSRobert Watson { 965db2661ceSRobert Watson struct mac_lomac *source, *dest; 966db2661ceSRobert Watson 96778007886SRobert Watson source = SLOT(newlabel); 96878007886SRobert Watson dest = SLOT(vplabel); 969db2661ceSRobert Watson 970db2661ceSRobert Watson try_relabel(source, dest); 971db2661ceSRobert Watson } 972db2661ceSRobert Watson 973db2661ceSRobert Watson static void 97478007886SRobert Watson mac_lomac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, 97578007886SRobert Watson struct label *delabel, struct vnode *vp, struct label *vplabel) 976db2661ceSRobert Watson { 977db2661ceSRobert Watson struct mac_lomac *source, *dest; 978db2661ceSRobert Watson 97978007886SRobert Watson source = SLOT(vplabel); 98078007886SRobert Watson dest = SLOT(delabel); 981db2661ceSRobert Watson 982db2661ceSRobert Watson mac_lomac_copy(source, dest); 983db2661ceSRobert Watson } 984db2661ceSRobert Watson 985db2661ceSRobert Watson static void 98678007886SRobert Watson mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *mplabel, 987db2661ceSRobert Watson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 98878007886SRobert Watson struct label *vplabel) 989db2661ceSRobert Watson { 990db2661ceSRobert Watson struct mac_lomac *source, *dest; 991db2661ceSRobert Watson 992db2661ceSRobert Watson source = SLOT(delabel); 99378007886SRobert Watson dest = SLOT(vplabel); 994db2661ceSRobert Watson 995db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 996db2661ceSRobert Watson } 997db2661ceSRobert Watson 998db2661ceSRobert Watson static int 99978007886SRobert Watson mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *mplabel, 100078007886SRobert Watson struct vnode *vp, struct label *vplabel) 1001db2661ceSRobert Watson { 1002db2661ceSRobert Watson struct mac_lomac temp, *source, *dest; 1003b247d661SMaxime Henrion int buflen, error; 1004db2661ceSRobert Watson 100578007886SRobert Watson source = SLOT(mplabel); 100678007886SRobert Watson dest = SLOT(vplabel); 1007db2661ceSRobert Watson 1008db2661ceSRobert Watson buflen = sizeof(temp); 1009db2661ceSRobert Watson bzero(&temp, buflen); 1010db2661ceSRobert Watson 1011db2661ceSRobert Watson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1012db2661ceSRobert Watson MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread); 1013db2661ceSRobert Watson if (error == ENOATTR || error == EOPNOTSUPP) { 1014eb542415SRobert Watson /* Fall back to the mntlabel. */ 1015db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1016db2661ceSRobert Watson return (0); 1017db2661ceSRobert Watson } else if (error) 1018db2661ceSRobert Watson return (error); 1019db2661ceSRobert Watson 1020db2661ceSRobert Watson if (buflen != sizeof(temp)) { 1021db2661ceSRobert Watson if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) { 1022db2661ceSRobert Watson printf("mac_lomac_associate_vnode_extattr: bad size %d\n", 1023db2661ceSRobert Watson buflen); 1024db2661ceSRobert Watson return (EPERM); 1025db2661ceSRobert Watson } 1026db2661ceSRobert Watson bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle)); 1027db2661ceSRobert Watson buflen = sizeof(temp); 1028db2661ceSRobert Watson (void)vn_extattr_set(vp, IO_NODELOCKED, 1029db2661ceSRobert Watson MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 1030db2661ceSRobert Watson buflen, (char *)&temp, curthread); 1031db2661ceSRobert Watson } 1032db2661ceSRobert Watson if (mac_lomac_valid(&temp) != 0) { 1033db2661ceSRobert Watson printf("mac_lomac_associate_vnode_extattr: invalid\n"); 1034db2661ceSRobert Watson return (EPERM); 1035db2661ceSRobert Watson } 1036db2661ceSRobert Watson if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) { 1037db2661ceSRobert Watson printf("mac_lomac_associate_vnode_extattr: not single\n"); 1038db2661ceSRobert Watson return (EPERM); 1039db2661ceSRobert Watson } 1040db2661ceSRobert Watson 1041db2661ceSRobert Watson mac_lomac_copy_single(&temp, dest); 1042db2661ceSRobert Watson return (0); 1043db2661ceSRobert Watson } 1044db2661ceSRobert Watson 1045db2661ceSRobert Watson static void 1046db2661ceSRobert Watson mac_lomac_associate_vnode_singlelabel(struct mount *mp, 104778007886SRobert Watson struct label *mplabel, struct vnode *vp, struct label *vplabel) 1048db2661ceSRobert Watson { 1049db2661ceSRobert Watson struct mac_lomac *source, *dest; 1050db2661ceSRobert Watson 105178007886SRobert Watson source = SLOT(mplabel); 105278007886SRobert Watson dest = SLOT(vplabel); 1053db2661ceSRobert Watson 1054db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1055db2661ceSRobert Watson } 1056db2661ceSRobert Watson 1057db2661ceSRobert Watson static int 1058db2661ceSRobert Watson mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 105978007886SRobert Watson struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 106078007886SRobert Watson struct vnode *vp, struct label *vplabel, struct componentname *cnp) 1061db2661ceSRobert Watson { 1062db2661ceSRobert Watson struct mac_lomac *source, *dest, *dir, temp; 1063db2661ceSRobert Watson size_t buflen; 1064db2661ceSRobert Watson int error; 1065db2661ceSRobert Watson 1066db2661ceSRobert Watson buflen = sizeof(temp); 1067db2661ceSRobert Watson bzero(&temp, buflen); 1068db2661ceSRobert Watson 1069eca8a663SRobert Watson source = SLOT(cred->cr_label); 107078007886SRobert Watson dest = SLOT(vplabel); 107178007886SRobert Watson dir = SLOT(dvplabel); 1072db2661ceSRobert Watson if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 1073db2661ceSRobert Watson mac_lomac_copy_auxsingle(dir, &temp); 1074db2661ceSRobert Watson mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 1075db2661ceSRobert Watson dir->ml_auxsingle.mle_grade); 1076db2661ceSRobert Watson } else { 1077db2661ceSRobert Watson mac_lomac_copy_single(source, &temp); 1078db2661ceSRobert Watson } 1079db2661ceSRobert Watson 1080db2661ceSRobert Watson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1081db2661ceSRobert Watson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1082db2661ceSRobert Watson if (error == 0) 1083db2661ceSRobert Watson mac_lomac_copy(&temp, dest); 1084db2661ceSRobert Watson return (error); 1085db2661ceSRobert Watson } 1086db2661ceSRobert Watson 1087db2661ceSRobert Watson static int 1088db2661ceSRobert Watson mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 108978007886SRobert Watson struct label *vplabel, struct label *intlabel) 1090db2661ceSRobert Watson { 1091db2661ceSRobert Watson struct mac_lomac *source, temp; 1092db2661ceSRobert Watson size_t buflen; 1093db2661ceSRobert Watson int error; 1094db2661ceSRobert Watson 1095db2661ceSRobert Watson buflen = sizeof(temp); 1096db2661ceSRobert Watson bzero(&temp, buflen); 1097db2661ceSRobert Watson 1098db2661ceSRobert Watson source = SLOT(intlabel); 1099db2661ceSRobert Watson if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1100db2661ceSRobert Watson return (0); 1101db2661ceSRobert Watson 1102db2661ceSRobert Watson mac_lomac_copy_single(source, &temp); 1103db2661ceSRobert Watson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1104db2661ceSRobert Watson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1105db2661ceSRobert Watson return (error); 1106db2661ceSRobert Watson } 1107db2661ceSRobert Watson 1108db2661ceSRobert Watson /* 1109db2661ceSRobert Watson * Labeling event operations: IPC object. 1110db2661ceSRobert Watson */ 1111db2661ceSRobert Watson static void 1112a557af22SRobert Watson mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel, 1113a557af22SRobert Watson struct inpcb *inp, struct label *inplabel) 1114a557af22SRobert Watson { 1115a557af22SRobert Watson struct mac_lomac *source, *dest; 1116a557af22SRobert Watson 1117a557af22SRobert Watson source = SLOT(solabel); 1118a557af22SRobert Watson dest = SLOT(inplabel); 1119a557af22SRobert Watson 1120a557af22SRobert Watson mac_lomac_copy_single(source, dest); 1121a557af22SRobert Watson } 1122a557af22SRobert Watson 1123a557af22SRobert Watson static void 112478007886SRobert Watson mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *solabel, 112578007886SRobert Watson struct mbuf *m, struct label *mlabel) 1126db2661ceSRobert Watson { 1127db2661ceSRobert Watson struct mac_lomac *source, *dest; 1128db2661ceSRobert Watson 112978007886SRobert Watson source = SLOT(solabel); 113078007886SRobert Watson dest = SLOT(mlabel); 1131db2661ceSRobert Watson 1132db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1133db2661ceSRobert Watson } 1134db2661ceSRobert Watson 1135db2661ceSRobert Watson static void 113678007886SRobert Watson mac_lomac_create_socket(struct ucred *cred, struct socket *so, 113778007886SRobert Watson struct label *solabel) 1138db2661ceSRobert Watson { 1139db2661ceSRobert Watson struct mac_lomac *source, *dest; 1140db2661ceSRobert Watson 1141eca8a663SRobert Watson source = SLOT(cred->cr_label); 114278007886SRobert Watson dest = SLOT(solabel); 1143db2661ceSRobert Watson 1144db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1145db2661ceSRobert Watson } 1146db2661ceSRobert Watson 1147db2661ceSRobert Watson static void 11484795b82cSRobert Watson mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp, 114978007886SRobert Watson struct label *pplabel) 1150db2661ceSRobert Watson { 1151db2661ceSRobert Watson struct mac_lomac *source, *dest; 1152db2661ceSRobert Watson 1153eca8a663SRobert Watson source = SLOT(cred->cr_label); 115478007886SRobert Watson dest = SLOT(pplabel); 1155db2661ceSRobert Watson 1156db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1157db2661ceSRobert Watson } 1158db2661ceSRobert Watson 1159db2661ceSRobert Watson static void 116078007886SRobert Watson mac_lomac_create_socket_from_socket(struct socket *oldso, 116178007886SRobert Watson struct label *oldsolabel, struct socket *newso, struct label *newsolabel) 1162db2661ceSRobert Watson { 1163db2661ceSRobert Watson struct mac_lomac *source, *dest; 1164db2661ceSRobert Watson 116578007886SRobert Watson source = SLOT(oldsolabel); 116678007886SRobert Watson dest = SLOT(newsolabel); 1167db2661ceSRobert Watson 1168db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1169db2661ceSRobert Watson } 1170db2661ceSRobert Watson 1171db2661ceSRobert Watson static void 117278007886SRobert Watson mac_lomac_relabel_socket(struct ucred *cred, struct socket *so, 117378007886SRobert Watson struct label *solabel, struct label *newlabel) 1174db2661ceSRobert Watson { 1175db2661ceSRobert Watson struct mac_lomac *source, *dest; 1176db2661ceSRobert Watson 1177db2661ceSRobert Watson source = SLOT(newlabel); 117878007886SRobert Watson dest = SLOT(solabel); 1179db2661ceSRobert Watson 1180db2661ceSRobert Watson try_relabel(source, dest); 1181db2661ceSRobert Watson } 1182db2661ceSRobert Watson 1183db2661ceSRobert Watson static void 11844795b82cSRobert Watson mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp, 118578007886SRobert Watson struct label *pplabel, struct label *newlabel) 1186db2661ceSRobert Watson { 1187db2661ceSRobert Watson struct mac_lomac *source, *dest; 1188db2661ceSRobert Watson 1189db2661ceSRobert Watson source = SLOT(newlabel); 119078007886SRobert Watson dest = SLOT(pplabel); 1191db2661ceSRobert Watson 1192db2661ceSRobert Watson try_relabel(source, dest); 1193db2661ceSRobert Watson } 1194db2661ceSRobert Watson 1195db2661ceSRobert Watson static void 119678007886SRobert Watson mac_lomac_set_socket_peer_from_mbuf(struct mbuf *m, struct label *mlabel, 119778007886SRobert Watson struct socket *so, struct label *sopeerlabel) 1198db2661ceSRobert Watson { 1199db2661ceSRobert Watson struct mac_lomac *source, *dest; 1200db2661ceSRobert Watson 120178007886SRobert Watson source = SLOT(mlabel); 120278007886SRobert Watson dest = SLOT(sopeerlabel); 1203db2661ceSRobert Watson 1204db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1205db2661ceSRobert Watson } 1206db2661ceSRobert Watson 1207db2661ceSRobert Watson /* 1208db2661ceSRobert Watson * Labeling event operations: network objects. 1209db2661ceSRobert Watson */ 1210db2661ceSRobert Watson static void 121178007886SRobert Watson mac_lomac_set_socket_peer_from_socket(struct socket *oldso, 121278007886SRobert Watson struct label *oldsolabel, struct socket *newso, 121378007886SRobert Watson struct label *newsopeerlabel) 1214db2661ceSRobert Watson { 1215db2661ceSRobert Watson struct mac_lomac *source, *dest; 1216db2661ceSRobert Watson 121778007886SRobert Watson source = SLOT(oldsolabel); 121878007886SRobert Watson dest = SLOT(newsopeerlabel); 1219db2661ceSRobert Watson 1220db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1221db2661ceSRobert Watson } 1222db2661ceSRobert Watson 1223db2661ceSRobert Watson static void 122478007886SRobert Watson mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *d, 122578007886SRobert Watson struct label *dlabel) 1226db2661ceSRobert Watson { 1227db2661ceSRobert Watson struct mac_lomac *source, *dest; 1228db2661ceSRobert Watson 1229eca8a663SRobert Watson source = SLOT(cred->cr_label); 123078007886SRobert Watson dest = SLOT(dlabel); 1231db2661ceSRobert Watson 1232db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1233db2661ceSRobert Watson } 1234db2661ceSRobert Watson 1235db2661ceSRobert Watson static void 123678007886SRobert Watson mac_lomac_create_ifnet(struct ifnet *ifp, struct label *ifplabel) 1237db2661ceSRobert Watson { 12389bf40edeSBrooks Davis char tifname[IFNAMSIZ], *p, *q; 1239db2661ceSRobert Watson char tiflist[sizeof(trusted_interfaces)]; 1240db2661ceSRobert Watson struct mac_lomac *dest; 1241db2661ceSRobert Watson int len, grade; 1242db2661ceSRobert Watson 124378007886SRobert Watson dest = SLOT(ifplabel); 1244db2661ceSRobert Watson 124578007886SRobert Watson if (ifp->if_type == IFT_LOOP) { 1246db2661ceSRobert Watson grade = MAC_LOMAC_TYPE_EQUAL; 1247db2661ceSRobert Watson goto set; 1248db2661ceSRobert Watson } 1249db2661ceSRobert Watson 1250db2661ceSRobert Watson if (trust_all_interfaces) { 1251db2661ceSRobert Watson grade = MAC_LOMAC_TYPE_HIGH; 1252db2661ceSRobert Watson goto set; 1253db2661ceSRobert Watson } 1254db2661ceSRobert Watson 1255db2661ceSRobert Watson grade = MAC_LOMAC_TYPE_LOW; 1256db2661ceSRobert Watson 1257db2661ceSRobert Watson if (trusted_interfaces[0] == '\0' || 1258db2661ceSRobert Watson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1259db2661ceSRobert Watson goto set; 1260db2661ceSRobert Watson 1261db2661ceSRobert Watson bzero(tiflist, sizeof(tiflist)); 1262db2661ceSRobert Watson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1263db2661ceSRobert Watson if(*p != ' ' && *p != '\t') 1264db2661ceSRobert Watson *q = *p; 1265db2661ceSRobert Watson 1266db2661ceSRobert Watson for (p = q = tiflist;; p++) { 1267db2661ceSRobert Watson if (*p == ',' || *p == '\0') { 1268db2661ceSRobert Watson len = p - q; 1269db2661ceSRobert Watson if (len < IFNAMSIZ) { 1270db2661ceSRobert Watson bzero(tifname, sizeof(tifname)); 1271db2661ceSRobert Watson bcopy(q, tifname, len); 127278007886SRobert Watson if (strcmp(tifname, ifp->if_xname) == 0) { 1273db2661ceSRobert Watson grade = MAC_LOMAC_TYPE_HIGH; 1274db2661ceSRobert Watson break; 1275db2661ceSRobert Watson } 1276db2661ceSRobert Watson } 1277db2661ceSRobert Watson else { 1278db2661ceSRobert Watson *p = '\0'; 1279db2661ceSRobert Watson printf("MAC/LOMAC warning: interface name " 1280db2661ceSRobert Watson "\"%s\" is too long (must be < %d)\n", 1281db2661ceSRobert Watson q, IFNAMSIZ); 1282db2661ceSRobert Watson } 1283db2661ceSRobert Watson if (*p == '\0') 1284db2661ceSRobert Watson break; 1285db2661ceSRobert Watson q = p + 1; 1286db2661ceSRobert Watson } 1287db2661ceSRobert Watson } 1288db2661ceSRobert Watson set: 1289db2661ceSRobert Watson mac_lomac_set_single(dest, grade, 0); 1290db2661ceSRobert Watson mac_lomac_set_range(dest, grade, 0, grade, 0); 1291db2661ceSRobert Watson } 1292db2661ceSRobert Watson 1293db2661ceSRobert Watson static void 129478007886SRobert Watson mac_lomac_create_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 129578007886SRobert Watson struct label *ipqlabel) 1296db2661ceSRobert Watson { 1297db2661ceSRobert Watson struct mac_lomac *source, *dest; 1298db2661ceSRobert Watson 129978007886SRobert Watson source = SLOT(mlabel); 1300db2661ceSRobert Watson dest = SLOT(ipqlabel); 1301db2661ceSRobert Watson 1302db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1303db2661ceSRobert Watson } 1304db2661ceSRobert Watson 1305db2661ceSRobert Watson static void 1306db2661ceSRobert Watson mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 130778007886SRobert Watson struct mbuf *m, struct label *mlabel) 1308db2661ceSRobert Watson { 1309db2661ceSRobert Watson struct mac_lomac *source, *dest; 1310db2661ceSRobert Watson 1311db2661ceSRobert Watson source = SLOT(ipqlabel); 131278007886SRobert Watson dest = SLOT(mlabel); 1313db2661ceSRobert Watson 1314db2661ceSRobert Watson /* Just use the head, since we require them all to match. */ 1315db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1316db2661ceSRobert Watson } 1317db2661ceSRobert Watson 1318db2661ceSRobert Watson static void 131978007886SRobert Watson mac_lomac_create_fragment(struct mbuf *m, struct label *mlabel, 132078007886SRobert Watson struct mbuf *frag, struct label *fraglabel) 1321db2661ceSRobert Watson { 1322db2661ceSRobert Watson struct mac_lomac *source, *dest; 1323db2661ceSRobert Watson 132478007886SRobert Watson source = SLOT(mlabel); 132578007886SRobert Watson dest = SLOT(fraglabel); 1326db2661ceSRobert Watson 1327db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1328db2661ceSRobert Watson } 1329db2661ceSRobert Watson 1330db2661ceSRobert Watson static void 13312d92ec98SRobert Watson mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 13322d92ec98SRobert Watson struct mbuf *m, struct label *mlabel) 13332d92ec98SRobert Watson { 13342d92ec98SRobert Watson struct mac_lomac *source, *dest; 13352d92ec98SRobert Watson 13362d92ec98SRobert Watson source = SLOT(inplabel); 13372d92ec98SRobert Watson dest = SLOT(mlabel); 13382d92ec98SRobert Watson 13392d92ec98SRobert Watson mac_lomac_copy_single(source, dest); 13402d92ec98SRobert Watson } 13412d92ec98SRobert Watson 13422d92ec98SRobert Watson static void 134378007886SRobert Watson mac_lomac_create_mbuf_linklayer(struct ifnet *ifp, struct label *ifplabel, 134478007886SRobert Watson struct mbuf *m, struct label *mlabel) 1345db2661ceSRobert Watson { 1346db2661ceSRobert Watson struct mac_lomac *dest; 1347db2661ceSRobert Watson 134878007886SRobert Watson dest = SLOT(mlabel); 1349db2661ceSRobert Watson 1350db2661ceSRobert Watson mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1351db2661ceSRobert Watson } 1352db2661ceSRobert Watson 1353db2661ceSRobert Watson static void 135478007886SRobert Watson mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *d, struct label *dlabel, 135578007886SRobert Watson struct mbuf *m, struct label *mlabel) 1356db2661ceSRobert Watson { 1357db2661ceSRobert Watson struct mac_lomac *source, *dest; 1358db2661ceSRobert Watson 135978007886SRobert Watson source = SLOT(dlabel); 136078007886SRobert Watson dest = SLOT(mlabel); 1361db2661ceSRobert Watson 1362db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1363db2661ceSRobert Watson } 1364db2661ceSRobert Watson 1365db2661ceSRobert Watson static void 136678007886SRobert Watson mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifp, struct label *ifplabel, 136778007886SRobert Watson struct mbuf *m, struct label *mlabel) 1368db2661ceSRobert Watson { 1369db2661ceSRobert Watson struct mac_lomac *source, *dest; 1370db2661ceSRobert Watson 137178007886SRobert Watson source = SLOT(ifplabel); 137278007886SRobert Watson dest = SLOT(mlabel); 1373db2661ceSRobert Watson 1374db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1375db2661ceSRobert Watson } 1376db2661ceSRobert Watson 1377db2661ceSRobert Watson static void 137878007886SRobert Watson mac_lomac_create_mbuf_multicast_encap(struct mbuf *m, struct label *mlabel, 137978007886SRobert Watson struct ifnet *ifp, struct label *ifplabel, struct mbuf *mnew, 138078007886SRobert Watson struct label *mnewlabel) 1381db2661ceSRobert Watson { 1382db2661ceSRobert Watson struct mac_lomac *source, *dest; 1383db2661ceSRobert Watson 138478007886SRobert Watson source = SLOT(mlabel); 138578007886SRobert Watson dest = SLOT(mnewlabel); 1386db2661ceSRobert Watson 1387db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1388db2661ceSRobert Watson } 1389db2661ceSRobert Watson 1390db2661ceSRobert Watson static void 139178007886SRobert Watson mac_lomac_create_mbuf_netlayer(struct mbuf *m, struct label *mlabel, 139278007886SRobert Watson struct mbuf *mnew, struct label *mnewlabel) 1393db2661ceSRobert Watson { 1394db2661ceSRobert Watson struct mac_lomac *source, *dest; 1395db2661ceSRobert Watson 139678007886SRobert Watson source = SLOT(mlabel); 139778007886SRobert Watson dest = SLOT(mnewlabel); 1398db2661ceSRobert Watson 1399db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1400db2661ceSRobert Watson } 1401db2661ceSRobert Watson 1402db2661ceSRobert Watson static int 140378007886SRobert Watson mac_lomac_fragment_match(struct mbuf *m, struct label *mlabel, 1404db2661ceSRobert Watson struct ipq *ipq, struct label *ipqlabel) 1405db2661ceSRobert Watson { 1406db2661ceSRobert Watson struct mac_lomac *a, *b; 1407db2661ceSRobert Watson 1408db2661ceSRobert Watson a = SLOT(ipqlabel); 140978007886SRobert Watson b = SLOT(mlabel); 1410db2661ceSRobert Watson 1411db2661ceSRobert Watson return (mac_lomac_equal_single(a, b)); 1412db2661ceSRobert Watson } 1413db2661ceSRobert Watson 1414db2661ceSRobert Watson static void 141578007886SRobert Watson mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifp, 141678007886SRobert Watson struct label *ifplabel, struct label *newlabel) 1417db2661ceSRobert Watson { 1418db2661ceSRobert Watson struct mac_lomac *source, *dest; 1419db2661ceSRobert Watson 1420db2661ceSRobert Watson source = SLOT(newlabel); 142178007886SRobert Watson dest = SLOT(ifplabel); 1422db2661ceSRobert Watson 1423db2661ceSRobert Watson try_relabel(source, dest); 1424db2661ceSRobert Watson } 1425db2661ceSRobert Watson 1426db2661ceSRobert Watson static void 142778007886SRobert Watson mac_lomac_update_ipq(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 142878007886SRobert Watson struct label *ipqlabel) 1429db2661ceSRobert Watson { 1430db2661ceSRobert Watson 1431db2661ceSRobert Watson /* NOOP: we only accept matching labels, so no need to update */ 1432db2661ceSRobert Watson } 1433db2661ceSRobert Watson 1434a557af22SRobert Watson static void 1435a557af22SRobert Watson mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1436a557af22SRobert Watson struct inpcb *inp, struct label *inplabel) 1437a557af22SRobert Watson { 1438a557af22SRobert Watson struct mac_lomac *source, *dest; 1439a557af22SRobert Watson 1440a557af22SRobert Watson source = SLOT(solabel); 1441a557af22SRobert Watson dest = SLOT(inplabel); 1442a557af22SRobert Watson 1443a557af22SRobert Watson mac_lomac_copy_single(source, dest); 1444a557af22SRobert Watson } 1445a557af22SRobert Watson 1446d94f2a68SChristian S.J. Peron static void 1447430fc756SChristian S.J. Peron mac_lomac_init_syncache_from_inpcb(struct label *label, struct inpcb *inp) 1448430fc756SChristian S.J. Peron { 1449430fc756SChristian S.J. Peron struct mac_lomac *source, *dest; 1450430fc756SChristian S.J. Peron 1451430fc756SChristian S.J. Peron source = SLOT(inp->inp_label); 1452430fc756SChristian S.J. Peron dest = SLOT(label); 1453430fc756SChristian S.J. Peron mac_lomac_copy(source, dest); 1454430fc756SChristian S.J. Peron } 1455430fc756SChristian S.J. Peron 1456430fc756SChristian S.J. Peron static void 1457430fc756SChristian S.J. Peron mac_lomac_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m, 145878007886SRobert Watson struct label *mlabel) 1459430fc756SChristian S.J. Peron { 1460430fc756SChristian S.J. Peron struct mac_lomac *source, *dest; 1461430fc756SChristian S.J. Peron 1462430fc756SChristian S.J. Peron source = SLOT(sc_label); 146378007886SRobert Watson dest = SLOT(mlabel); 1464430fc756SChristian S.J. Peron mac_lomac_copy(source, dest); 1465430fc756SChristian S.J. Peron } 1466430fc756SChristian S.J. Peron 1467430fc756SChristian S.J. Peron static void 146878007886SRobert Watson mac_lomac_create_mbuf_from_firewall(struct mbuf *m, struct label *mlabel) 1469d94f2a68SChristian S.J. Peron { 1470d94f2a68SChristian S.J. Peron struct mac_lomac *dest; 1471d94f2a68SChristian S.J. Peron 147278007886SRobert Watson dest = SLOT(mlabel); 1473d94f2a68SChristian S.J. Peron 1474d94f2a68SChristian S.J. Peron /* XXX: where is the label for the firewall really comming from? */ 1475d94f2a68SChristian S.J. Peron mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1476d94f2a68SChristian S.J. Peron } 1477d94f2a68SChristian S.J. Peron 1478db2661ceSRobert Watson /* 1479db2661ceSRobert Watson * Labeling event operations: processes. 1480db2661ceSRobert Watson */ 1481db2661ceSRobert Watson static void 1482db2661ceSRobert Watson mac_lomac_execve_transition(struct ucred *old, struct ucred *new, 148378007886SRobert Watson struct vnode *vp, struct label *vplabel, struct label *interpvnodelabel, 148478007886SRobert Watson struct image_params *imgp, struct label *execlabel) 1485db2661ceSRobert Watson { 1486db2661ceSRobert Watson struct mac_lomac *source, *dest, *obj, *robj; 1487db2661ceSRobert Watson 1488eca8a663SRobert Watson source = SLOT(old->cr_label); 1489eca8a663SRobert Watson dest = SLOT(new->cr_label); 149078007886SRobert Watson obj = SLOT(vplabel); 1491db2661ceSRobert Watson robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1492db2661ceSRobert Watson 1493db2661ceSRobert Watson mac_lomac_copy(source, dest); 1494db2661ceSRobert Watson /* 1495db2661ceSRobert Watson * If there's an auxiliary label on the real object, respect it 1496db2661ceSRobert Watson * and assume that this level should be assumed immediately if 1497db2661ceSRobert Watson * a higher level is currently in place. 1498db2661ceSRobert Watson */ 1499db2661ceSRobert Watson if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1500db2661ceSRobert Watson !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 1501db2661ceSRobert Watson && mac_lomac_auxsingle_in_range(robj, dest)) 1502db2661ceSRobert Watson mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type, 1503db2661ceSRobert Watson robj->ml_auxsingle.mle_grade); 1504db2661ceSRobert Watson /* 1505db2661ceSRobert Watson * Restructuring to use the execve transitioning mechanism 1506db2661ceSRobert Watson * instead of the normal demotion mechanism here would be 1507db2661ceSRobert Watson * difficult, so just copy the label over and perform standard 1508db2661ceSRobert Watson * demotion. This is also non-optimal because it will result 1509db2661ceSRobert Watson * in the intermediate label "new" being created and immediately 1510db2661ceSRobert Watson * recycled. 1511db2661ceSRobert Watson */ 1512db2661ceSRobert Watson if (mac_lomac_enabled && revocation_enabled && 1513db2661ceSRobert Watson !mac_lomac_dominate_single(obj, source)) 1514db2661ceSRobert Watson (void)maybe_demote(source, obj, "executing", "file", vp); 1515db2661ceSRobert Watson } 1516db2661ceSRobert Watson 1517db2661ceSRobert Watson static int 1518db2661ceSRobert Watson mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp, 151978007886SRobert Watson struct label *vplabel, struct label *interpvnodelabel, 1520db2661ceSRobert Watson struct image_params *imgp, struct label *execlabel) 1521db2661ceSRobert Watson { 1522db2661ceSRobert Watson struct mac_lomac *subj, *obj, *robj; 1523db2661ceSRobert Watson 1524db2661ceSRobert Watson if (!mac_lomac_enabled || !revocation_enabled) 1525db2661ceSRobert Watson return (0); 1526db2661ceSRobert Watson 1527eca8a663SRobert Watson subj = SLOT(old->cr_label); 152878007886SRobert Watson obj = SLOT(vplabel); 1529db2661ceSRobert Watson robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1530db2661ceSRobert Watson 1531db2661ceSRobert Watson return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1532db2661ceSRobert Watson !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 1533db2661ceSRobert Watson && mac_lomac_auxsingle_in_range(robj, subj)) || 1534db2661ceSRobert Watson !mac_lomac_dominate_single(obj, subj)); 1535db2661ceSRobert Watson } 1536db2661ceSRobert Watson 1537db2661ceSRobert Watson static void 1538db2661ceSRobert Watson mac_lomac_create_proc0(struct ucred *cred) 1539db2661ceSRobert Watson { 1540db2661ceSRobert Watson struct mac_lomac *dest; 1541db2661ceSRobert Watson 1542eca8a663SRobert Watson dest = SLOT(cred->cr_label); 1543db2661ceSRobert Watson 1544db2661ceSRobert Watson mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1545db2661ceSRobert Watson mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1546db2661ceSRobert Watson 0); 1547db2661ceSRobert Watson } 1548db2661ceSRobert Watson 1549db2661ceSRobert Watson static void 1550db2661ceSRobert Watson mac_lomac_create_proc1(struct ucred *cred) 1551db2661ceSRobert Watson { 1552db2661ceSRobert Watson struct mac_lomac *dest; 1553db2661ceSRobert Watson 1554eca8a663SRobert Watson dest = SLOT(cred->cr_label); 1555db2661ceSRobert Watson 1556db2661ceSRobert Watson mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0); 1557db2661ceSRobert Watson mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1558db2661ceSRobert Watson 0); 1559db2661ceSRobert Watson } 1560db2661ceSRobert Watson 1561db2661ceSRobert Watson static void 1562db2661ceSRobert Watson mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel) 1563db2661ceSRobert Watson { 1564db2661ceSRobert Watson struct mac_lomac *source, *dest; 1565db2661ceSRobert Watson 1566db2661ceSRobert Watson source = SLOT(newlabel); 1567eca8a663SRobert Watson dest = SLOT(cred->cr_label); 1568db2661ceSRobert Watson 1569db2661ceSRobert Watson try_relabel(source, dest); 1570db2661ceSRobert Watson } 1571db2661ceSRobert Watson 1572db2661ceSRobert Watson /* 1573db2661ceSRobert Watson * Access control checks. 1574db2661ceSRobert Watson */ 1575db2661ceSRobert Watson static int 157678007886SRobert Watson mac_lomac_check_bpfdesc_receive(struct bpf_d *d, struct label *dlabel, 157778007886SRobert Watson struct ifnet *ifp, struct label *ifplabel) 1578db2661ceSRobert Watson { 1579db2661ceSRobert Watson struct mac_lomac *a, *b; 1580db2661ceSRobert Watson 1581db2661ceSRobert Watson if (!mac_lomac_enabled) 1582db2661ceSRobert Watson return (0); 1583db2661ceSRobert Watson 158478007886SRobert Watson a = SLOT(dlabel); 158578007886SRobert Watson b = SLOT(ifplabel); 1586db2661ceSRobert Watson 1587db2661ceSRobert Watson if (mac_lomac_equal_single(a, b)) 1588db2661ceSRobert Watson return (0); 1589db2661ceSRobert Watson return (EACCES); 1590db2661ceSRobert Watson } 1591db2661ceSRobert Watson 1592db2661ceSRobert Watson static int 1593db2661ceSRobert Watson mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1594db2661ceSRobert Watson { 1595db2661ceSRobert Watson struct mac_lomac *subj, *new; 1596db2661ceSRobert Watson int error; 1597db2661ceSRobert Watson 1598eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1599db2661ceSRobert Watson new = SLOT(newlabel); 1600db2661ceSRobert Watson 1601db2661ceSRobert Watson /* 1602db2661ceSRobert Watson * If there is a LOMAC label update for the credential, it may 1603db2661ceSRobert Watson * be an update of the single, range, or both. 1604db2661ceSRobert Watson */ 1605db2661ceSRobert Watson error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1606db2661ceSRobert Watson if (error) 1607db2661ceSRobert Watson return (error); 1608db2661ceSRobert Watson 1609db2661ceSRobert Watson /* 1610db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 1611db2661ceSRobert Watson */ 1612db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1613db2661ceSRobert Watson /* 161484bdb083SRobert Watson * Fill in the missing parts from the previous label. 1615db2661ceSRobert Watson */ 161684bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 161784bdb083SRobert Watson mac_lomac_copy_single(subj, new); 161884bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 161984bdb083SRobert Watson mac_lomac_copy_range(subj, new); 1620db2661ceSRobert Watson 1621db2661ceSRobert Watson /* 1622db2661ceSRobert Watson * To change the LOMAC range on a credential, the new 1623db2661ceSRobert Watson * range label must be in the current range. 1624db2661ceSRobert Watson */ 162584bdb083SRobert Watson if (!mac_lomac_range_in_range(new, subj)) 162684bdb083SRobert Watson return (EPERM); 162784bdb083SRobert Watson 162884bdb083SRobert Watson /* 162984bdb083SRobert Watson * To change the LOMAC single label on a credential, the 163084bdb083SRobert Watson * new single label must be in the new range. Implicitly 163184bdb083SRobert Watson * from the previous check, the new single is in the old 163284bdb083SRobert Watson * range. 163384bdb083SRobert Watson */ 163484bdb083SRobert Watson if (!mac_lomac_single_in_range(new, new)) 1635db2661ceSRobert Watson return (EPERM); 1636db2661ceSRobert Watson 1637db2661ceSRobert Watson /* 1638db2661ceSRobert Watson * To have EQUAL in any component of the new credential 1639db2661ceSRobert Watson * LOMAC label, the subject must already have EQUAL in 1640db2661ceSRobert Watson * their label. 1641db2661ceSRobert Watson */ 1642db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 1643db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 1644db2661ceSRobert Watson if (error) 1645db2661ceSRobert Watson return (error); 1646db2661ceSRobert Watson } 1647db2661ceSRobert Watson 1648db2661ceSRobert Watson /* 1649db2661ceSRobert Watson * XXXMAC: Additional consistency tests regarding the 1650db2661ceSRobert Watson * single and range of the new label might be performed 1651db2661ceSRobert Watson * here. 1652db2661ceSRobert Watson */ 1653db2661ceSRobert Watson } 1654db2661ceSRobert Watson 1655db2661ceSRobert Watson return (0); 1656db2661ceSRobert Watson } 1657db2661ceSRobert Watson 1658db2661ceSRobert Watson static int 165978007886SRobert Watson mac_lomac_check_cred_visible(struct ucred *cr1, struct ucred *cr2) 1660db2661ceSRobert Watson { 1661db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1662db2661ceSRobert Watson 1663db2661ceSRobert Watson if (!mac_lomac_enabled) 1664db2661ceSRobert Watson return (0); 1665db2661ceSRobert Watson 166678007886SRobert Watson subj = SLOT(cr1->cr_label); 166778007886SRobert Watson obj = SLOT(cr2->cr_label); 1668db2661ceSRobert Watson 1669db2661ceSRobert Watson /* XXX: range */ 1670db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1671db2661ceSRobert Watson return (ESRCH); 1672db2661ceSRobert Watson 1673db2661ceSRobert Watson return (0); 1674db2661ceSRobert Watson } 1675db2661ceSRobert Watson 1676db2661ceSRobert Watson static int 167778007886SRobert Watson mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 167878007886SRobert Watson struct label *ifplabel, struct label *newlabel) 1679db2661ceSRobert Watson { 1680db2661ceSRobert Watson struct mac_lomac *subj, *new; 1681db2661ceSRobert Watson int error; 1682db2661ceSRobert Watson 1683eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1684db2661ceSRobert Watson new = SLOT(newlabel); 1685db2661ceSRobert Watson 1686db2661ceSRobert Watson /* 1687db2661ceSRobert Watson * If there is a LOMAC label update for the interface, it may 1688db2661ceSRobert Watson * be an update of the single, range, or both. 1689db2661ceSRobert Watson */ 1690db2661ceSRobert Watson error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1691db2661ceSRobert Watson if (error) 1692db2661ceSRobert Watson return (error); 1693db2661ceSRobert Watson 1694db2661ceSRobert Watson /* 1695db2661ceSRobert Watson * Relabling network interfaces requires LOMAC privilege. 1696db2661ceSRobert Watson */ 1697db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 1698db2661ceSRobert Watson if (error) 1699db2661ceSRobert Watson return (error); 1700db2661ceSRobert Watson 1701db2661ceSRobert Watson /* 1702db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 1703db2661ceSRobert Watson */ 1704db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1705db2661ceSRobert Watson /* 170684bdb083SRobert Watson * Fill in the missing parts from the previous label. 170784bdb083SRobert Watson */ 170884bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 170984bdb083SRobert Watson mac_lomac_copy_single(subj, new); 171084bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 171184bdb083SRobert Watson mac_lomac_copy_range(subj, new); 171284bdb083SRobert Watson 171384bdb083SRobert Watson /* 1714db2661ceSRobert Watson * Rely on the traditional superuser status for the LOMAC 1715db2661ceSRobert Watson * interface relabel requirements. XXXMAC: This will go 1716db2661ceSRobert Watson * away. 1717acd3428bSRobert Watson * 1718acd3428bSRobert Watson * XXXRW: This is also redundant to a higher layer check. 1719db2661ceSRobert Watson */ 1720acd3428bSRobert Watson error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0); 1721db2661ceSRobert Watson if (error) 1722db2661ceSRobert Watson return (EPERM); 1723db2661ceSRobert Watson 1724db2661ceSRobert Watson /* 1725db2661ceSRobert Watson * XXXMAC: Additional consistency tests regarding the single 1726db2661ceSRobert Watson * and the range of the new label might be performed here. 1727db2661ceSRobert Watson */ 1728db2661ceSRobert Watson } 1729db2661ceSRobert Watson 1730db2661ceSRobert Watson return (0); 1731db2661ceSRobert Watson } 1732db2661ceSRobert Watson 1733db2661ceSRobert Watson static int 173478007886SRobert Watson mac_lomac_check_ifnet_transmit(struct ifnet *ifp, struct label *ifplabel, 173578007886SRobert Watson struct mbuf *m, struct label *mlabel) 1736db2661ceSRobert Watson { 1737db2661ceSRobert Watson struct mac_lomac *p, *i; 1738db2661ceSRobert Watson 1739db2661ceSRobert Watson if (!mac_lomac_enabled) 1740db2661ceSRobert Watson return (0); 1741db2661ceSRobert Watson 174278007886SRobert Watson p = SLOT(mlabel); 174378007886SRobert Watson i = SLOT(ifplabel); 1744db2661ceSRobert Watson 1745db2661ceSRobert Watson return (mac_lomac_single_in_range(p, i) ? 0 : EACCES); 1746db2661ceSRobert Watson } 1747db2661ceSRobert Watson 1748db2661ceSRobert Watson static int 1749a557af22SRobert Watson mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1750a557af22SRobert Watson struct mbuf *m, struct label *mlabel) 1751a557af22SRobert Watson { 1752a557af22SRobert Watson struct mac_lomac *p, *i; 1753a557af22SRobert Watson 1754a557af22SRobert Watson if (!mac_lomac_enabled) 1755a557af22SRobert Watson return (0); 1756a557af22SRobert Watson 1757a557af22SRobert Watson p = SLOT(mlabel); 1758a557af22SRobert Watson i = SLOT(inplabel); 1759a557af22SRobert Watson 1760a557af22SRobert Watson return (mac_lomac_equal_single(p, i) ? 0 : EACCES); 1761a557af22SRobert Watson } 1762a557af22SRobert Watson 1763a557af22SRobert Watson static int 1764db2661ceSRobert Watson mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp, 176578007886SRobert Watson struct label *vplabel) 1766db2661ceSRobert Watson { 1767db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1768db2661ceSRobert Watson 1769db2661ceSRobert Watson if (!mac_lomac_enabled) 1770db2661ceSRobert Watson return (0); 1771db2661ceSRobert Watson 1772eca8a663SRobert Watson subj = SLOT(cred->cr_label); 177378007886SRobert Watson obj = SLOT(vplabel); 1774db2661ceSRobert Watson 1775db2661ceSRobert Watson if (mac_lomac_subject_privileged(subj)) 1776db2661ceSRobert Watson return (EPERM); 1777db2661ceSRobert Watson 1778db2661ceSRobert Watson if (!mac_lomac_high_single(obj)) 1779db2661ceSRobert Watson return (EACCES); 1780db2661ceSRobert Watson 1781db2661ceSRobert Watson return (0); 1782db2661ceSRobert Watson } 1783db2661ceSRobert Watson 1784db2661ceSRobert Watson static int 17854795b82cSRobert Watson mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 178678007886SRobert Watson struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1787db2661ceSRobert Watson { 1788db2661ceSRobert Watson 1789db2661ceSRobert Watson if (!mac_lomac_enabled) 1790db2661ceSRobert Watson return (0); 1791db2661ceSRobert Watson 1792db2661ceSRobert Watson /* XXX: This will be implemented soon... */ 1793db2661ceSRobert Watson 1794db2661ceSRobert Watson return (0); 1795db2661ceSRobert Watson } 1796db2661ceSRobert Watson 1797db2661ceSRobert Watson static int 17984795b82cSRobert Watson mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp, 179978007886SRobert Watson struct label *pplabel) 1800db2661ceSRobert Watson { 1801db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1802db2661ceSRobert Watson 1803db2661ceSRobert Watson if (!mac_lomac_enabled) 1804db2661ceSRobert Watson return (0); 1805db2661ceSRobert Watson 1806eca8a663SRobert Watson subj = SLOT(cred->cr_label); 180778007886SRobert Watson obj = SLOT(pplabel); 1808db2661ceSRobert Watson 1809db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1810db2661ceSRobert Watson return (maybe_demote(subj, obj, "reading", "pipe", NULL)); 1811db2661ceSRobert Watson 1812db2661ceSRobert Watson return (0); 1813db2661ceSRobert Watson } 1814db2661ceSRobert Watson 1815db2661ceSRobert Watson static int 18164795b82cSRobert Watson mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 181778007886SRobert Watson struct label *pplabel, struct label *newlabel) 1818db2661ceSRobert Watson { 1819db2661ceSRobert Watson struct mac_lomac *subj, *obj, *new; 1820db2661ceSRobert Watson int error; 1821db2661ceSRobert Watson 1822db2661ceSRobert Watson new = SLOT(newlabel); 1823eca8a663SRobert Watson subj = SLOT(cred->cr_label); 182478007886SRobert Watson obj = SLOT(pplabel); 1825db2661ceSRobert Watson 1826db2661ceSRobert Watson /* 1827db2661ceSRobert Watson * If there is a LOMAC label update for a pipe, it must be a 1828db2661ceSRobert Watson * single update. 1829db2661ceSRobert Watson */ 1830db2661ceSRobert Watson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1831db2661ceSRobert Watson if (error) 1832db2661ceSRobert Watson return (error); 1833db2661ceSRobert Watson 1834db2661ceSRobert Watson /* 1835db2661ceSRobert Watson * To perform a relabel of a pipe (LOMAC label or not), LOMAC must 1836db2661ceSRobert Watson * authorize the relabel. 1837db2661ceSRobert Watson */ 1838db2661ceSRobert Watson if (!mac_lomac_single_in_range(obj, subj)) 1839db2661ceSRobert Watson return (EPERM); 1840db2661ceSRobert Watson 1841db2661ceSRobert Watson /* 1842db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 1843db2661ceSRobert Watson */ 1844db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1845db2661ceSRobert Watson /* 1846db2661ceSRobert Watson * To change the LOMAC label on a pipe, the new pipe label 1847db2661ceSRobert Watson * must be in the subject range. 1848db2661ceSRobert Watson */ 1849db2661ceSRobert Watson if (!mac_lomac_single_in_range(new, subj)) 1850db2661ceSRobert Watson return (EPERM); 1851db2661ceSRobert Watson 1852db2661ceSRobert Watson /* 1853db2661ceSRobert Watson * To change the LOMAC label on a pipe to be EQUAL, the 1854db2661ceSRobert Watson * subject must have appropriate privilege. 1855db2661ceSRobert Watson */ 1856db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 1857db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 1858db2661ceSRobert Watson if (error) 1859db2661ceSRobert Watson return (error); 1860db2661ceSRobert Watson } 1861db2661ceSRobert Watson } 1862db2661ceSRobert Watson 1863db2661ceSRobert Watson return (0); 1864db2661ceSRobert Watson } 1865db2661ceSRobert Watson 1866db2661ceSRobert Watson static int 18674795b82cSRobert Watson mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp, 186878007886SRobert Watson struct label *pplabel) 1869db2661ceSRobert Watson { 1870db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1871db2661ceSRobert Watson 1872db2661ceSRobert Watson if (!mac_lomac_enabled) 1873db2661ceSRobert Watson return (0); 1874db2661ceSRobert Watson 1875eca8a663SRobert Watson subj = SLOT(cred->cr_label); 187678007886SRobert Watson obj = SLOT(pplabel); 1877db2661ceSRobert Watson 1878db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 1879db2661ceSRobert Watson return (EACCES); 1880db2661ceSRobert Watson 1881db2661ceSRobert Watson return (0); 1882db2661ceSRobert Watson } 1883db2661ceSRobert Watson 1884db2661ceSRobert Watson static int 188578007886SRobert Watson mac_lomac_check_proc_debug(struct ucred *cred, struct proc *p) 1886db2661ceSRobert Watson { 1887db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1888db2661ceSRobert Watson 1889db2661ceSRobert Watson if (!mac_lomac_enabled) 1890db2661ceSRobert Watson return (0); 1891db2661ceSRobert Watson 1892eca8a663SRobert Watson subj = SLOT(cred->cr_label); 189378007886SRobert Watson obj = SLOT(p->p_ucred->cr_label); 1894db2661ceSRobert Watson 1895db2661ceSRobert Watson /* XXX: range checks */ 1896db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1897db2661ceSRobert Watson return (ESRCH); 1898db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 1899db2661ceSRobert Watson return (EACCES); 1900db2661ceSRobert Watson 1901db2661ceSRobert Watson return (0); 1902db2661ceSRobert Watson } 1903db2661ceSRobert Watson 1904db2661ceSRobert Watson static int 190578007886SRobert Watson mac_lomac_check_proc_sched(struct ucred *cred, struct proc *p) 1906db2661ceSRobert Watson { 1907db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1908db2661ceSRobert Watson 1909db2661ceSRobert Watson if (!mac_lomac_enabled) 1910db2661ceSRobert Watson return (0); 1911db2661ceSRobert Watson 1912eca8a663SRobert Watson subj = SLOT(cred->cr_label); 191378007886SRobert Watson obj = SLOT(p->p_ucred->cr_label); 1914db2661ceSRobert Watson 1915db2661ceSRobert Watson /* XXX: range checks */ 1916db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1917db2661ceSRobert Watson return (ESRCH); 1918db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 1919db2661ceSRobert Watson return (EACCES); 1920db2661ceSRobert Watson 1921db2661ceSRobert Watson return (0); 1922db2661ceSRobert Watson } 1923db2661ceSRobert Watson 1924db2661ceSRobert Watson static int 192578007886SRobert Watson mac_lomac_check_proc_signal(struct ucred *cred, struct proc *p, int signum) 1926db2661ceSRobert Watson { 1927db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1928db2661ceSRobert Watson 1929db2661ceSRobert Watson if (!mac_lomac_enabled) 1930db2661ceSRobert Watson return (0); 1931db2661ceSRobert Watson 1932eca8a663SRobert Watson subj = SLOT(cred->cr_label); 193378007886SRobert Watson obj = SLOT(p->p_ucred->cr_label); 1934db2661ceSRobert Watson 1935db2661ceSRobert Watson /* XXX: range checks */ 1936db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1937db2661ceSRobert Watson return (ESRCH); 1938db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 1939db2661ceSRobert Watson return (EACCES); 1940db2661ceSRobert Watson 1941db2661ceSRobert Watson return (0); 1942db2661ceSRobert Watson } 1943db2661ceSRobert Watson 1944db2661ceSRobert Watson static int 194578007886SRobert Watson mac_lomac_check_socket_deliver(struct socket *so, struct label *solabel, 194678007886SRobert Watson struct mbuf *m, struct label *mlabel) 1947db2661ceSRobert Watson { 1948db2661ceSRobert Watson struct mac_lomac *p, *s; 1949db2661ceSRobert Watson 1950db2661ceSRobert Watson if (!mac_lomac_enabled) 1951db2661ceSRobert Watson return (0); 1952db2661ceSRobert Watson 195378007886SRobert Watson p = SLOT(mlabel); 195478007886SRobert Watson s = SLOT(solabel); 1955db2661ceSRobert Watson 1956db2661ceSRobert Watson return (mac_lomac_equal_single(p, s) ? 0 : EACCES); 1957db2661ceSRobert Watson } 1958db2661ceSRobert Watson 1959db2661ceSRobert Watson static int 196078007886SRobert Watson mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *so, 196178007886SRobert Watson struct label *solabel, struct label *newlabel) 1962db2661ceSRobert Watson { 1963db2661ceSRobert Watson struct mac_lomac *subj, *obj, *new; 1964db2661ceSRobert Watson int error; 1965db2661ceSRobert Watson 1966db2661ceSRobert Watson new = SLOT(newlabel); 1967eca8a663SRobert Watson subj = SLOT(cred->cr_label); 196878007886SRobert Watson obj = SLOT(solabel); 1969db2661ceSRobert Watson 1970db2661ceSRobert Watson /* 1971db2661ceSRobert Watson * If there is a LOMAC label update for the socket, it may be 1972db2661ceSRobert Watson * an update of single. 1973db2661ceSRobert Watson */ 1974db2661ceSRobert Watson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1975db2661ceSRobert Watson if (error) 1976db2661ceSRobert Watson return (error); 1977db2661ceSRobert Watson 1978db2661ceSRobert Watson /* 1979db2661ceSRobert Watson * To relabel a socket, the old socket single must be in the subject 1980db2661ceSRobert Watson * range. 1981db2661ceSRobert Watson */ 1982db2661ceSRobert Watson if (!mac_lomac_single_in_range(obj, subj)) 1983db2661ceSRobert Watson return (EPERM); 1984db2661ceSRobert Watson 1985db2661ceSRobert Watson /* 1986db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 1987db2661ceSRobert Watson */ 1988db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1989db2661ceSRobert Watson /* 1990db2661ceSRobert Watson * To relabel a socket, the new socket single must be in 1991db2661ceSRobert Watson * the subject range. 1992db2661ceSRobert Watson */ 1993db2661ceSRobert Watson if (!mac_lomac_single_in_range(new, subj)) 1994db2661ceSRobert Watson return (EPERM); 1995db2661ceSRobert Watson 1996db2661ceSRobert Watson /* 1997db2661ceSRobert Watson * To change the LOMAC label on the socket to contain EQUAL, 1998db2661ceSRobert Watson * the subject must have appropriate privilege. 1999db2661ceSRobert Watson */ 2000db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 2001db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 2002db2661ceSRobert Watson if (error) 2003db2661ceSRobert Watson return (error); 2004db2661ceSRobert Watson } 2005db2661ceSRobert Watson } 2006db2661ceSRobert Watson 2007db2661ceSRobert Watson return (0); 2008db2661ceSRobert Watson } 2009db2661ceSRobert Watson 2010db2661ceSRobert Watson static int 201178007886SRobert Watson mac_lomac_check_socket_visible(struct ucred *cred, struct socket *so, 201278007886SRobert Watson struct label *solabel) 2013db2661ceSRobert Watson { 2014db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2015db2661ceSRobert Watson 2016db2661ceSRobert Watson if (!mac_lomac_enabled) 2017db2661ceSRobert Watson return (0); 2018db2661ceSRobert Watson 2019eca8a663SRobert Watson subj = SLOT(cred->cr_label); 202078007886SRobert Watson obj = SLOT(solabel); 2021db2661ceSRobert Watson 2022db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 2023db2661ceSRobert Watson return (ENOENT); 2024db2661ceSRobert Watson 2025db2661ceSRobert Watson return (0); 2026db2661ceSRobert Watson } 2027db2661ceSRobert Watson 2028c14d15aeSRobert Watson /* 2029c14d15aeSRobert Watson * Some system privileges are allowed regardless of integrity grade; others 2030c14d15aeSRobert Watson * are allowed only when running with privilege with respect to the LOMAC 2031c14d15aeSRobert Watson * policy as they might otherwise allow bypassing of the integrity policy. 2032c14d15aeSRobert Watson */ 2033c14d15aeSRobert Watson static int 2034c14d15aeSRobert Watson mac_lomac_priv_check(struct ucred *cred, int priv) 2035c14d15aeSRobert Watson { 2036c14d15aeSRobert Watson struct mac_lomac *subj; 2037c14d15aeSRobert Watson int error; 2038c14d15aeSRobert Watson 2039c14d15aeSRobert Watson if (!mac_lomac_enabled) 2040c14d15aeSRobert Watson return (0); 2041c14d15aeSRobert Watson 2042c14d15aeSRobert Watson /* 2043c14d15aeSRobert Watson * Exempt only specific privileges from the LOMAC integrity policy. 2044c14d15aeSRobert Watson */ 2045c14d15aeSRobert Watson switch (priv) { 2046c14d15aeSRobert Watson case PRIV_KTRACE: 2047c14d15aeSRobert Watson case PRIV_MSGBUF: 2048c14d15aeSRobert Watson 2049c14d15aeSRobert Watson /* 2050c14d15aeSRobert Watson * Allow processes to manipulate basic process audit properties, and 2051c14d15aeSRobert Watson * to submit audit records. 2052c14d15aeSRobert Watson */ 2053c14d15aeSRobert Watson case PRIV_AUDIT_GETAUDIT: 2054c14d15aeSRobert Watson case PRIV_AUDIT_SETAUDIT: 2055c14d15aeSRobert Watson case PRIV_AUDIT_SUBMIT: 2056c14d15aeSRobert Watson 2057c14d15aeSRobert Watson /* 2058c14d15aeSRobert Watson * Allow processes to manipulate their regular UNIX credentials. 2059c14d15aeSRobert Watson */ 2060c14d15aeSRobert Watson case PRIV_CRED_SETUID: 2061c14d15aeSRobert Watson case PRIV_CRED_SETEUID: 2062c14d15aeSRobert Watson case PRIV_CRED_SETGID: 2063c14d15aeSRobert Watson case PRIV_CRED_SETEGID: 2064c14d15aeSRobert Watson case PRIV_CRED_SETGROUPS: 2065c14d15aeSRobert Watson case PRIV_CRED_SETREUID: 2066c14d15aeSRobert Watson case PRIV_CRED_SETREGID: 2067c14d15aeSRobert Watson case PRIV_CRED_SETRESUID: 2068c14d15aeSRobert Watson case PRIV_CRED_SETRESGID: 2069c14d15aeSRobert Watson 2070c14d15aeSRobert Watson /* 2071c14d15aeSRobert Watson * Allow processes to perform system monitoring. 2072c14d15aeSRobert Watson */ 2073c14d15aeSRobert Watson case PRIV_SEEOTHERGIDS: 2074c14d15aeSRobert Watson case PRIV_SEEOTHERUIDS: 2075c14d15aeSRobert Watson break; 2076c14d15aeSRobert Watson 2077c14d15aeSRobert Watson /* 2078c14d15aeSRobert Watson * Allow access to general process debugging facilities. We 2079c14d15aeSRobert Watson * separately control debugging based on MAC label. 2080c14d15aeSRobert Watson */ 2081c14d15aeSRobert Watson case PRIV_DEBUG_DIFFCRED: 2082c14d15aeSRobert Watson case PRIV_DEBUG_SUGID: 2083c14d15aeSRobert Watson case PRIV_DEBUG_UNPRIV: 2084c14d15aeSRobert Watson 2085c14d15aeSRobert Watson /* 2086c14d15aeSRobert Watson * Allow manipulating jails. 2087c14d15aeSRobert Watson */ 2088c14d15aeSRobert Watson case PRIV_JAIL_ATTACH: 2089c14d15aeSRobert Watson 2090c14d15aeSRobert Watson /* 2091c14d15aeSRobert Watson * Allow privilege with respect to the Partition policy, but not the 2092c14d15aeSRobert Watson * Privs policy. 2093c14d15aeSRobert Watson */ 2094c14d15aeSRobert Watson case PRIV_MAC_PARTITION: 2095c14d15aeSRobert Watson 2096c14d15aeSRobert Watson /* 2097c14d15aeSRobert Watson * Allow privilege with respect to process resource limits and login 2098c14d15aeSRobert Watson * context. 2099c14d15aeSRobert Watson */ 2100c14d15aeSRobert Watson case PRIV_PROC_LIMIT: 2101c14d15aeSRobert Watson case PRIV_PROC_SETLOGIN: 2102c14d15aeSRobert Watson case PRIV_PROC_SETRLIMIT: 2103c14d15aeSRobert Watson 2104c14d15aeSRobert Watson /* 2105c14d15aeSRobert Watson * Allow System V and POSIX IPC privileges. 2106c14d15aeSRobert Watson */ 2107c14d15aeSRobert Watson case PRIV_IPC_READ: 2108c14d15aeSRobert Watson case PRIV_IPC_WRITE: 2109c14d15aeSRobert Watson case PRIV_IPC_ADMIN: 2110c14d15aeSRobert Watson case PRIV_IPC_MSGSIZE: 2111c14d15aeSRobert Watson case PRIV_MQ_ADMIN: 2112c14d15aeSRobert Watson 2113c14d15aeSRobert Watson /* 2114c14d15aeSRobert Watson * Allow certain scheduler manipulations -- possibly this should be 2115c14d15aeSRobert Watson * controlled by more fine-grained policy, as potentially low 2116c14d15aeSRobert Watson * integrity processes can deny CPU to higher integrity ones. 2117c14d15aeSRobert Watson */ 2118c14d15aeSRobert Watson case PRIV_SCHED_DIFFCRED: 2119c14d15aeSRobert Watson case PRIV_SCHED_SETPRIORITY: 2120c14d15aeSRobert Watson case PRIV_SCHED_RTPRIO: 2121c14d15aeSRobert Watson case PRIV_SCHED_SETPOLICY: 2122c14d15aeSRobert Watson case PRIV_SCHED_SET: 2123c14d15aeSRobert Watson case PRIV_SCHED_SETPARAM: 2124c14d15aeSRobert Watson 2125c14d15aeSRobert Watson /* 2126c14d15aeSRobert Watson * More IPC privileges. 2127c14d15aeSRobert Watson */ 2128c14d15aeSRobert Watson case PRIV_SEM_WRITE: 2129c14d15aeSRobert Watson 2130c14d15aeSRobert Watson /* 2131c14d15aeSRobert Watson * Allow signaling privileges subject to integrity policy. 2132c14d15aeSRobert Watson */ 2133c14d15aeSRobert Watson case PRIV_SIGNAL_DIFFCRED: 2134c14d15aeSRobert Watson case PRIV_SIGNAL_SUGID: 2135c14d15aeSRobert Watson 2136c14d15aeSRobert Watson /* 2137c14d15aeSRobert Watson * Allow access to only limited sysctls from lower integrity levels; 2138c14d15aeSRobert Watson * piggy-back on the Jail definition. 2139c14d15aeSRobert Watson */ 2140c14d15aeSRobert Watson case PRIV_SYSCTL_WRITEJAIL: 2141c14d15aeSRobert Watson 2142c14d15aeSRobert Watson /* 2143c14d15aeSRobert Watson * Allow TTY-based privileges, subject to general device access using 2144c14d15aeSRobert Watson * labels on TTY device nodes, but not console privilege. 2145c14d15aeSRobert Watson */ 2146c14d15aeSRobert Watson case PRIV_TTY_DRAINWAIT: 2147c14d15aeSRobert Watson case PRIV_TTY_DTRWAIT: 2148c14d15aeSRobert Watson case PRIV_TTY_EXCLUSIVE: 2149c14d15aeSRobert Watson case PRIV_TTY_PRISON: 2150c14d15aeSRobert Watson case PRIV_TTY_STI: 2151c14d15aeSRobert Watson case PRIV_TTY_SETA: 2152c14d15aeSRobert Watson 2153c14d15aeSRobert Watson /* 2154c14d15aeSRobert Watson * Grant most VFS privileges, as almost all are in practice bounded 2155c14d15aeSRobert Watson * by more specific checks using labels. 2156c14d15aeSRobert Watson */ 2157c14d15aeSRobert Watson case PRIV_VFS_READ: 2158c14d15aeSRobert Watson case PRIV_VFS_WRITE: 2159c14d15aeSRobert Watson case PRIV_VFS_ADMIN: 2160c14d15aeSRobert Watson case PRIV_VFS_EXEC: 2161c14d15aeSRobert Watson case PRIV_VFS_LOOKUP: 2162c14d15aeSRobert Watson case PRIV_VFS_CHFLAGS_DEV: 2163c14d15aeSRobert Watson case PRIV_VFS_CHOWN: 2164c14d15aeSRobert Watson case PRIV_VFS_CHROOT: 2165c14d15aeSRobert Watson case PRIV_VFS_RETAINSUGID: 2166c14d15aeSRobert Watson case PRIV_VFS_EXCEEDQUOTA: 2167c14d15aeSRobert Watson case PRIV_VFS_FCHROOT: 2168c14d15aeSRobert Watson case PRIV_VFS_FHOPEN: 2169c14d15aeSRobert Watson case PRIV_VFS_FHSTATFS: 2170c14d15aeSRobert Watson case PRIV_VFS_GENERATION: 2171c14d15aeSRobert Watson case PRIV_VFS_GETFH: 2172c14d15aeSRobert Watson case PRIV_VFS_GETQUOTA: 2173c14d15aeSRobert Watson case PRIV_VFS_LINK: 2174c14d15aeSRobert Watson case PRIV_VFS_MOUNT: 2175c14d15aeSRobert Watson case PRIV_VFS_MOUNT_OWNER: 2176c14d15aeSRobert Watson case PRIV_VFS_MOUNT_PERM: 2177c14d15aeSRobert Watson case PRIV_VFS_MOUNT_SUIDDIR: 2178c14d15aeSRobert Watson case PRIV_VFS_MOUNT_NONUSER: 2179c14d15aeSRobert Watson case PRIV_VFS_SETGID: 2180c14d15aeSRobert Watson case PRIV_VFS_STICKYFILE: 2181c14d15aeSRobert Watson case PRIV_VFS_SYSFLAGS: 2182c14d15aeSRobert Watson case PRIV_VFS_UNMOUNT: 2183c14d15aeSRobert Watson 2184c14d15aeSRobert Watson /* 2185c14d15aeSRobert Watson * Allow VM privileges; it would be nice if these were subject to 2186c14d15aeSRobert Watson * resource limits. 2187c14d15aeSRobert Watson */ 2188c14d15aeSRobert Watson case PRIV_VM_MADV_PROTECT: 2189c14d15aeSRobert Watson case PRIV_VM_MLOCK: 2190c14d15aeSRobert Watson case PRIV_VM_MUNLOCK: 2191c14d15aeSRobert Watson 2192c14d15aeSRobert Watson /* 2193c14d15aeSRobert Watson * Allow some but not all network privileges. In general, dont allow 2194c14d15aeSRobert Watson * reconfiguring the network stack, just normal use. 2195c14d15aeSRobert Watson */ 2196c14d15aeSRobert Watson case PRIV_NETATALK_RESERVEDPORT: 2197c14d15aeSRobert Watson case PRIV_NETINET_RESERVEDPORT: 2198c14d15aeSRobert Watson case PRIV_NETINET_RAW: 2199c14d15aeSRobert Watson case PRIV_NETINET_REUSEPORT: 2200c14d15aeSRobert Watson case PRIV_NETIPX_RESERVEDPORT: 2201c14d15aeSRobert Watson case PRIV_NETIPX_RAW: 2202c14d15aeSRobert Watson break; 2203c14d15aeSRobert Watson 2204c14d15aeSRobert Watson /* 2205c14d15aeSRobert Watson * All remaining system privileges are allow only if the process 2206c14d15aeSRobert Watson * holds privilege with respect to the LOMAC policy. 2207c14d15aeSRobert Watson */ 2208c14d15aeSRobert Watson default: 2209c14d15aeSRobert Watson subj = SLOT(cred->cr_label); 2210c14d15aeSRobert Watson error = mac_lomac_subject_privileged(subj); 2211c14d15aeSRobert Watson if (error) 2212c14d15aeSRobert Watson return (error); 2213c14d15aeSRobert Watson } 2214c14d15aeSRobert Watson return (0); 2215c14d15aeSRobert Watson } 2216c14d15aeSRobert Watson 2217c14d15aeSRobert Watson 2218db2661ceSRobert Watson static int 221918717f69SRobert Watson mac_lomac_check_system_acct(struct ucred *cred, struct vnode *vp, 222078007886SRobert Watson struct label *vplabel) 222118717f69SRobert Watson { 222218717f69SRobert Watson struct mac_lomac *subj, *obj; 222318717f69SRobert Watson 222418717f69SRobert Watson if (!mac_lomac_enabled) 222518717f69SRobert Watson return (0); 222618717f69SRobert Watson 222718717f69SRobert Watson subj = SLOT(cred->cr_label); 222878007886SRobert Watson obj = SLOT(vplabel); 222918717f69SRobert Watson 223018717f69SRobert Watson if (mac_lomac_subject_privileged(subj)) 223118717f69SRobert Watson return (EPERM); 223218717f69SRobert Watson 223318717f69SRobert Watson if (!mac_lomac_high_single(obj)) 223418717f69SRobert Watson return (EACCES); 223518717f69SRobert Watson 223618717f69SRobert Watson return (0); 223718717f69SRobert Watson } 223818717f69SRobert Watson 223918717f69SRobert Watson static int 224018717f69SRobert Watson mac_lomac_check_system_auditctl(struct ucred *cred, struct vnode *vp, 224178007886SRobert Watson struct label *vplabel) 224218717f69SRobert Watson { 224318717f69SRobert Watson struct mac_lomac *subj, *obj; 224418717f69SRobert Watson 224518717f69SRobert Watson if (!mac_lomac_enabled) 224618717f69SRobert Watson return (0); 224718717f69SRobert Watson 224818717f69SRobert Watson subj = SLOT(cred->cr_label); 224978007886SRobert Watson obj = SLOT(vplabel); 225018717f69SRobert Watson 225118717f69SRobert Watson if (mac_lomac_subject_privileged(subj)) 225218717f69SRobert Watson return (EPERM); 225318717f69SRobert Watson 225418717f69SRobert Watson if (!mac_lomac_high_single(obj)) 225518717f69SRobert Watson return (EACCES); 225618717f69SRobert Watson 225718717f69SRobert Watson return (0); 225818717f69SRobert Watson } 225918717f69SRobert Watson 226018717f69SRobert Watson static int 226118717f69SRobert Watson mac_lomac_check_system_swapoff(struct ucred *cred, struct vnode *vp, 226278007886SRobert Watson struct label *vplabel) 226318717f69SRobert Watson { 226418717f69SRobert Watson struct mac_lomac *subj; 226518717f69SRobert Watson 226618717f69SRobert Watson if (!mac_lomac_enabled) 226718717f69SRobert Watson return (0); 226818717f69SRobert Watson 226918717f69SRobert Watson subj = SLOT(cred->cr_label); 227018717f69SRobert Watson 227118717f69SRobert Watson if (mac_lomac_subject_privileged(subj)) 227218717f69SRobert Watson return (EPERM); 227318717f69SRobert Watson 227418717f69SRobert Watson return (0); 227518717f69SRobert Watson } 227618717f69SRobert Watson 227718717f69SRobert Watson static int 2278db2661ceSRobert Watson mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp, 227978007886SRobert Watson struct label *vplabel) 2280db2661ceSRobert Watson { 2281db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2282db2661ceSRobert Watson 2283db2661ceSRobert Watson if (!mac_lomac_enabled) 2284db2661ceSRobert Watson return (0); 2285db2661ceSRobert Watson 2286eca8a663SRobert Watson subj = SLOT(cred->cr_label); 228778007886SRobert Watson obj = SLOT(vplabel); 2288db2661ceSRobert Watson 2289db2661ceSRobert Watson if (mac_lomac_subject_privileged(subj)) 2290db2661ceSRobert Watson return (EPERM); 2291db2661ceSRobert Watson 2292db2661ceSRobert Watson if (!mac_lomac_high_single(obj)) 2293db2661ceSRobert Watson return (EACCES); 2294db2661ceSRobert Watson 2295db2661ceSRobert Watson return (0); 2296db2661ceSRobert Watson } 2297db2661ceSRobert Watson 2298db2661ceSRobert Watson static int 229963dba32bSPawel Jakub Dawidek mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 230063dba32bSPawel Jakub Dawidek void *arg1, int arg2, struct sysctl_req *req) 2301db2661ceSRobert Watson { 2302db2661ceSRobert Watson struct mac_lomac *subj; 2303db2661ceSRobert Watson 2304db2661ceSRobert Watson if (!mac_lomac_enabled) 2305db2661ceSRobert Watson return (0); 2306db2661ceSRobert Watson 2307eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2308db2661ceSRobert Watson 2309db2661ceSRobert Watson /* 231063dba32bSPawel Jakub Dawidek * Treat sysctl variables without CTLFLAG_ANYBODY flag as 231163dba32bSPawel Jakub Dawidek * lomac/high, but also require privilege to change them. 2312db2661ceSRobert Watson */ 231363dba32bSPawel Jakub Dawidek if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2314db2661ceSRobert Watson #ifdef notdef 2315db2661ceSRobert Watson if (!mac_lomac_subject_dominate_high(subj)) 2316db2661ceSRobert Watson return (EACCES); 2317db2661ceSRobert Watson #endif 2318db2661ceSRobert Watson 2319db2661ceSRobert Watson if (mac_lomac_subject_privileged(subj)) 2320db2661ceSRobert Watson return (EPERM); 2321db2661ceSRobert Watson } 2322db2661ceSRobert Watson 2323db2661ceSRobert Watson return (0); 2324db2661ceSRobert Watson } 2325db2661ceSRobert Watson 2326db2661ceSRobert Watson static int 2327db2661ceSRobert Watson mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 232878007886SRobert Watson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2329db2661ceSRobert Watson { 2330db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2331db2661ceSRobert Watson 2332db2661ceSRobert Watson if (!mac_lomac_enabled) 2333db2661ceSRobert Watson return (0); 2334db2661ceSRobert Watson 2335eca8a663SRobert Watson subj = SLOT(cred->cr_label); 233678007886SRobert Watson obj = SLOT(dvplabel); 2337db2661ceSRobert Watson 2338db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2339db2661ceSRobert Watson return (EACCES); 2340db2661ceSRobert Watson if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2341db2661ceSRobert Watson !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2342db2661ceSRobert Watson return (EACCES); 2343db2661ceSRobert Watson 2344db2661ceSRobert Watson return (0); 2345db2661ceSRobert Watson } 2346db2661ceSRobert Watson 2347db2661ceSRobert Watson static int 2348db2661ceSRobert Watson mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 234978007886SRobert Watson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2350db2661ceSRobert Watson struct componentname *cnp) 2351db2661ceSRobert Watson { 2352db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2353db2661ceSRobert Watson 2354db2661ceSRobert Watson if (!mac_lomac_enabled) 2355db2661ceSRobert Watson return (0); 2356db2661ceSRobert Watson 2357eca8a663SRobert Watson subj = SLOT(cred->cr_label); 235878007886SRobert Watson obj = SLOT(dvplabel); 2359db2661ceSRobert Watson 2360db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2361db2661ceSRobert Watson return (EACCES); 2362db2661ceSRobert Watson 236378007886SRobert Watson obj = SLOT(vplabel); 2364db2661ceSRobert Watson 2365db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2366db2661ceSRobert Watson return (EACCES); 2367db2661ceSRobert Watson 2368db2661ceSRobert Watson return (0); 2369db2661ceSRobert Watson } 2370db2661ceSRobert Watson 2371db2661ceSRobert Watson static int 2372db2661ceSRobert Watson mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 237378007886SRobert Watson struct label *vplabel, acl_type_t type) 2374db2661ceSRobert Watson { 2375db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2376db2661ceSRobert Watson 2377db2661ceSRobert Watson if (!mac_lomac_enabled) 2378db2661ceSRobert Watson return (0); 2379db2661ceSRobert Watson 2380eca8a663SRobert Watson subj = SLOT(cred->cr_label); 238178007886SRobert Watson obj = SLOT(vplabel); 2382db2661ceSRobert Watson 2383db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2384db2661ceSRobert Watson return (EACCES); 2385db2661ceSRobert Watson 2386db2661ceSRobert Watson return (0); 2387db2661ceSRobert Watson } 2388db2661ceSRobert Watson 2389db2661ceSRobert Watson static int 2390db2661ceSRobert Watson mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 239178007886SRobert Watson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2392db2661ceSRobert Watson struct componentname *cnp) 2393db2661ceSRobert Watson { 2394db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2395db2661ceSRobert Watson 2396db2661ceSRobert Watson if (!mac_lomac_enabled) 2397db2661ceSRobert Watson return (0); 2398db2661ceSRobert Watson 2399eca8a663SRobert Watson subj = SLOT(cred->cr_label); 240078007886SRobert Watson obj = SLOT(dvplabel); 2401db2661ceSRobert Watson 2402db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2403db2661ceSRobert Watson return (EACCES); 2404db2661ceSRobert Watson 240578007886SRobert Watson obj = SLOT(vplabel); 2406db2661ceSRobert Watson 2407db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2408db2661ceSRobert Watson return (EACCES); 2409db2661ceSRobert Watson 2410db2661ceSRobert Watson return (0); 2411db2661ceSRobert Watson } 2412db2661ceSRobert Watson 2413db2661ceSRobert Watson static int 2414db2661ceSRobert Watson mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 241578007886SRobert Watson struct label *vplabel, int prot, int flags) 2416db2661ceSRobert Watson { 2417db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2418db2661ceSRobert Watson 2419db2661ceSRobert Watson /* 2420db2661ceSRobert Watson * Rely on the use of open()-time protections to handle 2421db2661ceSRobert Watson * non-revocation cases. 2422db2661ceSRobert Watson */ 2423db2661ceSRobert Watson if (!mac_lomac_enabled) 2424db2661ceSRobert Watson return (0); 2425db2661ceSRobert Watson 2426eca8a663SRobert Watson subj = SLOT(cred->cr_label); 242778007886SRobert Watson obj = SLOT(vplabel); 2428db2661ceSRobert Watson 2429c92163dcSChristian S.J. Peron if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2430db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2431db2661ceSRobert Watson return (EACCES); 2432db2661ceSRobert Watson } 2433db2661ceSRobert Watson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2434db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 2435db2661ceSRobert Watson return (maybe_demote(subj, obj, "mapping", "file", vp)); 2436db2661ceSRobert Watson } 2437db2661ceSRobert Watson 2438db2661ceSRobert Watson return (0); 2439db2661ceSRobert Watson } 2440db2661ceSRobert Watson 2441db2661ceSRobert Watson static void 2442db2661ceSRobert Watson mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, 244378007886SRobert Watson struct label *vplabel, /* XXX vm_prot_t */ int *prot) 2444db2661ceSRobert Watson { 2445db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2446db2661ceSRobert Watson 2447db2661ceSRobert Watson /* 2448db2661ceSRobert Watson * Rely on the use of open()-time protections to handle 2449db2661ceSRobert Watson * non-revocation cases. 2450db2661ceSRobert Watson */ 2451db2661ceSRobert Watson if (!mac_lomac_enabled || !revocation_enabled) 2452db2661ceSRobert Watson return; 2453db2661ceSRobert Watson 2454eca8a663SRobert Watson subj = SLOT(cred->cr_label); 245578007886SRobert Watson obj = SLOT(vplabel); 2456db2661ceSRobert Watson 2457db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2458db2661ceSRobert Watson *prot &= ~VM_PROT_WRITE; 2459db2661ceSRobert Watson } 2460db2661ceSRobert Watson 2461db2661ceSRobert Watson static int 2462db2661ceSRobert Watson mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp, 246378007886SRobert Watson struct label *vplabel, int acc_mode) 2464db2661ceSRobert Watson { 2465db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2466db2661ceSRobert Watson 2467db2661ceSRobert Watson if (!mac_lomac_enabled) 2468db2661ceSRobert Watson return (0); 2469db2661ceSRobert Watson 2470eca8a663SRobert Watson subj = SLOT(cred->cr_label); 247178007886SRobert Watson obj = SLOT(vplabel); 2472db2661ceSRobert Watson 2473db2661ceSRobert Watson /* XXX privilege override for admin? */ 2474db2661ceSRobert Watson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2475db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2476db2661ceSRobert Watson return (EACCES); 2477db2661ceSRobert Watson } 2478db2661ceSRobert Watson 2479db2661ceSRobert Watson return (0); 2480db2661ceSRobert Watson } 2481db2661ceSRobert Watson 2482db2661ceSRobert Watson static int 2483db2661ceSRobert Watson mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 248478007886SRobert Watson struct vnode *vp, struct label *vplabel) 2485db2661ceSRobert Watson { 2486db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2487db2661ceSRobert Watson 2488db2661ceSRobert Watson if (!mac_lomac_enabled || !revocation_enabled) 2489db2661ceSRobert Watson return (0); 2490db2661ceSRobert Watson 2491eca8a663SRobert Watson subj = SLOT(active_cred->cr_label); 249278007886SRobert Watson obj = SLOT(vplabel); 2493db2661ceSRobert Watson 2494db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 2495db2661ceSRobert Watson return (maybe_demote(subj, obj, "reading", "file", vp)); 2496db2661ceSRobert Watson 2497db2661ceSRobert Watson return (0); 2498db2661ceSRobert Watson } 2499db2661ceSRobert Watson 2500db2661ceSRobert Watson static int 2501db2661ceSRobert Watson mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 250278007886SRobert Watson struct label *vplabel, struct label *newlabel) 2503db2661ceSRobert Watson { 2504db2661ceSRobert Watson struct mac_lomac *old, *new, *subj; 2505db2661ceSRobert Watson int error; 2506db2661ceSRobert Watson 250778007886SRobert Watson old = SLOT(vplabel); 2508db2661ceSRobert Watson new = SLOT(newlabel); 2509eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2510db2661ceSRobert Watson 2511db2661ceSRobert Watson /* 2512db2661ceSRobert Watson * If there is a LOMAC label update for the vnode, it must be a 2513db2661ceSRobert Watson * single label, with an optional explicit auxiliary single. 2514db2661ceSRobert Watson */ 2515db2661ceSRobert Watson error = lomac_atmostflags(new, 2516db2661ceSRobert Watson MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2517db2661ceSRobert Watson if (error) 2518db2661ceSRobert Watson return (error); 2519db2661ceSRobert Watson 2520db2661ceSRobert Watson /* 2521db2661ceSRobert Watson * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2522db2661ceSRobert Watson * authorize the relabel. 2523db2661ceSRobert Watson */ 2524db2661ceSRobert Watson if (!mac_lomac_single_in_range(old, subj)) 2525db2661ceSRobert Watson return (EPERM); 2526db2661ceSRobert Watson 2527db2661ceSRobert Watson /* 2528db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 2529db2661ceSRobert Watson */ 2530db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2531db2661ceSRobert Watson /* 2532db2661ceSRobert Watson * To change the LOMAC label on a vnode, the new vnode label 2533db2661ceSRobert Watson * must be in the subject range. 2534db2661ceSRobert Watson */ 2535db2661ceSRobert Watson if (!mac_lomac_single_in_range(new, subj)) 2536db2661ceSRobert Watson return (EPERM); 2537db2661ceSRobert Watson 2538db2661ceSRobert Watson /* 2539db2661ceSRobert Watson * To change the LOMAC label on the vnode to be EQUAL, 2540db2661ceSRobert Watson * the subject must have appropriate privilege. 2541db2661ceSRobert Watson */ 2542db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 2543db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 2544db2661ceSRobert Watson if (error) 2545db2661ceSRobert Watson return (error); 2546db2661ceSRobert Watson } 2547db2661ceSRobert Watson } 2548db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2549db2661ceSRobert Watson /* 255084bdb083SRobert Watson * Fill in the missing parts from the previous label. 255184bdb083SRobert Watson */ 255284bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 255384bdb083SRobert Watson mac_lomac_copy_single(subj, new); 255484bdb083SRobert Watson 255584bdb083SRobert Watson /* 2556db2661ceSRobert Watson * To change the auxiliary LOMAC label on a vnode, the new 2557db2661ceSRobert Watson * vnode label must be in the subject range. 2558db2661ceSRobert Watson */ 2559db2661ceSRobert Watson if (!mac_lomac_auxsingle_in_range(new, subj)) 2560db2661ceSRobert Watson return (EPERM); 2561db2661ceSRobert Watson 2562db2661ceSRobert Watson /* 2563db2661ceSRobert Watson * To change the auxiliary LOMAC label on the vnode to be 2564db2661ceSRobert Watson * EQUAL, the subject must have appropriate privilege. 2565db2661ceSRobert Watson */ 2566db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 2567db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 2568db2661ceSRobert Watson if (error) 2569db2661ceSRobert Watson return (error); 2570db2661ceSRobert Watson } 2571db2661ceSRobert Watson } 2572db2661ceSRobert Watson 2573db2661ceSRobert Watson return (0); 2574db2661ceSRobert Watson } 2575db2661ceSRobert Watson 2576db2661ceSRobert Watson static int 2577db2661ceSRobert Watson mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 257878007886SRobert Watson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2579db2661ceSRobert Watson struct componentname *cnp) 2580db2661ceSRobert Watson { 2581db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2582db2661ceSRobert Watson 2583db2661ceSRobert Watson if (!mac_lomac_enabled) 2584db2661ceSRobert Watson return (0); 2585db2661ceSRobert Watson 2586eca8a663SRobert Watson subj = SLOT(cred->cr_label); 258778007886SRobert Watson obj = SLOT(dvplabel); 2588db2661ceSRobert Watson 2589db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2590db2661ceSRobert Watson return (EACCES); 2591db2661ceSRobert Watson 259278007886SRobert Watson obj = SLOT(vplabel); 2593db2661ceSRobert Watson 2594db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2595db2661ceSRobert Watson return (EACCES); 2596db2661ceSRobert Watson 2597db2661ceSRobert Watson return (0); 2598db2661ceSRobert Watson } 2599db2661ceSRobert Watson 2600db2661ceSRobert Watson static int 2601db2661ceSRobert Watson mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 260278007886SRobert Watson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 260378007886SRobert Watson int samedir, struct componentname *cnp) 2604db2661ceSRobert Watson { 2605db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2606db2661ceSRobert Watson 2607db2661ceSRobert Watson if (!mac_lomac_enabled) 2608db2661ceSRobert Watson return (0); 2609db2661ceSRobert Watson 2610eca8a663SRobert Watson subj = SLOT(cred->cr_label); 261178007886SRobert Watson obj = SLOT(dvplabel); 2612db2661ceSRobert Watson 2613db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2614db2661ceSRobert Watson return (EACCES); 2615db2661ceSRobert Watson 2616db2661ceSRobert Watson if (vp != NULL) { 261778007886SRobert Watson obj = SLOT(vplabel); 2618db2661ceSRobert Watson 2619db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2620db2661ceSRobert Watson return (EACCES); 2621db2661ceSRobert Watson } 2622db2661ceSRobert Watson 2623db2661ceSRobert Watson return (0); 2624db2661ceSRobert Watson } 2625db2661ceSRobert Watson 2626db2661ceSRobert Watson static int 2627db2661ceSRobert Watson mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 262878007886SRobert Watson struct label *vplabel) 2629db2661ceSRobert Watson { 2630db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2631db2661ceSRobert Watson 2632db2661ceSRobert Watson if (!mac_lomac_enabled) 2633db2661ceSRobert Watson return (0); 2634db2661ceSRobert Watson 2635eca8a663SRobert Watson subj = SLOT(cred->cr_label); 263678007886SRobert Watson obj = SLOT(vplabel); 2637db2661ceSRobert Watson 2638db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2639db2661ceSRobert Watson return (EACCES); 2640db2661ceSRobert Watson 2641db2661ceSRobert Watson return (0); 2642db2661ceSRobert Watson } 2643db2661ceSRobert Watson 2644db2661ceSRobert Watson static int 2645db2661ceSRobert Watson mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 264678007886SRobert Watson struct label *vplabel, acl_type_t type, struct acl *acl) 2647db2661ceSRobert Watson { 2648db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2649db2661ceSRobert Watson 2650db2661ceSRobert Watson if (!mac_lomac_enabled) 2651db2661ceSRobert Watson return (0); 2652db2661ceSRobert Watson 2653eca8a663SRobert Watson subj = SLOT(cred->cr_label); 265478007886SRobert Watson obj = SLOT(vplabel); 2655db2661ceSRobert Watson 2656db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2657db2661ceSRobert Watson return (EACCES); 2658db2661ceSRobert Watson 2659db2661ceSRobert Watson return (0); 2660db2661ceSRobert Watson } 2661db2661ceSRobert Watson 2662db2661ceSRobert Watson static int 2663db2661ceSRobert Watson mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 266478007886SRobert Watson struct label *vplabel, int attrnamespace, const char *name, 2665db2661ceSRobert Watson struct uio *uio) 2666db2661ceSRobert Watson { 2667db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2668db2661ceSRobert Watson 2669db2661ceSRobert Watson if (!mac_lomac_enabled) 2670db2661ceSRobert Watson return (0); 2671db2661ceSRobert Watson 2672eca8a663SRobert Watson subj = SLOT(cred->cr_label); 267378007886SRobert Watson obj = SLOT(vplabel); 2674db2661ceSRobert Watson 2675db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2676db2661ceSRobert Watson return (EACCES); 2677db2661ceSRobert Watson 2678db2661ceSRobert Watson /* XXX: protect the MAC EA in a special way? */ 2679db2661ceSRobert Watson 2680db2661ceSRobert Watson return (0); 2681db2661ceSRobert Watson } 2682db2661ceSRobert Watson 2683db2661ceSRobert Watson static int 2684db2661ceSRobert Watson mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 268578007886SRobert Watson struct label *vplabel, u_long flags) 2686db2661ceSRobert Watson { 2687db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2688db2661ceSRobert Watson 2689db2661ceSRobert Watson if (!mac_lomac_enabled) 2690db2661ceSRobert Watson return (0); 2691db2661ceSRobert Watson 2692eca8a663SRobert Watson subj = SLOT(cred->cr_label); 269378007886SRobert Watson obj = SLOT(vplabel); 2694db2661ceSRobert Watson 2695db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2696db2661ceSRobert Watson return (EACCES); 2697db2661ceSRobert Watson 2698db2661ceSRobert Watson return (0); 2699db2661ceSRobert Watson } 2700db2661ceSRobert Watson 2701db2661ceSRobert Watson static int 2702db2661ceSRobert Watson mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 270378007886SRobert Watson struct label *vplabel, mode_t mode) 2704db2661ceSRobert Watson { 2705db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2706db2661ceSRobert Watson 2707db2661ceSRobert Watson if (!mac_lomac_enabled) 2708db2661ceSRobert Watson return (0); 2709db2661ceSRobert Watson 2710eca8a663SRobert Watson subj = SLOT(cred->cr_label); 271178007886SRobert Watson obj = SLOT(vplabel); 2712db2661ceSRobert Watson 2713db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2714db2661ceSRobert Watson return (EACCES); 2715db2661ceSRobert Watson 2716db2661ceSRobert Watson return (0); 2717db2661ceSRobert Watson } 2718db2661ceSRobert Watson 2719db2661ceSRobert Watson static int 2720db2661ceSRobert Watson mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 272178007886SRobert Watson struct label *vplabel, uid_t uid, gid_t gid) 2722db2661ceSRobert Watson { 2723db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2724db2661ceSRobert Watson 2725db2661ceSRobert Watson if (!mac_lomac_enabled) 2726db2661ceSRobert Watson return (0); 2727db2661ceSRobert Watson 2728eca8a663SRobert Watson subj = SLOT(cred->cr_label); 272978007886SRobert Watson obj = SLOT(vplabel); 2730db2661ceSRobert Watson 2731db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2732db2661ceSRobert Watson return (EACCES); 2733db2661ceSRobert Watson 2734db2661ceSRobert Watson return (0); 2735db2661ceSRobert Watson } 2736db2661ceSRobert Watson 2737db2661ceSRobert Watson static int 2738db2661ceSRobert Watson mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 273978007886SRobert Watson struct label *vplabel, struct timespec atime, struct timespec mtime) 2740db2661ceSRobert Watson { 2741db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2742db2661ceSRobert Watson 2743db2661ceSRobert Watson if (!mac_lomac_enabled) 2744db2661ceSRobert Watson return (0); 2745db2661ceSRobert Watson 2746eca8a663SRobert Watson subj = SLOT(cred->cr_label); 274778007886SRobert Watson obj = SLOT(vplabel); 2748db2661ceSRobert Watson 2749db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2750db2661ceSRobert Watson return (EACCES); 2751db2661ceSRobert Watson 2752db2661ceSRobert Watson return (0); 2753db2661ceSRobert Watson } 2754db2661ceSRobert Watson 2755db2661ceSRobert Watson static int 2756db2661ceSRobert Watson mac_lomac_check_vnode_write(struct ucred *active_cred, 275778007886SRobert Watson struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 2758db2661ceSRobert Watson { 2759db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2760db2661ceSRobert Watson 2761db2661ceSRobert Watson if (!mac_lomac_enabled || !revocation_enabled) 2762db2661ceSRobert Watson return (0); 2763db2661ceSRobert Watson 2764eca8a663SRobert Watson subj = SLOT(active_cred->cr_label); 276578007886SRobert Watson obj = SLOT(vplabel); 2766db2661ceSRobert Watson 2767db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2768db2661ceSRobert Watson return (EACCES); 2769db2661ceSRobert Watson 2770db2661ceSRobert Watson return (0); 2771db2661ceSRobert Watson } 2772db2661ceSRobert Watson 2773db2661ceSRobert Watson static void 2774db2661ceSRobert Watson mac_lomac_thread_userret(struct thread *td) 2775db2661ceSRobert Watson { 2776db2661ceSRobert Watson struct proc *p = td->td_proc; 2777eca8a663SRobert Watson struct mac_lomac_proc *subj = PSLOT(p->p_label); 2778db2661ceSRobert Watson struct ucred *newcred, *oldcred; 2779db2661ceSRobert Watson int dodrop; 2780db2661ceSRobert Watson 2781db2661ceSRobert Watson mtx_lock(&subj->mtx); 2782db2661ceSRobert Watson if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 2783db2661ceSRobert Watson dodrop = 0; 2784db2661ceSRobert Watson mtx_unlock(&subj->mtx); 2785db2661ceSRobert Watson newcred = crget(); 2786db2661ceSRobert Watson /* 2787db2661ceSRobert Watson * Prevent a lock order reversal in 2788db2661ceSRobert Watson * mac_cred_mmapped_drop_perms; ideally, the other 2789db2661ceSRobert Watson * user of subj->mtx wouldn't be holding Giant. 2790db2661ceSRobert Watson */ 2791db2661ceSRobert Watson mtx_lock(&Giant); 2792db2661ceSRobert Watson PROC_LOCK(p); 2793db2661ceSRobert Watson mtx_lock(&subj->mtx); 2794db2661ceSRobert Watson /* 2795db2661ceSRobert Watson * Check if we lost the race while allocating the cred. 2796db2661ceSRobert Watson */ 2797db2661ceSRobert Watson if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2798db2661ceSRobert Watson crfree(newcred); 2799db2661ceSRobert Watson goto out; 2800db2661ceSRobert Watson } 2801db2661ceSRobert Watson oldcred = p->p_ucred; 2802db2661ceSRobert Watson crcopy(newcred, oldcred); 2803db2661ceSRobert Watson crhold(newcred); 2804eca8a663SRobert Watson mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2805db2661ceSRobert Watson p->p_ucred = newcred; 2806db2661ceSRobert Watson crfree(oldcred); 2807db2661ceSRobert Watson dodrop = 1; 2808db2661ceSRobert Watson out: 2809db2661ceSRobert Watson mtx_unlock(&subj->mtx); 2810db2661ceSRobert Watson PROC_UNLOCK(p); 2811db2661ceSRobert Watson if (dodrop) 2812db2661ceSRobert Watson mac_cred_mmapped_drop_perms(curthread, newcred); 2813db2661ceSRobert Watson mtx_unlock(&Giant); 2814db2661ceSRobert Watson } else { 2815db2661ceSRobert Watson mtx_unlock(&subj->mtx); 2816db2661ceSRobert Watson } 2817db2661ceSRobert Watson } 2818db2661ceSRobert Watson 2819db2661ceSRobert Watson static struct mac_policy_ops mac_lomac_ops = 2820db2661ceSRobert Watson { 2821db2661ceSRobert Watson .mpo_init = mac_lomac_init, 2822db2661ceSRobert Watson .mpo_init_bpfdesc_label = mac_lomac_init_label, 2823db2661ceSRobert Watson .mpo_init_cred_label = mac_lomac_init_label, 2824db2661ceSRobert Watson .mpo_init_devfsdirent_label = mac_lomac_init_label, 2825db2661ceSRobert Watson .mpo_init_ifnet_label = mac_lomac_init_label, 2826430fc756SChristian S.J. Peron .mpo_init_syncache_label = mac_lomac_init_label_waitcheck, 2827a557af22SRobert Watson .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck, 28285e7ce478SRobert Watson .mpo_init_ipq_label = mac_lomac_init_label_waitcheck, 2829db2661ceSRobert Watson .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck, 2830db2661ceSRobert Watson .mpo_init_mount_label = mac_lomac_init_label, 2831db2661ceSRobert Watson .mpo_init_pipe_label = mac_lomac_init_label, 2832db2661ceSRobert Watson .mpo_init_proc_label = mac_lomac_init_proc_label, 2833db2661ceSRobert Watson .mpo_init_socket_label = mac_lomac_init_label_waitcheck, 2834db2661ceSRobert Watson .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck, 2835db2661ceSRobert Watson .mpo_init_vnode_label = mac_lomac_init_label, 2836430fc756SChristian S.J. Peron .mpo_init_syncache_from_inpcb = mac_lomac_init_syncache_from_inpcb, 2837db2661ceSRobert Watson .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label, 2838db2661ceSRobert Watson .mpo_destroy_cred_label = mac_lomac_destroy_label, 2839db2661ceSRobert Watson .mpo_destroy_devfsdirent_label = mac_lomac_destroy_label, 2840db2661ceSRobert Watson .mpo_destroy_ifnet_label = mac_lomac_destroy_label, 2841a557af22SRobert Watson .mpo_destroy_inpcb_label = mac_lomac_destroy_label, 2842db2661ceSRobert Watson .mpo_destroy_ipq_label = mac_lomac_destroy_label, 2843db2661ceSRobert Watson .mpo_destroy_mbuf_label = mac_lomac_destroy_label, 2844db2661ceSRobert Watson .mpo_destroy_mount_label = mac_lomac_destroy_label, 2845db2661ceSRobert Watson .mpo_destroy_pipe_label = mac_lomac_destroy_label, 2846db2661ceSRobert Watson .mpo_destroy_proc_label = mac_lomac_destroy_proc_label, 2847430fc756SChristian S.J. Peron .mpo_destroy_syncache_label = mac_lomac_destroy_label, 2848db2661ceSRobert Watson .mpo_destroy_socket_label = mac_lomac_destroy_label, 2849db2661ceSRobert Watson .mpo_destroy_socket_peer_label = mac_lomac_destroy_label, 2850db2661ceSRobert Watson .mpo_destroy_vnode_label = mac_lomac_destroy_label, 285156d9e932SRobert Watson .mpo_copy_cred_label = mac_lomac_copy_label, 28522220907bSRobert Watson .mpo_copy_ifnet_label = mac_lomac_copy_label, 2853985a0d97SRobert Watson .mpo_copy_mbuf_label = mac_lomac_copy_label, 2854db2661ceSRobert Watson .mpo_copy_pipe_label = mac_lomac_copy_label, 2855b0323ea3SRobert Watson .mpo_copy_socket_label = mac_lomac_copy_label, 2856db2661ceSRobert Watson .mpo_copy_vnode_label = mac_lomac_copy_label, 2857db2661ceSRobert Watson .mpo_externalize_cred_label = mac_lomac_externalize_label, 2858db2661ceSRobert Watson .mpo_externalize_ifnet_label = mac_lomac_externalize_label, 2859db2661ceSRobert Watson .mpo_externalize_pipe_label = mac_lomac_externalize_label, 2860db2661ceSRobert Watson .mpo_externalize_socket_label = mac_lomac_externalize_label, 2861db2661ceSRobert Watson .mpo_externalize_socket_peer_label = mac_lomac_externalize_label, 2862db2661ceSRobert Watson .mpo_externalize_vnode_label = mac_lomac_externalize_label, 2863db2661ceSRobert Watson .mpo_internalize_cred_label = mac_lomac_internalize_label, 2864db2661ceSRobert Watson .mpo_internalize_ifnet_label = mac_lomac_internalize_label, 2865db2661ceSRobert Watson .mpo_internalize_pipe_label = mac_lomac_internalize_label, 2866db2661ceSRobert Watson .mpo_internalize_socket_label = mac_lomac_internalize_label, 2867db2661ceSRobert Watson .mpo_internalize_vnode_label = mac_lomac_internalize_label, 2868db2661ceSRobert Watson .mpo_create_devfs_device = mac_lomac_create_devfs_device, 2869db2661ceSRobert Watson .mpo_create_devfs_directory = mac_lomac_create_devfs_directory, 2870db2661ceSRobert Watson .mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink, 2871db2661ceSRobert Watson .mpo_create_mount = mac_lomac_create_mount, 2872db2661ceSRobert Watson .mpo_relabel_vnode = mac_lomac_relabel_vnode, 2873db2661ceSRobert Watson .mpo_update_devfsdirent = mac_lomac_update_devfsdirent, 2874db2661ceSRobert Watson .mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs, 2875db2661ceSRobert Watson .mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr, 2876db2661ceSRobert Watson .mpo_associate_vnode_singlelabel = 2877db2661ceSRobert Watson mac_lomac_associate_vnode_singlelabel, 2878db2661ceSRobert Watson .mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr, 2879db2661ceSRobert Watson .mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr, 2880db2661ceSRobert Watson .mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket, 2881430fc756SChristian S.J. Peron .mpo_create_mbuf_from_syncache = mac_lomac_create_mbuf_from_syncache, 2882db2661ceSRobert Watson .mpo_create_pipe = mac_lomac_create_pipe, 2883db2661ceSRobert Watson .mpo_create_socket = mac_lomac_create_socket, 2884db2661ceSRobert Watson .mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket, 2885db2661ceSRobert Watson .mpo_relabel_pipe = mac_lomac_relabel_pipe, 2886db2661ceSRobert Watson .mpo_relabel_socket = mac_lomac_relabel_socket, 2887db2661ceSRobert Watson .mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf, 2888db2661ceSRobert Watson .mpo_set_socket_peer_from_socket = 2889db2661ceSRobert Watson mac_lomac_set_socket_peer_from_socket, 2890db2661ceSRobert Watson .mpo_create_bpfdesc = mac_lomac_create_bpfdesc, 2891db2661ceSRobert Watson .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq, 2892db2661ceSRobert Watson .mpo_create_fragment = mac_lomac_create_fragment, 2893db2661ceSRobert Watson .mpo_create_ifnet = mac_lomac_create_ifnet, 2894a557af22SRobert Watson .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket, 2895db2661ceSRobert Watson .mpo_create_ipq = mac_lomac_create_ipq, 28962d92ec98SRobert Watson .mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb, 2897db2661ceSRobert Watson .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer, 2898db2661ceSRobert Watson .mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc, 2899db2661ceSRobert Watson .mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet, 2900db2661ceSRobert Watson .mpo_create_mbuf_multicast_encap = 2901db2661ceSRobert Watson mac_lomac_create_mbuf_multicast_encap, 2902db2661ceSRobert Watson .mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer, 2903db2661ceSRobert Watson .mpo_fragment_match = mac_lomac_fragment_match, 2904db2661ceSRobert Watson .mpo_relabel_ifnet = mac_lomac_relabel_ifnet, 2905db2661ceSRobert Watson .mpo_update_ipq = mac_lomac_update_ipq, 2906a557af22SRobert Watson .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel, 2907db2661ceSRobert Watson .mpo_execve_transition = mac_lomac_execve_transition, 2908db2661ceSRobert Watson .mpo_execve_will_transition = mac_lomac_execve_will_transition, 2909db2661ceSRobert Watson .mpo_create_proc0 = mac_lomac_create_proc0, 2910db2661ceSRobert Watson .mpo_create_proc1 = mac_lomac_create_proc1, 2911db2661ceSRobert Watson .mpo_relabel_cred = mac_lomac_relabel_cred, 2912db2661ceSRobert Watson .mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive, 2913db2661ceSRobert Watson .mpo_check_cred_relabel = mac_lomac_check_cred_relabel, 2914db2661ceSRobert Watson .mpo_check_cred_visible = mac_lomac_check_cred_visible, 2915db2661ceSRobert Watson .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel, 2916db2661ceSRobert Watson .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit, 2917a557af22SRobert Watson .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver, 2918db2661ceSRobert Watson .mpo_check_kld_load = mac_lomac_check_kld_load, 2919db2661ceSRobert Watson .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl, 2920db2661ceSRobert Watson .mpo_check_pipe_read = mac_lomac_check_pipe_read, 2921db2661ceSRobert Watson .mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel, 2922db2661ceSRobert Watson .mpo_check_pipe_write = mac_lomac_check_pipe_write, 2923db2661ceSRobert Watson .mpo_check_proc_debug = mac_lomac_check_proc_debug, 2924db2661ceSRobert Watson .mpo_check_proc_sched = mac_lomac_check_proc_sched, 2925db2661ceSRobert Watson .mpo_check_proc_signal = mac_lomac_check_proc_signal, 2926db2661ceSRobert Watson .mpo_check_socket_deliver = mac_lomac_check_socket_deliver, 2927db2661ceSRobert Watson .mpo_check_socket_relabel = mac_lomac_check_socket_relabel, 2928db2661ceSRobert Watson .mpo_check_socket_visible = mac_lomac_check_socket_visible, 292918717f69SRobert Watson .mpo_check_system_acct = mac_lomac_check_system_acct, 293018717f69SRobert Watson .mpo_check_system_auditctl = mac_lomac_check_system_auditctl, 293118717f69SRobert Watson .mpo_check_system_swapoff = mac_lomac_check_system_swapoff, 2932db2661ceSRobert Watson .mpo_check_system_swapon = mac_lomac_check_system_swapon, 2933db2661ceSRobert Watson .mpo_check_system_sysctl = mac_lomac_check_system_sysctl, 2934db2661ceSRobert Watson .mpo_check_vnode_access = mac_lomac_check_vnode_open, 2935db2661ceSRobert Watson .mpo_check_vnode_create = mac_lomac_check_vnode_create, 2936db2661ceSRobert Watson .mpo_check_vnode_delete = mac_lomac_check_vnode_delete, 2937db2661ceSRobert Watson .mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl, 2938db2661ceSRobert Watson .mpo_check_vnode_link = mac_lomac_check_vnode_link, 2939db2661ceSRobert Watson .mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap, 2940db2661ceSRobert Watson .mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade, 2941db2661ceSRobert Watson .mpo_check_vnode_open = mac_lomac_check_vnode_open, 2942db2661ceSRobert Watson .mpo_check_vnode_read = mac_lomac_check_vnode_read, 2943db2661ceSRobert Watson .mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel, 2944db2661ceSRobert Watson .mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from, 2945db2661ceSRobert Watson .mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to, 2946db2661ceSRobert Watson .mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke, 2947db2661ceSRobert Watson .mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl, 2948db2661ceSRobert Watson .mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr, 2949db2661ceSRobert Watson .mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags, 2950db2661ceSRobert Watson .mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode, 2951db2661ceSRobert Watson .mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner, 2952db2661ceSRobert Watson .mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes, 2953db2661ceSRobert Watson .mpo_check_vnode_write = mac_lomac_check_vnode_write, 2954db2661ceSRobert Watson .mpo_thread_userret = mac_lomac_thread_userret, 2955d94f2a68SChristian S.J. Peron .mpo_create_mbuf_from_firewall = mac_lomac_create_mbuf_from_firewall, 2956c14d15aeSRobert Watson .mpo_priv_check = mac_lomac_priv_check, 2957db2661ceSRobert Watson }; 2958db2661ceSRobert Watson 2959db2661ceSRobert Watson MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC", 2960aa6a0037SRobert Watson MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, 2961aa6a0037SRobert Watson &mac_lomac_slot); 2962