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