1db2661ceSRobert Watson /*- 2f6a41092SRobert Watson * Copyright (c) 1999-2002 Robert N. M. Watson 3f6a41092SRobert Watson * Copyright (c) 2001-2003 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. 39db2661ceSRobert Watson * Low-watermark floating label mandatory integrity policy. 40db2661ceSRobert Watson */ 41db2661ceSRobert Watson 42db2661ceSRobert Watson #include <sys/types.h> 43db2661ceSRobert Watson #include <sys/param.h> 44db2661ceSRobert Watson #include <sys/acl.h> 45db2661ceSRobert Watson #include <sys/conf.h> 46db2661ceSRobert Watson #include <sys/extattr.h> 47db2661ceSRobert Watson #include <sys/kernel.h> 48db2661ceSRobert Watson #include <sys/mac.h> 49db2661ceSRobert Watson #include <sys/malloc.h> 50db2661ceSRobert Watson #include <sys/mount.h> 51db2661ceSRobert Watson #include <sys/proc.h> 52f51e5803SRobert Watson #include <sys/sbuf.h> 53db2661ceSRobert Watson #include <sys/systm.h> 54db2661ceSRobert Watson #include <sys/sysproto.h> 55db2661ceSRobert Watson #include <sys/sysent.h> 56db2661ceSRobert Watson #include <sys/systm.h> 57db2661ceSRobert Watson #include <sys/vnode.h> 58db2661ceSRobert Watson #include <sys/file.h> 59db2661ceSRobert Watson #include <sys/socket.h> 60db2661ceSRobert Watson #include <sys/socketvar.h> 61db2661ceSRobert Watson #include <sys/pipe.h> 62db2661ceSRobert Watson #include <sys/sysctl.h> 63db2661ceSRobert Watson #include <sys/syslog.h> 64db2661ceSRobert Watson 65db2661ceSRobert Watson #include <fs/devfs/devfs.h> 66db2661ceSRobert Watson 67db2661ceSRobert Watson #include <net/bpfdesc.h> 68db2661ceSRobert Watson #include <net/if.h> 69db2661ceSRobert Watson #include <net/if_types.h> 70db2661ceSRobert Watson #include <net/if_var.h> 71db2661ceSRobert Watson 72db2661ceSRobert Watson #include <netinet/in.h> 73a557af22SRobert Watson #include <netinet/in_pcb.h> 74db2661ceSRobert Watson #include <netinet/ip_var.h> 75db2661ceSRobert Watson 76db2661ceSRobert Watson #include <vm/vm.h> 77db2661ceSRobert Watson 78db2661ceSRobert Watson #include <sys/mac_policy.h> 79db2661ceSRobert Watson 80db2661ceSRobert Watson #include <security/mac_lomac/mac_lomac.h> 81db2661ceSRobert Watson 82db2661ceSRobert Watson struct mac_lomac_proc { 83db2661ceSRobert Watson struct mac_lomac mac_lomac; 84db2661ceSRobert Watson struct mtx mtx; 85db2661ceSRobert Watson }; 86db2661ceSRobert Watson 87db2661ceSRobert Watson SYSCTL_DECL(_security_mac); 88db2661ceSRobert Watson 89db2661ceSRobert Watson SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0, 90db2661ceSRobert Watson "TrustedBSD mac_lomac policy controls"); 91db2661ceSRobert Watson 92db2661ceSRobert Watson static int mac_lomac_label_size = sizeof(struct mac_lomac); 93db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD, 94db2661ceSRobert Watson &mac_lomac_label_size, 0, "Size of struct mac_lomac"); 95db2661ceSRobert Watson 96eba0370dSRobert Watson static int mac_lomac_enabled = 1; 97db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW, 98db2661ceSRobert Watson &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy"); 99db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled); 100db2661ceSRobert Watson 101db2661ceSRobert Watson static int destroyed_not_inited; 102db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 103db2661ceSRobert Watson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 104db2661ceSRobert Watson 105db2661ceSRobert Watson static int trust_all_interfaces = 0; 106db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 107db2661ceSRobert Watson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC"); 108db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces); 109db2661ceSRobert Watson 110db2661ceSRobert Watson static char trusted_interfaces[128]; 111db2661ceSRobert Watson SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 112db2661ceSRobert Watson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC"); 113db2661ceSRobert Watson TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces, 114db2661ceSRobert Watson sizeof(trusted_interfaces)); 115db2661ceSRobert Watson 116db2661ceSRobert Watson static int ptys_equal = 0; 117db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW, 118db2661ceSRobert Watson &ptys_equal, 0, "Label pty devices as lomac/equal on create"); 119db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal); 120db2661ceSRobert Watson 121db2661ceSRobert Watson static int revocation_enabled = 1; 122db2661ceSRobert Watson SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW, 123db2661ceSRobert Watson &revocation_enabled, 0, "Revoke access to objects on relabel"); 124db2661ceSRobert Watson TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled); 125db2661ceSRobert Watson 126db2661ceSRobert Watson static int mac_lomac_slot; 127db2661ceSRobert Watson #define SLOT(l) ((struct mac_lomac *)LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr) 128db2661ceSRobert Watson #define PSLOT(l) ((struct mac_lomac_proc *) \ 129db2661ceSRobert Watson LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr) 130db2661ceSRobert Watson 131db2661ceSRobert Watson MALLOC_DEFINE(M_MACLOMAC, "lomac label", "MAC/LOMAC labels"); 132db2661ceSRobert Watson 133db2661ceSRobert Watson static struct mac_lomac * 134db2661ceSRobert Watson lomac_alloc(int flag) 135db2661ceSRobert Watson { 136db2661ceSRobert Watson struct mac_lomac *mac_lomac; 137db2661ceSRobert Watson 138db2661ceSRobert Watson mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag); 139db2661ceSRobert Watson 140db2661ceSRobert Watson return (mac_lomac); 141db2661ceSRobert Watson } 142db2661ceSRobert Watson 143db2661ceSRobert Watson static void 144db2661ceSRobert Watson lomac_free(struct mac_lomac *mac_lomac) 145db2661ceSRobert Watson { 146db2661ceSRobert Watson 147db2661ceSRobert Watson if (mac_lomac != NULL) 148db2661ceSRobert Watson free(mac_lomac, M_MACLOMAC); 149db2661ceSRobert Watson else 150db2661ceSRobert Watson atomic_add_int(&destroyed_not_inited, 1); 151db2661ceSRobert Watson } 152db2661ceSRobert Watson 153db2661ceSRobert Watson static int 154db2661ceSRobert Watson lomac_atmostflags(struct mac_lomac *mac_lomac, int flags) 155db2661ceSRobert Watson { 156db2661ceSRobert Watson 157db2661ceSRobert Watson if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags) 158db2661ceSRobert Watson return (EINVAL); 159db2661ceSRobert Watson return (0); 160db2661ceSRobert Watson } 161db2661ceSRobert Watson 162db2661ceSRobert Watson static int 163db2661ceSRobert Watson mac_lomac_dominate_element(struct mac_lomac_element *a, 164db2661ceSRobert Watson struct mac_lomac_element *b) 165db2661ceSRobert Watson { 166db2661ceSRobert Watson 167db2661ceSRobert Watson switch (a->mle_type) { 168db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 169db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 170db2661ceSRobert Watson return (1); 171db2661ceSRobert Watson 172db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 173db2661ceSRobert Watson switch (b->mle_type) { 174db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 175db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 176db2661ceSRobert Watson return (0); 177db2661ceSRobert Watson 178db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 179db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 180db2661ceSRobert Watson return (1); 181db2661ceSRobert Watson 182db2661ceSRobert Watson default: 183db2661ceSRobert Watson panic("mac_lomac_dominate_element: b->mle_type invalid"); 184db2661ceSRobert Watson } 185db2661ceSRobert Watson 186db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 187db2661ceSRobert Watson switch (b->mle_type) { 188db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 189db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 190db2661ceSRobert Watson return (1); 191db2661ceSRobert Watson 192db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 193db2661ceSRobert Watson return (0); 194db2661ceSRobert Watson 195db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 196db2661ceSRobert Watson return (a->mle_grade >= b->mle_grade); 197db2661ceSRobert Watson 198db2661ceSRobert Watson default: 199db2661ceSRobert Watson panic("mac_lomac_dominate_element: b->mle_type invalid"); 200db2661ceSRobert Watson } 201db2661ceSRobert Watson 202db2661ceSRobert Watson default: 203db2661ceSRobert Watson panic("mac_lomac_dominate_element: a->mle_type invalid"); 204db2661ceSRobert Watson } 205db2661ceSRobert Watson } 206db2661ceSRobert Watson 207db2661ceSRobert Watson static int 208db2661ceSRobert Watson mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb) 209db2661ceSRobert Watson { 210db2661ceSRobert Watson 211db2661ceSRobert Watson return (mac_lomac_dominate_element(&rangeb->ml_rangehigh, 212db2661ceSRobert Watson &rangea->ml_rangehigh) && 213db2661ceSRobert Watson mac_lomac_dominate_element(&rangea->ml_rangelow, 214db2661ceSRobert Watson &rangeb->ml_rangelow)); 215db2661ceSRobert Watson } 216db2661ceSRobert Watson 217db2661ceSRobert Watson static int 218db2661ceSRobert Watson mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range) 219db2661ceSRobert Watson { 220db2661ceSRobert Watson 221db2661ceSRobert Watson KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 222db2661ceSRobert Watson ("mac_lomac_single_in_range: a not single")); 223db2661ceSRobert Watson KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 224db2661ceSRobert Watson ("mac_lomac_single_in_range: b not range")); 225db2661ceSRobert Watson 226db2661ceSRobert Watson return (mac_lomac_dominate_element(&range->ml_rangehigh, 227db2661ceSRobert Watson &single->ml_single) && 228db2661ceSRobert Watson mac_lomac_dominate_element(&single->ml_single, 229db2661ceSRobert Watson &range->ml_rangelow)); 230db2661ceSRobert Watson } 231db2661ceSRobert Watson 232db2661ceSRobert Watson static int 233db2661ceSRobert Watson mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range) 234db2661ceSRobert Watson { 235db2661ceSRobert Watson 236db2661ceSRobert Watson KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 237db2661ceSRobert Watson ("mac_lomac_single_in_range: a not auxsingle")); 238db2661ceSRobert Watson KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 239db2661ceSRobert Watson ("mac_lomac_single_in_range: b not range")); 240db2661ceSRobert Watson 241db2661ceSRobert Watson return (mac_lomac_dominate_element(&range->ml_rangehigh, 242db2661ceSRobert Watson &single->ml_auxsingle) && 243db2661ceSRobert Watson mac_lomac_dominate_element(&single->ml_auxsingle, 244db2661ceSRobert Watson &range->ml_rangelow)); 245db2661ceSRobert Watson } 246db2661ceSRobert Watson 247db2661ceSRobert Watson static int 248db2661ceSRobert Watson mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b) 249db2661ceSRobert Watson { 250db2661ceSRobert Watson KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 251db2661ceSRobert Watson ("mac_lomac_dominate_single: a not single")); 252db2661ceSRobert Watson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 253db2661ceSRobert Watson ("mac_lomac_dominate_single: b not single")); 254db2661ceSRobert Watson 255db2661ceSRobert Watson return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single)); 256db2661ceSRobert Watson } 257db2661ceSRobert Watson 258db2661ceSRobert Watson static int 259db2661ceSRobert Watson mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b) 260db2661ceSRobert Watson { 261db2661ceSRobert Watson KASSERT((~a->ml_flags & 262db2661ceSRobert Watson (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0, 263db2661ceSRobert Watson ("mac_lomac_dominate_single: a not subject")); 264db2661ceSRobert Watson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 265db2661ceSRobert Watson ("mac_lomac_dominate_single: b not single")); 266db2661ceSRobert Watson 267db2661ceSRobert Watson return (mac_lomac_dominate_element(&a->ml_rangehigh, 268db2661ceSRobert Watson &b->ml_single)); 269db2661ceSRobert Watson } 270db2661ceSRobert Watson 271db2661ceSRobert Watson static int 272db2661ceSRobert Watson mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b) 273db2661ceSRobert Watson { 274db2661ceSRobert Watson 275db2661ceSRobert Watson if (a->mle_type == MAC_LOMAC_TYPE_EQUAL || 276db2661ceSRobert Watson b->mle_type == MAC_LOMAC_TYPE_EQUAL) 277db2661ceSRobert Watson return (1); 278db2661ceSRobert Watson 279db2661ceSRobert Watson return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade); 280db2661ceSRobert Watson } 281db2661ceSRobert Watson 282db2661ceSRobert Watson static int 283db2661ceSRobert Watson mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b) 284db2661ceSRobert Watson { 285db2661ceSRobert Watson 286db2661ceSRobert Watson KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 287db2661ceSRobert Watson ("mac_lomac_equal_single: a not single")); 288db2661ceSRobert Watson KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 289db2661ceSRobert Watson ("mac_lomac_equal_single: b not single")); 290db2661ceSRobert Watson 291db2661ceSRobert Watson return (mac_lomac_equal_element(&a->ml_single, &b->ml_single)); 292db2661ceSRobert Watson } 293db2661ceSRobert Watson 294db2661ceSRobert Watson static int 295db2661ceSRobert Watson mac_lomac_contains_equal(struct mac_lomac *mac_lomac) 296db2661ceSRobert Watson { 297db2661ceSRobert Watson 298db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) 299db2661ceSRobert Watson if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 300db2661ceSRobert Watson return (1); 301db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) 302db2661ceSRobert Watson if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL) 303db2661ceSRobert Watson return (1); 304db2661ceSRobert Watson 305db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 306db2661ceSRobert Watson if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL) 307db2661ceSRobert Watson return (1); 308db2661ceSRobert Watson if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 309db2661ceSRobert Watson return (1); 310db2661ceSRobert Watson } 311db2661ceSRobert Watson 312db2661ceSRobert Watson return (0); 313db2661ceSRobert Watson } 314db2661ceSRobert Watson 315db2661ceSRobert Watson static int 316db2661ceSRobert Watson mac_lomac_subject_privileged(struct mac_lomac *mac_lomac) 317db2661ceSRobert Watson { 318db2661ceSRobert Watson 319db2661ceSRobert Watson KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) == 320db2661ceSRobert Watson MAC_LOMAC_FLAGS_BOTH, 321db2661ceSRobert Watson ("mac_lomac_subject_privileged: subject doesn't have both labels")); 322db2661ceSRobert Watson 323db2661ceSRobert Watson /* If the single is EQUAL, it's ok. */ 324db2661ceSRobert Watson if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 325db2661ceSRobert Watson return (0); 326db2661ceSRobert Watson 327db2661ceSRobert Watson /* If either range endpoint is EQUAL, it's ok. */ 328db2661ceSRobert Watson if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL || 329db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 330db2661ceSRobert Watson return (0); 331db2661ceSRobert Watson 332db2661ceSRobert Watson /* If the range is low-high, it's ok. */ 333db2661ceSRobert Watson if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW && 334db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH) 335db2661ceSRobert Watson return (0); 336db2661ceSRobert Watson 337db2661ceSRobert Watson /* It's not ok. */ 338db2661ceSRobert Watson return (EPERM); 339db2661ceSRobert Watson } 340db2661ceSRobert Watson 341db2661ceSRobert Watson static int 342db2661ceSRobert Watson mac_lomac_high_single(struct mac_lomac *mac_lomac) 343db2661ceSRobert Watson { 344db2661ceSRobert Watson 345db2661ceSRobert Watson KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 346db2661ceSRobert Watson ("mac_lomac_high_single: mac_lomac not single")); 347db2661ceSRobert Watson 348db2661ceSRobert Watson return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH); 349db2661ceSRobert Watson } 350db2661ceSRobert Watson 351db2661ceSRobert Watson static int 352db2661ceSRobert Watson mac_lomac_valid(struct mac_lomac *mac_lomac) 353db2661ceSRobert Watson { 354db2661ceSRobert Watson 355db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 356db2661ceSRobert Watson switch (mac_lomac->ml_single.mle_type) { 357db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 358db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 359db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 360db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 361db2661ceSRobert Watson break; 362db2661ceSRobert Watson 363db2661ceSRobert Watson default: 364db2661ceSRobert Watson return (EINVAL); 365db2661ceSRobert Watson } 366db2661ceSRobert Watson } else { 367db2661ceSRobert Watson if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF) 368db2661ceSRobert Watson return (EINVAL); 369db2661ceSRobert Watson } 370db2661ceSRobert Watson 371db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { 372db2661ceSRobert Watson switch (mac_lomac->ml_auxsingle.mle_type) { 373db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 374db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 375db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 376db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 377db2661ceSRobert Watson break; 378db2661ceSRobert Watson 379db2661ceSRobert Watson default: 380db2661ceSRobert Watson return (EINVAL); 381db2661ceSRobert Watson } 382db2661ceSRobert Watson } else { 383db2661ceSRobert Watson if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF) 384db2661ceSRobert Watson return (EINVAL); 385db2661ceSRobert Watson } 386db2661ceSRobert Watson 387db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 388db2661ceSRobert Watson switch (mac_lomac->ml_rangelow.mle_type) { 389db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 390db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 391db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 392db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 393db2661ceSRobert Watson break; 394db2661ceSRobert Watson 395db2661ceSRobert Watson default: 396db2661ceSRobert Watson return (EINVAL); 397db2661ceSRobert Watson } 398db2661ceSRobert Watson 399db2661ceSRobert Watson switch (mac_lomac->ml_rangehigh.mle_type) { 400db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 401db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 402db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 403db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 404db2661ceSRobert Watson break; 405db2661ceSRobert Watson 406db2661ceSRobert Watson default: 407db2661ceSRobert Watson return (EINVAL); 408db2661ceSRobert Watson } 409db2661ceSRobert Watson if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh, 410db2661ceSRobert Watson &mac_lomac->ml_rangelow)) 411db2661ceSRobert Watson return (EINVAL); 412db2661ceSRobert Watson } else { 413db2661ceSRobert Watson if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF || 414db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF) 415db2661ceSRobert Watson return (EINVAL); 416db2661ceSRobert Watson } 417db2661ceSRobert Watson 418db2661ceSRobert Watson return (0); 419db2661ceSRobert Watson } 420db2661ceSRobert Watson 421db2661ceSRobert Watson static void 422db2661ceSRobert Watson mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow, 423db2661ceSRobert Watson u_short gradelow, u_short typehigh, u_short gradehigh) 424db2661ceSRobert Watson { 425db2661ceSRobert Watson 426db2661ceSRobert Watson mac_lomac->ml_rangelow.mle_type = typelow; 427db2661ceSRobert Watson mac_lomac->ml_rangelow.mle_grade = gradelow; 428db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_type = typehigh; 429db2661ceSRobert Watson mac_lomac->ml_rangehigh.mle_grade = gradehigh; 430db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE; 431db2661ceSRobert Watson } 432db2661ceSRobert Watson 433db2661ceSRobert Watson static void 434db2661ceSRobert Watson mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade) 435db2661ceSRobert Watson { 436db2661ceSRobert Watson 437db2661ceSRobert Watson mac_lomac->ml_single.mle_type = type; 438db2661ceSRobert Watson mac_lomac->ml_single.mle_grade = grade; 439db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 440db2661ceSRobert Watson } 441db2661ceSRobert Watson 442db2661ceSRobert Watson static void 443db2661ceSRobert Watson mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 444db2661ceSRobert Watson { 445db2661ceSRobert Watson 446db2661ceSRobert Watson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 447db2661ceSRobert Watson ("mac_lomac_copy_range: labelfrom not range")); 448db2661ceSRobert Watson 449db2661ceSRobert Watson labelto->ml_rangelow = labelfrom->ml_rangelow; 450db2661ceSRobert Watson labelto->ml_rangehigh = labelfrom->ml_rangehigh; 451db2661ceSRobert Watson labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE; 452db2661ceSRobert Watson } 453db2661ceSRobert Watson 454db2661ceSRobert Watson static void 455db2661ceSRobert Watson mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 456db2661ceSRobert Watson { 457db2661ceSRobert Watson 458db2661ceSRobert Watson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 459db2661ceSRobert Watson ("mac_lomac_copy_single: labelfrom not single")); 460db2661ceSRobert Watson 461db2661ceSRobert Watson labelto->ml_single = labelfrom->ml_single; 462db2661ceSRobert Watson labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 463db2661ceSRobert Watson } 464db2661ceSRobert Watson 465db2661ceSRobert Watson static void 466db2661ceSRobert Watson mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 467db2661ceSRobert Watson { 468db2661ceSRobert Watson 469db2661ceSRobert Watson KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 470db2661ceSRobert Watson ("mac_lomac_copy_auxsingle: labelfrom not auxsingle")); 471db2661ceSRobert Watson 472db2661ceSRobert Watson labelto->ml_auxsingle = labelfrom->ml_auxsingle; 473db2661ceSRobert Watson labelto->ml_flags |= MAC_LOMAC_FLAG_AUX; 474db2661ceSRobert Watson } 475db2661ceSRobert Watson 476db2661ceSRobert Watson static void 477db2661ceSRobert Watson mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest) 478db2661ceSRobert Watson { 479db2661ceSRobert Watson 480db2661ceSRobert Watson if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE) 481db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 482db2661ceSRobert Watson if (source->ml_flags & MAC_LOMAC_FLAG_AUX) 483db2661ceSRobert Watson mac_lomac_copy_auxsingle(source, dest); 484db2661ceSRobert Watson if (source->ml_flags & MAC_LOMAC_FLAG_RANGE) 485db2661ceSRobert Watson mac_lomac_copy_range(source, dest); 486db2661ceSRobert Watson } 487db2661ceSRobert Watson 488f51e5803SRobert Watson static int mac_lomac_to_string(struct sbuf *sb, 489f51e5803SRobert Watson struct mac_lomac *mac_lomac); 490db2661ceSRobert Watson 491db2661ceSRobert Watson static int 492db2661ceSRobert Watson maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 493db2661ceSRobert Watson const char *actionname, const char *objname, struct vnode *vpq) 494db2661ceSRobert Watson { 495f51e5803SRobert Watson struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb; 496f51e5803SRobert Watson char *subjlabeltext, *objlabeltext, *subjtext; 497f51e5803SRobert Watson struct mac_lomac cached_subjlabel; 498f51e5803SRobert Watson struct mac_lomac_proc *subj; 499db2661ceSRobert Watson struct vattr va; 500db2661ceSRobert Watson struct proc *p; 501db2661ceSRobert Watson pid_t pgid; 502db2661ceSRobert Watson 503eca8a663SRobert Watson subj = PSLOT(curthread->td_proc->p_label); 504f51e5803SRobert Watson 505db2661ceSRobert Watson p = curthread->td_proc; 506db2661ceSRobert Watson mtx_lock(&subj->mtx); 507db2661ceSRobert Watson if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 508db2661ceSRobert Watson /* 509db2661ceSRobert Watson * Check to see if the pending demotion would be more or 510db2661ceSRobert Watson * less severe than this one, and keep the more severe. 511db2661ceSRobert Watson * This can only happen for a multi-threaded application. 512db2661ceSRobert Watson */ 513db2661ceSRobert Watson if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) { 514db2661ceSRobert Watson mtx_unlock(&subj->mtx); 515db2661ceSRobert Watson return (0); 516db2661ceSRobert Watson } 517db2661ceSRobert Watson } 518db2661ceSRobert Watson bzero(&subj->mac_lomac, sizeof(subj->mac_lomac)); 519db2661ceSRobert Watson /* 520db2661ceSRobert Watson * Always demote the single label. 521db2661ceSRobert Watson */ 522db2661ceSRobert Watson mac_lomac_copy_single(objlabel, &subj->mac_lomac); 523db2661ceSRobert Watson /* 524db2661ceSRobert Watson * Start with the original range, then minimize each side of 525db2661ceSRobert Watson * the range to the point of not dominating the object. The 526db2661ceSRobert Watson * high side will always be demoted, of course. 527db2661ceSRobert Watson */ 528db2661ceSRobert Watson mac_lomac_copy_range(subjlabel, &subj->mac_lomac); 529db2661ceSRobert Watson if (!mac_lomac_dominate_element(&objlabel->ml_single, 530db2661ceSRobert Watson &subj->mac_lomac.ml_rangelow)) 531db2661ceSRobert Watson subj->mac_lomac.ml_rangelow = objlabel->ml_single; 532db2661ceSRobert Watson subj->mac_lomac.ml_rangehigh = objlabel->ml_single; 533db2661ceSRobert Watson subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE; 534db2661ceSRobert Watson mtx_lock_spin(&sched_lock); 5354a338afdSJulian Elischer curthread->td_flags |= TDF_ASTPENDING; 536db2661ceSRobert Watson curthread->td_proc->p_sflag |= PS_MACPEND; 537db2661ceSRobert Watson mtx_unlock_spin(&sched_lock); 538f51e5803SRobert Watson 539f51e5803SRobert Watson /* 540f51e5803SRobert Watson * Avoid memory allocation while holding a mutex; cache the 541f51e5803SRobert Watson * label. 542f51e5803SRobert Watson */ 543f51e5803SRobert Watson mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel); 544db2661ceSRobert Watson mtx_unlock(&subj->mtx); 545f51e5803SRobert Watson 546f51e5803SRobert Watson sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 547f51e5803SRobert Watson mac_lomac_to_string(&subjlabel_sb, subjlabel); 548f51e5803SRobert Watson sbuf_finish(&subjlabel_sb); 549f51e5803SRobert Watson subjlabeltext = sbuf_data(&subjlabel_sb); 550f51e5803SRobert Watson 551f51e5803SRobert Watson sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND); 552f51e5803SRobert Watson mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac); 553f51e5803SRobert Watson sbuf_finish(&subjtext_sb); 554f51e5803SRobert Watson subjtext = sbuf_data(&subjtext_sb); 555f51e5803SRobert Watson 556f51e5803SRobert Watson sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 557f51e5803SRobert Watson mac_lomac_to_string(&objlabel_sb, objlabel); 558f51e5803SRobert Watson sbuf_finish(&objlabel_sb); 559f51e5803SRobert Watson objlabeltext = sbuf_data(&objlabel_sb); 560f51e5803SRobert Watson 561db2661ceSRobert Watson pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ 562db2661ceSRobert Watson if (vpq != NULL && VOP_GETATTR(vpq, &va, curthread->td_ucred, 563db2661ceSRobert Watson curthread) == 0) { 564db2661ceSRobert Watson log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 565db2661ceSRobert Watson " level %s after %s a level-%s %s (inode=%ld, " 566db2661ceSRobert Watson "mountpount=%s)\n", 567db2661ceSRobert Watson subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 568db2661ceSRobert Watson p->p_comm, subjtext, actionname, objlabeltext, objname, 569db2661ceSRobert Watson va.va_fileid, vpq->v_mount->mnt_stat.f_mntonname); 570db2661ceSRobert Watson } else { 571db2661ceSRobert Watson log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 572db2661ceSRobert Watson " level %s after %s a level-%s %s\n", 573db2661ceSRobert Watson subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 574db2661ceSRobert Watson p->p_comm, subjtext, actionname, objlabeltext, objname); 575db2661ceSRobert Watson } 576db2661ceSRobert Watson 577f51e5803SRobert Watson sbuf_delete(&subjlabel_sb); 578f51e5803SRobert Watson sbuf_delete(&subjtext_sb); 579f51e5803SRobert Watson sbuf_delete(&objlabel_sb); 580f51e5803SRobert Watson 581db2661ceSRobert Watson return (0); 582db2661ceSRobert Watson } 583db2661ceSRobert Watson 584db2661ceSRobert Watson /* 585db2661ceSRobert Watson * Relabel "to" to "from" only if "from" is a valid label (contains 586db2661ceSRobert Watson * at least a single), as for a relabel operation which may or may 587db2661ceSRobert Watson * not involve a relevant label. 588db2661ceSRobert Watson */ 5897496ed81SRobert Watson static void 590db2661ceSRobert Watson try_relabel(struct mac_lomac *from, struct mac_lomac *to) 591db2661ceSRobert Watson { 592db2661ceSRobert Watson 593db2661ceSRobert Watson if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 594db2661ceSRobert Watson bzero(to, sizeof(*to)); 595db2661ceSRobert Watson mac_lomac_copy(from, to); 596db2661ceSRobert Watson } 597db2661ceSRobert Watson } 598db2661ceSRobert Watson 599db2661ceSRobert Watson /* 600db2661ceSRobert Watson * Policy module operations. 601db2661ceSRobert Watson */ 602db2661ceSRobert Watson static void 603db2661ceSRobert Watson mac_lomac_init(struct mac_policy_conf *conf) 604db2661ceSRobert Watson { 605db2661ceSRobert Watson 606db2661ceSRobert Watson } 607db2661ceSRobert Watson 608db2661ceSRobert Watson /* 609db2661ceSRobert Watson * Label operations. 610db2661ceSRobert Watson */ 611db2661ceSRobert Watson static void 612db2661ceSRobert Watson mac_lomac_init_label(struct label *label) 613db2661ceSRobert Watson { 614db2661ceSRobert Watson 615a163d034SWarner Losh SLOT(label) = lomac_alloc(M_WAITOK); 616db2661ceSRobert Watson } 617db2661ceSRobert Watson 618db2661ceSRobert Watson static int 619db2661ceSRobert Watson mac_lomac_init_label_waitcheck(struct label *label, int flag) 620db2661ceSRobert Watson { 621db2661ceSRobert Watson 622db2661ceSRobert Watson SLOT(label) = lomac_alloc(flag); 623db2661ceSRobert Watson if (SLOT(label) == NULL) 624db2661ceSRobert Watson return (ENOMEM); 625db2661ceSRobert Watson 626db2661ceSRobert Watson return (0); 627db2661ceSRobert Watson } 628db2661ceSRobert Watson 629db2661ceSRobert Watson static void 630db2661ceSRobert Watson mac_lomac_init_proc_label(struct label *label) 631db2661ceSRobert Watson { 632db2661ceSRobert Watson 633db2661ceSRobert Watson PSLOT(label) = malloc(sizeof(struct mac_lomac_proc), M_MACLOMAC, 634a163d034SWarner Losh M_ZERO | M_WAITOK); 635db2661ceSRobert Watson mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF); 636db2661ceSRobert Watson } 637db2661ceSRobert Watson 638db2661ceSRobert Watson static void 639db2661ceSRobert Watson mac_lomac_destroy_label(struct label *label) 640db2661ceSRobert Watson { 641db2661ceSRobert Watson 642db2661ceSRobert Watson lomac_free(SLOT(label)); 643db2661ceSRobert Watson SLOT(label) = NULL; 644db2661ceSRobert Watson } 645db2661ceSRobert Watson 646db2661ceSRobert Watson static void 647db2661ceSRobert Watson mac_lomac_destroy_proc_label(struct label *label) 648db2661ceSRobert Watson { 649db2661ceSRobert Watson 650db2661ceSRobert Watson mtx_destroy(&PSLOT(label)->mtx); 651db2661ceSRobert Watson FREE(PSLOT(label), M_MACLOMAC); 652db2661ceSRobert Watson PSLOT(label) = NULL; 653db2661ceSRobert Watson } 654db2661ceSRobert Watson 655f51e5803SRobert Watson static int 656f51e5803SRobert Watson mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element) 657db2661ceSRobert Watson { 658db2661ceSRobert Watson 659db2661ceSRobert Watson switch (element->mle_type) { 660db2661ceSRobert Watson case MAC_LOMAC_TYPE_HIGH: 661f51e5803SRobert Watson return (sbuf_printf(sb, "high")); 662db2661ceSRobert Watson 663db2661ceSRobert Watson case MAC_LOMAC_TYPE_LOW: 664f51e5803SRobert Watson return (sbuf_printf(sb, "low")); 665db2661ceSRobert Watson 666db2661ceSRobert Watson case MAC_LOMAC_TYPE_EQUAL: 667f51e5803SRobert Watson return (sbuf_printf(sb, "equal")); 668db2661ceSRobert Watson 669db2661ceSRobert Watson case MAC_LOMAC_TYPE_GRADE: 670f51e5803SRobert Watson return (sbuf_printf(sb, "%d", element->mle_grade)); 671db2661ceSRobert Watson 672db2661ceSRobert Watson default: 673db2661ceSRobert Watson panic("mac_lomac_element_to_string: invalid type (%d)", 674db2661ceSRobert Watson element->mle_type); 675db2661ceSRobert Watson } 676db2661ceSRobert Watson } 677db2661ceSRobert Watson 678db2661ceSRobert Watson static int 679f51e5803SRobert Watson mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac) 680db2661ceSRobert Watson { 681db2661ceSRobert Watson 682db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 683f51e5803SRobert Watson if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single) 684f51e5803SRobert Watson == -1) 685f51e5803SRobert Watson return (EINVAL); 686db2661ceSRobert Watson } 687db2661ceSRobert Watson 688db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { 689f51e5803SRobert Watson if (sbuf_putc(sb, '[') == -1) 690f51e5803SRobert Watson return (EINVAL); 691db2661ceSRobert Watson 692f51e5803SRobert Watson if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle) 693f51e5803SRobert Watson == -1) 694f51e5803SRobert Watson return (EINVAL); 695db2661ceSRobert Watson 696f51e5803SRobert Watson if (sbuf_putc(sb, ']') == -1) 697f51e5803SRobert Watson return (EINVAL); 698db2661ceSRobert Watson } 699db2661ceSRobert Watson 700db2661ceSRobert Watson if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 701f51e5803SRobert Watson if (sbuf_putc(sb, '(') == -1) 702f51e5803SRobert Watson return (EINVAL); 703db2661ceSRobert Watson 704f51e5803SRobert Watson if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow) 705f51e5803SRobert Watson == -1) 706f51e5803SRobert Watson return (EINVAL); 707db2661ceSRobert Watson 708f51e5803SRobert Watson if (sbuf_putc(sb, '-') == -1) 709f51e5803SRobert Watson return (EINVAL); 710db2661ceSRobert Watson 711f51e5803SRobert Watson if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh) 712f51e5803SRobert Watson == -1) 713f51e5803SRobert Watson return (EINVAL); 714db2661ceSRobert Watson 7158a4b86b9SRobert Watson if (sbuf_putc(sb, ')') == -1) 716f51e5803SRobert Watson return (EINVAL); 717db2661ceSRobert Watson } 718db2661ceSRobert Watson 719db2661ceSRobert Watson return (0); 720db2661ceSRobert Watson } 721db2661ceSRobert Watson 722db2661ceSRobert Watson static int 723db2661ceSRobert Watson mac_lomac_externalize_label(struct label *label, char *element_name, 724f51e5803SRobert Watson struct sbuf *sb, int *claimed) 725db2661ceSRobert Watson { 726db2661ceSRobert Watson struct mac_lomac *mac_lomac; 727db2661ceSRobert Watson 728db2661ceSRobert Watson if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 729db2661ceSRobert Watson return (0); 730db2661ceSRobert Watson 731db2661ceSRobert Watson (*claimed)++; 732db2661ceSRobert Watson 733db2661ceSRobert Watson mac_lomac = SLOT(label); 734db2661ceSRobert Watson 735f51e5803SRobert Watson return (mac_lomac_to_string(sb, mac_lomac)); 736db2661ceSRobert Watson } 737db2661ceSRobert Watson 738db2661ceSRobert Watson static int 739db2661ceSRobert Watson mac_lomac_parse_element(struct mac_lomac_element *element, char *string) 740db2661ceSRobert Watson { 741db2661ceSRobert Watson 742db2661ceSRobert Watson if (strcmp(string, "high") == 0 || 743db2661ceSRobert Watson strcmp(string, "hi") == 0) { 744db2661ceSRobert Watson element->mle_type = MAC_LOMAC_TYPE_HIGH; 745db2661ceSRobert Watson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 746db2661ceSRobert Watson } else if (strcmp(string, "low") == 0 || 747db2661ceSRobert Watson strcmp(string, "lo") == 0) { 748db2661ceSRobert Watson element->mle_type = MAC_LOMAC_TYPE_LOW; 749db2661ceSRobert Watson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 750db2661ceSRobert Watson } else if (strcmp(string, "equal") == 0 || 751db2661ceSRobert Watson strcmp(string, "eq") == 0) { 752db2661ceSRobert Watson element->mle_type = MAC_LOMAC_TYPE_EQUAL; 753db2661ceSRobert Watson element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 754db2661ceSRobert Watson } else { 755db2661ceSRobert Watson char *p0, *p1; 756db2661ceSRobert Watson int d; 757db2661ceSRobert Watson 758db2661ceSRobert Watson p0 = string; 759db2661ceSRobert Watson d = strtol(p0, &p1, 10); 760db2661ceSRobert Watson 761db2661ceSRobert Watson if (d < 0 || d > 65535) 762db2661ceSRobert Watson return (EINVAL); 763db2661ceSRobert Watson element->mle_type = MAC_LOMAC_TYPE_GRADE; 764db2661ceSRobert Watson element->mle_grade = d; 765db2661ceSRobert Watson 766db2661ceSRobert Watson if (p1 == p0 || *p1 != '\0') 767db2661ceSRobert Watson return (EINVAL); 768db2661ceSRobert Watson } 769db2661ceSRobert Watson 770db2661ceSRobert Watson return (0); 771db2661ceSRobert Watson } 772db2661ceSRobert Watson 773db2661ceSRobert Watson /* 774db2661ceSRobert Watson * Note: destructively consumes the string, make a local copy before 775db2661ceSRobert Watson * calling if that's a problem. 776db2661ceSRobert Watson */ 777db2661ceSRobert Watson static int 778db2661ceSRobert Watson mac_lomac_parse(struct mac_lomac *mac_lomac, char *string) 779db2661ceSRobert Watson { 780db2661ceSRobert Watson char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle, 781db2661ceSRobert Watson *auxsingleend; 782db2661ceSRobert Watson int error; 783db2661ceSRobert Watson 784db2661ceSRobert Watson /* Do we have a range? */ 785db2661ceSRobert Watson single = string; 786db2661ceSRobert Watson range = index(string, '('); 787db2661ceSRobert Watson if (range == single) 788db2661ceSRobert Watson single = NULL; 789db2661ceSRobert Watson auxsingle = index(string, '['); 790db2661ceSRobert Watson if (auxsingle == single) 791db2661ceSRobert Watson single = NULL; 792db2661ceSRobert Watson if (range != NULL && auxsingle != NULL) 793db2661ceSRobert Watson return (EINVAL); 794db2661ceSRobert Watson rangelow = rangehigh = NULL; 795db2661ceSRobert Watson if (range != NULL) { 796db2661ceSRobert Watson /* Nul terminate the end of the single string. */ 797db2661ceSRobert Watson *range = '\0'; 798db2661ceSRobert Watson range++; 799db2661ceSRobert Watson rangelow = range; 800db2661ceSRobert Watson rangehigh = index(rangelow, '-'); 801db2661ceSRobert Watson if (rangehigh == NULL) 802db2661ceSRobert Watson return (EINVAL); 803db2661ceSRobert Watson rangehigh++; 804db2661ceSRobert Watson if (*rangelow == '\0' || *rangehigh == '\0') 805db2661ceSRobert Watson return (EINVAL); 806db2661ceSRobert Watson rangeend = index(rangehigh, ')'); 807db2661ceSRobert Watson if (rangeend == NULL) 808db2661ceSRobert Watson return (EINVAL); 809db2661ceSRobert Watson if (*(rangeend + 1) != '\0') 810db2661ceSRobert Watson return (EINVAL); 811db2661ceSRobert Watson /* Nul terminate the ends of the ranges. */ 812db2661ceSRobert Watson *(rangehigh - 1) = '\0'; 813db2661ceSRobert Watson *rangeend = '\0'; 814db2661ceSRobert Watson } 815db2661ceSRobert Watson KASSERT((rangelow != NULL && rangehigh != NULL) || 816db2661ceSRobert Watson (rangelow == NULL && rangehigh == NULL), 817db2661ceSRobert Watson ("mac_lomac_internalize_label: range mismatch")); 818db2661ceSRobert Watson if (auxsingle != NULL) { 819db2661ceSRobert Watson /* Nul terminate the end of the single string. */ 820db2661ceSRobert Watson *auxsingle = '\0'; 821db2661ceSRobert Watson auxsingle++; 822db2661ceSRobert Watson auxsingleend = index(auxsingle, ']'); 823db2661ceSRobert Watson if (auxsingleend == NULL) 824db2661ceSRobert Watson return (EINVAL); 825db2661ceSRobert Watson if (*(auxsingleend + 1) != '\0') 826db2661ceSRobert Watson return (EINVAL); 827db2661ceSRobert Watson /* Nul terminate the end of the auxsingle. */ 828db2661ceSRobert Watson *auxsingleend = '\0'; 829db2661ceSRobert Watson } 830db2661ceSRobert Watson 831db2661ceSRobert Watson bzero(mac_lomac, sizeof(*mac_lomac)); 832db2661ceSRobert Watson if (single != NULL) { 833db2661ceSRobert Watson error = mac_lomac_parse_element(&mac_lomac->ml_single, single); 834db2661ceSRobert Watson if (error) 835db2661ceSRobert Watson return (error); 836db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 837db2661ceSRobert Watson } 838db2661ceSRobert Watson 839db2661ceSRobert Watson if (auxsingle != NULL) { 840db2661ceSRobert Watson error = mac_lomac_parse_element(&mac_lomac->ml_auxsingle, 841db2661ceSRobert Watson auxsingle); 842db2661ceSRobert Watson if (error) 843db2661ceSRobert Watson return (error); 844db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_AUX; 845db2661ceSRobert Watson } 846db2661ceSRobert Watson 847db2661ceSRobert Watson if (rangelow != NULL) { 848db2661ceSRobert Watson error = mac_lomac_parse_element(&mac_lomac->ml_rangelow, 849db2661ceSRobert Watson rangelow); 850db2661ceSRobert Watson if (error) 851db2661ceSRobert Watson return (error); 852db2661ceSRobert Watson error = mac_lomac_parse_element(&mac_lomac->ml_rangehigh, 853db2661ceSRobert Watson rangehigh); 854db2661ceSRobert Watson if (error) 855db2661ceSRobert Watson return (error); 856db2661ceSRobert Watson mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE; 857db2661ceSRobert Watson } 858db2661ceSRobert Watson 859db2661ceSRobert Watson error = mac_lomac_valid(mac_lomac); 860db2661ceSRobert Watson if (error) 861db2661ceSRobert Watson return (error); 862db2661ceSRobert Watson 863db2661ceSRobert Watson return (0); 864db2661ceSRobert Watson } 865db2661ceSRobert Watson 866db2661ceSRobert Watson static int 867db2661ceSRobert Watson mac_lomac_internalize_label(struct label *label, char *element_name, 868db2661ceSRobert Watson char *element_data, int *claimed) 869db2661ceSRobert Watson { 870db2661ceSRobert Watson struct mac_lomac *mac_lomac, mac_lomac_temp; 871db2661ceSRobert Watson int error; 872db2661ceSRobert Watson 873db2661ceSRobert Watson if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 874db2661ceSRobert Watson return (0); 875db2661ceSRobert Watson 876db2661ceSRobert Watson (*claimed)++; 877db2661ceSRobert Watson 878db2661ceSRobert Watson error = mac_lomac_parse(&mac_lomac_temp, element_data); 879db2661ceSRobert Watson if (error) 880db2661ceSRobert Watson return (error); 881db2661ceSRobert Watson 882db2661ceSRobert Watson mac_lomac = SLOT(label); 883db2661ceSRobert Watson *mac_lomac = mac_lomac_temp; 884db2661ceSRobert Watson 885db2661ceSRobert Watson return (0); 886db2661ceSRobert Watson } 887db2661ceSRobert Watson 888db2661ceSRobert Watson static void 889db2661ceSRobert Watson mac_lomac_copy_label(struct label *src, struct label *dest) 890db2661ceSRobert Watson { 891db2661ceSRobert Watson 892db2661ceSRobert Watson *SLOT(dest) = *SLOT(src); 893db2661ceSRobert Watson } 894db2661ceSRobert Watson 895db2661ceSRobert Watson /* 896db2661ceSRobert Watson * Labeling event operations: file system objects, and things that look 897db2661ceSRobert Watson * a lot like file system objects. 898db2661ceSRobert Watson */ 899db2661ceSRobert Watson static void 900990b4b2dSRobert Watson mac_lomac_create_devfs_device(struct mount *mp, dev_t dev, 901990b4b2dSRobert Watson struct devfs_dirent *devfs_dirent, struct label *label) 902db2661ceSRobert Watson { 903db2661ceSRobert Watson struct mac_lomac *mac_lomac; 904db2661ceSRobert Watson int lomac_type; 905db2661ceSRobert Watson 906db2661ceSRobert Watson mac_lomac = SLOT(label); 907db2661ceSRobert Watson if (strcmp(dev->si_name, "null") == 0 || 908db2661ceSRobert Watson strcmp(dev->si_name, "zero") == 0 || 909db2661ceSRobert Watson strcmp(dev->si_name, "random") == 0 || 910db2661ceSRobert Watson strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 || 911db2661ceSRobert Watson strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0) 912db2661ceSRobert Watson lomac_type = MAC_LOMAC_TYPE_EQUAL; 913db2661ceSRobert Watson else if (ptys_equal && 914db2661ceSRobert Watson (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 915db2661ceSRobert Watson strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 916db2661ceSRobert Watson lomac_type = MAC_LOMAC_TYPE_EQUAL; 917db2661ceSRobert Watson else 918db2661ceSRobert Watson lomac_type = MAC_LOMAC_TYPE_HIGH; 919db2661ceSRobert Watson mac_lomac_set_single(mac_lomac, lomac_type, 0); 920db2661ceSRobert Watson } 921db2661ceSRobert Watson 922db2661ceSRobert Watson static void 923990b4b2dSRobert Watson mac_lomac_create_devfs_directory(struct mount *mp, char *dirname, 924990b4b2dSRobert Watson int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 925db2661ceSRobert Watson { 926db2661ceSRobert Watson struct mac_lomac *mac_lomac; 927db2661ceSRobert Watson 928db2661ceSRobert Watson mac_lomac = SLOT(label); 929db2661ceSRobert Watson mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0); 930db2661ceSRobert Watson } 931db2661ceSRobert Watson 932db2661ceSRobert Watson static void 933990b4b2dSRobert Watson mac_lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 934990b4b2dSRobert Watson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 935990b4b2dSRobert Watson struct label *delabel) 936db2661ceSRobert Watson { 937db2661ceSRobert Watson struct mac_lomac *source, *dest; 938db2661ceSRobert Watson 939eca8a663SRobert Watson source = SLOT(cred->cr_label); 940db2661ceSRobert Watson dest = SLOT(delabel); 941db2661ceSRobert Watson 942db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 943db2661ceSRobert Watson } 944db2661ceSRobert Watson 945db2661ceSRobert Watson static void 946db2661ceSRobert Watson mac_lomac_create_mount(struct ucred *cred, struct mount *mp, 947db2661ceSRobert Watson struct label *mntlabel, struct label *fslabel) 948db2661ceSRobert Watson { 949db2661ceSRobert Watson struct mac_lomac *source, *dest; 950db2661ceSRobert Watson 951eca8a663SRobert Watson source = SLOT(cred->cr_label); 952db2661ceSRobert Watson dest = SLOT(mntlabel); 953db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 954db2661ceSRobert Watson dest = SLOT(fslabel); 955db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 956db2661ceSRobert Watson } 957db2661ceSRobert Watson 958db2661ceSRobert Watson static void 959db2661ceSRobert Watson mac_lomac_create_root_mount(struct ucred *cred, struct mount *mp, 960db2661ceSRobert Watson struct label *mntlabel, struct label *fslabel) 961db2661ceSRobert Watson { 962db2661ceSRobert Watson struct mac_lomac *mac_lomac; 963db2661ceSRobert Watson 964db2661ceSRobert Watson /* Always mount root as high integrity. */ 965db2661ceSRobert Watson mac_lomac = SLOT(fslabel); 966db2661ceSRobert Watson mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0); 967db2661ceSRobert Watson mac_lomac = SLOT(mntlabel); 968db2661ceSRobert Watson mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0); 969db2661ceSRobert Watson } 970db2661ceSRobert Watson 971db2661ceSRobert Watson static void 972db2661ceSRobert Watson mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp, 973db2661ceSRobert Watson struct label *vnodelabel, struct label *label) 974db2661ceSRobert Watson { 975db2661ceSRobert Watson struct mac_lomac *source, *dest; 976db2661ceSRobert Watson 977db2661ceSRobert Watson source = SLOT(label); 978db2661ceSRobert Watson dest = SLOT(vnodelabel); 979db2661ceSRobert Watson 980db2661ceSRobert Watson try_relabel(source, dest); 981db2661ceSRobert Watson } 982db2661ceSRobert Watson 983db2661ceSRobert Watson static void 984990b4b2dSRobert Watson mac_lomac_update_devfsdirent(struct mount *mp, 985990b4b2dSRobert Watson struct devfs_dirent *devfs_dirent, struct label *direntlabel, 986990b4b2dSRobert Watson struct vnode *vp, struct label *vnodelabel) 987db2661ceSRobert Watson { 988db2661ceSRobert Watson struct mac_lomac *source, *dest; 989db2661ceSRobert Watson 990db2661ceSRobert Watson source = SLOT(vnodelabel); 991db2661ceSRobert Watson dest = SLOT(direntlabel); 992db2661ceSRobert Watson 993db2661ceSRobert Watson mac_lomac_copy(source, dest); 994db2661ceSRobert Watson } 995db2661ceSRobert Watson 996db2661ceSRobert Watson static void 997db2661ceSRobert Watson mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 998db2661ceSRobert Watson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 999db2661ceSRobert Watson struct label *vlabel) 1000db2661ceSRobert Watson { 1001db2661ceSRobert Watson struct mac_lomac *source, *dest; 1002db2661ceSRobert Watson 1003db2661ceSRobert Watson source = SLOT(delabel); 1004db2661ceSRobert Watson dest = SLOT(vlabel); 1005db2661ceSRobert Watson 1006db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1007db2661ceSRobert Watson } 1008db2661ceSRobert Watson 1009db2661ceSRobert Watson static int 1010db2661ceSRobert Watson mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 1011db2661ceSRobert Watson struct vnode *vp, struct label *vlabel) 1012db2661ceSRobert Watson { 1013db2661ceSRobert Watson struct mac_lomac temp, *source, *dest; 1014b247d661SMaxime Henrion int buflen, error; 1015db2661ceSRobert Watson 1016db2661ceSRobert Watson source = SLOT(fslabel); 1017db2661ceSRobert Watson dest = SLOT(vlabel); 1018db2661ceSRobert Watson 1019db2661ceSRobert Watson buflen = sizeof(temp); 1020db2661ceSRobert Watson bzero(&temp, buflen); 1021db2661ceSRobert Watson 1022db2661ceSRobert Watson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1023db2661ceSRobert Watson MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread); 1024db2661ceSRobert Watson if (error == ENOATTR || error == EOPNOTSUPP) { 1025db2661ceSRobert Watson /* Fall back to the fslabel. */ 1026db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1027db2661ceSRobert Watson return (0); 1028db2661ceSRobert Watson } else if (error) 1029db2661ceSRobert Watson return (error); 1030db2661ceSRobert Watson 1031db2661ceSRobert Watson if (buflen != sizeof(temp)) { 1032db2661ceSRobert Watson if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) { 1033db2661ceSRobert Watson printf("mac_lomac_associate_vnode_extattr: bad size %d\n", 1034db2661ceSRobert Watson buflen); 1035db2661ceSRobert Watson return (EPERM); 1036db2661ceSRobert Watson } 1037db2661ceSRobert Watson bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle)); 1038db2661ceSRobert Watson buflen = sizeof(temp); 1039db2661ceSRobert Watson (void)vn_extattr_set(vp, IO_NODELOCKED, 1040db2661ceSRobert Watson MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 1041db2661ceSRobert Watson buflen, (char *)&temp, curthread); 1042db2661ceSRobert Watson } 1043db2661ceSRobert Watson if (mac_lomac_valid(&temp) != 0) { 1044db2661ceSRobert Watson printf("mac_lomac_associate_vnode_extattr: invalid\n"); 1045db2661ceSRobert Watson return (EPERM); 1046db2661ceSRobert Watson } 1047db2661ceSRobert Watson if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) { 1048db2661ceSRobert Watson printf("mac_lomac_associate_vnode_extattr: not single\n"); 1049db2661ceSRobert Watson return (EPERM); 1050db2661ceSRobert Watson } 1051db2661ceSRobert Watson 1052db2661ceSRobert Watson mac_lomac_copy_single(&temp, dest); 1053db2661ceSRobert Watson return (0); 1054db2661ceSRobert Watson } 1055db2661ceSRobert Watson 1056db2661ceSRobert Watson static void 1057db2661ceSRobert Watson mac_lomac_associate_vnode_singlelabel(struct mount *mp, 1058db2661ceSRobert Watson struct label *fslabel, struct vnode *vp, struct label *vlabel) 1059db2661ceSRobert Watson { 1060db2661ceSRobert Watson struct mac_lomac *source, *dest; 1061db2661ceSRobert Watson 1062db2661ceSRobert Watson source = SLOT(fslabel); 1063db2661ceSRobert Watson dest = SLOT(vlabel); 1064db2661ceSRobert Watson 1065db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1066db2661ceSRobert Watson } 1067db2661ceSRobert Watson 1068db2661ceSRobert Watson static int 1069db2661ceSRobert Watson mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1070db2661ceSRobert Watson struct label *fslabel, struct vnode *dvp, struct label *dlabel, 1071db2661ceSRobert Watson struct vnode *vp, struct label *vlabel, struct componentname *cnp) 1072db2661ceSRobert Watson { 1073db2661ceSRobert Watson struct mac_lomac *source, *dest, *dir, temp; 1074db2661ceSRobert Watson size_t buflen; 1075db2661ceSRobert Watson int error; 1076db2661ceSRobert Watson 1077db2661ceSRobert Watson buflen = sizeof(temp); 1078db2661ceSRobert Watson bzero(&temp, buflen); 1079db2661ceSRobert Watson 1080eca8a663SRobert Watson source = SLOT(cred->cr_label); 1081db2661ceSRobert Watson dest = SLOT(vlabel); 1082db2661ceSRobert Watson dir = SLOT(dlabel); 1083db2661ceSRobert Watson if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 1084db2661ceSRobert Watson mac_lomac_copy_auxsingle(dir, &temp); 1085db2661ceSRobert Watson mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 1086db2661ceSRobert Watson dir->ml_auxsingle.mle_grade); 1087db2661ceSRobert Watson } else { 1088db2661ceSRobert Watson mac_lomac_copy_single(source, &temp); 1089db2661ceSRobert Watson } 1090db2661ceSRobert Watson 1091db2661ceSRobert Watson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1092db2661ceSRobert Watson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1093db2661ceSRobert Watson if (error == 0) 1094db2661ceSRobert Watson mac_lomac_copy(&temp, dest); 1095db2661ceSRobert Watson return (error); 1096db2661ceSRobert Watson } 1097db2661ceSRobert Watson 1098db2661ceSRobert Watson static int 1099db2661ceSRobert Watson mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1100db2661ceSRobert Watson struct label *vlabel, struct label *intlabel) 1101db2661ceSRobert Watson { 1102db2661ceSRobert Watson struct mac_lomac *source, temp; 1103db2661ceSRobert Watson size_t buflen; 1104db2661ceSRobert Watson int error; 1105db2661ceSRobert Watson 1106db2661ceSRobert Watson buflen = sizeof(temp); 1107db2661ceSRobert Watson bzero(&temp, buflen); 1108db2661ceSRobert Watson 1109db2661ceSRobert Watson source = SLOT(intlabel); 1110db2661ceSRobert Watson if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1111db2661ceSRobert Watson return (0); 1112db2661ceSRobert Watson 1113db2661ceSRobert Watson mac_lomac_copy_single(source, &temp); 1114db2661ceSRobert Watson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1115db2661ceSRobert Watson MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1116db2661ceSRobert Watson return (error); 1117db2661ceSRobert Watson } 1118db2661ceSRobert Watson 1119db2661ceSRobert Watson /* 1120db2661ceSRobert Watson * Labeling event operations: IPC object. 1121db2661ceSRobert Watson */ 1122db2661ceSRobert Watson static void 1123a557af22SRobert Watson mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel, 1124a557af22SRobert Watson struct inpcb *inp, struct label *inplabel) 1125a557af22SRobert Watson { 1126a557af22SRobert Watson struct mac_lomac *source, *dest; 1127a557af22SRobert Watson 1128a557af22SRobert Watson source = SLOT(solabel); 1129a557af22SRobert Watson dest = SLOT(inplabel); 1130a557af22SRobert Watson 1131a557af22SRobert Watson mac_lomac_copy_single(source, dest); 1132a557af22SRobert Watson } 1133a557af22SRobert Watson 1134a557af22SRobert Watson static void 1135db2661ceSRobert Watson mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1136db2661ceSRobert Watson struct mbuf *m, struct label *mbuflabel) 1137db2661ceSRobert Watson { 1138db2661ceSRobert Watson struct mac_lomac *source, *dest; 1139db2661ceSRobert Watson 1140db2661ceSRobert Watson source = SLOT(socketlabel); 1141db2661ceSRobert Watson dest = SLOT(mbuflabel); 1142db2661ceSRobert Watson 1143db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1144db2661ceSRobert Watson } 1145db2661ceSRobert Watson 1146db2661ceSRobert Watson static void 1147db2661ceSRobert Watson mac_lomac_create_socket(struct ucred *cred, struct socket *socket, 1148db2661ceSRobert Watson struct label *socketlabel) 1149db2661ceSRobert Watson { 1150db2661ceSRobert Watson struct mac_lomac *source, *dest; 1151db2661ceSRobert Watson 1152eca8a663SRobert Watson source = SLOT(cred->cr_label); 1153db2661ceSRobert Watson dest = SLOT(socketlabel); 1154db2661ceSRobert Watson 1155db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1156db2661ceSRobert Watson } 1157db2661ceSRobert Watson 1158db2661ceSRobert Watson static void 11594795b82cSRobert Watson mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp, 1160db2661ceSRobert Watson struct label *pipelabel) 1161db2661ceSRobert Watson { 1162db2661ceSRobert Watson struct mac_lomac *source, *dest; 1163db2661ceSRobert Watson 1164eca8a663SRobert Watson source = SLOT(cred->cr_label); 1165db2661ceSRobert Watson dest = SLOT(pipelabel); 1166db2661ceSRobert Watson 1167db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1168db2661ceSRobert Watson } 1169db2661ceSRobert Watson 1170db2661ceSRobert Watson static void 1171db2661ceSRobert Watson mac_lomac_create_socket_from_socket(struct socket *oldsocket, 1172db2661ceSRobert Watson struct label *oldsocketlabel, struct socket *newsocket, 1173db2661ceSRobert Watson struct label *newsocketlabel) 1174db2661ceSRobert Watson { 1175db2661ceSRobert Watson struct mac_lomac *source, *dest; 1176db2661ceSRobert Watson 1177db2661ceSRobert Watson source = SLOT(oldsocketlabel); 1178db2661ceSRobert Watson dest = SLOT(newsocketlabel); 1179db2661ceSRobert Watson 1180db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1181db2661ceSRobert Watson } 1182db2661ceSRobert Watson 1183db2661ceSRobert Watson static void 1184db2661ceSRobert Watson mac_lomac_relabel_socket(struct ucred *cred, struct socket *socket, 1185db2661ceSRobert Watson struct label *socketlabel, struct label *newlabel) 1186db2661ceSRobert Watson { 1187db2661ceSRobert Watson struct mac_lomac *source, *dest; 1188db2661ceSRobert Watson 1189db2661ceSRobert Watson source = SLOT(newlabel); 1190db2661ceSRobert Watson dest = SLOT(socketlabel); 1191db2661ceSRobert Watson 1192db2661ceSRobert Watson try_relabel(source, dest); 1193db2661ceSRobert Watson } 1194db2661ceSRobert Watson 1195db2661ceSRobert Watson static void 11964795b82cSRobert Watson mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1197db2661ceSRobert Watson struct label *pipelabel, struct label *newlabel) 1198db2661ceSRobert Watson { 1199db2661ceSRobert Watson struct mac_lomac *source, *dest; 1200db2661ceSRobert Watson 1201db2661ceSRobert Watson source = SLOT(newlabel); 1202db2661ceSRobert Watson dest = SLOT(pipelabel); 1203db2661ceSRobert Watson 1204db2661ceSRobert Watson try_relabel(source, dest); 1205db2661ceSRobert Watson } 1206db2661ceSRobert Watson 1207db2661ceSRobert Watson static void 1208db2661ceSRobert Watson mac_lomac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1209db2661ceSRobert Watson struct socket *socket, struct label *socketpeerlabel) 1210db2661ceSRobert Watson { 1211db2661ceSRobert Watson struct mac_lomac *source, *dest; 1212db2661ceSRobert Watson 1213db2661ceSRobert Watson source = SLOT(mbuflabel); 1214db2661ceSRobert Watson dest = SLOT(socketpeerlabel); 1215db2661ceSRobert Watson 1216db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1217db2661ceSRobert Watson } 1218db2661ceSRobert Watson 1219db2661ceSRobert Watson /* 1220db2661ceSRobert Watson * Labeling event operations: network objects. 1221db2661ceSRobert Watson */ 1222db2661ceSRobert Watson static void 1223db2661ceSRobert Watson mac_lomac_set_socket_peer_from_socket(struct socket *oldsocket, 1224db2661ceSRobert Watson struct label *oldsocketlabel, struct socket *newsocket, 1225db2661ceSRobert Watson struct label *newsocketpeerlabel) 1226db2661ceSRobert Watson { 1227db2661ceSRobert Watson struct mac_lomac *source, *dest; 1228db2661ceSRobert Watson 1229db2661ceSRobert Watson source = SLOT(oldsocketlabel); 1230db2661ceSRobert Watson dest = SLOT(newsocketpeerlabel); 1231db2661ceSRobert Watson 1232db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1233db2661ceSRobert Watson } 1234db2661ceSRobert Watson 1235db2661ceSRobert Watson static void 1236db2661ceSRobert Watson mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1237db2661ceSRobert Watson struct label *bpflabel) 1238db2661ceSRobert Watson { 1239db2661ceSRobert Watson struct mac_lomac *source, *dest; 1240db2661ceSRobert Watson 1241eca8a663SRobert Watson source = SLOT(cred->cr_label); 1242db2661ceSRobert Watson dest = SLOT(bpflabel); 1243db2661ceSRobert Watson 1244db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1245db2661ceSRobert Watson } 1246db2661ceSRobert Watson 1247db2661ceSRobert Watson static void 1248db2661ceSRobert Watson mac_lomac_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1249db2661ceSRobert Watson { 12509bf40edeSBrooks Davis char tifname[IFNAMSIZ], *p, *q; 1251db2661ceSRobert Watson char tiflist[sizeof(trusted_interfaces)]; 1252db2661ceSRobert Watson struct mac_lomac *dest; 1253db2661ceSRobert Watson int len, grade; 1254db2661ceSRobert Watson 1255db2661ceSRobert Watson dest = SLOT(ifnetlabel); 1256db2661ceSRobert Watson 1257db2661ceSRobert Watson if (ifnet->if_type == IFT_LOOP) { 1258db2661ceSRobert Watson grade = MAC_LOMAC_TYPE_EQUAL; 1259db2661ceSRobert Watson goto set; 1260db2661ceSRobert Watson } 1261db2661ceSRobert Watson 1262db2661ceSRobert Watson if (trust_all_interfaces) { 1263db2661ceSRobert Watson grade = MAC_LOMAC_TYPE_HIGH; 1264db2661ceSRobert Watson goto set; 1265db2661ceSRobert Watson } 1266db2661ceSRobert Watson 1267db2661ceSRobert Watson grade = MAC_LOMAC_TYPE_LOW; 1268db2661ceSRobert Watson 1269db2661ceSRobert Watson if (trusted_interfaces[0] == '\0' || 1270db2661ceSRobert Watson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1271db2661ceSRobert Watson goto set; 1272db2661ceSRobert Watson 1273db2661ceSRobert Watson bzero(tiflist, sizeof(tiflist)); 1274db2661ceSRobert Watson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1275db2661ceSRobert Watson if(*p != ' ' && *p != '\t') 1276db2661ceSRobert Watson *q = *p; 1277db2661ceSRobert Watson 1278db2661ceSRobert Watson for (p = q = tiflist;; p++) { 1279db2661ceSRobert Watson if (*p == ',' || *p == '\0') { 1280db2661ceSRobert Watson len = p - q; 1281db2661ceSRobert Watson if (len < IFNAMSIZ) { 1282db2661ceSRobert Watson bzero(tifname, sizeof(tifname)); 1283db2661ceSRobert Watson bcopy(q, tifname, len); 12849bf40edeSBrooks Davis if (strcmp(tifname, ifnet->if_xname) == 0) { 1285db2661ceSRobert Watson grade = MAC_LOMAC_TYPE_HIGH; 1286db2661ceSRobert Watson break; 1287db2661ceSRobert Watson } 1288db2661ceSRobert Watson } 1289db2661ceSRobert Watson else { 1290db2661ceSRobert Watson *p = '\0'; 1291db2661ceSRobert Watson printf("MAC/LOMAC warning: interface name " 1292db2661ceSRobert Watson "\"%s\" is too long (must be < %d)\n", 1293db2661ceSRobert Watson q, IFNAMSIZ); 1294db2661ceSRobert Watson } 1295db2661ceSRobert Watson if (*p == '\0') 1296db2661ceSRobert Watson break; 1297db2661ceSRobert Watson q = p + 1; 1298db2661ceSRobert Watson } 1299db2661ceSRobert Watson } 1300db2661ceSRobert Watson set: 1301db2661ceSRobert Watson mac_lomac_set_single(dest, grade, 0); 1302db2661ceSRobert Watson mac_lomac_set_range(dest, grade, 0, grade, 0); 1303db2661ceSRobert Watson } 1304db2661ceSRobert Watson 1305db2661ceSRobert Watson static void 1306db2661ceSRobert Watson mac_lomac_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1307db2661ceSRobert Watson struct ipq *ipq, struct label *ipqlabel) 1308db2661ceSRobert Watson { 1309db2661ceSRobert Watson struct mac_lomac *source, *dest; 1310db2661ceSRobert Watson 1311db2661ceSRobert Watson source = SLOT(fragmentlabel); 1312db2661ceSRobert Watson dest = SLOT(ipqlabel); 1313db2661ceSRobert Watson 1314db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1315db2661ceSRobert Watson } 1316db2661ceSRobert Watson 1317db2661ceSRobert Watson static void 1318db2661ceSRobert Watson mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1319db2661ceSRobert Watson struct mbuf *datagram, struct label *datagramlabel) 1320db2661ceSRobert Watson { 1321db2661ceSRobert Watson struct mac_lomac *source, *dest; 1322db2661ceSRobert Watson 1323db2661ceSRobert Watson source = SLOT(ipqlabel); 1324db2661ceSRobert Watson dest = SLOT(datagramlabel); 1325db2661ceSRobert Watson 1326db2661ceSRobert Watson /* Just use the head, since we require them all to match. */ 1327db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1328db2661ceSRobert Watson } 1329db2661ceSRobert Watson 1330db2661ceSRobert Watson static void 1331db2661ceSRobert Watson mac_lomac_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1332db2661ceSRobert Watson struct mbuf *fragment, struct label *fragmentlabel) 1333db2661ceSRobert Watson { 1334db2661ceSRobert Watson struct mac_lomac *source, *dest; 1335db2661ceSRobert Watson 1336db2661ceSRobert Watson source = SLOT(datagramlabel); 1337db2661ceSRobert Watson dest = SLOT(fragmentlabel); 1338db2661ceSRobert Watson 1339db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1340db2661ceSRobert Watson } 1341db2661ceSRobert Watson 1342db2661ceSRobert Watson static void 13432d92ec98SRobert Watson mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 13442d92ec98SRobert Watson struct mbuf *m, struct label *mlabel) 13452d92ec98SRobert Watson { 13462d92ec98SRobert Watson struct mac_lomac *source, *dest; 13472d92ec98SRobert Watson 13482d92ec98SRobert Watson source = SLOT(inplabel); 13492d92ec98SRobert Watson dest = SLOT(mlabel); 13502d92ec98SRobert Watson 13512d92ec98SRobert Watson mac_lomac_copy_single(source, dest); 13522d92ec98SRobert Watson } 13532d92ec98SRobert Watson 13542d92ec98SRobert Watson static void 1355db2661ceSRobert Watson mac_lomac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1356db2661ceSRobert Watson struct label *oldmbuflabel, struct mbuf *newmbuf, 1357db2661ceSRobert Watson struct label *newmbuflabel) 1358db2661ceSRobert Watson { 1359db2661ceSRobert Watson struct mac_lomac *source, *dest; 1360db2661ceSRobert Watson 1361db2661ceSRobert Watson source = SLOT(oldmbuflabel); 1362db2661ceSRobert Watson dest = SLOT(newmbuflabel); 1363db2661ceSRobert Watson 1364db2661ceSRobert Watson /* 1365db2661ceSRobert Watson * Because the source mbuf may not yet have been "created", 1366db2661ceSRobert Watson * just initialized, we do a conditional copy. Since we don't 1367db2661ceSRobert Watson * allow mbufs to have ranges, do a KASSERT to make sure that 1368db2661ceSRobert Watson * doesn't happen. 1369db2661ceSRobert Watson */ 1370db2661ceSRobert Watson KASSERT((source->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0, 1371db2661ceSRobert Watson ("mac_lomac_create_mbuf_from_mbuf: source mbuf has range")); 1372db2661ceSRobert Watson mac_lomac_copy(source, dest); 1373db2661ceSRobert Watson } 1374db2661ceSRobert Watson 1375db2661ceSRobert Watson static void 1376db2661ceSRobert Watson mac_lomac_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1377db2661ceSRobert Watson struct mbuf *mbuf, struct label *mbuflabel) 1378db2661ceSRobert Watson { 1379db2661ceSRobert Watson struct mac_lomac *dest; 1380db2661ceSRobert Watson 1381db2661ceSRobert Watson dest = SLOT(mbuflabel); 1382db2661ceSRobert Watson 1383db2661ceSRobert Watson mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1384db2661ceSRobert Watson } 1385db2661ceSRobert Watson 1386db2661ceSRobert Watson static void 1387db2661ceSRobert Watson mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1388db2661ceSRobert Watson struct mbuf *mbuf, struct label *mbuflabel) 1389db2661ceSRobert Watson { 1390db2661ceSRobert Watson struct mac_lomac *source, *dest; 1391db2661ceSRobert Watson 1392db2661ceSRobert Watson source = SLOT(bpflabel); 1393db2661ceSRobert Watson dest = SLOT(mbuflabel); 1394db2661ceSRobert Watson 1395db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1396db2661ceSRobert Watson } 1397db2661ceSRobert Watson 1398db2661ceSRobert Watson static void 1399db2661ceSRobert Watson mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1400db2661ceSRobert Watson struct mbuf *m, struct label *mbuflabel) 1401db2661ceSRobert Watson { 1402db2661ceSRobert Watson struct mac_lomac *source, *dest; 1403db2661ceSRobert Watson 1404db2661ceSRobert Watson source = SLOT(ifnetlabel); 1405db2661ceSRobert Watson dest = SLOT(mbuflabel); 1406db2661ceSRobert Watson 1407db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1408db2661ceSRobert Watson } 1409db2661ceSRobert Watson 1410db2661ceSRobert Watson static void 1411db2661ceSRobert Watson mac_lomac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1412db2661ceSRobert Watson struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1413db2661ceSRobert Watson struct mbuf *newmbuf, struct label *newmbuflabel) 1414db2661ceSRobert Watson { 1415db2661ceSRobert Watson struct mac_lomac *source, *dest; 1416db2661ceSRobert Watson 1417db2661ceSRobert Watson source = SLOT(oldmbuflabel); 1418db2661ceSRobert Watson dest = SLOT(newmbuflabel); 1419db2661ceSRobert Watson 1420db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1421db2661ceSRobert Watson } 1422db2661ceSRobert Watson 1423db2661ceSRobert Watson static void 1424db2661ceSRobert Watson mac_lomac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1425db2661ceSRobert Watson struct mbuf *newmbuf, struct label *newmbuflabel) 1426db2661ceSRobert Watson { 1427db2661ceSRobert Watson struct mac_lomac *source, *dest; 1428db2661ceSRobert Watson 1429db2661ceSRobert Watson source = SLOT(oldmbuflabel); 1430db2661ceSRobert Watson dest = SLOT(newmbuflabel); 1431db2661ceSRobert Watson 1432db2661ceSRobert Watson mac_lomac_copy_single(source, dest); 1433db2661ceSRobert Watson } 1434db2661ceSRobert Watson 1435db2661ceSRobert Watson static int 1436db2661ceSRobert Watson mac_lomac_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1437db2661ceSRobert Watson struct ipq *ipq, struct label *ipqlabel) 1438db2661ceSRobert Watson { 1439db2661ceSRobert Watson struct mac_lomac *a, *b; 1440db2661ceSRobert Watson 1441db2661ceSRobert Watson a = SLOT(ipqlabel); 1442db2661ceSRobert Watson b = SLOT(fragmentlabel); 1443db2661ceSRobert Watson 1444db2661ceSRobert Watson return (mac_lomac_equal_single(a, b)); 1445db2661ceSRobert Watson } 1446db2661ceSRobert Watson 1447db2661ceSRobert Watson static void 1448db2661ceSRobert Watson mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1449db2661ceSRobert Watson struct label *ifnetlabel, struct label *newlabel) 1450db2661ceSRobert Watson { 1451db2661ceSRobert Watson struct mac_lomac *source, *dest; 1452db2661ceSRobert Watson 1453db2661ceSRobert Watson source = SLOT(newlabel); 1454db2661ceSRobert Watson dest = SLOT(ifnetlabel); 1455db2661ceSRobert Watson 1456db2661ceSRobert Watson try_relabel(source, dest); 1457db2661ceSRobert Watson } 1458db2661ceSRobert Watson 1459db2661ceSRobert Watson static void 1460db2661ceSRobert Watson mac_lomac_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1461db2661ceSRobert Watson struct ipq *ipq, struct label *ipqlabel) 1462db2661ceSRobert Watson { 1463db2661ceSRobert Watson 1464db2661ceSRobert Watson /* NOOP: we only accept matching labels, so no need to update */ 1465db2661ceSRobert Watson } 1466db2661ceSRobert Watson 1467a557af22SRobert Watson static void 1468a557af22SRobert Watson mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1469a557af22SRobert Watson struct inpcb *inp, struct label *inplabel) 1470a557af22SRobert Watson { 1471a557af22SRobert Watson struct mac_lomac *source, *dest; 1472a557af22SRobert Watson 1473a557af22SRobert Watson source = SLOT(solabel); 1474a557af22SRobert Watson dest = SLOT(inplabel); 1475a557af22SRobert Watson 1476a557af22SRobert Watson mac_lomac_copy_single(source, dest); 1477a557af22SRobert Watson } 1478a557af22SRobert Watson 1479db2661ceSRobert Watson /* 1480db2661ceSRobert Watson * Labeling event operations: processes. 1481db2661ceSRobert Watson */ 1482db2661ceSRobert Watson static void 1483db2661ceSRobert Watson mac_lomac_execve_transition(struct ucred *old, struct ucred *new, 1484db2661ceSRobert Watson struct vnode *vp, struct label *vnodelabel, 1485db2661ceSRobert Watson struct label *interpvnodelabel, struct image_params *imgp, 1486db2661ceSRobert Watson struct label *execlabel) 1487db2661ceSRobert Watson { 1488db2661ceSRobert Watson struct mac_lomac *source, *dest, *obj, *robj; 1489db2661ceSRobert Watson 1490eca8a663SRobert Watson source = SLOT(old->cr_label); 1491eca8a663SRobert Watson dest = SLOT(new->cr_label); 1492db2661ceSRobert Watson obj = SLOT(vnodelabel); 1493db2661ceSRobert Watson robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1494db2661ceSRobert Watson 1495db2661ceSRobert Watson mac_lomac_copy(source, dest); 1496db2661ceSRobert Watson /* 1497db2661ceSRobert Watson * If there's an auxiliary label on the real object, respect it 1498db2661ceSRobert Watson * and assume that this level should be assumed immediately if 1499db2661ceSRobert Watson * a higher level is currently in place. 1500db2661ceSRobert Watson */ 1501db2661ceSRobert Watson if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1502db2661ceSRobert Watson !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 1503db2661ceSRobert Watson && mac_lomac_auxsingle_in_range(robj, dest)) 1504db2661ceSRobert Watson mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type, 1505db2661ceSRobert Watson robj->ml_auxsingle.mle_grade); 1506db2661ceSRobert Watson /* 1507db2661ceSRobert Watson * Restructuring to use the execve transitioning mechanism 1508db2661ceSRobert Watson * instead of the normal demotion mechanism here would be 1509db2661ceSRobert Watson * difficult, so just copy the label over and perform standard 1510db2661ceSRobert Watson * demotion. This is also non-optimal because it will result 1511db2661ceSRobert Watson * in the intermediate label "new" being created and immediately 1512db2661ceSRobert Watson * recycled. 1513db2661ceSRobert Watson */ 1514db2661ceSRobert Watson if (mac_lomac_enabled && revocation_enabled && 1515db2661ceSRobert Watson !mac_lomac_dominate_single(obj, source)) 1516db2661ceSRobert Watson (void)maybe_demote(source, obj, "executing", "file", vp); 1517db2661ceSRobert Watson } 1518db2661ceSRobert Watson 1519db2661ceSRobert Watson static int 1520db2661ceSRobert Watson mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp, 1521db2661ceSRobert Watson struct label *vnodelabel, struct label *interpvnodelabel, 1522db2661ceSRobert Watson struct image_params *imgp, struct label *execlabel) 1523db2661ceSRobert Watson { 1524db2661ceSRobert Watson struct mac_lomac *subj, *obj, *robj; 1525db2661ceSRobert Watson 1526db2661ceSRobert Watson if (!mac_lomac_enabled || !revocation_enabled) 1527db2661ceSRobert Watson return (0); 1528db2661ceSRobert Watson 1529eca8a663SRobert Watson subj = SLOT(old->cr_label); 1530db2661ceSRobert Watson obj = SLOT(vnodelabel); 1531db2661ceSRobert Watson robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1532db2661ceSRobert Watson 1533db2661ceSRobert Watson return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1534db2661ceSRobert Watson !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 1535db2661ceSRobert Watson && mac_lomac_auxsingle_in_range(robj, subj)) || 1536db2661ceSRobert Watson !mac_lomac_dominate_single(obj, subj)); 1537db2661ceSRobert Watson } 1538db2661ceSRobert Watson 1539db2661ceSRobert Watson static void 1540db2661ceSRobert Watson mac_lomac_create_proc0(struct ucred *cred) 1541db2661ceSRobert Watson { 1542db2661ceSRobert Watson struct mac_lomac *dest; 1543db2661ceSRobert Watson 1544eca8a663SRobert Watson dest = SLOT(cred->cr_label); 1545db2661ceSRobert Watson 1546db2661ceSRobert Watson mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1547db2661ceSRobert Watson mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1548db2661ceSRobert Watson 0); 1549db2661ceSRobert Watson } 1550db2661ceSRobert Watson 1551db2661ceSRobert Watson static void 1552db2661ceSRobert Watson mac_lomac_create_proc1(struct ucred *cred) 1553db2661ceSRobert Watson { 1554db2661ceSRobert Watson struct mac_lomac *dest; 1555db2661ceSRobert Watson 1556eca8a663SRobert Watson dest = SLOT(cred->cr_label); 1557db2661ceSRobert Watson 1558db2661ceSRobert Watson mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0); 1559db2661ceSRobert Watson mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1560db2661ceSRobert Watson 0); 1561db2661ceSRobert Watson } 1562db2661ceSRobert Watson 1563db2661ceSRobert Watson static void 1564db2661ceSRobert Watson mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel) 1565db2661ceSRobert Watson { 1566db2661ceSRobert Watson struct mac_lomac *source, *dest; 1567db2661ceSRobert Watson 1568db2661ceSRobert Watson source = SLOT(newlabel); 1569eca8a663SRobert Watson dest = SLOT(cred->cr_label); 1570db2661ceSRobert Watson 1571db2661ceSRobert Watson try_relabel(source, dest); 1572db2661ceSRobert Watson } 1573db2661ceSRobert Watson 1574db2661ceSRobert Watson /* 1575db2661ceSRobert Watson * Access control checks. 1576db2661ceSRobert Watson */ 1577db2661ceSRobert Watson static int 1578db2661ceSRobert Watson mac_lomac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1579db2661ceSRobert Watson struct ifnet *ifnet, struct label *ifnetlabel) 1580db2661ceSRobert Watson { 1581db2661ceSRobert Watson struct mac_lomac *a, *b; 1582db2661ceSRobert Watson 1583db2661ceSRobert Watson if (!mac_lomac_enabled) 1584db2661ceSRobert Watson return (0); 1585db2661ceSRobert Watson 1586db2661ceSRobert Watson a = SLOT(bpflabel); 1587db2661ceSRobert Watson b = SLOT(ifnetlabel); 1588db2661ceSRobert Watson 1589db2661ceSRobert Watson if (mac_lomac_equal_single(a, b)) 1590db2661ceSRobert Watson return (0); 1591db2661ceSRobert Watson return (EACCES); 1592db2661ceSRobert Watson } 1593db2661ceSRobert Watson 1594db2661ceSRobert Watson static int 1595db2661ceSRobert Watson mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1596db2661ceSRobert Watson { 1597db2661ceSRobert Watson struct mac_lomac *subj, *new; 1598db2661ceSRobert Watson int error; 1599db2661ceSRobert Watson 1600eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1601db2661ceSRobert Watson new = SLOT(newlabel); 1602db2661ceSRobert Watson 1603db2661ceSRobert Watson /* 1604db2661ceSRobert Watson * If there is a LOMAC label update for the credential, it may 1605db2661ceSRobert Watson * be an update of the single, range, or both. 1606db2661ceSRobert Watson */ 1607db2661ceSRobert Watson error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1608db2661ceSRobert Watson if (error) 1609db2661ceSRobert Watson return (error); 1610db2661ceSRobert Watson 1611db2661ceSRobert Watson /* 1612db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 1613db2661ceSRobert Watson */ 1614db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1615db2661ceSRobert Watson /* 161684bdb083SRobert Watson * Fill in the missing parts from the previous label. 1617db2661ceSRobert Watson */ 161884bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 161984bdb083SRobert Watson mac_lomac_copy_single(subj, new); 162084bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 162184bdb083SRobert Watson mac_lomac_copy_range(subj, new); 1622db2661ceSRobert Watson 1623db2661ceSRobert Watson /* 1624db2661ceSRobert Watson * To change the LOMAC range on a credential, the new 1625db2661ceSRobert Watson * range label must be in the current range. 1626db2661ceSRobert Watson */ 162784bdb083SRobert Watson if (!mac_lomac_range_in_range(new, subj)) 162884bdb083SRobert Watson return (EPERM); 162984bdb083SRobert Watson 163084bdb083SRobert Watson /* 163184bdb083SRobert Watson * To change the LOMAC single label on a credential, the 163284bdb083SRobert Watson * new single label must be in the new range. Implicitly 163384bdb083SRobert Watson * from the previous check, the new single is in the old 163484bdb083SRobert Watson * range. 163584bdb083SRobert Watson */ 163684bdb083SRobert Watson if (!mac_lomac_single_in_range(new, new)) 1637db2661ceSRobert Watson return (EPERM); 1638db2661ceSRobert Watson 1639db2661ceSRobert Watson /* 1640db2661ceSRobert Watson * To have EQUAL in any component of the new credential 1641db2661ceSRobert Watson * LOMAC label, the subject must already have EQUAL in 1642db2661ceSRobert Watson * their label. 1643db2661ceSRobert Watson */ 1644db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 1645db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 1646db2661ceSRobert Watson if (error) 1647db2661ceSRobert Watson return (error); 1648db2661ceSRobert Watson } 1649db2661ceSRobert Watson 1650db2661ceSRobert Watson /* 1651db2661ceSRobert Watson * XXXMAC: Additional consistency tests regarding the 1652db2661ceSRobert Watson * single and range of the new label might be performed 1653db2661ceSRobert Watson * here. 1654db2661ceSRobert Watson */ 1655db2661ceSRobert Watson } 1656db2661ceSRobert Watson 1657db2661ceSRobert Watson return (0); 1658db2661ceSRobert Watson } 1659db2661ceSRobert Watson 1660db2661ceSRobert Watson static int 1661db2661ceSRobert Watson mac_lomac_check_cred_visible(struct ucred *u1, struct ucred *u2) 1662db2661ceSRobert Watson { 1663db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1664db2661ceSRobert Watson 1665db2661ceSRobert Watson if (!mac_lomac_enabled) 1666db2661ceSRobert Watson return (0); 1667db2661ceSRobert Watson 1668eca8a663SRobert Watson subj = SLOT(u1->cr_label); 1669eca8a663SRobert Watson obj = SLOT(u2->cr_label); 1670db2661ceSRobert Watson 1671db2661ceSRobert Watson /* XXX: range */ 1672db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1673db2661ceSRobert Watson return (ESRCH); 1674db2661ceSRobert Watson 1675db2661ceSRobert Watson return (0); 1676db2661ceSRobert Watson } 1677db2661ceSRobert Watson 1678db2661ceSRobert Watson static int 1679db2661ceSRobert Watson mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1680db2661ceSRobert Watson struct label *ifnetlabel, struct label *newlabel) 1681db2661ceSRobert Watson { 1682db2661ceSRobert Watson struct mac_lomac *subj, *new; 1683db2661ceSRobert Watson int error; 1684db2661ceSRobert Watson 1685eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1686db2661ceSRobert Watson new = SLOT(newlabel); 1687db2661ceSRobert Watson 1688db2661ceSRobert Watson /* 1689db2661ceSRobert Watson * If there is a LOMAC label update for the interface, it may 1690db2661ceSRobert Watson * be an update of the single, range, or both. 1691db2661ceSRobert Watson */ 1692db2661ceSRobert Watson error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1693db2661ceSRobert Watson if (error) 1694db2661ceSRobert Watson return (error); 1695db2661ceSRobert Watson 1696db2661ceSRobert Watson /* 1697db2661ceSRobert Watson * Relabling network interfaces requires LOMAC privilege. 1698db2661ceSRobert Watson */ 1699db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 1700db2661ceSRobert Watson if (error) 1701db2661ceSRobert Watson return (error); 1702db2661ceSRobert Watson 1703db2661ceSRobert Watson /* 1704db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 1705db2661ceSRobert Watson */ 1706db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1707db2661ceSRobert Watson /* 170884bdb083SRobert Watson * Fill in the missing parts from the previous label. 170984bdb083SRobert Watson */ 171084bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 171184bdb083SRobert Watson mac_lomac_copy_single(subj, new); 171284bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 171384bdb083SRobert Watson mac_lomac_copy_range(subj, new); 171484bdb083SRobert Watson 171584bdb083SRobert Watson /* 1716db2661ceSRobert Watson * Rely on the traditional superuser status for the LOMAC 1717db2661ceSRobert Watson * interface relabel requirements. XXXMAC: This will go 1718db2661ceSRobert Watson * away. 1719db2661ceSRobert Watson */ 1720db2661ceSRobert Watson error = suser_cred(cred, 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 1734db2661ceSRobert Watson mac_lomac_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1735db2661ceSRobert Watson struct mbuf *m, struct label *mbuflabel) 1736db2661ceSRobert Watson { 1737db2661ceSRobert Watson struct mac_lomac *p, *i; 1738db2661ceSRobert Watson 1739db2661ceSRobert Watson if (!mac_lomac_enabled) 1740db2661ceSRobert Watson return (0); 1741db2661ceSRobert Watson 1742db2661ceSRobert Watson p = SLOT(mbuflabel); 1743db2661ceSRobert Watson i = SLOT(ifnetlabel); 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, 1765db2661ceSRobert Watson struct label *label) 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); 1773db2661ceSRobert Watson obj = SLOT(label); 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 1785db2661ceSRobert Watson mac_lomac_check_kld_unload(struct ucred *cred) 1786db2661ceSRobert Watson { 1787db2661ceSRobert Watson struct mac_lomac *subj; 1788db2661ceSRobert Watson 1789db2661ceSRobert Watson if (!mac_lomac_enabled) 1790db2661ceSRobert Watson return (0); 1791db2661ceSRobert Watson 1792eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1793db2661ceSRobert Watson 1794db2661ceSRobert Watson if (mac_lomac_subject_privileged(subj)) 1795db2661ceSRobert Watson return (EPERM); 1796db2661ceSRobert Watson 1797db2661ceSRobert Watson return (0); 1798db2661ceSRobert Watson } 1799db2661ceSRobert Watson 1800db2661ceSRobert Watson static int 18014795b82cSRobert Watson mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1802db2661ceSRobert Watson struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1803db2661ceSRobert Watson { 1804db2661ceSRobert Watson 1805db2661ceSRobert Watson if(!mac_lomac_enabled) 1806db2661ceSRobert Watson return (0); 1807db2661ceSRobert Watson 1808db2661ceSRobert Watson /* XXX: This will be implemented soon... */ 1809db2661ceSRobert Watson 1810db2661ceSRobert Watson return (0); 1811db2661ceSRobert Watson } 1812db2661ceSRobert Watson 1813db2661ceSRobert Watson static int 18144795b82cSRobert Watson mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1815db2661ceSRobert Watson struct label *pipelabel) 1816db2661ceSRobert Watson { 1817db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1818db2661ceSRobert Watson 1819db2661ceSRobert Watson if (!mac_lomac_enabled) 1820db2661ceSRobert Watson return (0); 1821db2661ceSRobert Watson 1822eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1823db2661ceSRobert Watson obj = SLOT((pipelabel)); 1824db2661ceSRobert Watson 1825db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1826db2661ceSRobert Watson return (maybe_demote(subj, obj, "reading", "pipe", NULL)); 1827db2661ceSRobert Watson 1828db2661ceSRobert Watson return (0); 1829db2661ceSRobert Watson } 1830db2661ceSRobert Watson 1831db2661ceSRobert Watson static int 18324795b82cSRobert Watson mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1833db2661ceSRobert Watson struct label *pipelabel, struct label *newlabel) 1834db2661ceSRobert Watson { 1835db2661ceSRobert Watson struct mac_lomac *subj, *obj, *new; 1836db2661ceSRobert Watson int error; 1837db2661ceSRobert Watson 1838db2661ceSRobert Watson new = SLOT(newlabel); 1839eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1840db2661ceSRobert Watson obj = SLOT(pipelabel); 1841db2661ceSRobert Watson 1842db2661ceSRobert Watson /* 1843db2661ceSRobert Watson * If there is a LOMAC label update for a pipe, it must be a 1844db2661ceSRobert Watson * single update. 1845db2661ceSRobert Watson */ 1846db2661ceSRobert Watson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1847db2661ceSRobert Watson if (error) 1848db2661ceSRobert Watson return (error); 1849db2661ceSRobert Watson 1850db2661ceSRobert Watson /* 1851db2661ceSRobert Watson * To perform a relabel of a pipe (LOMAC label or not), LOMAC must 1852db2661ceSRobert Watson * authorize the relabel. 1853db2661ceSRobert Watson */ 1854db2661ceSRobert Watson if (!mac_lomac_single_in_range(obj, subj)) 1855db2661ceSRobert Watson return (EPERM); 1856db2661ceSRobert Watson 1857db2661ceSRobert Watson /* 1858db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 1859db2661ceSRobert Watson */ 1860db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1861db2661ceSRobert Watson /* 1862db2661ceSRobert Watson * To change the LOMAC label on a pipe, the new pipe label 1863db2661ceSRobert Watson * must be in the subject range. 1864db2661ceSRobert Watson */ 1865db2661ceSRobert Watson if (!mac_lomac_single_in_range(new, subj)) 1866db2661ceSRobert Watson return (EPERM); 1867db2661ceSRobert Watson 1868db2661ceSRobert Watson /* 1869db2661ceSRobert Watson * To change the LOMAC label on a pipe to be EQUAL, the 1870db2661ceSRobert Watson * subject must have appropriate privilege. 1871db2661ceSRobert Watson */ 1872db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 1873db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 1874db2661ceSRobert Watson if (error) 1875db2661ceSRobert Watson return (error); 1876db2661ceSRobert Watson } 1877db2661ceSRobert Watson } 1878db2661ceSRobert Watson 1879db2661ceSRobert Watson return (0); 1880db2661ceSRobert Watson } 1881db2661ceSRobert Watson 1882db2661ceSRobert Watson static int 18834795b82cSRobert Watson mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp, 1884db2661ceSRobert Watson struct label *pipelabel) 1885db2661ceSRobert Watson { 1886db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1887db2661ceSRobert Watson 1888db2661ceSRobert Watson if (!mac_lomac_enabled) 1889db2661ceSRobert Watson return (0); 1890db2661ceSRobert Watson 1891eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1892db2661ceSRobert Watson obj = SLOT((pipelabel)); 1893db2661ceSRobert Watson 1894db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 1895db2661ceSRobert Watson return (EACCES); 1896db2661ceSRobert Watson 1897db2661ceSRobert Watson return (0); 1898db2661ceSRobert Watson } 1899db2661ceSRobert Watson 1900db2661ceSRobert Watson static int 1901db2661ceSRobert Watson mac_lomac_check_proc_debug(struct ucred *cred, struct proc *proc) 1902db2661ceSRobert Watson { 1903db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1904db2661ceSRobert Watson 1905db2661ceSRobert Watson if (!mac_lomac_enabled) 1906db2661ceSRobert Watson return (0); 1907db2661ceSRobert Watson 1908eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1909eca8a663SRobert Watson obj = SLOT(proc->p_ucred->cr_label); 1910db2661ceSRobert Watson 1911db2661ceSRobert Watson /* XXX: range checks */ 1912db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1913db2661ceSRobert Watson return (ESRCH); 1914db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 1915db2661ceSRobert Watson return (EACCES); 1916db2661ceSRobert Watson 1917db2661ceSRobert Watson return (0); 1918db2661ceSRobert Watson } 1919db2661ceSRobert Watson 1920db2661ceSRobert Watson static int 1921db2661ceSRobert Watson mac_lomac_check_proc_sched(struct ucred *cred, struct proc *proc) 1922db2661ceSRobert Watson { 1923db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1924db2661ceSRobert Watson 1925db2661ceSRobert Watson if (!mac_lomac_enabled) 1926db2661ceSRobert Watson return (0); 1927db2661ceSRobert Watson 1928eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1929eca8a663SRobert Watson obj = SLOT(proc->p_ucred->cr_label); 1930db2661ceSRobert Watson 1931db2661ceSRobert Watson /* XXX: range checks */ 1932db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1933db2661ceSRobert Watson return (ESRCH); 1934db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 1935db2661ceSRobert Watson return (EACCES); 1936db2661ceSRobert Watson 1937db2661ceSRobert Watson return (0); 1938db2661ceSRobert Watson } 1939db2661ceSRobert Watson 1940db2661ceSRobert Watson static int 1941db2661ceSRobert Watson mac_lomac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1942db2661ceSRobert Watson { 1943db2661ceSRobert Watson struct mac_lomac *subj, *obj; 1944db2661ceSRobert Watson 1945db2661ceSRobert Watson if (!mac_lomac_enabled) 1946db2661ceSRobert Watson return (0); 1947db2661ceSRobert Watson 1948eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1949eca8a663SRobert Watson obj = SLOT(proc->p_ucred->cr_label); 1950db2661ceSRobert Watson 1951db2661ceSRobert Watson /* XXX: range checks */ 1952db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 1953db2661ceSRobert Watson return (ESRCH); 1954db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 1955db2661ceSRobert Watson return (EACCES); 1956db2661ceSRobert Watson 1957db2661ceSRobert Watson return (0); 1958db2661ceSRobert Watson } 1959db2661ceSRobert Watson 1960db2661ceSRobert Watson static int 1961db2661ceSRobert Watson mac_lomac_check_socket_deliver(struct socket *so, struct label *socketlabel, 1962db2661ceSRobert Watson struct mbuf *m, struct label *mbuflabel) 1963db2661ceSRobert Watson { 1964db2661ceSRobert Watson struct mac_lomac *p, *s; 1965db2661ceSRobert Watson 1966db2661ceSRobert Watson if (!mac_lomac_enabled) 1967db2661ceSRobert Watson return (0); 1968db2661ceSRobert Watson 1969db2661ceSRobert Watson p = SLOT(mbuflabel); 1970db2661ceSRobert Watson s = SLOT(socketlabel); 1971db2661ceSRobert Watson 1972db2661ceSRobert Watson return (mac_lomac_equal_single(p, s) ? 0 : EACCES); 1973db2661ceSRobert Watson } 1974db2661ceSRobert Watson 1975db2661ceSRobert Watson static int 1976db2661ceSRobert Watson mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *socket, 1977db2661ceSRobert Watson struct label *socketlabel, struct label *newlabel) 1978db2661ceSRobert Watson { 1979db2661ceSRobert Watson struct mac_lomac *subj, *obj, *new; 1980db2661ceSRobert Watson int error; 1981db2661ceSRobert Watson 1982db2661ceSRobert Watson new = SLOT(newlabel); 1983eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1984db2661ceSRobert Watson obj = SLOT(socketlabel); 1985db2661ceSRobert Watson 1986db2661ceSRobert Watson /* 1987db2661ceSRobert Watson * If there is a LOMAC label update for the socket, it may be 1988db2661ceSRobert Watson * an update of single. 1989db2661ceSRobert Watson */ 1990db2661ceSRobert Watson error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1991db2661ceSRobert Watson if (error) 1992db2661ceSRobert Watson return (error); 1993db2661ceSRobert Watson 1994db2661ceSRobert Watson /* 1995db2661ceSRobert Watson * To relabel a socket, the old socket single must be in the subject 1996db2661ceSRobert Watson * range. 1997db2661ceSRobert Watson */ 1998db2661ceSRobert Watson if (!mac_lomac_single_in_range(obj, subj)) 1999db2661ceSRobert Watson return (EPERM); 2000db2661ceSRobert Watson 2001db2661ceSRobert Watson /* 2002db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 2003db2661ceSRobert Watson */ 2004db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2005db2661ceSRobert Watson /* 2006db2661ceSRobert Watson * To relabel a socket, the new socket single must be in 2007db2661ceSRobert Watson * the subject range. 2008db2661ceSRobert Watson */ 2009db2661ceSRobert Watson if (!mac_lomac_single_in_range(new, subj)) 2010db2661ceSRobert Watson return (EPERM); 2011db2661ceSRobert Watson 2012db2661ceSRobert Watson /* 2013db2661ceSRobert Watson * To change the LOMAC label on the socket to contain EQUAL, 2014db2661ceSRobert Watson * the subject must have appropriate privilege. 2015db2661ceSRobert Watson */ 2016db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 2017db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 2018db2661ceSRobert Watson if (error) 2019db2661ceSRobert Watson return (error); 2020db2661ceSRobert Watson } 2021db2661ceSRobert Watson } 2022db2661ceSRobert Watson 2023db2661ceSRobert Watson return (0); 2024db2661ceSRobert Watson } 2025db2661ceSRobert Watson 2026db2661ceSRobert Watson static int 2027db2661ceSRobert Watson mac_lomac_check_socket_visible(struct ucred *cred, struct socket *socket, 2028db2661ceSRobert Watson struct label *socketlabel) 2029db2661ceSRobert Watson { 2030db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2031db2661ceSRobert Watson 2032db2661ceSRobert Watson if (!mac_lomac_enabled) 2033db2661ceSRobert Watson return (0); 2034db2661ceSRobert Watson 2035eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2036db2661ceSRobert Watson obj = SLOT(socketlabel); 2037db2661ceSRobert Watson 2038db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 2039db2661ceSRobert Watson return (ENOENT); 2040db2661ceSRobert Watson 2041db2661ceSRobert Watson return (0); 2042db2661ceSRobert Watson } 2043db2661ceSRobert Watson 2044db2661ceSRobert Watson static int 2045db2661ceSRobert Watson mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp, 2046db2661ceSRobert Watson struct label *label) 2047db2661ceSRobert Watson { 2048db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2049db2661ceSRobert Watson 2050db2661ceSRobert Watson if (!mac_lomac_enabled) 2051db2661ceSRobert Watson return (0); 2052db2661ceSRobert Watson 2053eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2054db2661ceSRobert Watson obj = SLOT(label); 2055db2661ceSRobert Watson 2056db2661ceSRobert Watson if (mac_lomac_subject_privileged(subj)) 2057db2661ceSRobert Watson return (EPERM); 2058db2661ceSRobert Watson 2059db2661ceSRobert Watson if (!mac_lomac_high_single(obj)) 2060db2661ceSRobert Watson return (EACCES); 2061db2661ceSRobert Watson 2062db2661ceSRobert Watson return (0); 2063db2661ceSRobert Watson } 2064db2661ceSRobert Watson 2065db2661ceSRobert Watson static int 206663dba32bSPawel Jakub Dawidek mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 206763dba32bSPawel Jakub Dawidek void *arg1, int arg2, struct sysctl_req *req) 2068db2661ceSRobert Watson { 2069db2661ceSRobert Watson struct mac_lomac *subj; 2070db2661ceSRobert Watson 2071db2661ceSRobert Watson if (!mac_lomac_enabled) 2072db2661ceSRobert Watson return (0); 2073db2661ceSRobert Watson 2074eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2075db2661ceSRobert Watson 2076db2661ceSRobert Watson /* 207763dba32bSPawel Jakub Dawidek * Treat sysctl variables without CTLFLAG_ANYBODY flag as 207863dba32bSPawel Jakub Dawidek * lomac/high, but also require privilege to change them. 2079db2661ceSRobert Watson */ 208063dba32bSPawel Jakub Dawidek if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2081db2661ceSRobert Watson #ifdef notdef 2082db2661ceSRobert Watson if (!mac_lomac_subject_dominate_high(subj)) 2083db2661ceSRobert Watson return (EACCES); 2084db2661ceSRobert Watson #endif 2085db2661ceSRobert Watson 2086db2661ceSRobert Watson if (mac_lomac_subject_privileged(subj)) 2087db2661ceSRobert Watson return (EPERM); 2088db2661ceSRobert Watson } 2089db2661ceSRobert Watson 2090db2661ceSRobert Watson return (0); 2091db2661ceSRobert Watson } 2092db2661ceSRobert Watson 2093db2661ceSRobert Watson static int 2094db2661ceSRobert Watson mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2095db2661ceSRobert Watson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2096db2661ceSRobert Watson { 2097db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2098db2661ceSRobert Watson 2099db2661ceSRobert Watson if (!mac_lomac_enabled) 2100db2661ceSRobert Watson return (0); 2101db2661ceSRobert Watson 2102eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2103db2661ceSRobert Watson obj = SLOT(dlabel); 2104db2661ceSRobert Watson 2105db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2106db2661ceSRobert Watson return (EACCES); 2107db2661ceSRobert Watson if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2108db2661ceSRobert Watson !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2109db2661ceSRobert Watson return (EACCES); 2110db2661ceSRobert Watson 2111db2661ceSRobert Watson return (0); 2112db2661ceSRobert Watson } 2113db2661ceSRobert Watson 2114db2661ceSRobert Watson static int 2115db2661ceSRobert Watson mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2116db2661ceSRobert Watson struct label *dlabel, struct vnode *vp, struct label *label, 2117db2661ceSRobert Watson struct componentname *cnp) 2118db2661ceSRobert Watson { 2119db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2120db2661ceSRobert Watson 2121db2661ceSRobert Watson if (!mac_lomac_enabled) 2122db2661ceSRobert Watson return (0); 2123db2661ceSRobert Watson 2124eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2125db2661ceSRobert Watson obj = SLOT(dlabel); 2126db2661ceSRobert Watson 2127db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2128db2661ceSRobert Watson return (EACCES); 2129db2661ceSRobert Watson 2130db2661ceSRobert Watson obj = SLOT(label); 2131db2661ceSRobert Watson 2132db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2133db2661ceSRobert Watson return (EACCES); 2134db2661ceSRobert Watson 2135db2661ceSRobert Watson return (0); 2136db2661ceSRobert Watson } 2137db2661ceSRobert Watson 2138db2661ceSRobert Watson static int 2139db2661ceSRobert Watson mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2140db2661ceSRobert Watson struct label *label, acl_type_t type) 2141db2661ceSRobert Watson { 2142db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2143db2661ceSRobert Watson 2144db2661ceSRobert Watson if (!mac_lomac_enabled) 2145db2661ceSRobert Watson return (0); 2146db2661ceSRobert Watson 2147eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2148db2661ceSRobert Watson obj = SLOT(label); 2149db2661ceSRobert Watson 2150db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2151db2661ceSRobert Watson return (EACCES); 2152db2661ceSRobert Watson 2153db2661ceSRobert Watson return (0); 2154db2661ceSRobert Watson } 2155db2661ceSRobert Watson 2156db2661ceSRobert Watson static int 2157db2661ceSRobert Watson mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2158db2661ceSRobert Watson struct label *dlabel, struct vnode *vp, struct label *label, 2159db2661ceSRobert Watson struct componentname *cnp) 2160db2661ceSRobert Watson { 2161db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2162db2661ceSRobert Watson 2163db2661ceSRobert Watson if (!mac_lomac_enabled) 2164db2661ceSRobert Watson return (0); 2165db2661ceSRobert Watson 2166eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2167db2661ceSRobert Watson obj = SLOT(dlabel); 2168db2661ceSRobert Watson 2169db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2170db2661ceSRobert Watson return (EACCES); 2171db2661ceSRobert Watson 2172db2661ceSRobert Watson obj = SLOT(label); 2173db2661ceSRobert Watson 2174db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2175db2661ceSRobert Watson return (EACCES); 2176db2661ceSRobert Watson 2177db2661ceSRobert Watson return (0); 2178db2661ceSRobert Watson } 2179db2661ceSRobert Watson 2180db2661ceSRobert Watson static int 2181db2661ceSRobert Watson mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2182db2661ceSRobert Watson struct label *label, int prot) 2183db2661ceSRobert Watson { 2184db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2185db2661ceSRobert Watson 2186db2661ceSRobert Watson /* 2187db2661ceSRobert Watson * Rely on the use of open()-time protections to handle 2188db2661ceSRobert Watson * non-revocation cases. 2189db2661ceSRobert Watson */ 2190db2661ceSRobert Watson if (!mac_lomac_enabled) 2191db2661ceSRobert Watson return (0); 2192db2661ceSRobert Watson 2193eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2194db2661ceSRobert Watson obj = SLOT(label); 2195db2661ceSRobert Watson 2196db2661ceSRobert Watson if (prot & VM_PROT_WRITE) { 2197db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2198db2661ceSRobert Watson return (EACCES); 2199db2661ceSRobert Watson } 2200db2661ceSRobert Watson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2201db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 2202db2661ceSRobert Watson return (maybe_demote(subj, obj, "mapping", "file", vp)); 2203db2661ceSRobert Watson } 2204db2661ceSRobert Watson 2205db2661ceSRobert Watson return (0); 2206db2661ceSRobert Watson } 2207db2661ceSRobert Watson 2208db2661ceSRobert Watson static int 2209db2661ceSRobert Watson mac_lomac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, 2210db2661ceSRobert Watson struct label *label, int prot) 2211db2661ceSRobert Watson { 2212db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2213db2661ceSRobert Watson 2214db2661ceSRobert Watson /* 2215db2661ceSRobert Watson * Rely on the use of open()-time protections to handle 2216db2661ceSRobert Watson * non-revocation cases. 2217db2661ceSRobert Watson */ 2218db2661ceSRobert Watson if (!mac_lomac_enabled || !revocation_enabled) 2219db2661ceSRobert Watson return (0); 2220db2661ceSRobert Watson 2221eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2222db2661ceSRobert Watson obj = SLOT(label); 2223db2661ceSRobert Watson 2224db2661ceSRobert Watson if (prot & VM_PROT_WRITE) { 2225db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2226db2661ceSRobert Watson return (EACCES); 2227db2661ceSRobert Watson } 2228db2661ceSRobert Watson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2229db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 2230db2661ceSRobert Watson return (EACCES); 2231db2661ceSRobert Watson } 2232db2661ceSRobert Watson 2233db2661ceSRobert Watson return (0); 2234db2661ceSRobert Watson } 2235db2661ceSRobert Watson 2236db2661ceSRobert Watson static void 2237db2661ceSRobert Watson mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, 2238db2661ceSRobert Watson struct label *label, /* XXX vm_prot_t */ int *prot) 2239db2661ceSRobert Watson { 2240db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2241db2661ceSRobert Watson 2242db2661ceSRobert Watson /* 2243db2661ceSRobert Watson * Rely on the use of open()-time protections to handle 2244db2661ceSRobert Watson * non-revocation cases. 2245db2661ceSRobert Watson */ 2246db2661ceSRobert Watson if (!mac_lomac_enabled || !revocation_enabled) 2247db2661ceSRobert Watson return; 2248db2661ceSRobert Watson 2249eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2250db2661ceSRobert Watson obj = SLOT(label); 2251db2661ceSRobert Watson 2252db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2253db2661ceSRobert Watson *prot &= ~VM_PROT_WRITE; 2254db2661ceSRobert Watson } 2255db2661ceSRobert Watson 2256db2661ceSRobert Watson static int 2257db2661ceSRobert Watson mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp, 2258db2661ceSRobert Watson struct label *vnodelabel, int acc_mode) 2259db2661ceSRobert Watson { 2260db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2261db2661ceSRobert Watson 2262db2661ceSRobert Watson if (!mac_lomac_enabled) 2263db2661ceSRobert Watson return (0); 2264db2661ceSRobert Watson 2265eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2266db2661ceSRobert Watson obj = SLOT(vnodelabel); 2267db2661ceSRobert Watson 2268db2661ceSRobert Watson /* XXX privilege override for admin? */ 2269db2661ceSRobert Watson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2270db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2271db2661ceSRobert Watson return (EACCES); 2272db2661ceSRobert Watson } 2273db2661ceSRobert Watson 2274db2661ceSRobert Watson return (0); 2275db2661ceSRobert Watson } 2276db2661ceSRobert Watson 2277db2661ceSRobert Watson static int 2278db2661ceSRobert Watson mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2279db2661ceSRobert Watson struct vnode *vp, struct label *label) 2280db2661ceSRobert Watson { 2281db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2282db2661ceSRobert Watson 2283db2661ceSRobert Watson if (!mac_lomac_enabled || !revocation_enabled) 2284db2661ceSRobert Watson return (0); 2285db2661ceSRobert Watson 2286eca8a663SRobert Watson subj = SLOT(active_cred->cr_label); 2287db2661ceSRobert Watson obj = SLOT(label); 2288db2661ceSRobert Watson 2289db2661ceSRobert Watson if (!mac_lomac_dominate_single(obj, subj)) 2290db2661ceSRobert Watson return (maybe_demote(subj, obj, "reading", "file", vp)); 2291db2661ceSRobert Watson 2292db2661ceSRobert Watson return (0); 2293db2661ceSRobert Watson } 2294db2661ceSRobert Watson 2295db2661ceSRobert Watson static int 2296db2661ceSRobert Watson mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2297db2661ceSRobert Watson struct label *vnodelabel, struct label *newlabel) 2298db2661ceSRobert Watson { 2299db2661ceSRobert Watson struct mac_lomac *old, *new, *subj; 2300db2661ceSRobert Watson int error; 2301db2661ceSRobert Watson 2302db2661ceSRobert Watson old = SLOT(vnodelabel); 2303db2661ceSRobert Watson new = SLOT(newlabel); 2304eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2305db2661ceSRobert Watson 2306db2661ceSRobert Watson /* 2307db2661ceSRobert Watson * If there is a LOMAC label update for the vnode, it must be a 2308db2661ceSRobert Watson * single label, with an optional explicit auxiliary single. 2309db2661ceSRobert Watson */ 2310db2661ceSRobert Watson error = lomac_atmostflags(new, 2311db2661ceSRobert Watson MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2312db2661ceSRobert Watson if (error) 2313db2661ceSRobert Watson return (error); 2314db2661ceSRobert Watson 2315db2661ceSRobert Watson /* 2316db2661ceSRobert Watson * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2317db2661ceSRobert Watson * authorize the relabel. 2318db2661ceSRobert Watson */ 2319db2661ceSRobert Watson if (!mac_lomac_single_in_range(old, subj)) 2320db2661ceSRobert Watson return (EPERM); 2321db2661ceSRobert Watson 2322db2661ceSRobert Watson /* 2323db2661ceSRobert Watson * If the LOMAC label is to be changed, authorize as appropriate. 2324db2661ceSRobert Watson */ 2325db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2326db2661ceSRobert Watson /* 2327db2661ceSRobert Watson * To change the LOMAC label on a vnode, the new vnode label 2328db2661ceSRobert Watson * must be in the subject range. 2329db2661ceSRobert Watson */ 2330db2661ceSRobert Watson if (!mac_lomac_single_in_range(new, subj)) 2331db2661ceSRobert Watson return (EPERM); 2332db2661ceSRobert Watson 2333db2661ceSRobert Watson /* 2334db2661ceSRobert Watson * To change the LOMAC label on the vnode to be EQUAL, 2335db2661ceSRobert Watson * the subject must have appropriate privilege. 2336db2661ceSRobert Watson */ 2337db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 2338db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 2339db2661ceSRobert Watson if (error) 2340db2661ceSRobert Watson return (error); 2341db2661ceSRobert Watson } 2342db2661ceSRobert Watson } 2343db2661ceSRobert Watson if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2344db2661ceSRobert Watson /* 234584bdb083SRobert Watson * Fill in the missing parts from the previous label. 234684bdb083SRobert Watson */ 234784bdb083SRobert Watson if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 234884bdb083SRobert Watson mac_lomac_copy_single(subj, new); 234984bdb083SRobert Watson 235084bdb083SRobert Watson /* 2351db2661ceSRobert Watson * To change the auxiliary LOMAC label on a vnode, the new 2352db2661ceSRobert Watson * vnode label must be in the subject range. 2353db2661ceSRobert Watson */ 2354db2661ceSRobert Watson if (!mac_lomac_auxsingle_in_range(new, subj)) 2355db2661ceSRobert Watson return (EPERM); 2356db2661ceSRobert Watson 2357db2661ceSRobert Watson /* 2358db2661ceSRobert Watson * To change the auxiliary LOMAC label on the vnode to be 2359db2661ceSRobert Watson * EQUAL, the subject must have appropriate privilege. 2360db2661ceSRobert Watson */ 2361db2661ceSRobert Watson if (mac_lomac_contains_equal(new)) { 2362db2661ceSRobert Watson error = mac_lomac_subject_privileged(subj); 2363db2661ceSRobert Watson if (error) 2364db2661ceSRobert Watson return (error); 2365db2661ceSRobert Watson } 2366db2661ceSRobert Watson } 2367db2661ceSRobert Watson 2368db2661ceSRobert Watson return (0); 2369db2661ceSRobert Watson } 2370db2661ceSRobert Watson 2371db2661ceSRobert Watson static int 2372db2661ceSRobert Watson mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2373db2661ceSRobert Watson struct label *dlabel, struct vnode *vp, struct label *label, 2374db2661ceSRobert Watson struct componentname *cnp) 2375db2661ceSRobert Watson { 2376db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2377db2661ceSRobert Watson 2378db2661ceSRobert Watson if (!mac_lomac_enabled) 2379db2661ceSRobert Watson return (0); 2380db2661ceSRobert Watson 2381eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2382db2661ceSRobert Watson obj = SLOT(dlabel); 2383db2661ceSRobert Watson 2384db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2385db2661ceSRobert Watson return (EACCES); 2386db2661ceSRobert Watson 2387db2661ceSRobert Watson obj = SLOT(label); 2388db2661ceSRobert Watson 2389db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2390db2661ceSRobert Watson return (EACCES); 2391db2661ceSRobert Watson 2392db2661ceSRobert Watson return (0); 2393db2661ceSRobert Watson } 2394db2661ceSRobert Watson 2395db2661ceSRobert Watson static int 2396db2661ceSRobert Watson mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2397db2661ceSRobert Watson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2398db2661ceSRobert Watson struct componentname *cnp) 2399db2661ceSRobert Watson { 2400db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2401db2661ceSRobert Watson 2402db2661ceSRobert Watson if (!mac_lomac_enabled) 2403db2661ceSRobert Watson return (0); 2404db2661ceSRobert Watson 2405eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2406db2661ceSRobert Watson obj = SLOT(dlabel); 2407db2661ceSRobert Watson 2408db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2409db2661ceSRobert Watson return (EACCES); 2410db2661ceSRobert Watson 2411db2661ceSRobert Watson if (vp != NULL) { 2412db2661ceSRobert Watson obj = SLOT(label); 2413db2661ceSRobert Watson 2414db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2415db2661ceSRobert Watson return (EACCES); 2416db2661ceSRobert Watson } 2417db2661ceSRobert Watson 2418db2661ceSRobert Watson return (0); 2419db2661ceSRobert Watson } 2420db2661ceSRobert Watson 2421db2661ceSRobert Watson static int 2422db2661ceSRobert Watson mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2423db2661ceSRobert Watson struct label *label) 2424db2661ceSRobert Watson { 2425db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2426db2661ceSRobert Watson 2427db2661ceSRobert Watson if (!mac_lomac_enabled) 2428db2661ceSRobert Watson return (0); 2429db2661ceSRobert Watson 2430eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2431db2661ceSRobert Watson obj = SLOT(label); 2432db2661ceSRobert Watson 2433db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2434db2661ceSRobert Watson return (EACCES); 2435db2661ceSRobert Watson 2436db2661ceSRobert Watson return (0); 2437db2661ceSRobert Watson } 2438db2661ceSRobert Watson 2439db2661ceSRobert Watson static int 2440db2661ceSRobert Watson mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2441db2661ceSRobert Watson struct label *label, acl_type_t type, struct acl *acl) 2442db2661ceSRobert Watson { 2443db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2444db2661ceSRobert Watson 2445db2661ceSRobert Watson if (!mac_lomac_enabled) 2446db2661ceSRobert Watson return (0); 2447db2661ceSRobert Watson 2448eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2449db2661ceSRobert Watson obj = SLOT(label); 2450db2661ceSRobert Watson 2451db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2452db2661ceSRobert Watson return (EACCES); 2453db2661ceSRobert Watson 2454db2661ceSRobert Watson return (0); 2455db2661ceSRobert Watson } 2456db2661ceSRobert Watson 2457db2661ceSRobert Watson static int 2458db2661ceSRobert Watson mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2459db2661ceSRobert Watson struct label *vnodelabel, int attrnamespace, const char *name, 2460db2661ceSRobert Watson struct uio *uio) 2461db2661ceSRobert Watson { 2462db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2463db2661ceSRobert Watson 2464db2661ceSRobert Watson if (!mac_lomac_enabled) 2465db2661ceSRobert Watson return (0); 2466db2661ceSRobert Watson 2467eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2468db2661ceSRobert Watson obj = SLOT(vnodelabel); 2469db2661ceSRobert Watson 2470db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2471db2661ceSRobert Watson return (EACCES); 2472db2661ceSRobert Watson 2473db2661ceSRobert Watson /* XXX: protect the MAC EA in a special way? */ 2474db2661ceSRobert Watson 2475db2661ceSRobert Watson return (0); 2476db2661ceSRobert Watson } 2477db2661ceSRobert Watson 2478db2661ceSRobert Watson static int 2479db2661ceSRobert Watson mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2480db2661ceSRobert Watson struct label *vnodelabel, u_long flags) 2481db2661ceSRobert Watson { 2482db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2483db2661ceSRobert Watson 2484db2661ceSRobert Watson if (!mac_lomac_enabled) 2485db2661ceSRobert Watson return (0); 2486db2661ceSRobert Watson 2487eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2488db2661ceSRobert Watson obj = SLOT(vnodelabel); 2489db2661ceSRobert Watson 2490db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2491db2661ceSRobert Watson return (EACCES); 2492db2661ceSRobert Watson 2493db2661ceSRobert Watson return (0); 2494db2661ceSRobert Watson } 2495db2661ceSRobert Watson 2496db2661ceSRobert Watson static int 2497db2661ceSRobert Watson mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2498db2661ceSRobert Watson struct label *vnodelabel, mode_t mode) 2499db2661ceSRobert Watson { 2500db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2501db2661ceSRobert Watson 2502db2661ceSRobert Watson if (!mac_lomac_enabled) 2503db2661ceSRobert Watson return (0); 2504db2661ceSRobert Watson 2505eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2506db2661ceSRobert Watson obj = SLOT(vnodelabel); 2507db2661ceSRobert Watson 2508db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2509db2661ceSRobert Watson return (EACCES); 2510db2661ceSRobert Watson 2511db2661ceSRobert Watson return (0); 2512db2661ceSRobert Watson } 2513db2661ceSRobert Watson 2514db2661ceSRobert Watson static int 2515db2661ceSRobert Watson mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2516db2661ceSRobert Watson struct label *vnodelabel, uid_t uid, gid_t gid) 2517db2661ceSRobert Watson { 2518db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2519db2661ceSRobert Watson 2520db2661ceSRobert Watson if (!mac_lomac_enabled) 2521db2661ceSRobert Watson return (0); 2522db2661ceSRobert Watson 2523eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2524db2661ceSRobert Watson obj = SLOT(vnodelabel); 2525db2661ceSRobert Watson 2526db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2527db2661ceSRobert Watson return (EACCES); 2528db2661ceSRobert Watson 2529db2661ceSRobert Watson return (0); 2530db2661ceSRobert Watson } 2531db2661ceSRobert Watson 2532db2661ceSRobert Watson static int 2533db2661ceSRobert Watson mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2534db2661ceSRobert Watson struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2535db2661ceSRobert Watson { 2536db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2537db2661ceSRobert Watson 2538db2661ceSRobert Watson if (!mac_lomac_enabled) 2539db2661ceSRobert Watson return (0); 2540db2661ceSRobert Watson 2541eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2542db2661ceSRobert Watson obj = SLOT(vnodelabel); 2543db2661ceSRobert Watson 2544db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2545db2661ceSRobert Watson return (EACCES); 2546db2661ceSRobert Watson 2547db2661ceSRobert Watson return (0); 2548db2661ceSRobert Watson } 2549db2661ceSRobert Watson 2550db2661ceSRobert Watson static int 2551db2661ceSRobert Watson mac_lomac_check_vnode_write(struct ucred *active_cred, 2552db2661ceSRobert Watson struct ucred *file_cred, struct vnode *vp, struct label *label) 2553db2661ceSRobert Watson { 2554db2661ceSRobert Watson struct mac_lomac *subj, *obj; 2555db2661ceSRobert Watson 2556db2661ceSRobert Watson if (!mac_lomac_enabled || !revocation_enabled) 2557db2661ceSRobert Watson return (0); 2558db2661ceSRobert Watson 2559eca8a663SRobert Watson subj = SLOT(active_cred->cr_label); 2560db2661ceSRobert Watson obj = SLOT(label); 2561db2661ceSRobert Watson 2562db2661ceSRobert Watson if (!mac_lomac_subject_dominate(subj, obj)) 2563db2661ceSRobert Watson return (EACCES); 2564db2661ceSRobert Watson 2565db2661ceSRobert Watson return (0); 2566db2661ceSRobert Watson } 2567db2661ceSRobert Watson 2568db2661ceSRobert Watson static void 2569db2661ceSRobert Watson mac_lomac_thread_userret(struct thread *td) 2570db2661ceSRobert Watson { 2571db2661ceSRobert Watson struct proc *p = td->td_proc; 2572eca8a663SRobert Watson struct mac_lomac_proc *subj = PSLOT(p->p_label); 2573db2661ceSRobert Watson struct ucred *newcred, *oldcred; 2574db2661ceSRobert Watson int dodrop; 2575db2661ceSRobert Watson 2576db2661ceSRobert Watson mtx_lock(&subj->mtx); 2577db2661ceSRobert Watson if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 2578db2661ceSRobert Watson dodrop = 0; 2579db2661ceSRobert Watson mtx_unlock(&subj->mtx); 2580db2661ceSRobert Watson newcred = crget(); 2581db2661ceSRobert Watson /* 2582db2661ceSRobert Watson * Prevent a lock order reversal in 2583db2661ceSRobert Watson * mac_cred_mmapped_drop_perms; ideally, the other 2584db2661ceSRobert Watson * user of subj->mtx wouldn't be holding Giant. 2585db2661ceSRobert Watson */ 2586db2661ceSRobert Watson mtx_lock(&Giant); 2587db2661ceSRobert Watson PROC_LOCK(p); 2588db2661ceSRobert Watson mtx_lock(&subj->mtx); 2589db2661ceSRobert Watson /* 2590db2661ceSRobert Watson * Check if we lost the race while allocating the cred. 2591db2661ceSRobert Watson */ 2592db2661ceSRobert Watson if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2593db2661ceSRobert Watson crfree(newcred); 2594db2661ceSRobert Watson goto out; 2595db2661ceSRobert Watson } 2596db2661ceSRobert Watson oldcred = p->p_ucred; 2597db2661ceSRobert Watson crcopy(newcred, oldcred); 2598db2661ceSRobert Watson crhold(newcred); 2599eca8a663SRobert Watson mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2600db2661ceSRobert Watson p->p_ucred = newcred; 2601db2661ceSRobert Watson crfree(oldcred); 2602db2661ceSRobert Watson dodrop = 1; 2603db2661ceSRobert Watson out: 2604db2661ceSRobert Watson mtx_unlock(&subj->mtx); 2605db2661ceSRobert Watson PROC_UNLOCK(p); 2606db2661ceSRobert Watson if (dodrop) 2607db2661ceSRobert Watson mac_cred_mmapped_drop_perms(curthread, newcred); 2608db2661ceSRobert Watson mtx_unlock(&Giant); 2609db2661ceSRobert Watson } else { 2610db2661ceSRobert Watson mtx_unlock(&subj->mtx); 2611db2661ceSRobert Watson } 2612db2661ceSRobert Watson } 2613db2661ceSRobert Watson 2614db2661ceSRobert Watson static struct mac_policy_ops mac_lomac_ops = 2615db2661ceSRobert Watson { 2616db2661ceSRobert Watson .mpo_init = mac_lomac_init, 2617db2661ceSRobert Watson .mpo_init_bpfdesc_label = mac_lomac_init_label, 2618db2661ceSRobert Watson .mpo_init_cred_label = mac_lomac_init_label, 2619db2661ceSRobert Watson .mpo_init_devfsdirent_label = mac_lomac_init_label, 2620db2661ceSRobert Watson .mpo_init_ifnet_label = mac_lomac_init_label, 2621a557af22SRobert Watson .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck, 26225e7ce478SRobert Watson .mpo_init_ipq_label = mac_lomac_init_label_waitcheck, 2623db2661ceSRobert Watson .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck, 2624db2661ceSRobert Watson .mpo_init_mount_label = mac_lomac_init_label, 2625db2661ceSRobert Watson .mpo_init_mount_fs_label = mac_lomac_init_label, 2626db2661ceSRobert Watson .mpo_init_pipe_label = mac_lomac_init_label, 2627db2661ceSRobert Watson .mpo_init_proc_label = mac_lomac_init_proc_label, 2628db2661ceSRobert Watson .mpo_init_socket_label = mac_lomac_init_label_waitcheck, 2629db2661ceSRobert Watson .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck, 2630db2661ceSRobert Watson .mpo_init_vnode_label = mac_lomac_init_label, 2631db2661ceSRobert Watson .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label, 2632db2661ceSRobert Watson .mpo_destroy_cred_label = mac_lomac_destroy_label, 2633db2661ceSRobert Watson .mpo_destroy_devfsdirent_label = mac_lomac_destroy_label, 2634db2661ceSRobert Watson .mpo_destroy_ifnet_label = mac_lomac_destroy_label, 2635a557af22SRobert Watson .mpo_destroy_inpcb_label = mac_lomac_destroy_label, 2636db2661ceSRobert Watson .mpo_destroy_ipq_label = mac_lomac_destroy_label, 2637db2661ceSRobert Watson .mpo_destroy_mbuf_label = mac_lomac_destroy_label, 2638db2661ceSRobert Watson .mpo_destroy_mount_label = mac_lomac_destroy_label, 2639db2661ceSRobert Watson .mpo_destroy_mount_fs_label = mac_lomac_destroy_label, 2640db2661ceSRobert Watson .mpo_destroy_pipe_label = mac_lomac_destroy_label, 2641db2661ceSRobert Watson .mpo_destroy_proc_label = mac_lomac_destroy_proc_label, 2642db2661ceSRobert Watson .mpo_destroy_socket_label = mac_lomac_destroy_label, 2643db2661ceSRobert Watson .mpo_destroy_socket_peer_label = mac_lomac_destroy_label, 2644db2661ceSRobert Watson .mpo_destroy_vnode_label = mac_lomac_destroy_label, 264556d9e932SRobert Watson .mpo_copy_cred_label = mac_lomac_copy_label, 2646985a0d97SRobert Watson .mpo_copy_mbuf_label = mac_lomac_copy_label, 2647db2661ceSRobert Watson .mpo_copy_pipe_label = mac_lomac_copy_label, 2648b0323ea3SRobert Watson .mpo_copy_socket_label = mac_lomac_copy_label, 2649db2661ceSRobert Watson .mpo_copy_vnode_label = mac_lomac_copy_label, 2650db2661ceSRobert Watson .mpo_externalize_cred_label = mac_lomac_externalize_label, 2651db2661ceSRobert Watson .mpo_externalize_ifnet_label = mac_lomac_externalize_label, 2652db2661ceSRobert Watson .mpo_externalize_pipe_label = mac_lomac_externalize_label, 2653db2661ceSRobert Watson .mpo_externalize_socket_label = mac_lomac_externalize_label, 2654db2661ceSRobert Watson .mpo_externalize_socket_peer_label = mac_lomac_externalize_label, 2655db2661ceSRobert Watson .mpo_externalize_vnode_label = mac_lomac_externalize_label, 2656db2661ceSRobert Watson .mpo_internalize_cred_label = mac_lomac_internalize_label, 2657db2661ceSRobert Watson .mpo_internalize_ifnet_label = mac_lomac_internalize_label, 2658db2661ceSRobert Watson .mpo_internalize_pipe_label = mac_lomac_internalize_label, 2659db2661ceSRobert Watson .mpo_internalize_socket_label = mac_lomac_internalize_label, 2660db2661ceSRobert Watson .mpo_internalize_vnode_label = mac_lomac_internalize_label, 2661db2661ceSRobert Watson .mpo_create_devfs_device = mac_lomac_create_devfs_device, 2662db2661ceSRobert Watson .mpo_create_devfs_directory = mac_lomac_create_devfs_directory, 2663db2661ceSRobert Watson .mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink, 2664db2661ceSRobert Watson .mpo_create_mount = mac_lomac_create_mount, 2665db2661ceSRobert Watson .mpo_create_root_mount = mac_lomac_create_root_mount, 2666db2661ceSRobert Watson .mpo_relabel_vnode = mac_lomac_relabel_vnode, 2667db2661ceSRobert Watson .mpo_update_devfsdirent = mac_lomac_update_devfsdirent, 2668db2661ceSRobert Watson .mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs, 2669db2661ceSRobert Watson .mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr, 2670db2661ceSRobert Watson .mpo_associate_vnode_singlelabel = 2671db2661ceSRobert Watson mac_lomac_associate_vnode_singlelabel, 2672db2661ceSRobert Watson .mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr, 2673db2661ceSRobert Watson .mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr, 2674db2661ceSRobert Watson .mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket, 2675db2661ceSRobert Watson .mpo_create_pipe = mac_lomac_create_pipe, 2676db2661ceSRobert Watson .mpo_create_socket = mac_lomac_create_socket, 2677db2661ceSRobert Watson .mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket, 2678db2661ceSRobert Watson .mpo_relabel_pipe = mac_lomac_relabel_pipe, 2679db2661ceSRobert Watson .mpo_relabel_socket = mac_lomac_relabel_socket, 2680db2661ceSRobert Watson .mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf, 2681db2661ceSRobert Watson .mpo_set_socket_peer_from_socket = 2682db2661ceSRobert Watson mac_lomac_set_socket_peer_from_socket, 2683db2661ceSRobert Watson .mpo_create_bpfdesc = mac_lomac_create_bpfdesc, 2684db2661ceSRobert Watson .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq, 2685db2661ceSRobert Watson .mpo_create_fragment = mac_lomac_create_fragment, 2686db2661ceSRobert Watson .mpo_create_ifnet = mac_lomac_create_ifnet, 2687a557af22SRobert Watson .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket, 2688db2661ceSRobert Watson .mpo_create_ipq = mac_lomac_create_ipq, 26892d92ec98SRobert Watson .mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb, 2690db2661ceSRobert Watson .mpo_create_mbuf_from_mbuf = mac_lomac_create_mbuf_from_mbuf, 2691db2661ceSRobert Watson .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer, 2692db2661ceSRobert Watson .mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc, 2693db2661ceSRobert Watson .mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet, 2694db2661ceSRobert Watson .mpo_create_mbuf_multicast_encap = 2695db2661ceSRobert Watson mac_lomac_create_mbuf_multicast_encap, 2696db2661ceSRobert Watson .mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer, 2697db2661ceSRobert Watson .mpo_fragment_match = mac_lomac_fragment_match, 2698db2661ceSRobert Watson .mpo_relabel_ifnet = mac_lomac_relabel_ifnet, 2699db2661ceSRobert Watson .mpo_update_ipq = mac_lomac_update_ipq, 2700a557af22SRobert Watson .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel, 2701db2661ceSRobert Watson .mpo_execve_transition = mac_lomac_execve_transition, 2702db2661ceSRobert Watson .mpo_execve_will_transition = mac_lomac_execve_will_transition, 2703db2661ceSRobert Watson .mpo_create_proc0 = mac_lomac_create_proc0, 2704db2661ceSRobert Watson .mpo_create_proc1 = mac_lomac_create_proc1, 2705db2661ceSRobert Watson .mpo_relabel_cred = mac_lomac_relabel_cred, 2706db2661ceSRobert Watson .mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive, 2707db2661ceSRobert Watson .mpo_check_cred_relabel = mac_lomac_check_cred_relabel, 2708db2661ceSRobert Watson .mpo_check_cred_visible = mac_lomac_check_cred_visible, 2709db2661ceSRobert Watson .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel, 2710db2661ceSRobert Watson .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit, 2711a557af22SRobert Watson .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver, 2712db2661ceSRobert Watson .mpo_check_kld_load = mac_lomac_check_kld_load, 2713db2661ceSRobert Watson .mpo_check_kld_unload = mac_lomac_check_kld_unload, 2714db2661ceSRobert Watson .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl, 2715db2661ceSRobert Watson .mpo_check_pipe_read = mac_lomac_check_pipe_read, 2716db2661ceSRobert Watson .mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel, 2717db2661ceSRobert Watson .mpo_check_pipe_write = mac_lomac_check_pipe_write, 2718db2661ceSRobert Watson .mpo_check_proc_debug = mac_lomac_check_proc_debug, 2719db2661ceSRobert Watson .mpo_check_proc_sched = mac_lomac_check_proc_sched, 2720db2661ceSRobert Watson .mpo_check_proc_signal = mac_lomac_check_proc_signal, 2721db2661ceSRobert Watson .mpo_check_socket_deliver = mac_lomac_check_socket_deliver, 2722db2661ceSRobert Watson .mpo_check_socket_relabel = mac_lomac_check_socket_relabel, 2723db2661ceSRobert Watson .mpo_check_socket_visible = mac_lomac_check_socket_visible, 2724db2661ceSRobert Watson .mpo_check_system_swapon = mac_lomac_check_system_swapon, 2725db2661ceSRobert Watson .mpo_check_system_sysctl = mac_lomac_check_system_sysctl, 2726db2661ceSRobert Watson .mpo_check_vnode_access = mac_lomac_check_vnode_open, 2727db2661ceSRobert Watson .mpo_check_vnode_create = mac_lomac_check_vnode_create, 2728db2661ceSRobert Watson .mpo_check_vnode_delete = mac_lomac_check_vnode_delete, 2729db2661ceSRobert Watson .mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl, 2730db2661ceSRobert Watson .mpo_check_vnode_link = mac_lomac_check_vnode_link, 2731db2661ceSRobert Watson .mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap, 2732db2661ceSRobert Watson .mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade, 2733db2661ceSRobert Watson .mpo_check_vnode_mprotect = mac_lomac_check_vnode_mprotect, 2734db2661ceSRobert Watson .mpo_check_vnode_open = mac_lomac_check_vnode_open, 2735db2661ceSRobert Watson .mpo_check_vnode_read = mac_lomac_check_vnode_read, 2736db2661ceSRobert Watson .mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel, 2737db2661ceSRobert Watson .mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from, 2738db2661ceSRobert Watson .mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to, 2739db2661ceSRobert Watson .mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke, 2740db2661ceSRobert Watson .mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl, 2741db2661ceSRobert Watson .mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr, 2742db2661ceSRobert Watson .mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags, 2743db2661ceSRobert Watson .mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode, 2744db2661ceSRobert Watson .mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner, 2745db2661ceSRobert Watson .mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes, 2746db2661ceSRobert Watson .mpo_check_vnode_write = mac_lomac_check_vnode_write, 2747db2661ceSRobert Watson .mpo_thread_userret = mac_lomac_thread_userret, 2748db2661ceSRobert Watson }; 2749db2661ceSRobert Watson 2750db2661ceSRobert Watson MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC", 2751aa6a0037SRobert Watson MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, 2752aa6a0037SRobert Watson &mac_lomac_slot); 2753