1d8a7b7a3SRobert Watson /*- 29b6dd12eSRobert Watson * Copyright (c) 1999-2002, 2007-2011 Robert N. M. Watson 382d16d5eSRobert Watson * Copyright (c) 2001-2005 McAfee, Inc. 430d239bcSRobert Watson * Copyright (c) 2006 SPARTA, Inc. 5d8a7b7a3SRobert Watson * All rights reserved. 6d8a7b7a3SRobert Watson * 7d8a7b7a3SRobert Watson * This software was developed by Robert Watson for the TrustedBSD Project. 8d8a7b7a3SRobert Watson * 982d16d5eSRobert Watson * This software was developed for the FreeBSD Project in part by McAfee 1082d16d5eSRobert Watson * Research, the Security Research Division of McAfee, Inc. under 1182d16d5eSRobert Watson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 1282d16d5eSRobert Watson * CHATS research program. 13d8a7b7a3SRobert Watson * 1430d239bcSRobert Watson * This software was enhanced by SPARTA ISSO under SPAWAR contract 1530d239bcSRobert Watson * N66001-04-C-6019 ("SEFOS"). 1630d239bcSRobert Watson * 179b6dd12eSRobert Watson * This software was developed at the University of Cambridge Computer 189b6dd12eSRobert Watson * Laboratory with support from a grant from Google, Inc. 199b6dd12eSRobert Watson * 20d8a7b7a3SRobert Watson * Redistribution and use in source and binary forms, with or without 21d8a7b7a3SRobert Watson * modification, are permitted provided that the following conditions 22d8a7b7a3SRobert Watson * are met: 23d8a7b7a3SRobert Watson * 1. Redistributions of source code must retain the above copyright 24d8a7b7a3SRobert Watson * notice, this list of conditions and the following disclaimer. 25d8a7b7a3SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 26d8a7b7a3SRobert Watson * notice, this list of conditions and the following disclaimer in the 27d8a7b7a3SRobert Watson * documentation and/or other materials provided with the distribution. 28d8a7b7a3SRobert Watson * 29d8a7b7a3SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 30d8a7b7a3SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31d8a7b7a3SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32d8a7b7a3SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 33d8a7b7a3SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34d8a7b7a3SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35d8a7b7a3SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36d8a7b7a3SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37d8a7b7a3SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38d8a7b7a3SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39d8a7b7a3SRobert Watson * SUCH DAMAGE. 40d8a7b7a3SRobert Watson */ 41d8a7b7a3SRobert Watson 42d8a7b7a3SRobert Watson /* 43d8a7b7a3SRobert Watson * Developed by the TrustedBSD Project. 4430575990SRobert Watson * 45d8a7b7a3SRobert Watson * MLS fixed label mandatory confidentiality policy. 46d8a7b7a3SRobert Watson */ 47d8a7b7a3SRobert Watson 48d8a7b7a3SRobert Watson #include <sys/types.h> 49d8a7b7a3SRobert Watson #include <sys/param.h> 50d8a7b7a3SRobert Watson #include <sys/acl.h> 51d8a7b7a3SRobert Watson #include <sys/conf.h> 52763bbd2fSRobert Watson #include <sys/extattr.h> 53d8a7b7a3SRobert Watson #include <sys/kernel.h> 546aeb05d7STom Rhodes #include <sys/ksem.h> 55c92163dcSChristian S.J. Peron #include <sys/mman.h> 56cebf9431SBruce Evans #include <sys/malloc.h> 57d8a7b7a3SRobert Watson #include <sys/mount.h> 58d8a7b7a3SRobert Watson #include <sys/proc.h> 5905e830f1SRobert Watson #include <sys/sbuf.h> 60d8a7b7a3SRobert Watson #include <sys/systm.h> 61d8a7b7a3SRobert Watson #include <sys/sysproto.h> 62d8a7b7a3SRobert Watson #include <sys/sysent.h> 6324e8d0d0SRobert Watson #include <sys/systm.h> 64d8a7b7a3SRobert Watson #include <sys/vnode.h> 65d8a7b7a3SRobert Watson #include <sys/file.h> 66d8a7b7a3SRobert Watson #include <sys/socket.h> 67d8a7b7a3SRobert Watson #include <sys/socketvar.h> 68d8a7b7a3SRobert Watson #include <sys/pipe.h> 6936422989SPoul-Henning Kamp #include <sys/sx.h> 70d8a7b7a3SRobert Watson #include <sys/sysctl.h> 7182d16d5eSRobert Watson #include <sys/msg.h> 7282d16d5eSRobert Watson #include <sys/sem.h> 7382d16d5eSRobert Watson #include <sys/shm.h> 74d8a7b7a3SRobert Watson 75d8a7b7a3SRobert Watson #include <fs/devfs/devfs.h> 76d8a7b7a3SRobert Watson 77d8a7b7a3SRobert Watson #include <net/bpfdesc.h> 78d8a7b7a3SRobert Watson #include <net/if.h> 79d8a7b7a3SRobert Watson #include <net/if_types.h> 80d8a7b7a3SRobert Watson #include <net/if_var.h> 81d8a7b7a3SRobert Watson 82d8a7b7a3SRobert Watson #include <netinet/in.h> 83a557af22SRobert Watson #include <netinet/in_pcb.h> 84d8a7b7a3SRobert Watson #include <netinet/ip_var.h> 85d8a7b7a3SRobert Watson 862e8c6b26SRobert Watson #include <vm/uma.h> 87d8a7b7a3SRobert Watson #include <vm/vm.h> 88d8a7b7a3SRobert Watson 890efd6615SRobert Watson #include <security/mac/mac_policy.h> 90d8a7b7a3SRobert Watson #include <security/mac_mls/mac_mls.h> 91d8a7b7a3SRobert Watson 927029da5cSPawel Biernacki static SYSCTL_NODE(_security_mac, OID_AUTO, mls, 937029da5cSPawel Biernacki CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 94d8a7b7a3SRobert Watson "TrustedBSD mac_mls policy controls"); 95d8a7b7a3SRobert Watson 963f1a7a90SRobert Watson static int mls_label_size = sizeof(struct mac_mls); 97763bbd2fSRobert Watson SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD, 983f1a7a90SRobert Watson &mls_label_size, 0, "Size of struct mac_mls"); 99763bbd2fSRobert Watson 1003f1a7a90SRobert Watson static int mls_enabled = 1; 101af3b2549SHans Petter Selasky SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RWTUN, &mls_enabled, 0, 1023f1a7a90SRobert Watson "Enforce MAC/MLS policy"); 103d8a7b7a3SRobert Watson 104d8a7b7a3SRobert Watson static int destroyed_not_inited; 105d8a7b7a3SRobert Watson SYSCTL_INT(_security_mac_mls, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 106d8a7b7a3SRobert Watson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 107d8a7b7a3SRobert Watson 1080b9b85b9SRobert Watson static int ptys_equal = 0; 109af3b2549SHans Petter Selasky SYSCTL_INT(_security_mac_mls, OID_AUTO, ptys_equal, CTLFLAG_RWTUN, 1100b9b85b9SRobert Watson &ptys_equal, 0, "Label pty devices as mls/equal on create"); 1110b9b85b9SRobert Watson 112b382fe89SRobert Watson static int revocation_enabled = 0; 113af3b2549SHans Petter Selasky SYSCTL_INT(_security_mac_mls, OID_AUTO, revocation_enabled, CTLFLAG_RWTUN, 114b382fe89SRobert Watson &revocation_enabled, 0, "Revoke access to objects on relabel"); 115d8a7b7a3SRobert Watson 1162a1c79afSRobert Watson static int max_compartments = MAC_MLS_MAX_COMPARTMENTS; 1172a1c79afSRobert Watson SYSCTL_INT(_security_mac_mls, OID_AUTO, max_compartments, CTLFLAG_RD, 1182a1c79afSRobert Watson &max_compartments, 0, "Maximum compartments the policy supports"); 1192a1c79afSRobert Watson 1203f1a7a90SRobert Watson static int mls_slot; 1213f1a7a90SRobert Watson #define SLOT(l) ((struct mac_mls *)mac_label_get((l), mls_slot)) 1223f1a7a90SRobert Watson #define SLOT_SET(l, val) mac_label_set((l), mls_slot, (uintptr_t)(val)) 123d8a7b7a3SRobert Watson 1242e8c6b26SRobert Watson static uma_zone_t zone_mls; 125d8a7b7a3SRobert Watson 1262a1c79afSRobert Watson static __inline int 1272a1c79afSRobert Watson mls_bit_set_empty(u_char *set) { 1282a1c79afSRobert Watson int i; 1292a1c79afSRobert Watson 1302a1c79afSRobert Watson for (i = 0; i < MAC_MLS_MAX_COMPARTMENTS >> 3; i++) 1312a1c79afSRobert Watson if (set[i] != 0) 1322a1c79afSRobert Watson return (0); 1332a1c79afSRobert Watson return (1); 1342a1c79afSRobert Watson } 1352a1c79afSRobert Watson 136d8a7b7a3SRobert Watson static struct mac_mls * 13796adb909SRobert Watson mls_alloc(int flag) 138d8a7b7a3SRobert Watson { 139d8a7b7a3SRobert Watson 1402e8c6b26SRobert Watson return (uma_zalloc(zone_mls, flag | M_ZERO)); 141d8a7b7a3SRobert Watson } 142d8a7b7a3SRobert Watson 143d8a7b7a3SRobert Watson static void 1443f1a7a90SRobert Watson mls_free(struct mac_mls *mm) 145d8a7b7a3SRobert Watson { 146d8a7b7a3SRobert Watson 1473f1a7a90SRobert Watson if (mm != NULL) 1483f1a7a90SRobert Watson uma_zfree(zone_mls, mm); 149d8a7b7a3SRobert Watson else 150d8a7b7a3SRobert Watson atomic_add_int(&destroyed_not_inited, 1); 151d8a7b7a3SRobert Watson } 152d8a7b7a3SRobert Watson 153d8a7b7a3SRobert Watson static int 1543f1a7a90SRobert Watson mls_atmostflags(struct mac_mls *mm, int flags) 155b5f072b5SRobert Watson { 156b5f072b5SRobert Watson 1573f1a7a90SRobert Watson if ((mm->mm_flags & flags) != mm->mm_flags) 158b5f072b5SRobert Watson return (EINVAL); 159b5f072b5SRobert Watson return (0); 160b5f072b5SRobert Watson } 161b5f072b5SRobert Watson 162b5f072b5SRobert Watson static int 1633f1a7a90SRobert Watson mls_dominate_element(struct mac_mls_element *a, struct mac_mls_element *b) 164d8a7b7a3SRobert Watson { 1652a1c79afSRobert Watson int bit; 166d8a7b7a3SRobert Watson 167d8a7b7a3SRobert Watson switch (a->mme_type) { 168d8a7b7a3SRobert Watson case MAC_MLS_TYPE_EQUAL: 169d8a7b7a3SRobert Watson case MAC_MLS_TYPE_HIGH: 170d8a7b7a3SRobert Watson return (1); 171d8a7b7a3SRobert Watson 172d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LOW: 173d8a7b7a3SRobert Watson switch (b->mme_type) { 174d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LEVEL: 175d8a7b7a3SRobert Watson case MAC_MLS_TYPE_HIGH: 176d8a7b7a3SRobert Watson return (0); 177d8a7b7a3SRobert Watson 178d8a7b7a3SRobert Watson case MAC_MLS_TYPE_EQUAL: 179d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LOW: 180d8a7b7a3SRobert Watson return (1); 181d8a7b7a3SRobert Watson 182d8a7b7a3SRobert Watson default: 1833f1a7a90SRobert Watson panic("mls_dominate_element: b->mme_type invalid"); 184d8a7b7a3SRobert Watson } 185d8a7b7a3SRobert Watson 186d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LEVEL: 187d8a7b7a3SRobert Watson switch (b->mme_type) { 188d8a7b7a3SRobert Watson case MAC_MLS_TYPE_EQUAL: 189d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LOW: 190d8a7b7a3SRobert Watson return (1); 191d8a7b7a3SRobert Watson 192d8a7b7a3SRobert Watson case MAC_MLS_TYPE_HIGH: 193d8a7b7a3SRobert Watson return (0); 194d8a7b7a3SRobert Watson 195d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LEVEL: 1962a1c79afSRobert Watson for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) 1972a1c79afSRobert Watson if (!MAC_MLS_BIT_TEST(bit, 1982a1c79afSRobert Watson a->mme_compartments) && 1992a1c79afSRobert Watson MAC_MLS_BIT_TEST(bit, b->mme_compartments)) 2002a1c79afSRobert Watson return (0); 201d8a7b7a3SRobert Watson return (a->mme_level >= b->mme_level); 202d8a7b7a3SRobert Watson 203d8a7b7a3SRobert Watson default: 2043f1a7a90SRobert Watson panic("mls_dominate_element: b->mme_type invalid"); 205d8a7b7a3SRobert Watson } 206d8a7b7a3SRobert Watson 207d8a7b7a3SRobert Watson default: 2083f1a7a90SRobert Watson panic("mls_dominate_element: a->mme_type invalid"); 209d8a7b7a3SRobert Watson } 210d8a7b7a3SRobert Watson 211d8a7b7a3SRobert Watson return (0); 212d8a7b7a3SRobert Watson } 213d8a7b7a3SRobert Watson 214d8a7b7a3SRobert Watson static int 2153f1a7a90SRobert Watson mls_range_in_range(struct mac_mls *rangea, struct mac_mls *rangeb) 216d8a7b7a3SRobert Watson { 217d8a7b7a3SRobert Watson 2183f1a7a90SRobert Watson return (mls_dominate_element(&rangeb->mm_rangehigh, 219d8a7b7a3SRobert Watson &rangea->mm_rangehigh) && 2203f1a7a90SRobert Watson mls_dominate_element(&rangea->mm_rangelow, 221d8a7b7a3SRobert Watson &rangeb->mm_rangelow)); 222d8a7b7a3SRobert Watson } 223d8a7b7a3SRobert Watson 224d8a7b7a3SRobert Watson static int 2253f1a7a90SRobert Watson mls_effective_in_range(struct mac_mls *effective, struct mac_mls *range) 226d8a7b7a3SRobert Watson { 227d8a7b7a3SRobert Watson 228dee57980SRobert Watson KASSERT((effective->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 2293f1a7a90SRobert Watson ("mls_effective_in_range: a not effective")); 230728fbeeaSRobert Watson KASSERT((range->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 2313f1a7a90SRobert Watson ("mls_effective_in_range: b not range")); 232d8a7b7a3SRobert Watson 2333f1a7a90SRobert Watson return (mls_dominate_element(&range->mm_rangehigh, 234dee57980SRobert Watson &effective->mm_effective) && 2353f1a7a90SRobert Watson mls_dominate_element(&effective->mm_effective, 236d8a7b7a3SRobert Watson &range->mm_rangelow)); 237d8a7b7a3SRobert Watson 238d8a7b7a3SRobert Watson return (1); 239d8a7b7a3SRobert Watson } 240d8a7b7a3SRobert Watson 241d8a7b7a3SRobert Watson static int 2423f1a7a90SRobert Watson mls_dominate_effective(struct mac_mls *a, struct mac_mls *b) 243d8a7b7a3SRobert Watson { 244dee57980SRobert Watson KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 2453f1a7a90SRobert Watson ("mls_dominate_effective: a not effective")); 246dee57980SRobert Watson KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 2473f1a7a90SRobert Watson ("mls_dominate_effective: b not effective")); 248d8a7b7a3SRobert Watson 2493f1a7a90SRobert Watson return (mls_dominate_element(&a->mm_effective, &b->mm_effective)); 250d8a7b7a3SRobert Watson } 251d8a7b7a3SRobert Watson 252d8a7b7a3SRobert Watson static int 2533f1a7a90SRobert Watson mls_equal_element(struct mac_mls_element *a, struct mac_mls_element *b) 254d8a7b7a3SRobert Watson { 255d8a7b7a3SRobert Watson 256d8a7b7a3SRobert Watson if (a->mme_type == MAC_MLS_TYPE_EQUAL || 257d8a7b7a3SRobert Watson b->mme_type == MAC_MLS_TYPE_EQUAL) 258d8a7b7a3SRobert Watson return (1); 259d8a7b7a3SRobert Watson 260d8a7b7a3SRobert Watson return (a->mme_type == b->mme_type && a->mme_level == b->mme_level); 261d8a7b7a3SRobert Watson } 262d8a7b7a3SRobert Watson 263d8a7b7a3SRobert Watson static int 2643f1a7a90SRobert Watson mls_equal_effective(struct mac_mls *a, struct mac_mls *b) 265d8a7b7a3SRobert Watson { 266d8a7b7a3SRobert Watson 267dee57980SRobert Watson KASSERT((a->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 2683f1a7a90SRobert Watson ("mls_equal_effective: a not effective")); 269dee57980SRobert Watson KASSERT((b->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 2703f1a7a90SRobert Watson ("mls_equal_effective: b not effective")); 271d8a7b7a3SRobert Watson 2723f1a7a90SRobert Watson return (mls_equal_element(&a->mm_effective, &b->mm_effective)); 273d8a7b7a3SRobert Watson } 274d8a7b7a3SRobert Watson 275d8a7b7a3SRobert Watson static int 2763f1a7a90SRobert Watson mls_contains_equal(struct mac_mls *mm) 277b5f072b5SRobert Watson { 278b5f072b5SRobert Watson 2793f1a7a90SRobert Watson if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 2803f1a7a90SRobert Watson if (mm->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 281b5f072b5SRobert Watson return (1); 282b5f072b5SRobert Watson 2833f1a7a90SRobert Watson if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 2843f1a7a90SRobert Watson if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL) 285b5f072b5SRobert Watson return (1); 2863f1a7a90SRobert Watson if (mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 287b5f072b5SRobert Watson return (1); 288b5f072b5SRobert Watson } 289b5f072b5SRobert Watson 290b5f072b5SRobert Watson return (0); 291b5f072b5SRobert Watson } 292b5f072b5SRobert Watson 293b5f072b5SRobert Watson static int 2943f1a7a90SRobert Watson mls_subject_privileged(struct mac_mls *mm) 295b5f072b5SRobert Watson { 296b5f072b5SRobert Watson 2973f1a7a90SRobert Watson KASSERT((mm->mm_flags & MAC_MLS_FLAGS_BOTH) == MAC_MLS_FLAGS_BOTH, 2983f1a7a90SRobert Watson ("mls_subject_privileged: subject doesn't have both labels")); 299b5f072b5SRobert Watson 300dee57980SRobert Watson /* If the effective is EQUAL, it's ok. */ 3013f1a7a90SRobert Watson if (mm->mm_effective.mme_type == MAC_MLS_TYPE_EQUAL) 302b5f072b5SRobert Watson return (0); 303b5f072b5SRobert Watson 304b5f072b5SRobert Watson /* If either range endpoint is EQUAL, it's ok. */ 3053f1a7a90SRobert Watson if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_EQUAL || 3063f1a7a90SRobert Watson mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_EQUAL) 307b5f072b5SRobert Watson return (0); 308b5f072b5SRobert Watson 309b5f072b5SRobert Watson /* If the range is low-high, it's ok. */ 3103f1a7a90SRobert Watson if (mm->mm_rangelow.mme_type == MAC_MLS_TYPE_LOW && 3113f1a7a90SRobert Watson mm->mm_rangehigh.mme_type == MAC_MLS_TYPE_HIGH) 312b5f072b5SRobert Watson return (0); 313b5f072b5SRobert Watson 314b5f072b5SRobert Watson /* It's not ok. */ 315b5f072b5SRobert Watson return (EPERM); 316b5f072b5SRobert Watson } 317b5f072b5SRobert Watson 318b5f072b5SRobert Watson static int 3193f1a7a90SRobert Watson mls_valid(struct mac_mls *mm) 320d8a7b7a3SRobert Watson { 321d8a7b7a3SRobert Watson 3223f1a7a90SRobert Watson if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 3233f1a7a90SRobert Watson switch (mm->mm_effective.mme_type) { 324d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LEVEL: 325d8a7b7a3SRobert Watson break; 326d8a7b7a3SRobert Watson 327d8a7b7a3SRobert Watson case MAC_MLS_TYPE_EQUAL: 328d8a7b7a3SRobert Watson case MAC_MLS_TYPE_HIGH: 329d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LOW: 3303f1a7a90SRobert Watson if (mm->mm_effective.mme_level != 0 || 3312a1c79afSRobert Watson !MAC_MLS_BIT_SET_EMPTY( 3323f1a7a90SRobert Watson mm->mm_effective.mme_compartments)) 333d8a7b7a3SRobert Watson return (EINVAL); 334d8a7b7a3SRobert Watson break; 335d8a7b7a3SRobert Watson 336d8a7b7a3SRobert Watson default: 337d8a7b7a3SRobert Watson return (EINVAL); 338d8a7b7a3SRobert Watson } 339d8a7b7a3SRobert Watson } else { 3403f1a7a90SRobert Watson if (mm->mm_effective.mme_type != MAC_MLS_TYPE_UNDEF) 341d8a7b7a3SRobert Watson return (EINVAL); 342d8a7b7a3SRobert Watson } 343d8a7b7a3SRobert Watson 3443f1a7a90SRobert Watson if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 3453f1a7a90SRobert Watson switch (mm->mm_rangelow.mme_type) { 346d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LEVEL: 347d8a7b7a3SRobert Watson break; 348d8a7b7a3SRobert Watson 349d8a7b7a3SRobert Watson case MAC_MLS_TYPE_EQUAL: 350d8a7b7a3SRobert Watson case MAC_MLS_TYPE_HIGH: 351d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LOW: 3523f1a7a90SRobert Watson if (mm->mm_rangelow.mme_level != 0 || 3532a1c79afSRobert Watson !MAC_MLS_BIT_SET_EMPTY( 3543f1a7a90SRobert Watson mm->mm_rangelow.mme_compartments)) 355d8a7b7a3SRobert Watson return (EINVAL); 356d8a7b7a3SRobert Watson break; 357d8a7b7a3SRobert Watson 358d8a7b7a3SRobert Watson default: 359d8a7b7a3SRobert Watson return (EINVAL); 360d8a7b7a3SRobert Watson } 361d8a7b7a3SRobert Watson 3623f1a7a90SRobert Watson switch (mm->mm_rangehigh.mme_type) { 363d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LEVEL: 364d8a7b7a3SRobert Watson break; 365d8a7b7a3SRobert Watson 366d8a7b7a3SRobert Watson case MAC_MLS_TYPE_EQUAL: 367d8a7b7a3SRobert Watson case MAC_MLS_TYPE_HIGH: 368d8a7b7a3SRobert Watson case MAC_MLS_TYPE_LOW: 3693f1a7a90SRobert Watson if (mm->mm_rangehigh.mme_level != 0 || 3702a1c79afSRobert Watson !MAC_MLS_BIT_SET_EMPTY( 3713f1a7a90SRobert Watson mm->mm_rangehigh.mme_compartments)) 372d8a7b7a3SRobert Watson return (EINVAL); 373d8a7b7a3SRobert Watson break; 374d8a7b7a3SRobert Watson 375d8a7b7a3SRobert Watson default: 376d8a7b7a3SRobert Watson return (EINVAL); 377d8a7b7a3SRobert Watson } 3783f1a7a90SRobert Watson if (!mls_dominate_element(&mm->mm_rangehigh, 3793f1a7a90SRobert Watson &mm->mm_rangelow)) 380d8a7b7a3SRobert Watson return (EINVAL); 381d8a7b7a3SRobert Watson } else { 3823f1a7a90SRobert Watson if (mm->mm_rangelow.mme_type != MAC_MLS_TYPE_UNDEF || 3833f1a7a90SRobert Watson mm->mm_rangehigh.mme_type != MAC_MLS_TYPE_UNDEF) 384d8a7b7a3SRobert Watson return (EINVAL); 385d8a7b7a3SRobert Watson } 386d8a7b7a3SRobert Watson 387d8a7b7a3SRobert Watson return (0); 388d8a7b7a3SRobert Watson } 389d8a7b7a3SRobert Watson 390d8a7b7a3SRobert Watson static void 3913f1a7a90SRobert Watson mls_set_range(struct mac_mls *mm, u_short typelow, u_short levellow, 3923f1a7a90SRobert Watson u_char *compartmentslow, u_short typehigh, u_short levelhigh, 3933f1a7a90SRobert Watson u_char *compartmentshigh) 394d8a7b7a3SRobert Watson { 395d8a7b7a3SRobert Watson 3963f1a7a90SRobert Watson mm->mm_rangelow.mme_type = typelow; 3973f1a7a90SRobert Watson mm->mm_rangelow.mme_level = levellow; 3982a1c79afSRobert Watson if (compartmentslow != NULL) 39995b85ca3SRobert Watson memcpy(mm->mm_rangelow.mme_compartments, compartmentslow, 4003f1a7a90SRobert Watson sizeof(mm->mm_rangelow.mme_compartments)); 4013f1a7a90SRobert Watson mm->mm_rangehigh.mme_type = typehigh; 4023f1a7a90SRobert Watson mm->mm_rangehigh.mme_level = levelhigh; 4032a1c79afSRobert Watson if (compartmentshigh != NULL) 40495b85ca3SRobert Watson memcpy(mm->mm_rangehigh.mme_compartments, compartmentshigh, 4053f1a7a90SRobert Watson sizeof(mm->mm_rangehigh.mme_compartments)); 4063f1a7a90SRobert Watson mm->mm_flags |= MAC_MLS_FLAG_RANGE; 407d8a7b7a3SRobert Watson } 408d8a7b7a3SRobert Watson 409d8a7b7a3SRobert Watson static void 4103f1a7a90SRobert Watson mls_set_effective(struct mac_mls *mm, u_short type, u_short level, 4112a1c79afSRobert Watson u_char *compartments) 412d8a7b7a3SRobert Watson { 413d8a7b7a3SRobert Watson 4143f1a7a90SRobert Watson mm->mm_effective.mme_type = type; 4153f1a7a90SRobert Watson mm->mm_effective.mme_level = level; 4162a1c79afSRobert Watson if (compartments != NULL) 4173f1a7a90SRobert Watson memcpy(mm->mm_effective.mme_compartments, compartments, 4183f1a7a90SRobert Watson sizeof(mm->mm_effective.mme_compartments)); 4193f1a7a90SRobert Watson mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 420d8a7b7a3SRobert Watson } 421d8a7b7a3SRobert Watson 422d8a7b7a3SRobert Watson static void 4233f1a7a90SRobert Watson mls_copy_range(struct mac_mls *labelfrom, struct mac_mls *labelto) 424d8a7b7a3SRobert Watson { 4252a1c79afSRobert Watson 426d8a7b7a3SRobert Watson KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_RANGE) != 0, 4273f1a7a90SRobert Watson ("mls_copy_range: labelfrom not range")); 428d8a7b7a3SRobert Watson 429d8a7b7a3SRobert Watson labelto->mm_rangelow = labelfrom->mm_rangelow; 430d8a7b7a3SRobert Watson labelto->mm_rangehigh = labelfrom->mm_rangehigh; 431d8a7b7a3SRobert Watson labelto->mm_flags |= MAC_MLS_FLAG_RANGE; 432d8a7b7a3SRobert Watson } 433d8a7b7a3SRobert Watson 434d8a7b7a3SRobert Watson static void 4353f1a7a90SRobert Watson mls_copy_effective(struct mac_mls *labelfrom, struct mac_mls *labelto) 436d8a7b7a3SRobert Watson { 437d8a7b7a3SRobert Watson 438dee57980SRobert Watson KASSERT((labelfrom->mm_flags & MAC_MLS_FLAG_EFFECTIVE) != 0, 4393f1a7a90SRobert Watson ("mls_copy_effective: labelfrom not effective")); 440d8a7b7a3SRobert Watson 441dee57980SRobert Watson labelto->mm_effective = labelfrom->mm_effective; 442dee57980SRobert Watson labelto->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 443d8a7b7a3SRobert Watson } 444d8a7b7a3SRobert Watson 44536cf29fdSRobert Watson static void 4463f1a7a90SRobert Watson mls_copy(struct mac_mls *source, struct mac_mls *dest) 44736cf29fdSRobert Watson { 44836cf29fdSRobert Watson 449dee57980SRobert Watson if (source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) 4503f1a7a90SRobert Watson mls_copy_effective(source, dest); 45136cf29fdSRobert Watson if (source->mm_flags & MAC_MLS_FLAG_RANGE) 4523f1a7a90SRobert Watson mls_copy_range(source, dest); 45336cf29fdSRobert Watson } 45436cf29fdSRobert Watson 455d8a7b7a3SRobert Watson /* 456d8a7b7a3SRobert Watson * Policy module operations. 457d8a7b7a3SRobert Watson */ 458d8a7b7a3SRobert Watson static void 4593f1a7a90SRobert Watson mls_init(struct mac_policy_conf *conf) 460d8a7b7a3SRobert Watson { 461d8a7b7a3SRobert Watson 4622e8c6b26SRobert Watson zone_mls = uma_zcreate("mac_mls", sizeof(struct mac_mls), NULL, 4632e8c6b26SRobert Watson NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 464d8a7b7a3SRobert Watson } 465d8a7b7a3SRobert Watson 466d8a7b7a3SRobert Watson /* 467d8a7b7a3SRobert Watson * Label operations. 468d8a7b7a3SRobert Watson */ 469d8a7b7a3SRobert Watson static void 4703f1a7a90SRobert Watson mls_init_label(struct label *label) 471d8a7b7a3SRobert Watson { 472d8a7b7a3SRobert Watson 4731477f588SAlexander Kabaev SLOT_SET(label, mls_alloc(M_WAITOK)); 474d8a7b7a3SRobert Watson } 475d8a7b7a3SRobert Watson 476d8a7b7a3SRobert Watson static int 4773f1a7a90SRobert Watson mls_init_label_waitcheck(struct label *label, int flag) 478d8a7b7a3SRobert Watson { 479d8a7b7a3SRobert Watson 4801477f588SAlexander Kabaev SLOT_SET(label, mls_alloc(flag)); 481d8a7b7a3SRobert Watson if (SLOT(label) == NULL) 482d8a7b7a3SRobert Watson return (ENOMEM); 483d8a7b7a3SRobert Watson 484d8a7b7a3SRobert Watson return (0); 485d8a7b7a3SRobert Watson } 486d8a7b7a3SRobert Watson 487d8a7b7a3SRobert Watson static void 4883f1a7a90SRobert Watson mls_destroy_label(struct label *label) 489d8a7b7a3SRobert Watson { 490d8a7b7a3SRobert Watson 491d8a7b7a3SRobert Watson mls_free(SLOT(label)); 4921477f588SAlexander Kabaev SLOT_SET(label, NULL); 493d8a7b7a3SRobert Watson } 494d8a7b7a3SRobert Watson 49524e8d0d0SRobert Watson /* 4963f1a7a90SRobert Watson * mls_element_to_string() accepts an sbuf and MLS element. It converts the 4973f1a7a90SRobert Watson * MLS element to a string and stores the result in the sbuf; if there isn't 4983f1a7a90SRobert Watson * space in the sbuf, -1 is returned. 49924e8d0d0SRobert Watson */ 50005e830f1SRobert Watson static int 5013f1a7a90SRobert Watson mls_element_to_string(struct sbuf *sb, struct mac_mls_element *element) 50224e8d0d0SRobert Watson { 50305e830f1SRobert Watson int i, first; 50424e8d0d0SRobert Watson 50524e8d0d0SRobert Watson switch (element->mme_type) { 50624e8d0d0SRobert Watson case MAC_MLS_TYPE_HIGH: 50705e830f1SRobert Watson return (sbuf_printf(sb, "high")); 50824e8d0d0SRobert Watson 50924e8d0d0SRobert Watson case MAC_MLS_TYPE_LOW: 51005e830f1SRobert Watson return (sbuf_printf(sb, "low")); 51124e8d0d0SRobert Watson 51224e8d0d0SRobert Watson case MAC_MLS_TYPE_EQUAL: 51305e830f1SRobert Watson return (sbuf_printf(sb, "equal")); 51424e8d0d0SRobert Watson 51524e8d0d0SRobert Watson case MAC_MLS_TYPE_LEVEL: 51605e830f1SRobert Watson if (sbuf_printf(sb, "%d", element->mme_level) == -1) 51705e830f1SRobert Watson return (-1); 51805e830f1SRobert Watson 51905e830f1SRobert Watson first = 1; 52005e830f1SRobert Watson for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) { 52105e830f1SRobert Watson if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) { 52205e830f1SRobert Watson if (first) { 52305e830f1SRobert Watson if (sbuf_putc(sb, ':') == -1) 52405e830f1SRobert Watson return (-1); 52505e830f1SRobert Watson if (sbuf_printf(sb, "%d", i) == -1) 52605e830f1SRobert Watson return (-1); 52705e830f1SRobert Watson first = 0; 52805e830f1SRobert Watson } else { 52905e830f1SRobert Watson if (sbuf_printf(sb, "+%d", i) == -1) 53005e830f1SRobert Watson return (-1); 53124e8d0d0SRobert Watson } 53205e830f1SRobert Watson } 53305e830f1SRobert Watson } 53405e830f1SRobert Watson return (0); 53524e8d0d0SRobert Watson 53624e8d0d0SRobert Watson default: 5373f1a7a90SRobert Watson panic("mls_element_to_string: invalid type (%d)", 53824e8d0d0SRobert Watson element->mme_type); 53924e8d0d0SRobert Watson } 54024e8d0d0SRobert Watson } 54124e8d0d0SRobert Watson 54205e830f1SRobert Watson /* 5433f1a7a90SRobert Watson * mls_to_string() converts an MLS label to a string, and places the results 5443f1a7a90SRobert Watson * in the passed sbuf. It returns 0 on success, or EINVAL if there isn't 5453f1a7a90SRobert Watson * room in the sbuf. Note: the sbuf will be modified even in a failure case, 5463f1a7a90SRobert Watson * so the caller may need to revert the sbuf by restoring the offset if 5473f1a7a90SRobert Watson * that's undesired. 54805e830f1SRobert Watson */ 54905e830f1SRobert Watson static int 5503f1a7a90SRobert Watson mls_to_string(struct sbuf *sb, struct mac_mls *mm) 55124e8d0d0SRobert Watson { 55224e8d0d0SRobert Watson 5533f1a7a90SRobert Watson if (mm->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 5543f1a7a90SRobert Watson if (mls_element_to_string(sb, &mm->mm_effective) == -1) 55524e8d0d0SRobert Watson return (EINVAL); 55624e8d0d0SRobert Watson } 55724e8d0d0SRobert Watson 5583f1a7a90SRobert Watson if (mm->mm_flags & MAC_MLS_FLAG_RANGE) { 559f51e5803SRobert Watson if (sbuf_putc(sb, '(') == -1) 56024e8d0d0SRobert Watson return (EINVAL); 56124e8d0d0SRobert Watson 5623f1a7a90SRobert Watson if (mls_element_to_string(sb, &mm->mm_rangelow) == -1) 56324e8d0d0SRobert Watson return (EINVAL); 56424e8d0d0SRobert Watson 565f51e5803SRobert Watson if (sbuf_putc(sb, '-') == -1) 56624e8d0d0SRobert Watson return (EINVAL); 56724e8d0d0SRobert Watson 5683f1a7a90SRobert Watson if (mls_element_to_string(sb, &mm->mm_rangehigh) == -1) 56924e8d0d0SRobert Watson return (EINVAL); 57024e8d0d0SRobert Watson 571f51e5803SRobert Watson if (sbuf_putc(sb, ')') == -1) 57224e8d0d0SRobert Watson return (EINVAL); 57324e8d0d0SRobert Watson } 57424e8d0d0SRobert Watson 57524e8d0d0SRobert Watson return (0); 57624e8d0d0SRobert Watson } 57724e8d0d0SRobert Watson 578d8a7b7a3SRobert Watson static int 5793f1a7a90SRobert Watson mls_externalize_label(struct label *label, char *element_name, 580f51e5803SRobert Watson struct sbuf *sb, int *claimed) 58124e8d0d0SRobert Watson { 5823f1a7a90SRobert Watson struct mac_mls *mm; 58324e8d0d0SRobert Watson 58424e8d0d0SRobert Watson if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 58524e8d0d0SRobert Watson return (0); 58624e8d0d0SRobert Watson 58724e8d0d0SRobert Watson (*claimed)++; 58824e8d0d0SRobert Watson 5893f1a7a90SRobert Watson mm = SLOT(label); 59024e8d0d0SRobert Watson 5913f1a7a90SRobert Watson return (mls_to_string(sb, mm)); 59224e8d0d0SRobert Watson } 59324e8d0d0SRobert Watson 59424e8d0d0SRobert Watson static int 5953f1a7a90SRobert Watson mls_parse_element(struct mac_mls_element *element, char *string) 596d8a7b7a3SRobert Watson { 5977792fe57SRobert Watson char *compartment, *end, *level; 5987792fe57SRobert Watson int value; 59924e8d0d0SRobert Watson 6003f1a7a90SRobert Watson if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { 60124e8d0d0SRobert Watson element->mme_type = MAC_MLS_TYPE_HIGH; 60224e8d0d0SRobert Watson element->mme_level = MAC_MLS_TYPE_UNDEF; 6033f1a7a90SRobert Watson } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { 60424e8d0d0SRobert Watson element->mme_type = MAC_MLS_TYPE_LOW; 60524e8d0d0SRobert Watson element->mme_level = MAC_MLS_TYPE_UNDEF; 60624e8d0d0SRobert Watson } else if (strcmp(string, "equal") == 0 || 60724e8d0d0SRobert Watson strcmp(string, "eq") == 0) { 60824e8d0d0SRobert Watson element->mme_type = MAC_MLS_TYPE_EQUAL; 60924e8d0d0SRobert Watson element->mme_level = MAC_MLS_TYPE_UNDEF; 61024e8d0d0SRobert Watson } else { 61124e8d0d0SRobert Watson element->mme_type = MAC_MLS_TYPE_LEVEL; 61224e8d0d0SRobert Watson 6137792fe57SRobert Watson /* 6147792fe57SRobert Watson * Numeric level piece of the element. 6157792fe57SRobert Watson */ 6167792fe57SRobert Watson level = strsep(&string, ":"); 6177792fe57SRobert Watson value = strtol(level, &end, 10); 6187792fe57SRobert Watson if (end == level || *end != '\0') 61924e8d0d0SRobert Watson return (EINVAL); 6207792fe57SRobert Watson if (value < 0 || value > 65535) 6217792fe57SRobert Watson return (EINVAL); 6227792fe57SRobert Watson element->mme_level = value; 6237792fe57SRobert Watson 6247792fe57SRobert Watson /* 6253f1a7a90SRobert Watson * Optional compartment piece of the element. If none are 6263f1a7a90SRobert Watson * included, we assume that the label has no compartments. 6277792fe57SRobert Watson */ 6287792fe57SRobert Watson if (string == NULL) 62924e8d0d0SRobert Watson return (0); 6307792fe57SRobert Watson if (*string == '\0') 63124e8d0d0SRobert Watson return (0); 63224e8d0d0SRobert Watson 6337792fe57SRobert Watson while ((compartment = strsep(&string, "+")) != NULL) { 6347792fe57SRobert Watson value = strtol(compartment, &end, 10); 6357792fe57SRobert Watson if (compartment == end || *end != '\0') 63624e8d0d0SRobert Watson return (EINVAL); 6377792fe57SRobert Watson if (value < 1 || value > MAC_MLS_MAX_COMPARTMENTS) 63824e8d0d0SRobert Watson return (EINVAL); 6397792fe57SRobert Watson MAC_MLS_BIT_SET(value, element->mme_compartments); 64024e8d0d0SRobert Watson } 64124e8d0d0SRobert Watson } 64224e8d0d0SRobert Watson 64324e8d0d0SRobert Watson return (0); 64424e8d0d0SRobert Watson } 64524e8d0d0SRobert Watson 64624e8d0d0SRobert Watson /* 6473f1a7a90SRobert Watson * Note: destructively consumes the string, make a local copy before calling 6483f1a7a90SRobert Watson * if that's a problem. 64924e8d0d0SRobert Watson */ 65024e8d0d0SRobert Watson static int 6513f1a7a90SRobert Watson mls_parse(struct mac_mls *mm, char *string) 65224e8d0d0SRobert Watson { 653dee57980SRobert Watson char *rangehigh, *rangelow, *effective; 654d8a7b7a3SRobert Watson int error; 655d8a7b7a3SRobert Watson 656dee57980SRobert Watson effective = strsep(&string, "("); 657dee57980SRobert Watson if (*effective == '\0') 658dee57980SRobert Watson effective = NULL; 6597792fe57SRobert Watson 6607792fe57SRobert Watson if (string != NULL) { 6617792fe57SRobert Watson rangelow = strsep(&string, "-"); 6627792fe57SRobert Watson if (string == NULL) 6637792fe57SRobert Watson return (EINVAL); 6647792fe57SRobert Watson rangehigh = strsep(&string, ")"); 6657792fe57SRobert Watson if (string == NULL) 6667792fe57SRobert Watson return (EINVAL); 6677792fe57SRobert Watson if (*string != '\0') 6687792fe57SRobert Watson return (EINVAL); 669c2ea1fecSRobert Watson } else { 670c2ea1fecSRobert Watson rangelow = NULL; 671c2ea1fecSRobert Watson rangehigh = NULL; 6727792fe57SRobert Watson } 6737792fe57SRobert Watson 67424e8d0d0SRobert Watson KASSERT((rangelow != NULL && rangehigh != NULL) || 67524e8d0d0SRobert Watson (rangelow == NULL && rangehigh == NULL), 6763f1a7a90SRobert Watson ("mls_parse: range mismatch")); 67724e8d0d0SRobert Watson 6783f1a7a90SRobert Watson bzero(mm, sizeof(*mm)); 679dee57980SRobert Watson if (effective != NULL) { 6803f1a7a90SRobert Watson error = mls_parse_element(&mm->mm_effective, effective); 68124e8d0d0SRobert Watson if (error) 68224e8d0d0SRobert Watson return (error); 6833f1a7a90SRobert Watson mm->mm_flags |= MAC_MLS_FLAG_EFFECTIVE; 68424e8d0d0SRobert Watson } 68524e8d0d0SRobert Watson 68624e8d0d0SRobert Watson if (rangelow != NULL) { 68795b85ca3SRobert Watson error = mls_parse_element(&mm->mm_rangelow, rangelow); 68824e8d0d0SRobert Watson if (error) 68924e8d0d0SRobert Watson return (error); 69095b85ca3SRobert Watson error = mls_parse_element(&mm->mm_rangehigh, rangehigh); 69124e8d0d0SRobert Watson if (error) 69224e8d0d0SRobert Watson return (error); 6933f1a7a90SRobert Watson mm->mm_flags |= MAC_MLS_FLAG_RANGE; 69424e8d0d0SRobert Watson } 695d8a7b7a3SRobert Watson 6963f1a7a90SRobert Watson error = mls_valid(mm); 697d8a7b7a3SRobert Watson if (error) 698d8a7b7a3SRobert Watson return (error); 699d8a7b7a3SRobert Watson 70024e8d0d0SRobert Watson return (0); 70124e8d0d0SRobert Watson } 70224e8d0d0SRobert Watson 70324e8d0d0SRobert Watson static int 7043f1a7a90SRobert Watson mls_internalize_label(struct label *label, char *element_name, 70524e8d0d0SRobert Watson char *element_data, int *claimed) 70624e8d0d0SRobert Watson { 7073f1a7a90SRobert Watson struct mac_mls *mm, mm_temp; 70824e8d0d0SRobert Watson int error; 70924e8d0d0SRobert Watson 71024e8d0d0SRobert Watson if (strcmp(MAC_MLS_LABEL_NAME, element_name) != 0) 71124e8d0d0SRobert Watson return (0); 71224e8d0d0SRobert Watson 71324e8d0d0SRobert Watson (*claimed)++; 71424e8d0d0SRobert Watson 7153f1a7a90SRobert Watson error = mls_parse(&mm_temp, element_data); 71624e8d0d0SRobert Watson if (error) 71724e8d0d0SRobert Watson return (error); 71824e8d0d0SRobert Watson 7193f1a7a90SRobert Watson mm = SLOT(label); 7203f1a7a90SRobert Watson *mm = mm_temp; 721d8a7b7a3SRobert Watson 722d8a7b7a3SRobert Watson return (0); 723d8a7b7a3SRobert Watson } 724d8a7b7a3SRobert Watson 72524e8d0d0SRobert Watson static void 7263f1a7a90SRobert Watson mls_copy_label(struct label *src, struct label *dest) 72724e8d0d0SRobert Watson { 72824e8d0d0SRobert Watson 72924e8d0d0SRobert Watson *SLOT(dest) = *SLOT(src); 73024e8d0d0SRobert Watson } 73124e8d0d0SRobert Watson 732d8a7b7a3SRobert Watson /* 733eb320b0eSRobert Watson * Object-specific entry point implementations are sorted alphabetically by 734eb320b0eSRobert Watson * object type name and then by operation. 735d8a7b7a3SRobert Watson */ 736d8a7b7a3SRobert Watson static int 7373f1a7a90SRobert Watson mls_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 73878007886SRobert Watson struct ifnet *ifp, struct label *ifplabel) 739d8a7b7a3SRobert Watson { 740d8a7b7a3SRobert Watson struct mac_mls *a, *b; 741d8a7b7a3SRobert Watson 7423f1a7a90SRobert Watson if (!mls_enabled) 743d8a7b7a3SRobert Watson return (0); 744d8a7b7a3SRobert Watson 74578007886SRobert Watson a = SLOT(dlabel); 74678007886SRobert Watson b = SLOT(ifplabel); 747d8a7b7a3SRobert Watson 7483f1a7a90SRobert Watson if (mls_equal_effective(a, b)) 749d8a7b7a3SRobert Watson return (0); 750d8a7b7a3SRobert Watson return (EACCES); 751d8a7b7a3SRobert Watson } 752d8a7b7a3SRobert Watson 753eb320b0eSRobert Watson static void 754eb320b0eSRobert Watson mls_bpfdesc_create(struct ucred *cred, struct bpf_d *d, struct label *dlabel) 755eb320b0eSRobert Watson { 756eb320b0eSRobert Watson struct mac_mls *source, *dest; 757eb320b0eSRobert Watson 758eb320b0eSRobert Watson source = SLOT(cred->cr_label); 759eb320b0eSRobert Watson dest = SLOT(dlabel); 760eb320b0eSRobert Watson 761eb320b0eSRobert Watson mls_copy_effective(source, dest); 762eb320b0eSRobert Watson } 763eb320b0eSRobert Watson 764eb320b0eSRobert Watson static void 765eb320b0eSRobert Watson mls_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 766eb320b0eSRobert Watson struct mbuf *m, struct label *mlabel) 767eb320b0eSRobert Watson { 768eb320b0eSRobert Watson struct mac_mls *source, *dest; 769eb320b0eSRobert Watson 770eb320b0eSRobert Watson source = SLOT(dlabel); 771eb320b0eSRobert Watson dest = SLOT(mlabel); 772eb320b0eSRobert Watson 773eb320b0eSRobert Watson mls_copy_effective(source, dest); 774eb320b0eSRobert Watson } 775eb320b0eSRobert Watson 776212ab0cfSRobert Watson static void 777212ab0cfSRobert Watson mls_cred_associate_nfsd(struct ucred *cred) 778212ab0cfSRobert Watson { 779212ab0cfSRobert Watson struct mac_mls *label; 780212ab0cfSRobert Watson 781212ab0cfSRobert Watson label = SLOT(cred->cr_label); 782212ab0cfSRobert Watson mls_set_effective(label, MAC_MLS_TYPE_LOW, 0, NULL); 783212ab0cfSRobert Watson mls_set_range(label, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 784212ab0cfSRobert Watson NULL); 785212ab0cfSRobert Watson } 786212ab0cfSRobert Watson 787d8a7b7a3SRobert Watson static int 7883f1a7a90SRobert Watson mls_cred_check_relabel(struct ucred *cred, struct label *newlabel) 789d8a7b7a3SRobert Watson { 790d8a7b7a3SRobert Watson struct mac_mls *subj, *new; 791b5f072b5SRobert Watson int error; 792d8a7b7a3SRobert Watson 793eca8a663SRobert Watson subj = SLOT(cred->cr_label); 794d8a7b7a3SRobert Watson new = SLOT(newlabel); 795d8a7b7a3SRobert Watson 796b5f072b5SRobert Watson /* 7973f1a7a90SRobert Watson * If there is an MLS label update for the credential, it may be an 7983f1a7a90SRobert Watson * update of effective, range, or both. 799b5f072b5SRobert Watson */ 800b5f072b5SRobert Watson error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 801b5f072b5SRobert Watson if (error) 802b5f072b5SRobert Watson return (error); 803d8a7b7a3SRobert Watson 804d8a7b7a3SRobert Watson /* 805b5f072b5SRobert Watson * If the MLS label is to be changed, authorize as appropriate. 806d8a7b7a3SRobert Watson */ 807b5f072b5SRobert Watson if (new->mm_flags & MAC_MLS_FLAGS_BOTH) { 808d8a7b7a3SRobert Watson /* 8093f1a7a90SRobert Watson * If the change request modifies both the MLS label 8103f1a7a90SRobert Watson * effective and range, check that the new effective will be 8113f1a7a90SRobert Watson * in the new range. 81212613c76SRobert Watson */ 81312613c76SRobert Watson if ((new->mm_flags & MAC_MLS_FLAGS_BOTH) == 8143f1a7a90SRobert Watson MAC_MLS_FLAGS_BOTH && !mls_effective_in_range(new, new)) 81512613c76SRobert Watson return (EINVAL); 81612613c76SRobert Watson 81712613c76SRobert Watson /* 8183f1a7a90SRobert Watson * To change the MLS effective label on a credential, the new 8193f1a7a90SRobert Watson * effective label must be in the current range. 820d8a7b7a3SRobert Watson */ 821dee57980SRobert Watson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE && 8223f1a7a90SRobert Watson !mls_effective_in_range(new, subj)) 823d8a7b7a3SRobert Watson return (EPERM); 824d8a7b7a3SRobert Watson 825d8a7b7a3SRobert Watson /* 8263f1a7a90SRobert Watson * To change the MLS range label on a credential, the new 8273f1a7a90SRobert Watson * range must be in the current range. 828d8a7b7a3SRobert Watson */ 829b5f072b5SRobert Watson if (new->mm_flags & MAC_MLS_FLAG_RANGE && 8303f1a7a90SRobert Watson !mls_range_in_range(new, subj)) 831d8a7b7a3SRobert Watson return (EPERM); 832d8a7b7a3SRobert Watson 833d8a7b7a3SRobert Watson /* 8343f1a7a90SRobert Watson * To have EQUAL in any component of the new credential MLS 8353f1a7a90SRobert Watson * label, the subject must already have EQUAL in their label. 836d8a7b7a3SRobert Watson */ 8373f1a7a90SRobert Watson if (mls_contains_equal(new)) { 8383f1a7a90SRobert Watson error = mls_subject_privileged(subj); 839b5f072b5SRobert Watson if (error) 840b5f072b5SRobert Watson return (error); 841b5f072b5SRobert Watson } 842b5f072b5SRobert Watson } 843d8a7b7a3SRobert Watson 844d8a7b7a3SRobert Watson return (0); 845d8a7b7a3SRobert Watson } 846d8a7b7a3SRobert Watson 847d8a7b7a3SRobert Watson static int 8483f1a7a90SRobert Watson mls_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 849d8a7b7a3SRobert Watson { 850d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 851d8a7b7a3SRobert Watson 8523f1a7a90SRobert Watson if (!mls_enabled) 853d8a7b7a3SRobert Watson return (0); 854d8a7b7a3SRobert Watson 85578007886SRobert Watson subj = SLOT(cr1->cr_label); 85678007886SRobert Watson obj = SLOT(cr2->cr_label); 857d8a7b7a3SRobert Watson 858d8a7b7a3SRobert Watson /* XXX: range */ 8593f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 860d8a7b7a3SRobert Watson return (ESRCH); 861d8a7b7a3SRobert Watson 862d8a7b7a3SRobert Watson return (0); 863d8a7b7a3SRobert Watson } 864d8a7b7a3SRobert Watson 865eb320b0eSRobert Watson static void 866212ab0cfSRobert Watson mls_cred_create_init(struct ucred *cred) 867212ab0cfSRobert Watson { 868212ab0cfSRobert Watson struct mac_mls *dest; 869212ab0cfSRobert Watson 870212ab0cfSRobert Watson dest = SLOT(cred->cr_label); 871212ab0cfSRobert Watson 872212ab0cfSRobert Watson mls_set_effective(dest, MAC_MLS_TYPE_LOW, 0, NULL); 873212ab0cfSRobert Watson mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 874212ab0cfSRobert Watson NULL); 875212ab0cfSRobert Watson } 876212ab0cfSRobert Watson 877212ab0cfSRobert Watson static void 878212ab0cfSRobert Watson mls_cred_create_swapper(struct ucred *cred) 879212ab0cfSRobert Watson { 880212ab0cfSRobert Watson struct mac_mls *dest; 881212ab0cfSRobert Watson 882212ab0cfSRobert Watson dest = SLOT(cred->cr_label); 883212ab0cfSRobert Watson 884212ab0cfSRobert Watson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 885212ab0cfSRobert Watson mls_set_range(dest, MAC_MLS_TYPE_LOW, 0, NULL, MAC_MLS_TYPE_HIGH, 0, 886212ab0cfSRobert Watson NULL); 887212ab0cfSRobert Watson } 888212ab0cfSRobert Watson 889212ab0cfSRobert Watson static void 890eb320b0eSRobert Watson mls_cred_relabel(struct ucred *cred, struct label *newlabel) 891eb320b0eSRobert Watson { 892eb320b0eSRobert Watson struct mac_mls *source, *dest; 893eb320b0eSRobert Watson 894eb320b0eSRobert Watson source = SLOT(newlabel); 895eb320b0eSRobert Watson dest = SLOT(cred->cr_label); 896eb320b0eSRobert Watson 897eb320b0eSRobert Watson mls_copy(source, dest); 898eb320b0eSRobert Watson } 899eb320b0eSRobert Watson 900eb320b0eSRobert Watson static void 901eb320b0eSRobert Watson mls_devfs_create_device(struct ucred *cred, struct mount *mp, 902eb320b0eSRobert Watson struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 903eb320b0eSRobert Watson { 904eb320b0eSRobert Watson struct mac_mls *mm; 9057870adb6SEd Schouten const char *dn; 906eb320b0eSRobert Watson int mls_type; 907eb320b0eSRobert Watson 908eb320b0eSRobert Watson mm = SLOT(delabel); 9097870adb6SEd Schouten dn = devtoname(dev); 9107870adb6SEd Schouten if (strcmp(dn, "null") == 0 || 9117870adb6SEd Schouten strcmp(dn, "zero") == 0 || 9127870adb6SEd Schouten strcmp(dn, "random") == 0 || 9137870adb6SEd Schouten strncmp(dn, "fd/", strlen("fd/")) == 0) 914eb320b0eSRobert Watson mls_type = MAC_MLS_TYPE_EQUAL; 9157870adb6SEd Schouten else if (strcmp(dn, "kmem") == 0 || 9167870adb6SEd Schouten strcmp(dn, "mem") == 0) 917eb320b0eSRobert Watson mls_type = MAC_MLS_TYPE_HIGH; 918eb320b0eSRobert Watson else if (ptys_equal && 9197870adb6SEd Schouten (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 9207870adb6SEd Schouten strncmp(dn, "pts/", strlen("pts/")) == 0 || 9217870adb6SEd Schouten strncmp(dn, "ptyp", strlen("ptyp")) == 0)) 922eb320b0eSRobert Watson mls_type = MAC_MLS_TYPE_EQUAL; 923eb320b0eSRobert Watson else 924eb320b0eSRobert Watson mls_type = MAC_MLS_TYPE_LOW; 925eb320b0eSRobert Watson mls_set_effective(mm, mls_type, 0, NULL); 926eb320b0eSRobert Watson } 927eb320b0eSRobert Watson 928eb320b0eSRobert Watson static void 929eb320b0eSRobert Watson mls_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 930eb320b0eSRobert Watson struct devfs_dirent *de, struct label *delabel) 931eb320b0eSRobert Watson { 932eb320b0eSRobert Watson struct mac_mls *mm; 933eb320b0eSRobert Watson 934eb320b0eSRobert Watson mm = SLOT(delabel); 935eb320b0eSRobert Watson mls_set_effective(mm, MAC_MLS_TYPE_LOW, 0, NULL); 936eb320b0eSRobert Watson } 937eb320b0eSRobert Watson 938eb320b0eSRobert Watson static void 939eb320b0eSRobert Watson mls_devfs_create_symlink(struct ucred *cred, struct mount *mp, 940eb320b0eSRobert Watson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 941eb320b0eSRobert Watson struct label *delabel) 942eb320b0eSRobert Watson { 943eb320b0eSRobert Watson struct mac_mls *source, *dest; 944eb320b0eSRobert Watson 945eb320b0eSRobert Watson source = SLOT(cred->cr_label); 946eb320b0eSRobert Watson dest = SLOT(delabel); 947eb320b0eSRobert Watson 948eb320b0eSRobert Watson mls_copy_effective(source, dest); 949eb320b0eSRobert Watson } 950eb320b0eSRobert Watson 951eb320b0eSRobert Watson static void 952eb320b0eSRobert Watson mls_devfs_update(struct mount *mp, struct devfs_dirent *de, 953eb320b0eSRobert Watson struct label *delabel, struct vnode *vp, struct label *vplabel) 954eb320b0eSRobert Watson { 955eb320b0eSRobert Watson struct mac_mls *source, *dest; 956eb320b0eSRobert Watson 957eb320b0eSRobert Watson source = SLOT(vplabel); 958eb320b0eSRobert Watson dest = SLOT(delabel); 959eb320b0eSRobert Watson 960eb320b0eSRobert Watson mls_copy_effective(source, dest); 961eb320b0eSRobert Watson } 962eb320b0eSRobert Watson 963eb320b0eSRobert Watson static void 964eb320b0eSRobert Watson mls_devfs_vnode_associate(struct mount *mp, struct label *mplabel, 965eb320b0eSRobert Watson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 966eb320b0eSRobert Watson struct label *vplabel) 967eb320b0eSRobert Watson { 968eb320b0eSRobert Watson struct mac_mls *source, *dest; 969eb320b0eSRobert Watson 970eb320b0eSRobert Watson source = SLOT(delabel); 971eb320b0eSRobert Watson dest = SLOT(vplabel); 972eb320b0eSRobert Watson 973eb320b0eSRobert Watson mls_copy_effective(source, dest); 974eb320b0eSRobert Watson } 975eb320b0eSRobert Watson 976d8a7b7a3SRobert Watson static int 9773f1a7a90SRobert Watson mls_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 97878007886SRobert Watson struct label *ifplabel, struct label *newlabel) 979d8a7b7a3SRobert Watson { 980d8a7b7a3SRobert Watson struct mac_mls *subj, *new; 981b5f072b5SRobert Watson int error; 982d8a7b7a3SRobert Watson 983eca8a663SRobert Watson subj = SLOT(cred->cr_label); 984d8a7b7a3SRobert Watson new = SLOT(newlabel); 985d8a7b7a3SRobert Watson 986b5f072b5SRobert Watson /* 9873f1a7a90SRobert Watson * If there is an MLS label update for the interface, it may be an 9883f1a7a90SRobert Watson * update of effective, range, or both. 989b5f072b5SRobert Watson */ 990b5f072b5SRobert Watson error = mls_atmostflags(new, MAC_MLS_FLAGS_BOTH); 991b5f072b5SRobert Watson if (error) 992b5f072b5SRobert Watson return (error); 993d8a7b7a3SRobert Watson 994b5f072b5SRobert Watson /* 99513031647SRobert Watson * Relabeling network interfaces requires MLS privilege. 996b5f072b5SRobert Watson */ 9975ac3b035SRobert Watson return (mls_subject_privileged(subj)); 998d8a7b7a3SRobert Watson } 999d8a7b7a3SRobert Watson 1000d8a7b7a3SRobert Watson static int 10013f1a7a90SRobert Watson mls_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 100278007886SRobert Watson struct mbuf *m, struct label *mlabel) 1003d8a7b7a3SRobert Watson { 1004d8a7b7a3SRobert Watson struct mac_mls *p, *i; 1005d8a7b7a3SRobert Watson 10063f1a7a90SRobert Watson if (!mls_enabled) 1007d8a7b7a3SRobert Watson return (0); 1008d8a7b7a3SRobert Watson 100978007886SRobert Watson p = SLOT(mlabel); 101078007886SRobert Watson i = SLOT(ifplabel); 1011d8a7b7a3SRobert Watson 10123f1a7a90SRobert Watson return (mls_effective_in_range(p, i) ? 0 : EACCES); 1013d8a7b7a3SRobert Watson } 1014d8a7b7a3SRobert Watson 1015eb320b0eSRobert Watson static void 1016eb320b0eSRobert Watson mls_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1017eb320b0eSRobert Watson { 1018eb320b0eSRobert Watson struct mac_mls *dest; 1019eb320b0eSRobert Watson int type; 1020eb320b0eSRobert Watson 1021eb320b0eSRobert Watson dest = SLOT(ifplabel); 1022eb320b0eSRobert Watson 1023*30af2c13SJustin Hibbits if (if_gettype(ifp) == IFT_LOOP) 1024eb320b0eSRobert Watson type = MAC_MLS_TYPE_EQUAL; 1025eb320b0eSRobert Watson else 1026eb320b0eSRobert Watson type = MAC_MLS_TYPE_LOW; 1027eb320b0eSRobert Watson 1028eb320b0eSRobert Watson mls_set_effective(dest, type, 0, NULL); 1029eb320b0eSRobert Watson mls_set_range(dest, type, 0, NULL, type, 0, NULL); 1030eb320b0eSRobert Watson } 1031eb320b0eSRobert Watson 1032eb320b0eSRobert Watson static void 1033eb320b0eSRobert Watson mls_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1034eb320b0eSRobert Watson struct mbuf *m, struct label *mlabel) 1035eb320b0eSRobert Watson { 1036eb320b0eSRobert Watson struct mac_mls *source, *dest; 1037eb320b0eSRobert Watson 1038eb320b0eSRobert Watson source = SLOT(ifplabel); 1039eb320b0eSRobert Watson dest = SLOT(mlabel); 1040eb320b0eSRobert Watson 1041eb320b0eSRobert Watson mls_copy_effective(source, dest); 1042eb320b0eSRobert Watson } 1043eb320b0eSRobert Watson 1044eb320b0eSRobert Watson static void 1045eb320b0eSRobert Watson mls_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1046eb320b0eSRobert Watson struct label *ifplabel, struct label *newlabel) 1047eb320b0eSRobert Watson { 1048eb320b0eSRobert Watson struct mac_mls *source, *dest; 1049eb320b0eSRobert Watson 1050eb320b0eSRobert Watson source = SLOT(newlabel); 1051eb320b0eSRobert Watson dest = SLOT(ifplabel); 1052eb320b0eSRobert Watson 1053eb320b0eSRobert Watson mls_copy(source, dest); 1054eb320b0eSRobert Watson } 1055eb320b0eSRobert Watson 1056d8a7b7a3SRobert Watson static int 10573f1a7a90SRobert Watson mls_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1058a557af22SRobert Watson struct mbuf *m, struct label *mlabel) 1059a557af22SRobert Watson { 1060a557af22SRobert Watson struct mac_mls *p, *i; 1061a557af22SRobert Watson 10623f1a7a90SRobert Watson if (!mls_enabled) 1063a557af22SRobert Watson return (0); 1064a557af22SRobert Watson 1065a557af22SRobert Watson p = SLOT(mlabel); 1066a557af22SRobert Watson i = SLOT(inplabel); 1067a557af22SRobert Watson 10683f1a7a90SRobert Watson return (mls_equal_effective(p, i) ? 0 : EACCES); 1069a557af22SRobert Watson } 1070a557af22SRobert Watson 10717fb179baSBjoern A. Zeeb static int 10727fb179baSBjoern A. Zeeb mls_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 10737fb179baSBjoern A. Zeeb struct label *inplabel) 10747fb179baSBjoern A. Zeeb { 10757fb179baSBjoern A. Zeeb struct mac_mls *subj, *obj; 10767fb179baSBjoern A. Zeeb 10777fb179baSBjoern A. Zeeb if (!mls_enabled) 10787fb179baSBjoern A. Zeeb return (0); 10797fb179baSBjoern A. Zeeb 10807fb179baSBjoern A. Zeeb subj = SLOT(cred->cr_label); 10817fb179baSBjoern A. Zeeb obj = SLOT(inplabel); 10827fb179baSBjoern A. Zeeb 10837fb179baSBjoern A. Zeeb if (!mls_dominate_effective(subj, obj)) 10847fb179baSBjoern A. Zeeb return (ENOENT); 10857fb179baSBjoern A. Zeeb 10867fb179baSBjoern A. Zeeb return (0); 10877fb179baSBjoern A. Zeeb } 10887fb179baSBjoern A. Zeeb 1089eb320b0eSRobert Watson static void 1090eb320b0eSRobert Watson mls_inpcb_create(struct socket *so, struct label *solabel, struct inpcb *inp, 1091eb320b0eSRobert Watson struct label *inplabel) 109282d16d5eSRobert Watson { 1093eb320b0eSRobert Watson struct mac_mls *source, *dest; 109482d16d5eSRobert Watson 1095eb320b0eSRobert Watson source = SLOT(solabel); 1096eb320b0eSRobert Watson dest = SLOT(inplabel); 109782d16d5eSRobert Watson 1098eb320b0eSRobert Watson mls_copy_effective(source, dest); 1099eb320b0eSRobert Watson } 110082d16d5eSRobert Watson 1101eb320b0eSRobert Watson static void 1102eb320b0eSRobert Watson mls_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1103eb320b0eSRobert Watson struct mbuf *m, struct label *mlabel) 1104eb320b0eSRobert Watson { 1105eb320b0eSRobert Watson struct mac_mls *source, *dest; 110682d16d5eSRobert Watson 1107eb320b0eSRobert Watson source = SLOT(inplabel); 1108eb320b0eSRobert Watson dest = SLOT(mlabel); 1109eb320b0eSRobert Watson 1110eb320b0eSRobert Watson mls_copy_effective(source, dest); 1111eb320b0eSRobert Watson } 1112eb320b0eSRobert Watson 1113eb320b0eSRobert Watson static void 1114eb320b0eSRobert Watson mls_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1115eb320b0eSRobert Watson struct inpcb *inp, struct label *inplabel) 1116eb320b0eSRobert Watson { 1117eb320b0eSRobert Watson struct mac_mls *source, *dest; 1118eb320b0eSRobert Watson 11193de40469SRobert Watson SOCK_LOCK_ASSERT(so); 11203de40469SRobert Watson 1121eb320b0eSRobert Watson source = SLOT(solabel); 1122eb320b0eSRobert Watson dest = SLOT(inplabel); 1123eb320b0eSRobert Watson 1124eb320b0eSRobert Watson mls_copy(source, dest); 1125eb320b0eSRobert Watson } 1126eb320b0eSRobert Watson 1127eb320b0eSRobert Watson static void 1128048e1287SRobert Watson mls_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1129048e1287SRobert Watson struct label *q6label) 1130048e1287SRobert Watson { 1131048e1287SRobert Watson struct mac_mls *source, *dest; 1132048e1287SRobert Watson 1133048e1287SRobert Watson source = SLOT(mlabel); 1134048e1287SRobert Watson dest = SLOT(q6label); 1135048e1287SRobert Watson 1136048e1287SRobert Watson mls_copy_effective(source, dest); 1137048e1287SRobert Watson } 1138048e1287SRobert Watson 1139048e1287SRobert Watson static int 1140048e1287SRobert Watson mls_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1141048e1287SRobert Watson struct label *q6label) 1142048e1287SRobert Watson { 1143048e1287SRobert Watson struct mac_mls *a, *b; 1144048e1287SRobert Watson 1145048e1287SRobert Watson a = SLOT(q6label); 1146048e1287SRobert Watson b = SLOT(mlabel); 1147048e1287SRobert Watson 1148048e1287SRobert Watson return (mls_equal_effective(a, b)); 1149048e1287SRobert Watson } 1150048e1287SRobert Watson 1151048e1287SRobert Watson static void 1152048e1287SRobert Watson mls_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1153048e1287SRobert Watson struct label *mlabel) 1154048e1287SRobert Watson { 1155048e1287SRobert Watson struct mac_mls *source, *dest; 1156048e1287SRobert Watson 1157048e1287SRobert Watson source = SLOT(q6label); 1158048e1287SRobert Watson dest = SLOT(mlabel); 1159048e1287SRobert Watson 1160048e1287SRobert Watson /* Just use the head, since we require them all to match. */ 1161048e1287SRobert Watson mls_copy_effective(source, dest); 1162048e1287SRobert Watson } 1163048e1287SRobert Watson 1164048e1287SRobert Watson static void 1165048e1287SRobert Watson mls_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1166048e1287SRobert Watson struct label *q6label) 1167048e1287SRobert Watson { 1168048e1287SRobert Watson 1169048e1287SRobert Watson /* NOOP: we only accept matching labels, so no need to update */ 1170048e1287SRobert Watson } 1171048e1287SRobert Watson 1172048e1287SRobert Watson static void 117337f44cb4SRobert Watson mls_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 117437f44cb4SRobert Watson struct label *qlabel) 1175eb320b0eSRobert Watson { 1176eb320b0eSRobert Watson struct mac_mls *source, *dest; 1177eb320b0eSRobert Watson 1178eb320b0eSRobert Watson source = SLOT(mlabel); 117937f44cb4SRobert Watson dest = SLOT(qlabel); 1180eb320b0eSRobert Watson 1181eb320b0eSRobert Watson mls_copy_effective(source, dest); 118282d16d5eSRobert Watson } 118382d16d5eSRobert Watson 118482d16d5eSRobert Watson static int 118537f44cb4SRobert Watson mls_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 118637f44cb4SRobert Watson struct label *qlabel) 118782d16d5eSRobert Watson { 1188eb320b0eSRobert Watson struct mac_mls *a, *b; 118982d16d5eSRobert Watson 119037f44cb4SRobert Watson a = SLOT(qlabel); 1191eb320b0eSRobert Watson b = SLOT(mlabel); 119282d16d5eSRobert Watson 1193eb320b0eSRobert Watson return (mls_equal_effective(a, b)); 119482d16d5eSRobert Watson } 119582d16d5eSRobert Watson 1196eb320b0eSRobert Watson static void 119737f44cb4SRobert Watson mls_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1198eb320b0eSRobert Watson struct label *mlabel) 119982d16d5eSRobert Watson { 1200eb320b0eSRobert Watson struct mac_mls *source, *dest; 120182d16d5eSRobert Watson 120237f44cb4SRobert Watson source = SLOT(qlabel); 1203eb320b0eSRobert Watson dest = SLOT(mlabel); 120482d16d5eSRobert Watson 1205eb320b0eSRobert Watson /* Just use the head, since we require them all to match. */ 1206eb320b0eSRobert Watson mls_copy_effective(source, dest); 120782d16d5eSRobert Watson } 120882d16d5eSRobert Watson 1209eb320b0eSRobert Watson static void 121037f44cb4SRobert Watson mls_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 121137f44cb4SRobert Watson struct label *qlabel) 121282d16d5eSRobert Watson { 121382d16d5eSRobert Watson 1214eb320b0eSRobert Watson /* NOOP: we only accept matching labels, so no need to update */ 121582d16d5eSRobert Watson } 121682d16d5eSRobert Watson 121782d16d5eSRobert Watson static int 12183f1a7a90SRobert Watson mls_mount_check_stat(struct ucred *cred, struct mount *mp, 1219d8a7b7a3SRobert Watson struct label *mntlabel) 1220d8a7b7a3SRobert Watson { 1221d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 1222d8a7b7a3SRobert Watson 12233f1a7a90SRobert Watson if (!mls_enabled) 1224d8a7b7a3SRobert Watson return (0); 1225d8a7b7a3SRobert Watson 1226eca8a663SRobert Watson subj = SLOT(cred->cr_label); 1227d8a7b7a3SRobert Watson obj = SLOT(mntlabel); 1228d8a7b7a3SRobert Watson 12293f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 1230d8a7b7a3SRobert Watson return (EACCES); 1231d8a7b7a3SRobert Watson 1232d8a7b7a3SRobert Watson return (0); 1233d8a7b7a3SRobert Watson } 1234d8a7b7a3SRobert Watson 1235eb320b0eSRobert Watson static void 1236eb320b0eSRobert Watson mls_mount_create(struct ucred *cred, struct mount *mp, struct label *mplabel) 1237eb320b0eSRobert Watson { 1238eb320b0eSRobert Watson struct mac_mls *source, *dest; 1239eb320b0eSRobert Watson 1240eb320b0eSRobert Watson source = SLOT(cred->cr_label); 1241eb320b0eSRobert Watson dest = SLOT(mplabel); 1242eb320b0eSRobert Watson 1243eb320b0eSRobert Watson mls_copy_effective(source, dest); 1244eb320b0eSRobert Watson } 1245eb320b0eSRobert Watson 1246eb320b0eSRobert Watson static void 1247eb320b0eSRobert Watson mls_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1248eb320b0eSRobert Watson struct mbuf *m, struct label *mlabel) 1249eb320b0eSRobert Watson { 1250eb320b0eSRobert Watson struct mac_mls *dest; 1251eb320b0eSRobert Watson 1252eb320b0eSRobert Watson dest = SLOT(mlabel); 1253eb320b0eSRobert Watson 1254eb320b0eSRobert Watson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1255eb320b0eSRobert Watson } 1256eb320b0eSRobert Watson 1257eb320b0eSRobert Watson static void 1258eb320b0eSRobert Watson mls_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1259eb320b0eSRobert Watson struct mbuf *msend, struct label *msendlabel) 1260eb320b0eSRobert Watson { 1261eb320b0eSRobert Watson struct mac_mls *source, *dest; 1262eb320b0eSRobert Watson 1263eb320b0eSRobert Watson source = SLOT(mrecvlabel); 1264eb320b0eSRobert Watson dest = SLOT(msendlabel); 1265eb320b0eSRobert Watson 1266eb320b0eSRobert Watson mls_copy_effective(source, dest); 1267eb320b0eSRobert Watson } 1268eb320b0eSRobert Watson 1269eb320b0eSRobert Watson static void 1270eb320b0eSRobert Watson mls_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1271eb320b0eSRobert Watson { 1272eb320b0eSRobert Watson struct mac_mls *dest; 1273eb320b0eSRobert Watson 1274eb320b0eSRobert Watson dest = SLOT(mlabel); 1275eb320b0eSRobert Watson 1276bc5ade0dSPedro F. Giffuni /* XXX: where is the label for the firewall really coming from? */ 1277eb320b0eSRobert Watson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1278eb320b0eSRobert Watson } 1279eb320b0eSRobert Watson 1280eb320b0eSRobert Watson static void 1281eb320b0eSRobert Watson mls_netinet_fragment(struct mbuf *m, struct label *mlabel, struct mbuf *frag, 1282eb320b0eSRobert Watson struct label *fraglabel) 1283eb320b0eSRobert Watson { 1284eb320b0eSRobert Watson struct mac_mls *source, *dest; 1285eb320b0eSRobert Watson 1286eb320b0eSRobert Watson source = SLOT(mlabel); 1287eb320b0eSRobert Watson dest = SLOT(fraglabel); 1288eb320b0eSRobert Watson 1289eb320b0eSRobert Watson mls_copy_effective(source, dest); 1290eb320b0eSRobert Watson } 1291eb320b0eSRobert Watson 1292eb320b0eSRobert Watson static void 1293eb320b0eSRobert Watson mls_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1294eb320b0eSRobert Watson struct mbuf *msend, struct label *msendlabel) 1295eb320b0eSRobert Watson { 1296eb320b0eSRobert Watson struct mac_mls *source, *dest; 1297eb320b0eSRobert Watson 1298eb320b0eSRobert Watson source = SLOT(mrecvlabel); 1299eb320b0eSRobert Watson dest = SLOT(msendlabel); 1300eb320b0eSRobert Watson 1301eb320b0eSRobert Watson mls_copy_effective(source, dest); 1302eb320b0eSRobert Watson } 1303eb320b0eSRobert Watson 1304eb320b0eSRobert Watson static void 1305eb320b0eSRobert Watson mls_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1306eb320b0eSRobert Watson struct mbuf *m, struct label *mlabel) 1307eb320b0eSRobert Watson { 1308eb320b0eSRobert Watson struct mac_mls *dest; 1309eb320b0eSRobert Watson 1310eb320b0eSRobert Watson dest = SLOT(mlabel); 1311eb320b0eSRobert Watson 1312eb320b0eSRobert Watson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1313eb320b0eSRobert Watson } 1314eb320b0eSRobert Watson 1315eb320b0eSRobert Watson static void 1316eb320b0eSRobert Watson mls_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1317eb320b0eSRobert Watson struct mbuf *m, struct label *mlabel) 1318eb320b0eSRobert Watson { 1319eb320b0eSRobert Watson struct mac_mls *dest; 1320eb320b0eSRobert Watson 1321eb320b0eSRobert Watson dest = SLOT(mlabel); 1322eb320b0eSRobert Watson 1323eb320b0eSRobert Watson mls_set_effective(dest, MAC_MLS_TYPE_EQUAL, 0, NULL); 1324eb320b0eSRobert Watson } 1325eb320b0eSRobert Watson 1326d8a7b7a3SRobert Watson static int 13273f1a7a90SRobert Watson mls_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 132878007886SRobert Watson struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1329d8a7b7a3SRobert Watson { 1330d8a7b7a3SRobert Watson 13313f1a7a90SRobert Watson if (!mls_enabled) 1332d8a7b7a3SRobert Watson return (0); 1333d8a7b7a3SRobert Watson 1334d8a7b7a3SRobert Watson /* XXX: This will be implemented soon... */ 1335d8a7b7a3SRobert Watson 1336d8a7b7a3SRobert Watson return (0); 1337d8a7b7a3SRobert Watson } 1338d8a7b7a3SRobert Watson 1339d8a7b7a3SRobert Watson static int 13403f1a7a90SRobert Watson mls_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 134178007886SRobert Watson struct label *pplabel) 1342d8a7b7a3SRobert Watson { 1343d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 1344d8a7b7a3SRobert Watson 13453f1a7a90SRobert Watson if (!mls_enabled) 1346d8a7b7a3SRobert Watson return (0); 1347d8a7b7a3SRobert Watson 1348eca8a663SRobert Watson subj = SLOT(cred->cr_label); 134978007886SRobert Watson obj = SLOT(pplabel); 1350d8a7b7a3SRobert Watson 13513f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 1352d8a7b7a3SRobert Watson return (EACCES); 1353c024c3eeSRobert Watson 1354c024c3eeSRobert Watson return (0); 1355d8a7b7a3SRobert Watson } 1356d8a7b7a3SRobert Watson 1357c024c3eeSRobert Watson static int 13583f1a7a90SRobert Watson mls_pipe_check_read(struct ucred *cred, struct pipepair *pp, 135978007886SRobert Watson struct label *pplabel) 1360c024c3eeSRobert Watson { 1361c024c3eeSRobert Watson struct mac_mls *subj, *obj; 1362c024c3eeSRobert Watson 13633f1a7a90SRobert Watson if (!mls_enabled) 1364c024c3eeSRobert Watson return (0); 1365c024c3eeSRobert Watson 1366eca8a663SRobert Watson subj = SLOT(cred->cr_label); 136778007886SRobert Watson obj = SLOT(pplabel); 1368c024c3eeSRobert Watson 13693f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 1370c024c3eeSRobert Watson return (EACCES); 1371c024c3eeSRobert Watson 1372d8a7b7a3SRobert Watson return (0); 1373d8a7b7a3SRobert Watson } 1374d8a7b7a3SRobert Watson 1375d8a7b7a3SRobert Watson static int 13763f1a7a90SRobert Watson mls_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 137778007886SRobert Watson struct label *pplabel, struct label *newlabel) 1378d8a7b7a3SRobert Watson { 1379d8a7b7a3SRobert Watson struct mac_mls *subj, *obj, *new; 1380b5f072b5SRobert Watson int error; 1381d8a7b7a3SRobert Watson 1382d8a7b7a3SRobert Watson new = SLOT(newlabel); 1383eca8a663SRobert Watson subj = SLOT(cred->cr_label); 138478007886SRobert Watson obj = SLOT(pplabel); 1385d8a7b7a3SRobert Watson 1386b5f072b5SRobert Watson /* 13873f1a7a90SRobert Watson * If there is an MLS label update for a pipe, it must be a effective 13883f1a7a90SRobert Watson * update. 1389b5f072b5SRobert Watson */ 1390dee57980SRobert Watson error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1391b5f072b5SRobert Watson if (error) 1392b5f072b5SRobert Watson return (error); 1393d8a7b7a3SRobert Watson 1394d8a7b7a3SRobert Watson /* 1395b5f072b5SRobert Watson * To perform a relabel of a pipe (MLS label or not), MLS must 1396b5f072b5SRobert Watson * authorize the relabel. 1397d8a7b7a3SRobert Watson */ 13983f1a7a90SRobert Watson if (!mls_effective_in_range(obj, subj)) 1399d8a7b7a3SRobert Watson return (EPERM); 1400d8a7b7a3SRobert Watson 1401d8a7b7a3SRobert Watson /* 1402b5f072b5SRobert Watson * If the MLS label is to be changed, authorize as appropriate. 1403b5f072b5SRobert Watson */ 1404dee57980SRobert Watson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1405b5f072b5SRobert Watson /* 14063f1a7a90SRobert Watson * To change the MLS label on a pipe, the new pipe label must 14073f1a7a90SRobert Watson * be in the subject range. 1408d8a7b7a3SRobert Watson */ 14093f1a7a90SRobert Watson if (!mls_effective_in_range(new, subj)) 1410d8a7b7a3SRobert Watson return (EPERM); 1411d8a7b7a3SRobert Watson 1412d8a7b7a3SRobert Watson /* 14133f1a7a90SRobert Watson * To change the MLS label on a pipe to be EQUAL, the subject 14143f1a7a90SRobert Watson * must have appropriate privilege. 1415d8a7b7a3SRobert Watson */ 14163f1a7a90SRobert Watson if (mls_contains_equal(new)) { 14173f1a7a90SRobert Watson error = mls_subject_privileged(subj); 1418b5f072b5SRobert Watson if (error) 1419b5f072b5SRobert Watson return (error); 1420b5f072b5SRobert Watson } 1421b5f072b5SRobert Watson } 1422d8a7b7a3SRobert Watson 1423d8a7b7a3SRobert Watson return (0); 1424d8a7b7a3SRobert Watson } 1425d8a7b7a3SRobert Watson 1426d8a7b7a3SRobert Watson static int 14273f1a7a90SRobert Watson mls_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 142878007886SRobert Watson struct label *pplabel) 1429c024c3eeSRobert Watson { 1430c024c3eeSRobert Watson struct mac_mls *subj, *obj; 1431c024c3eeSRobert Watson 14323f1a7a90SRobert Watson if (!mls_enabled) 1433c024c3eeSRobert Watson return (0); 1434c024c3eeSRobert Watson 1435eca8a663SRobert Watson subj = SLOT(cred->cr_label); 143678007886SRobert Watson obj = SLOT(pplabel); 1437c024c3eeSRobert Watson 14383f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 1439c024c3eeSRobert Watson return (EACCES); 1440c024c3eeSRobert Watson 1441c024c3eeSRobert Watson return (0); 1442c024c3eeSRobert Watson } 1443c024c3eeSRobert Watson 1444c024c3eeSRobert Watson static int 14453f1a7a90SRobert Watson mls_pipe_check_write(struct ucred *cred, struct pipepair *pp, 144678007886SRobert Watson struct label *pplabel) 1447c024c3eeSRobert Watson { 1448c024c3eeSRobert Watson struct mac_mls *subj, *obj; 1449c024c3eeSRobert Watson 14503f1a7a90SRobert Watson if (!mls_enabled) 1451c024c3eeSRobert Watson return (0); 1452c024c3eeSRobert Watson 1453eca8a663SRobert Watson subj = SLOT(cred->cr_label); 145478007886SRobert Watson obj = SLOT(pplabel); 1455c024c3eeSRobert Watson 14563f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 1457c024c3eeSRobert Watson return (EACCES); 1458c024c3eeSRobert Watson 1459c024c3eeSRobert Watson return (0); 1460c024c3eeSRobert Watson } 1461c024c3eeSRobert Watson 1462eb320b0eSRobert Watson static void 1463eb320b0eSRobert Watson mls_pipe_create(struct ucred *cred, struct pipepair *pp, 1464eb320b0eSRobert Watson struct label *pplabel) 146552648411SRobert Watson { 1466eb320b0eSRobert Watson struct mac_mls *source, *dest; 146752648411SRobert Watson 1468eb320b0eSRobert Watson source = SLOT(cred->cr_label); 1469eb320b0eSRobert Watson dest = SLOT(pplabel); 147052648411SRobert Watson 1471eb320b0eSRobert Watson mls_copy_effective(source, dest); 1472eb320b0eSRobert Watson } 147352648411SRobert Watson 1474eb320b0eSRobert Watson static void 1475eb320b0eSRobert Watson mls_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1476eb320b0eSRobert Watson struct label *pplabel, struct label *newlabel) 1477eb320b0eSRobert Watson { 1478eb320b0eSRobert Watson struct mac_mls *source, *dest; 147952648411SRobert Watson 1480eb320b0eSRobert Watson source = SLOT(newlabel); 1481eb320b0eSRobert Watson dest = SLOT(pplabel); 1482eb320b0eSRobert Watson 1483eb320b0eSRobert Watson mls_copy(source, dest); 148452648411SRobert Watson } 148552648411SRobert Watson 148652648411SRobert Watson static int 14876bc1e9cdSJohn Baldwin mls_posixsem_check_openunlink(struct ucred *cred, struct ksem *ks, 1488fe09513eSRobert Watson struct label *kslabel) 148952648411SRobert Watson { 149052648411SRobert Watson struct mac_mls *subj, *obj; 149152648411SRobert Watson 14923f1a7a90SRobert Watson if (!mls_enabled) 149352648411SRobert Watson return (0); 149452648411SRobert Watson 149552648411SRobert Watson subj = SLOT(cred->cr_label); 1496fe09513eSRobert Watson obj = SLOT(kslabel); 149752648411SRobert Watson 14986bc1e9cdSJohn Baldwin if (!mls_dominate_effective(obj, subj)) 14996bc1e9cdSJohn Baldwin return (EACCES); 15006bc1e9cdSJohn Baldwin 15016bc1e9cdSJohn Baldwin return (0); 15026bc1e9cdSJohn Baldwin } 15036bc1e9cdSJohn Baldwin 15046bc1e9cdSJohn Baldwin static int 15056bc1e9cdSJohn Baldwin mls_posixsem_check_rdonly(struct ucred *active_cred, struct ucred *file_cred, 15066bc1e9cdSJohn Baldwin struct ksem *ks, struct label *kslabel) 15076bc1e9cdSJohn Baldwin { 15086bc1e9cdSJohn Baldwin struct mac_mls *subj, *obj; 15096bc1e9cdSJohn Baldwin 15106bc1e9cdSJohn Baldwin if (!mls_enabled) 15116bc1e9cdSJohn Baldwin return (0); 15126bc1e9cdSJohn Baldwin 15136bc1e9cdSJohn Baldwin subj = SLOT(active_cred->cr_label); 15146bc1e9cdSJohn Baldwin obj = SLOT(kslabel); 15156bc1e9cdSJohn Baldwin 15163f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 151752648411SRobert Watson return (EACCES); 151852648411SRobert Watson 151952648411SRobert Watson return (0); 152052648411SRobert Watson } 152152648411SRobert Watson 152252648411SRobert Watson static int 15239b6dd12eSRobert Watson mls_posixsem_check_setmode(struct ucred *cred, struct ksem *ks, 15249b6dd12eSRobert Watson struct label *shmlabel, mode_t mode) 15259b6dd12eSRobert Watson { 15269b6dd12eSRobert Watson struct mac_mls *subj, *obj; 15279b6dd12eSRobert Watson 15289b6dd12eSRobert Watson if (!mls_enabled) 15299b6dd12eSRobert Watson return (0); 15309b6dd12eSRobert Watson 15319b6dd12eSRobert Watson subj = SLOT(cred->cr_label); 15329b6dd12eSRobert Watson obj = SLOT(shmlabel); 15339b6dd12eSRobert Watson 15349b6dd12eSRobert Watson if (!mls_dominate_effective(obj, subj)) 15359b6dd12eSRobert Watson return (EACCES); 15369b6dd12eSRobert Watson 15379b6dd12eSRobert Watson return (0); 15389b6dd12eSRobert Watson } 15399b6dd12eSRobert Watson 15409b6dd12eSRobert Watson static int 15419b6dd12eSRobert Watson mls_posixsem_check_setowner(struct ucred *cred, struct ksem *ks, 15429b6dd12eSRobert Watson struct label *shmlabel, uid_t uid, gid_t gid) 15439b6dd12eSRobert Watson { 15449b6dd12eSRobert Watson struct mac_mls *subj, *obj; 15459b6dd12eSRobert Watson 15469b6dd12eSRobert Watson if (!mls_enabled) 15479b6dd12eSRobert Watson return (0); 15489b6dd12eSRobert Watson 15499b6dd12eSRobert Watson subj = SLOT(cred->cr_label); 15509b6dd12eSRobert Watson obj = SLOT(shmlabel); 15519b6dd12eSRobert Watson 15529b6dd12eSRobert Watson if (!mls_dominate_effective(obj, subj)) 15539b6dd12eSRobert Watson return (EACCES); 15549b6dd12eSRobert Watson 15559b6dd12eSRobert Watson return (0); 15569b6dd12eSRobert Watson } 15579b6dd12eSRobert Watson 15589b6dd12eSRobert Watson static int 15596bc1e9cdSJohn Baldwin mls_posixsem_check_write(struct ucred *active_cred, struct ucred *file_cred, 15606bc1e9cdSJohn Baldwin struct ksem *ks, struct label *kslabel) 1561eb320b0eSRobert Watson { 1562eb320b0eSRobert Watson struct mac_mls *subj, *obj; 1563eb320b0eSRobert Watson 1564eb320b0eSRobert Watson if (!mls_enabled) 1565eb320b0eSRobert Watson return (0); 1566eb320b0eSRobert Watson 15676bc1e9cdSJohn Baldwin subj = SLOT(active_cred->cr_label); 1568eb320b0eSRobert Watson obj = SLOT(kslabel); 1569eb320b0eSRobert Watson 1570eb320b0eSRobert Watson if (!mls_dominate_effective(obj, subj)) 1571eb320b0eSRobert Watson return (EACCES); 1572eb320b0eSRobert Watson 1573eb320b0eSRobert Watson return (0); 1574eb320b0eSRobert Watson } 1575eb320b0eSRobert Watson 1576eb320b0eSRobert Watson static void 1577eb320b0eSRobert Watson mls_posixsem_create(struct ucred *cred, struct ksem *ks, 1578eb320b0eSRobert Watson struct label *kslabel) 1579eb320b0eSRobert Watson { 1580eb320b0eSRobert Watson struct mac_mls *source, *dest; 1581eb320b0eSRobert Watson 1582eb320b0eSRobert Watson source = SLOT(cred->cr_label); 1583eb320b0eSRobert Watson dest = SLOT(kslabel); 1584eb320b0eSRobert Watson 1585eb320b0eSRobert Watson mls_copy_effective(source, dest); 1586eb320b0eSRobert Watson } 1587eb320b0eSRobert Watson 1588eb320b0eSRobert Watson static int 15899b6dd12eSRobert Watson mls_posixshm_check_mmap(struct ucred *cred, struct shmfd *shmfd, 15909b6dd12eSRobert Watson struct label *shmlabel, int prot, int flags) 15919b6dd12eSRobert Watson { 15929b6dd12eSRobert Watson struct mac_mls *subj, *obj; 15939b6dd12eSRobert Watson 15949b6dd12eSRobert Watson if (!mls_enabled) 15959b6dd12eSRobert Watson return (0); 15969b6dd12eSRobert Watson 15979b6dd12eSRobert Watson subj = SLOT(cred->cr_label); 15989b6dd12eSRobert Watson obj = SLOT(shmlabel); 15999b6dd12eSRobert Watson 16009b6dd12eSRobert Watson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 16019b6dd12eSRobert Watson if (!mls_dominate_effective(subj, obj)) 16029b6dd12eSRobert Watson return (EACCES); 16039b6dd12eSRobert Watson } 16049b6dd12eSRobert Watson if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 16059b6dd12eSRobert Watson if (!mls_dominate_effective(obj, subj)) 16069b6dd12eSRobert Watson return (EACCES); 16079b6dd12eSRobert Watson } 16089b6dd12eSRobert Watson 16099b6dd12eSRobert Watson return (0); 16109b6dd12eSRobert Watson } 16119b6dd12eSRobert Watson 16129b6dd12eSRobert Watson static int 16139b6dd12eSRobert Watson mls_posixshm_check_open(struct ucred *cred, struct shmfd *shmfd, 16149b6dd12eSRobert Watson struct label *shmlabel, accmode_t accmode) 16159b6dd12eSRobert Watson { 16169b6dd12eSRobert Watson struct mac_mls *subj, *obj; 16179b6dd12eSRobert Watson 16189b6dd12eSRobert Watson if (!mls_enabled) 16199b6dd12eSRobert Watson return (0); 16209b6dd12eSRobert Watson 16219b6dd12eSRobert Watson subj = SLOT(cred->cr_label); 16229b6dd12eSRobert Watson obj = SLOT(shmlabel); 16239b6dd12eSRobert Watson 16249b6dd12eSRobert Watson if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 16259b6dd12eSRobert Watson if (!mls_dominate_effective(subj, obj)) 16269b6dd12eSRobert Watson return (EACCES); 16279b6dd12eSRobert Watson } 16289b6dd12eSRobert Watson if (accmode & VMODIFY_PERMS) { 16299b6dd12eSRobert Watson if (!mls_dominate_effective(obj, subj)) 16309b6dd12eSRobert Watson return (EACCES); 16319b6dd12eSRobert Watson } 16329b6dd12eSRobert Watson 16339b6dd12eSRobert Watson return (0); 16349b6dd12eSRobert Watson } 16359b6dd12eSRobert Watson 16369b6dd12eSRobert Watson static int 1637940cb0e2SKonstantin Belousov mls_posixshm_check_read(struct ucred *active_cred, struct ucred *file_cred, 1638940cb0e2SKonstantin Belousov struct shmfd *shm, struct label *shmlabel) 1639940cb0e2SKonstantin Belousov { 1640940cb0e2SKonstantin Belousov struct mac_mls *subj, *obj; 1641940cb0e2SKonstantin Belousov 1642940cb0e2SKonstantin Belousov if (!mls_enabled || !revocation_enabled) 1643940cb0e2SKonstantin Belousov return (0); 1644940cb0e2SKonstantin Belousov 1645940cb0e2SKonstantin Belousov subj = SLOT(active_cred->cr_label); 1646940cb0e2SKonstantin Belousov obj = SLOT(shmlabel); 1647940cb0e2SKonstantin Belousov 1648940cb0e2SKonstantin Belousov if (!mls_dominate_effective(subj, obj)) 1649940cb0e2SKonstantin Belousov return (EACCES); 1650940cb0e2SKonstantin Belousov 1651940cb0e2SKonstantin Belousov return (0); 1652940cb0e2SKonstantin Belousov } 1653940cb0e2SKonstantin Belousov 1654940cb0e2SKonstantin Belousov static int 16559b6dd12eSRobert Watson mls_posixshm_check_setmode(struct ucred *cred, struct shmfd *shmfd, 16569b6dd12eSRobert Watson struct label *shmlabel, mode_t mode) 16579b6dd12eSRobert Watson { 16589b6dd12eSRobert Watson struct mac_mls *subj, *obj; 16599b6dd12eSRobert Watson 16609b6dd12eSRobert Watson if (!mls_enabled) 16619b6dd12eSRobert Watson return (0); 16629b6dd12eSRobert Watson 16639b6dd12eSRobert Watson subj = SLOT(cred->cr_label); 16649b6dd12eSRobert Watson obj = SLOT(shmlabel); 16659b6dd12eSRobert Watson 16669b6dd12eSRobert Watson if (!mls_dominate_effective(obj, subj)) 16679b6dd12eSRobert Watson return (EACCES); 16689b6dd12eSRobert Watson 16699b6dd12eSRobert Watson return (0); 16709b6dd12eSRobert Watson } 16719b6dd12eSRobert Watson 16729b6dd12eSRobert Watson static int 16739b6dd12eSRobert Watson mls_posixshm_check_setowner(struct ucred *cred, struct shmfd *shmfd, 16749b6dd12eSRobert Watson struct label *shmlabel, uid_t uid, gid_t gid) 16759b6dd12eSRobert Watson { 16769b6dd12eSRobert Watson struct mac_mls *subj, *obj; 16779b6dd12eSRobert Watson 16789b6dd12eSRobert Watson if (!mls_enabled) 16799b6dd12eSRobert Watson return (0); 16809b6dd12eSRobert Watson 16819b6dd12eSRobert Watson subj = SLOT(cred->cr_label); 16829b6dd12eSRobert Watson obj = SLOT(shmlabel); 16839b6dd12eSRobert Watson 16849b6dd12eSRobert Watson if (!mls_dominate_effective(obj, subj)) 16859b6dd12eSRobert Watson return (EACCES); 16869b6dd12eSRobert Watson 16879b6dd12eSRobert Watson return (0); 16889b6dd12eSRobert Watson } 16899b6dd12eSRobert Watson 16909b6dd12eSRobert Watson static int 16919b6dd12eSRobert Watson mls_posixshm_check_stat(struct ucred *active_cred, struct ucred *file_cred, 16929b6dd12eSRobert Watson struct shmfd *shmfd, struct label *shmlabel) 16939b6dd12eSRobert Watson { 16949b6dd12eSRobert Watson struct mac_mls *subj, *obj; 16959b6dd12eSRobert Watson 16969b6dd12eSRobert Watson if (!mls_enabled) 16979b6dd12eSRobert Watson return (0); 16989b6dd12eSRobert Watson 16999b6dd12eSRobert Watson subj = SLOT(active_cred->cr_label); 17009b6dd12eSRobert Watson obj = SLOT(shmlabel); 17019b6dd12eSRobert Watson 17029b6dd12eSRobert Watson if (!mls_dominate_effective(subj, obj)) 17039b6dd12eSRobert Watson return (EACCES); 17049b6dd12eSRobert Watson 17059b6dd12eSRobert Watson return (0); 17069b6dd12eSRobert Watson } 17079b6dd12eSRobert Watson 17089b6dd12eSRobert Watson static int 17099b6dd12eSRobert Watson mls_posixshm_check_truncate(struct ucred *active_cred, 17109b6dd12eSRobert Watson struct ucred *file_cred, struct shmfd *shmfd, struct label *shmlabel) 17119b6dd12eSRobert Watson { 17129b6dd12eSRobert Watson struct mac_mls *subj, *obj; 17139b6dd12eSRobert Watson 17149b6dd12eSRobert Watson if (!mls_enabled) 17159b6dd12eSRobert Watson return (0); 17169b6dd12eSRobert Watson 17179b6dd12eSRobert Watson subj = SLOT(active_cred->cr_label); 17189b6dd12eSRobert Watson obj = SLOT(shmlabel); 17199b6dd12eSRobert Watson 17209b6dd12eSRobert Watson if (!mls_dominate_effective(obj, subj)) 17219b6dd12eSRobert Watson return (EACCES); 17229b6dd12eSRobert Watson 17239b6dd12eSRobert Watson return (0); 17249b6dd12eSRobert Watson } 17259b6dd12eSRobert Watson 17269b6dd12eSRobert Watson static int 17279b6dd12eSRobert Watson mls_posixshm_check_unlink(struct ucred *cred, struct shmfd *shmfd, 17289b6dd12eSRobert Watson struct label *shmlabel) 17299b6dd12eSRobert Watson { 17309b6dd12eSRobert Watson struct mac_mls *subj, *obj; 17319b6dd12eSRobert Watson 17329b6dd12eSRobert Watson if (!mls_enabled) 17339b6dd12eSRobert Watson return (0); 17349b6dd12eSRobert Watson 17359b6dd12eSRobert Watson subj = SLOT(cred->cr_label); 17369b6dd12eSRobert Watson obj = SLOT(shmlabel); 17379b6dd12eSRobert Watson 17389b6dd12eSRobert Watson if (!mls_dominate_effective(obj, subj)) 17399b6dd12eSRobert Watson return (EACCES); 17409b6dd12eSRobert Watson 17419b6dd12eSRobert Watson return (0); 17429b6dd12eSRobert Watson } 17439b6dd12eSRobert Watson 1744940cb0e2SKonstantin Belousov static int 1745940cb0e2SKonstantin Belousov mls_posixshm_check_write(struct ucred *active_cred, struct ucred *file_cred, 1746940cb0e2SKonstantin Belousov struct shmfd *shm, struct label *shmlabel) 1747940cb0e2SKonstantin Belousov { 1748940cb0e2SKonstantin Belousov struct mac_mls *subj, *obj; 1749940cb0e2SKonstantin Belousov 1750940cb0e2SKonstantin Belousov if (!mls_enabled || !revocation_enabled) 1751940cb0e2SKonstantin Belousov return (0); 1752940cb0e2SKonstantin Belousov 1753940cb0e2SKonstantin Belousov subj = SLOT(active_cred->cr_label); 1754940cb0e2SKonstantin Belousov obj = SLOT(shmlabel); 1755940cb0e2SKonstantin Belousov 1756940cb0e2SKonstantin Belousov if (!mls_dominate_effective(subj, obj)) 1757940cb0e2SKonstantin Belousov return (EACCES); 1758940cb0e2SKonstantin Belousov 1759940cb0e2SKonstantin Belousov return (0); 1760940cb0e2SKonstantin Belousov } 1761940cb0e2SKonstantin Belousov 17629b6dd12eSRobert Watson static void 17639b6dd12eSRobert Watson mls_posixshm_create(struct ucred *cred, struct shmfd *shmfd, 17649b6dd12eSRobert Watson struct label *shmlabel) 17659b6dd12eSRobert Watson { 17669b6dd12eSRobert Watson struct mac_mls *source, *dest; 17679b6dd12eSRobert Watson 17689b6dd12eSRobert Watson source = SLOT(cred->cr_label); 17699b6dd12eSRobert Watson dest = SLOT(shmlabel); 17709b6dd12eSRobert Watson 17719b6dd12eSRobert Watson mls_copy_effective(source, dest); 17729b6dd12eSRobert Watson } 17739b6dd12eSRobert Watson 17749b6dd12eSRobert Watson static int 17753f1a7a90SRobert Watson mls_proc_check_debug(struct ucred *cred, struct proc *p) 1776d8a7b7a3SRobert Watson { 1777d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 1778d8a7b7a3SRobert Watson 17793f1a7a90SRobert Watson if (!mls_enabled) 1780d8a7b7a3SRobert Watson return (0); 1781d8a7b7a3SRobert Watson 1782eca8a663SRobert Watson subj = SLOT(cred->cr_label); 178378007886SRobert Watson obj = SLOT(p->p_ucred->cr_label); 1784d8a7b7a3SRobert Watson 1785d8a7b7a3SRobert Watson /* XXX: range checks */ 17863f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 1787d8a7b7a3SRobert Watson return (ESRCH); 17883f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 1789d8a7b7a3SRobert Watson return (EACCES); 1790d8a7b7a3SRobert Watson 1791d8a7b7a3SRobert Watson return (0); 1792d8a7b7a3SRobert Watson } 1793d8a7b7a3SRobert Watson 1794d8a7b7a3SRobert Watson static int 17953f1a7a90SRobert Watson mls_proc_check_sched(struct ucred *cred, struct proc *p) 1796d8a7b7a3SRobert Watson { 1797d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 1798d8a7b7a3SRobert Watson 17993f1a7a90SRobert Watson if (!mls_enabled) 1800d8a7b7a3SRobert Watson return (0); 1801d8a7b7a3SRobert Watson 1802eca8a663SRobert Watson subj = SLOT(cred->cr_label); 180378007886SRobert Watson obj = SLOT(p->p_ucred->cr_label); 1804d8a7b7a3SRobert Watson 1805d8a7b7a3SRobert Watson /* XXX: range checks */ 18063f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 1807d8a7b7a3SRobert Watson return (ESRCH); 18083f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 1809d8a7b7a3SRobert Watson return (EACCES); 1810d8a7b7a3SRobert Watson 1811d8a7b7a3SRobert Watson return (0); 1812d8a7b7a3SRobert Watson } 1813d8a7b7a3SRobert Watson 1814d8a7b7a3SRobert Watson static int 18153f1a7a90SRobert Watson mls_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1816d8a7b7a3SRobert Watson { 1817d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 1818d8a7b7a3SRobert Watson 18193f1a7a90SRobert Watson if (!mls_enabled) 1820d8a7b7a3SRobert Watson return (0); 1821d8a7b7a3SRobert Watson 1822eca8a663SRobert Watson subj = SLOT(cred->cr_label); 182378007886SRobert Watson obj = SLOT(p->p_ucred->cr_label); 1824d8a7b7a3SRobert Watson 1825d8a7b7a3SRobert Watson /* XXX: range checks */ 18263f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 1827d8a7b7a3SRobert Watson return (ESRCH); 18283f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 1829d8a7b7a3SRobert Watson return (EACCES); 1830d8a7b7a3SRobert Watson 1831d8a7b7a3SRobert Watson return (0); 1832d8a7b7a3SRobert Watson } 1833d8a7b7a3SRobert Watson 1834d8a7b7a3SRobert Watson static int 18353f1a7a90SRobert Watson mls_socket_check_deliver(struct socket *so, struct label *solabel, 183678007886SRobert Watson struct mbuf *m, struct label *mlabel) 1837d8a7b7a3SRobert Watson { 1838d8a7b7a3SRobert Watson struct mac_mls *p, *s; 18393de40469SRobert Watson int error; 1840d8a7b7a3SRobert Watson 18413f1a7a90SRobert Watson if (!mls_enabled) 1842d8a7b7a3SRobert Watson return (0); 1843d8a7b7a3SRobert Watson 184478007886SRobert Watson p = SLOT(mlabel); 184578007886SRobert Watson s = SLOT(solabel); 1846d8a7b7a3SRobert Watson 18473de40469SRobert Watson SOCK_LOCK(so); 18483de40469SRobert Watson error = mls_equal_effective(p, s) ? 0 : EACCES; 18493de40469SRobert Watson SOCK_UNLOCK(so); 18503de40469SRobert Watson 18513de40469SRobert Watson return (error); 1852d8a7b7a3SRobert Watson } 1853d8a7b7a3SRobert Watson 1854d8a7b7a3SRobert Watson static int 18553f1a7a90SRobert Watson mls_socket_check_relabel(struct ucred *cred, struct socket *so, 185678007886SRobert Watson struct label *solabel, struct label *newlabel) 1857d8a7b7a3SRobert Watson { 1858d8a7b7a3SRobert Watson struct mac_mls *subj, *obj, *new; 1859b5f072b5SRobert Watson int error; 1860d8a7b7a3SRobert Watson 18613de40469SRobert Watson SOCK_LOCK_ASSERT(so); 18623de40469SRobert Watson 1863d8a7b7a3SRobert Watson new = SLOT(newlabel); 1864eca8a663SRobert Watson subj = SLOT(cred->cr_label); 186578007886SRobert Watson obj = SLOT(solabel); 1866d8a7b7a3SRobert Watson 1867b5f072b5SRobert Watson /* 18683f1a7a90SRobert Watson * If there is an MLS label update for the socket, it may be an 18693f1a7a90SRobert Watson * update of effective. 1870b5f072b5SRobert Watson */ 1871dee57980SRobert Watson error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 1872b5f072b5SRobert Watson if (error) 1873b5f072b5SRobert Watson return (error); 1874d8a7b7a3SRobert Watson 1875d8a7b7a3SRobert Watson /* 18763f1a7a90SRobert Watson * To relabel a socket, the old socket effective must be in the 18773f1a7a90SRobert Watson * subject range. 1878d8a7b7a3SRobert Watson */ 18793f1a7a90SRobert Watson if (!mls_effective_in_range(obj, subj)) 1880d8a7b7a3SRobert Watson return (EPERM); 1881d8a7b7a3SRobert Watson 1882d8a7b7a3SRobert Watson /* 1883b5f072b5SRobert Watson * If the MLS label is to be changed, authorize as appropriate. 1884b5f072b5SRobert Watson */ 1885dee57980SRobert Watson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 1886b5f072b5SRobert Watson /* 1887dee57980SRobert Watson * To relabel a socket, the new socket effective must be in 1888b5f072b5SRobert Watson * the subject range. 1889d8a7b7a3SRobert Watson */ 18903f1a7a90SRobert Watson if (!mls_effective_in_range(new, subj)) 1891d8a7b7a3SRobert Watson return (EPERM); 1892d8a7b7a3SRobert Watson 1893d8a7b7a3SRobert Watson /* 1894b5f072b5SRobert Watson * To change the MLS label on the socket to contain EQUAL, 1895b5f072b5SRobert Watson * the subject must have appropriate privilege. 1896d8a7b7a3SRobert Watson */ 18973f1a7a90SRobert Watson if (mls_contains_equal(new)) { 18983f1a7a90SRobert Watson error = mls_subject_privileged(subj); 1899b5f072b5SRobert Watson if (error) 1900b5f072b5SRobert Watson return (error); 1901b5f072b5SRobert Watson } 1902b5f072b5SRobert Watson } 1903d8a7b7a3SRobert Watson 1904d8a7b7a3SRobert Watson return (0); 1905d8a7b7a3SRobert Watson } 1906d8a7b7a3SRobert Watson 1907d8a7b7a3SRobert Watson static int 19083f1a7a90SRobert Watson mls_socket_check_visible(struct ucred *cred, struct socket *so, 190978007886SRobert Watson struct label *solabel) 1910d8a7b7a3SRobert Watson { 1911d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 1912d8a7b7a3SRobert Watson 19133f1a7a90SRobert Watson if (!mls_enabled) 1914d8a7b7a3SRobert Watson return (0); 1915d8a7b7a3SRobert Watson 1916eca8a663SRobert Watson subj = SLOT(cred->cr_label); 191778007886SRobert Watson obj = SLOT(solabel); 1918d8a7b7a3SRobert Watson 19193de40469SRobert Watson SOCK_LOCK(so); 19203de40469SRobert Watson if (!mls_dominate_effective(subj, obj)) { 19213de40469SRobert Watson SOCK_UNLOCK(so); 1922d8a7b7a3SRobert Watson return (ENOENT); 19233de40469SRobert Watson } 19243de40469SRobert Watson SOCK_UNLOCK(so); 1925d8a7b7a3SRobert Watson 1926d8a7b7a3SRobert Watson return (0); 1927d8a7b7a3SRobert Watson } 1928d8a7b7a3SRobert Watson 1929eb320b0eSRobert Watson static void 1930eb320b0eSRobert Watson mls_socket_create(struct ucred *cred, struct socket *so, 1931eb320b0eSRobert Watson struct label *solabel) 1932eb320b0eSRobert Watson { 1933eb320b0eSRobert Watson struct mac_mls *source, *dest; 1934eb320b0eSRobert Watson 1935eb320b0eSRobert Watson source = SLOT(cred->cr_label); 1936eb320b0eSRobert Watson dest = SLOT(solabel); 1937eb320b0eSRobert Watson 1938eb320b0eSRobert Watson mls_copy_effective(source, dest); 1939eb320b0eSRobert Watson } 1940eb320b0eSRobert Watson 1941eb320b0eSRobert Watson static void 1942eb320b0eSRobert Watson mls_socket_create_mbuf(struct socket *so, struct label *solabel, 1943eb320b0eSRobert Watson struct mbuf *m, struct label *mlabel) 1944eb320b0eSRobert Watson { 1945eb320b0eSRobert Watson struct mac_mls *source, *dest; 1946eb320b0eSRobert Watson 1947eb320b0eSRobert Watson source = SLOT(solabel); 1948eb320b0eSRobert Watson dest = SLOT(mlabel); 1949eb320b0eSRobert Watson 19503de40469SRobert Watson SOCK_LOCK(so); 1951eb320b0eSRobert Watson mls_copy_effective(source, dest); 19523de40469SRobert Watson SOCK_UNLOCK(so); 1953eb320b0eSRobert Watson } 1954eb320b0eSRobert Watson 1955eb320b0eSRobert Watson static void 1956eb320b0eSRobert Watson mls_socket_newconn(struct socket *oldso, struct label *oldsolabel, 1957eb320b0eSRobert Watson struct socket *newso, struct label *newsolabel) 1958eb320b0eSRobert Watson { 19593de40469SRobert Watson struct mac_mls source, *dest; 1960eb320b0eSRobert Watson 19613de40469SRobert Watson SOCK_LOCK(oldso); 19623de40469SRobert Watson source = *SLOT(oldsolabel); 19633de40469SRobert Watson SOCK_UNLOCK(oldso); 19643de40469SRobert Watson 1965eb320b0eSRobert Watson dest = SLOT(newsolabel); 1966eb320b0eSRobert Watson 19673de40469SRobert Watson SOCK_LOCK(newso); 19683de40469SRobert Watson mls_copy_effective(&source, dest); 19693de40469SRobert Watson SOCK_UNLOCK(newso); 1970eb320b0eSRobert Watson } 1971eb320b0eSRobert Watson 1972eb320b0eSRobert Watson static void 1973eb320b0eSRobert Watson mls_socket_relabel(struct ucred *cred, struct socket *so, 1974eb320b0eSRobert Watson struct label *solabel, struct label *newlabel) 1975eb320b0eSRobert Watson { 1976eb320b0eSRobert Watson struct mac_mls *source, *dest; 1977eb320b0eSRobert Watson 19783de40469SRobert Watson SOCK_LOCK_ASSERT(so); 19793de40469SRobert Watson 1980eb320b0eSRobert Watson source = SLOT(newlabel); 1981eb320b0eSRobert Watson dest = SLOT(solabel); 1982eb320b0eSRobert Watson 1983eb320b0eSRobert Watson mls_copy(source, dest); 1984eb320b0eSRobert Watson } 1985eb320b0eSRobert Watson 1986eb320b0eSRobert Watson static void 1987eb320b0eSRobert Watson mls_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 1988eb320b0eSRobert Watson struct socket *so, struct label *sopeerlabel) 1989eb320b0eSRobert Watson { 1990eb320b0eSRobert Watson struct mac_mls *source, *dest; 1991eb320b0eSRobert Watson 1992eb320b0eSRobert Watson source = SLOT(mlabel); 1993eb320b0eSRobert Watson dest = SLOT(sopeerlabel); 1994eb320b0eSRobert Watson 19953de40469SRobert Watson SOCK_LOCK(so); 1996eb320b0eSRobert Watson mls_copy_effective(source, dest); 19973de40469SRobert Watson SOCK_UNLOCK(so); 1998eb320b0eSRobert Watson } 1999eb320b0eSRobert Watson 2000eb320b0eSRobert Watson static void 2001eb320b0eSRobert Watson mls_socketpeer_set_from_socket(struct socket *oldso, 2002eb320b0eSRobert Watson struct label *oldsolabel, struct socket *newso, 2003eb320b0eSRobert Watson struct label *newsopeerlabel) 2004eb320b0eSRobert Watson { 20053de40469SRobert Watson struct mac_mls source, *dest; 2006eb320b0eSRobert Watson 20073de40469SRobert Watson SOCK_LOCK(oldso); 20083de40469SRobert Watson source = *SLOT(oldsolabel); 20093de40469SRobert Watson SOCK_UNLOCK(oldso); 20103de40469SRobert Watson 2011eb320b0eSRobert Watson dest = SLOT(newsopeerlabel); 2012eb320b0eSRobert Watson 20133de40469SRobert Watson SOCK_LOCK(newso); 20143de40469SRobert Watson mls_copy_effective(&source, dest); 20153de40469SRobert Watson SOCK_UNLOCK(newso); 2016eb320b0eSRobert Watson } 2017eb320b0eSRobert Watson 2018eb320b0eSRobert Watson static void 2019eb320b0eSRobert Watson mls_syncache_create(struct label *label, struct inpcb *inp) 2020eb320b0eSRobert Watson { 2021eb320b0eSRobert Watson struct mac_mls *source, *dest; 2022eb320b0eSRobert Watson 2023eb320b0eSRobert Watson source = SLOT(inp->inp_label); 2024eb320b0eSRobert Watson dest = SLOT(label); 2025eb320b0eSRobert Watson 2026eb320b0eSRobert Watson mls_copy_effective(source, dest); 2027eb320b0eSRobert Watson } 2028eb320b0eSRobert Watson 2029eb320b0eSRobert Watson static void 2030eb320b0eSRobert Watson mls_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2031eb320b0eSRobert Watson struct label *mlabel) 2032eb320b0eSRobert Watson { 2033eb320b0eSRobert Watson struct mac_mls *source, *dest; 2034eb320b0eSRobert Watson 2035eb320b0eSRobert Watson source = SLOT(sc_label); 2036eb320b0eSRobert Watson dest = SLOT(mlabel); 2037eb320b0eSRobert Watson 2038eb320b0eSRobert Watson mls_copy_effective(source, dest); 2039eb320b0eSRobert Watson } 2040eb320b0eSRobert Watson 2041d8a7b7a3SRobert Watson static int 20423f1a7a90SRobert Watson mls_system_check_acct(struct ucred *cred, struct vnode *vp, 204378007886SRobert Watson struct label *vplabel) 204418717f69SRobert Watson { 204518717f69SRobert Watson struct mac_mls *subj, *obj; 204618717f69SRobert Watson 20473f1a7a90SRobert Watson if (!mls_enabled) 204818717f69SRobert Watson return (0); 204918717f69SRobert Watson 2050e623c220SChristian Brueffer if (vplabel == NULL) 2051e623c220SChristian Brueffer return (0); 2052e623c220SChristian Brueffer 205318717f69SRobert Watson subj = SLOT(cred->cr_label); 205478007886SRobert Watson obj = SLOT(vplabel); 205518717f69SRobert Watson 20563f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj) || 20573f1a7a90SRobert Watson !mls_dominate_effective(subj, obj)) 205818717f69SRobert Watson return (EACCES); 205918717f69SRobert Watson 206018717f69SRobert Watson return (0); 206118717f69SRobert Watson } 206218717f69SRobert Watson 206318717f69SRobert Watson static int 20643f1a7a90SRobert Watson mls_system_check_auditctl(struct ucred *cred, struct vnode *vp, 206578007886SRobert Watson struct label *vplabel) 206618717f69SRobert Watson { 206718717f69SRobert Watson struct mac_mls *subj, *obj; 206818717f69SRobert Watson 20693f1a7a90SRobert Watson if (!mls_enabled) 207018717f69SRobert Watson return (0); 207118717f69SRobert Watson 207218717f69SRobert Watson subj = SLOT(cred->cr_label); 207378007886SRobert Watson obj = SLOT(vplabel); 207418717f69SRobert Watson 20753f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj) || 20763f1a7a90SRobert Watson !mls_dominate_effective(subj, obj)) 207718717f69SRobert Watson return (EACCES); 207818717f69SRobert Watson 207918717f69SRobert Watson return (0); 208018717f69SRobert Watson } 208118717f69SRobert Watson 208218717f69SRobert Watson static int 20833f1a7a90SRobert Watson mls_system_check_swapon(struct ucred *cred, struct vnode *vp, 208478007886SRobert Watson struct label *vplabel) 20854c64787aSRobert Watson { 20864c64787aSRobert Watson struct mac_mls *subj, *obj; 20874c64787aSRobert Watson 20883f1a7a90SRobert Watson if (!mls_enabled) 20894c64787aSRobert Watson return (0); 20904c64787aSRobert Watson 2091eca8a663SRobert Watson subj = SLOT(cred->cr_label); 209278007886SRobert Watson obj = SLOT(vplabel); 20934c64787aSRobert Watson 20943f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj) || 20953f1a7a90SRobert Watson !mls_dominate_effective(subj, obj)) 20964c64787aSRobert Watson return (EACCES); 20974c64787aSRobert Watson 20984c64787aSRobert Watson return (0); 20994c64787aSRobert Watson } 21004c64787aSRobert Watson 2101eb320b0eSRobert Watson static void 2102eb320b0eSRobert Watson mls_sysvmsg_cleanup(struct label *msglabel) 2103eb320b0eSRobert Watson { 2104eb320b0eSRobert Watson 2105eb320b0eSRobert Watson bzero(SLOT(msglabel), sizeof(struct mac_mls)); 2106eb320b0eSRobert Watson } 2107eb320b0eSRobert Watson 2108eb320b0eSRobert Watson static void 2109eb320b0eSRobert Watson mls_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2110eb320b0eSRobert Watson struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 2111eb320b0eSRobert Watson { 2112eb320b0eSRobert Watson struct mac_mls *source, *dest; 2113eb320b0eSRobert Watson 2114eb320b0eSRobert Watson /* Ignore the msgq label. */ 2115eb320b0eSRobert Watson source = SLOT(cred->cr_label); 2116eb320b0eSRobert Watson dest = SLOT(msglabel); 2117eb320b0eSRobert Watson 2118eb320b0eSRobert Watson mls_copy_effective(source, dest); 2119eb320b0eSRobert Watson } 2120eb320b0eSRobert Watson 2121eb320b0eSRobert Watson static int 2122eb320b0eSRobert Watson mls_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 2123eb320b0eSRobert Watson struct label *msglabel) 2124eb320b0eSRobert Watson { 2125eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2126eb320b0eSRobert Watson 2127eb320b0eSRobert Watson if (!mls_enabled) 2128eb320b0eSRobert Watson return (0); 2129eb320b0eSRobert Watson 2130eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2131eb320b0eSRobert Watson obj = SLOT(msglabel); 2132eb320b0eSRobert Watson 2133eb320b0eSRobert Watson if (!mls_dominate_effective(subj, obj)) 2134eb320b0eSRobert Watson return (EACCES); 2135eb320b0eSRobert Watson 2136eb320b0eSRobert Watson return (0); 2137eb320b0eSRobert Watson } 2138eb320b0eSRobert Watson 2139eb320b0eSRobert Watson static int 2140eb320b0eSRobert Watson mls_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 2141eb320b0eSRobert Watson struct label *msglabel) 2142eb320b0eSRobert Watson { 2143eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2144eb320b0eSRobert Watson 2145eb320b0eSRobert Watson if (!mls_enabled) 2146eb320b0eSRobert Watson return (0); 2147eb320b0eSRobert Watson 2148eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2149eb320b0eSRobert Watson obj = SLOT(msglabel); 2150eb320b0eSRobert Watson 2151eb320b0eSRobert Watson if (!mls_dominate_effective(obj, subj)) 2152eb320b0eSRobert Watson return (EACCES); 2153eb320b0eSRobert Watson 2154eb320b0eSRobert Watson return (0); 2155eb320b0eSRobert Watson } 2156eb320b0eSRobert Watson 2157eb320b0eSRobert Watson static int 2158eb320b0eSRobert Watson mls_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 2159eb320b0eSRobert Watson struct label *msqklabel) 2160eb320b0eSRobert Watson { 2161eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2162eb320b0eSRobert Watson 2163eb320b0eSRobert Watson if (!mls_enabled) 2164eb320b0eSRobert Watson return (0); 2165eb320b0eSRobert Watson 2166eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2167eb320b0eSRobert Watson obj = SLOT(msqklabel); 2168eb320b0eSRobert Watson 2169eb320b0eSRobert Watson if (!mls_dominate_effective(subj, obj)) 2170eb320b0eSRobert Watson return (EACCES); 2171eb320b0eSRobert Watson 2172eb320b0eSRobert Watson return (0); 2173eb320b0eSRobert Watson } 2174eb320b0eSRobert Watson 2175eb320b0eSRobert Watson static int 2176eb320b0eSRobert Watson mls_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 2177eb320b0eSRobert Watson struct label *msqklabel) 2178eb320b0eSRobert Watson { 2179eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2180eb320b0eSRobert Watson 2181eb320b0eSRobert Watson if (!mls_enabled) 2182eb320b0eSRobert Watson return (0); 2183eb320b0eSRobert Watson 2184eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2185eb320b0eSRobert Watson obj = SLOT(msqklabel); 2186eb320b0eSRobert Watson 2187eb320b0eSRobert Watson if (!mls_dominate_effective(obj, subj)) 2188eb320b0eSRobert Watson return (EACCES); 2189eb320b0eSRobert Watson 2190eb320b0eSRobert Watson return (0); 2191eb320b0eSRobert Watson } 2192eb320b0eSRobert Watson 2193eb320b0eSRobert Watson static int 2194eb320b0eSRobert Watson mls_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 2195eb320b0eSRobert Watson struct label *msqklabel) 2196eb320b0eSRobert Watson { 2197eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2198eb320b0eSRobert Watson 2199eb320b0eSRobert Watson if (!mls_enabled) 2200eb320b0eSRobert Watson return (0); 2201eb320b0eSRobert Watson 2202eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2203eb320b0eSRobert Watson obj = SLOT(msqklabel); 2204eb320b0eSRobert Watson 2205eb320b0eSRobert Watson if (!mls_dominate_effective(subj, obj)) 2206eb320b0eSRobert Watson return (EACCES); 2207eb320b0eSRobert Watson 2208eb320b0eSRobert Watson return (0); 2209eb320b0eSRobert Watson } 2210eb320b0eSRobert Watson 2211eb320b0eSRobert Watson static int 2212eb320b0eSRobert Watson mls_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 2213eb320b0eSRobert Watson struct label *msqklabel, int cmd) 2214eb320b0eSRobert Watson { 2215eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2216eb320b0eSRobert Watson 2217eb320b0eSRobert Watson if (!mls_enabled) 2218eb320b0eSRobert Watson return (0); 2219eb320b0eSRobert Watson 2220eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2221eb320b0eSRobert Watson obj = SLOT(msqklabel); 2222eb320b0eSRobert Watson 2223eb320b0eSRobert Watson switch(cmd) { 2224eb320b0eSRobert Watson case IPC_RMID: 2225eb320b0eSRobert Watson case IPC_SET: 2226eb320b0eSRobert Watson if (!mls_dominate_effective(obj, subj)) 2227eb320b0eSRobert Watson return (EACCES); 2228eb320b0eSRobert Watson break; 2229eb320b0eSRobert Watson 2230eb320b0eSRobert Watson case IPC_STAT: 2231eb320b0eSRobert Watson if (!mls_dominate_effective(subj, obj)) 2232eb320b0eSRobert Watson return (EACCES); 2233eb320b0eSRobert Watson break; 2234eb320b0eSRobert Watson 2235eb320b0eSRobert Watson default: 2236eb320b0eSRobert Watson return (EACCES); 2237eb320b0eSRobert Watson } 2238eb320b0eSRobert Watson 2239eb320b0eSRobert Watson return (0); 2240eb320b0eSRobert Watson } 2241eb320b0eSRobert Watson 2242eb320b0eSRobert Watson static void 2243eb320b0eSRobert Watson mls_sysvmsq_cleanup(struct label *msqlabel) 2244eb320b0eSRobert Watson { 2245eb320b0eSRobert Watson 2246eb320b0eSRobert Watson bzero(SLOT(msqlabel), sizeof(struct mac_mls)); 2247eb320b0eSRobert Watson } 2248eb320b0eSRobert Watson 2249eb320b0eSRobert Watson static void 2250eb320b0eSRobert Watson mls_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 2251eb320b0eSRobert Watson struct label *msqlabel) 2252eb320b0eSRobert Watson { 2253eb320b0eSRobert Watson struct mac_mls *source, *dest; 2254eb320b0eSRobert Watson 2255eb320b0eSRobert Watson source = SLOT(cred->cr_label); 2256eb320b0eSRobert Watson dest = SLOT(msqlabel); 2257eb320b0eSRobert Watson 2258eb320b0eSRobert Watson mls_copy_effective(source, dest); 2259eb320b0eSRobert Watson } 2260eb320b0eSRobert Watson 2261eb320b0eSRobert Watson static int 2262eb320b0eSRobert Watson mls_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 2263eb320b0eSRobert Watson struct label *semaklabel, int cmd) 2264eb320b0eSRobert Watson { 2265eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2266eb320b0eSRobert Watson 2267eb320b0eSRobert Watson if (!mls_enabled) 2268eb320b0eSRobert Watson return (0); 2269eb320b0eSRobert Watson 2270eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2271eb320b0eSRobert Watson obj = SLOT(semaklabel); 2272eb320b0eSRobert Watson 2273eb320b0eSRobert Watson switch(cmd) { 2274eb320b0eSRobert Watson case IPC_RMID: 2275eb320b0eSRobert Watson case IPC_SET: 2276eb320b0eSRobert Watson case SETVAL: 2277eb320b0eSRobert Watson case SETALL: 2278eb320b0eSRobert Watson if (!mls_dominate_effective(obj, subj)) 2279eb320b0eSRobert Watson return (EACCES); 2280eb320b0eSRobert Watson break; 2281eb320b0eSRobert Watson 2282eb320b0eSRobert Watson case IPC_STAT: 2283eb320b0eSRobert Watson case GETVAL: 2284eb320b0eSRobert Watson case GETPID: 2285eb320b0eSRobert Watson case GETNCNT: 2286eb320b0eSRobert Watson case GETZCNT: 2287eb320b0eSRobert Watson case GETALL: 2288eb320b0eSRobert Watson if (!mls_dominate_effective(subj, obj)) 2289eb320b0eSRobert Watson return (EACCES); 2290eb320b0eSRobert Watson break; 2291eb320b0eSRobert Watson 2292eb320b0eSRobert Watson default: 2293eb320b0eSRobert Watson return (EACCES); 2294eb320b0eSRobert Watson } 2295eb320b0eSRobert Watson 2296eb320b0eSRobert Watson return (0); 2297eb320b0eSRobert Watson } 2298eb320b0eSRobert Watson 2299eb320b0eSRobert Watson static int 2300eb320b0eSRobert Watson mls_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 2301eb320b0eSRobert Watson struct label *semaklabel) 2302eb320b0eSRobert Watson { 2303eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2304eb320b0eSRobert Watson 2305eb320b0eSRobert Watson if (!mls_enabled) 2306eb320b0eSRobert Watson return (0); 2307eb320b0eSRobert Watson 2308eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2309eb320b0eSRobert Watson obj = SLOT(semaklabel); 2310eb320b0eSRobert Watson 2311eb320b0eSRobert Watson if (!mls_dominate_effective(subj, obj)) 2312eb320b0eSRobert Watson return (EACCES); 2313eb320b0eSRobert Watson 2314eb320b0eSRobert Watson return (0); 2315eb320b0eSRobert Watson } 2316eb320b0eSRobert Watson 2317eb320b0eSRobert Watson static int 2318eb320b0eSRobert Watson mls_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 2319eb320b0eSRobert Watson struct label *semaklabel, size_t accesstype) 2320eb320b0eSRobert Watson { 2321eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2322eb320b0eSRobert Watson 2323eb320b0eSRobert Watson if (!mls_enabled) 2324eb320b0eSRobert Watson return (0); 2325eb320b0eSRobert Watson 2326eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2327eb320b0eSRobert Watson obj = SLOT(semaklabel); 2328eb320b0eSRobert Watson 2329eb320b0eSRobert Watson if( accesstype & SEM_R ) 2330eb320b0eSRobert Watson if (!mls_dominate_effective(subj, obj)) 2331eb320b0eSRobert Watson return (EACCES); 2332eb320b0eSRobert Watson 2333eb320b0eSRobert Watson if( accesstype & SEM_A ) 2334eb320b0eSRobert Watson if (!mls_dominate_effective(obj, subj)) 2335eb320b0eSRobert Watson return (EACCES); 2336eb320b0eSRobert Watson 2337eb320b0eSRobert Watson return (0); 2338eb320b0eSRobert Watson } 2339eb320b0eSRobert Watson 2340eb320b0eSRobert Watson static void 2341eb320b0eSRobert Watson mls_sysvsem_cleanup(struct label *semalabel) 2342eb320b0eSRobert Watson { 2343eb320b0eSRobert Watson 2344eb320b0eSRobert Watson bzero(SLOT(semalabel), sizeof(struct mac_mls)); 2345eb320b0eSRobert Watson } 2346eb320b0eSRobert Watson 2347eb320b0eSRobert Watson static void 2348eb320b0eSRobert Watson mls_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 2349eb320b0eSRobert Watson struct label *semalabel) 2350eb320b0eSRobert Watson { 2351eb320b0eSRobert Watson struct mac_mls *source, *dest; 2352eb320b0eSRobert Watson 2353eb320b0eSRobert Watson source = SLOT(cred->cr_label); 2354eb320b0eSRobert Watson dest = SLOT(semalabel); 2355eb320b0eSRobert Watson 2356eb320b0eSRobert Watson mls_copy_effective(source, dest); 2357eb320b0eSRobert Watson } 2358eb320b0eSRobert Watson 2359eb320b0eSRobert Watson static int 2360eb320b0eSRobert Watson mls_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 2361eb320b0eSRobert Watson struct label *shmseglabel, int shmflg) 2362eb320b0eSRobert Watson { 2363eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2364eb320b0eSRobert Watson 2365eb320b0eSRobert Watson if (!mls_enabled) 2366eb320b0eSRobert Watson return (0); 2367eb320b0eSRobert Watson 2368eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2369eb320b0eSRobert Watson obj = SLOT(shmseglabel); 2370eb320b0eSRobert Watson 2371eb320b0eSRobert Watson if (!mls_dominate_effective(subj, obj)) 2372eb320b0eSRobert Watson return (EACCES); 2373eb320b0eSRobert Watson if ((shmflg & SHM_RDONLY) == 0) { 2374eb320b0eSRobert Watson if (!mls_dominate_effective(obj, subj)) 2375eb320b0eSRobert Watson return (EACCES); 2376eb320b0eSRobert Watson } 2377eb320b0eSRobert Watson 2378eb320b0eSRobert Watson return (0); 2379eb320b0eSRobert Watson } 2380eb320b0eSRobert Watson 2381eb320b0eSRobert Watson static int 2382eb320b0eSRobert Watson mls_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 2383eb320b0eSRobert Watson struct label *shmseglabel, int cmd) 2384eb320b0eSRobert Watson { 2385eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2386eb320b0eSRobert Watson 2387eb320b0eSRobert Watson if (!mls_enabled) 2388eb320b0eSRobert Watson return (0); 2389eb320b0eSRobert Watson 2390eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2391eb320b0eSRobert Watson obj = SLOT(shmseglabel); 2392eb320b0eSRobert Watson 2393eb320b0eSRobert Watson switch(cmd) { 2394eb320b0eSRobert Watson case IPC_RMID: 2395eb320b0eSRobert Watson case IPC_SET: 2396eb320b0eSRobert Watson if (!mls_dominate_effective(obj, subj)) 2397eb320b0eSRobert Watson return (EACCES); 2398eb320b0eSRobert Watson break; 2399eb320b0eSRobert Watson 2400eb320b0eSRobert Watson case IPC_STAT: 2401eb320b0eSRobert Watson case SHM_STAT: 2402eb320b0eSRobert Watson if (!mls_dominate_effective(subj, obj)) 2403eb320b0eSRobert Watson return (EACCES); 2404eb320b0eSRobert Watson break; 2405eb320b0eSRobert Watson 2406eb320b0eSRobert Watson default: 2407eb320b0eSRobert Watson return (EACCES); 2408eb320b0eSRobert Watson } 2409eb320b0eSRobert Watson 2410eb320b0eSRobert Watson return (0); 2411eb320b0eSRobert Watson } 2412eb320b0eSRobert Watson 2413eb320b0eSRobert Watson static int 2414eb320b0eSRobert Watson mls_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 2415eb320b0eSRobert Watson struct label *shmseglabel, int shmflg) 2416eb320b0eSRobert Watson { 2417eb320b0eSRobert Watson struct mac_mls *subj, *obj; 2418eb320b0eSRobert Watson 2419eb320b0eSRobert Watson if (!mls_enabled) 2420eb320b0eSRobert Watson return (0); 2421eb320b0eSRobert Watson 2422eb320b0eSRobert Watson subj = SLOT(cred->cr_label); 2423eb320b0eSRobert Watson obj = SLOT(shmseglabel); 2424eb320b0eSRobert Watson 2425eb320b0eSRobert Watson if (!mls_dominate_effective(obj, subj)) 2426eb320b0eSRobert Watson return (EACCES); 2427eb320b0eSRobert Watson 2428eb320b0eSRobert Watson return (0); 2429eb320b0eSRobert Watson } 2430eb320b0eSRobert Watson 2431eb320b0eSRobert Watson static void 2432eb320b0eSRobert Watson mls_sysvshm_cleanup(struct label *shmlabel) 2433eb320b0eSRobert Watson { 2434eb320b0eSRobert Watson 2435eb320b0eSRobert Watson bzero(SLOT(shmlabel), sizeof(struct mac_mls)); 2436eb320b0eSRobert Watson } 2437eb320b0eSRobert Watson 2438eb320b0eSRobert Watson static void 2439eb320b0eSRobert Watson mls_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 2440eb320b0eSRobert Watson struct label *shmlabel) 2441eb320b0eSRobert Watson { 2442eb320b0eSRobert Watson struct mac_mls *source, *dest; 2443eb320b0eSRobert Watson 2444eb320b0eSRobert Watson source = SLOT(cred->cr_label); 2445eb320b0eSRobert Watson dest = SLOT(shmlabel); 2446eb320b0eSRobert Watson 2447eb320b0eSRobert Watson mls_copy_effective(source, dest); 2448eb320b0eSRobert Watson } 2449eb320b0eSRobert Watson 2450eb320b0eSRobert Watson static int 2451eb320b0eSRobert Watson mls_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2452eb320b0eSRobert Watson struct vnode *vp, struct label *vplabel) 2453eb320b0eSRobert Watson { 2454eb320b0eSRobert Watson struct mac_mls mm_temp, *source, *dest; 2455eb320b0eSRobert Watson int buflen, error; 2456eb320b0eSRobert Watson 2457eb320b0eSRobert Watson source = SLOT(mplabel); 2458eb320b0eSRobert Watson dest = SLOT(vplabel); 2459eb320b0eSRobert Watson 2460eb320b0eSRobert Watson buflen = sizeof(mm_temp); 2461eb320b0eSRobert Watson bzero(&mm_temp, buflen); 2462eb320b0eSRobert Watson 2463eb320b0eSRobert Watson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 2464eb320b0eSRobert Watson MAC_MLS_EXTATTR_NAME, &buflen, (char *) &mm_temp, curthread); 2465eb320b0eSRobert Watson if (error == ENOATTR || error == EOPNOTSUPP) { 2466eb320b0eSRobert Watson /* Fall back to the mntlabel. */ 2467eb320b0eSRobert Watson mls_copy_effective(source, dest); 2468eb320b0eSRobert Watson return (0); 2469eb320b0eSRobert Watson } else if (error) 2470eb320b0eSRobert Watson return (error); 2471eb320b0eSRobert Watson 2472eb320b0eSRobert Watson if (buflen != sizeof(mm_temp)) { 2473eb320b0eSRobert Watson printf("mls_vnode_associate_extattr: bad size %d\n", buflen); 2474eb320b0eSRobert Watson return (EPERM); 2475eb320b0eSRobert Watson } 2476eb320b0eSRobert Watson if (mls_valid(&mm_temp) != 0) { 2477eb320b0eSRobert Watson printf("mls_vnode_associate_extattr: invalid\n"); 2478eb320b0eSRobert Watson return (EPERM); 2479eb320b0eSRobert Watson } 2480eb320b0eSRobert Watson if ((mm_temp.mm_flags & MAC_MLS_FLAGS_BOTH) != 2481eb320b0eSRobert Watson MAC_MLS_FLAG_EFFECTIVE) { 2482eb320b0eSRobert Watson printf("mls_associated_vnode_extattr: not effective\n"); 2483eb320b0eSRobert Watson return (EPERM); 2484eb320b0eSRobert Watson } 2485eb320b0eSRobert Watson 2486eb320b0eSRobert Watson mls_copy_effective(&mm_temp, dest); 2487eb320b0eSRobert Watson return (0); 2488eb320b0eSRobert Watson } 2489eb320b0eSRobert Watson 2490eb320b0eSRobert Watson static void 2491eb320b0eSRobert Watson mls_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2492eb320b0eSRobert Watson struct vnode *vp, struct label *vplabel) 2493eb320b0eSRobert Watson { 2494eb320b0eSRobert Watson struct mac_mls *source, *dest; 2495eb320b0eSRobert Watson 2496eb320b0eSRobert Watson source = SLOT(mplabel); 2497eb320b0eSRobert Watson dest = SLOT(vplabel); 2498eb320b0eSRobert Watson 2499eb320b0eSRobert Watson mls_copy_effective(source, dest); 2500eb320b0eSRobert Watson } 2501eb320b0eSRobert Watson 25024c64787aSRobert Watson static int 25033f1a7a90SRobert Watson mls_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 250478007886SRobert Watson struct label *dvplabel) 2505d8a7b7a3SRobert Watson { 2506d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2507d8a7b7a3SRobert Watson 25083f1a7a90SRobert Watson if (!mls_enabled) 2509d8a7b7a3SRobert Watson return (0); 2510d8a7b7a3SRobert Watson 2511eca8a663SRobert Watson subj = SLOT(cred->cr_label); 251278007886SRobert Watson obj = SLOT(dvplabel); 2513d8a7b7a3SRobert Watson 25143f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2515d8a7b7a3SRobert Watson return (EACCES); 2516d8a7b7a3SRobert Watson 2517d8a7b7a3SRobert Watson return (0); 2518d8a7b7a3SRobert Watson } 2519d8a7b7a3SRobert Watson 2520d8a7b7a3SRobert Watson static int 25213f1a7a90SRobert Watson mls_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 252278007886SRobert Watson struct label *dvplabel) 2523d8a7b7a3SRobert Watson { 2524d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2525d8a7b7a3SRobert Watson 25263f1a7a90SRobert Watson if (!mls_enabled) 2527d8a7b7a3SRobert Watson return (0); 2528d8a7b7a3SRobert Watson 2529eca8a663SRobert Watson subj = SLOT(cred->cr_label); 253078007886SRobert Watson obj = SLOT(dvplabel); 2531d8a7b7a3SRobert Watson 25323f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2533d8a7b7a3SRobert Watson return (EACCES); 2534d8a7b7a3SRobert Watson 2535d8a7b7a3SRobert Watson return (0); 2536d8a7b7a3SRobert Watson } 2537d8a7b7a3SRobert Watson 2538d8a7b7a3SRobert Watson static int 25393f1a7a90SRobert Watson mls_vnode_check_create(struct ucred *cred, struct vnode *dvp, 254078007886SRobert Watson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2541d8a7b7a3SRobert Watson { 2542d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2543d8a7b7a3SRobert Watson 25443f1a7a90SRobert Watson if (!mls_enabled) 2545d8a7b7a3SRobert Watson return (0); 2546d8a7b7a3SRobert Watson 2547eca8a663SRobert Watson subj = SLOT(cred->cr_label); 254878007886SRobert Watson obj = SLOT(dvplabel); 2549d8a7b7a3SRobert Watson 25503f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2551d8a7b7a3SRobert Watson return (EACCES); 2552d8a7b7a3SRobert Watson 2553d8a7b7a3SRobert Watson return (0); 2554d8a7b7a3SRobert Watson } 2555d8a7b7a3SRobert Watson 2556d8a7b7a3SRobert Watson static int 25573f1a7a90SRobert Watson mls_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 255878007886SRobert Watson struct label *vplabel, acl_type_t type) 2559d8a7b7a3SRobert Watson { 2560d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2561d8a7b7a3SRobert Watson 25623f1a7a90SRobert Watson if (!mls_enabled) 2563d8a7b7a3SRobert Watson return (0); 2564d8a7b7a3SRobert Watson 2565eca8a663SRobert Watson subj = SLOT(cred->cr_label); 256678007886SRobert Watson obj = SLOT(vplabel); 2567d8a7b7a3SRobert Watson 25683f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2569d8a7b7a3SRobert Watson return (EACCES); 2570d8a7b7a3SRobert Watson 2571d8a7b7a3SRobert Watson return (0); 2572d8a7b7a3SRobert Watson } 2573d8a7b7a3SRobert Watson 2574d8a7b7a3SRobert Watson static int 25753f1a7a90SRobert Watson mls_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 257678007886SRobert Watson struct label *vplabel, int attrnamespace, const char *name) 257754e2c147SRobert Watson { 257854e2c147SRobert Watson struct mac_mls *subj, *obj; 257954e2c147SRobert Watson 25803f1a7a90SRobert Watson if (!mls_enabled) 258154e2c147SRobert Watson return (0); 258254e2c147SRobert Watson 2583eca8a663SRobert Watson subj = SLOT(cred->cr_label); 258478007886SRobert Watson obj = SLOT(vplabel); 258554e2c147SRobert Watson 25863f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 258754e2c147SRobert Watson return (EACCES); 258854e2c147SRobert Watson 258954e2c147SRobert Watson return (0); 259054e2c147SRobert Watson } 259154e2c147SRobert Watson 259254e2c147SRobert Watson static int 25933f1a7a90SRobert Watson mls_vnode_check_exec(struct ucred *cred, struct vnode *vp, 259478007886SRobert Watson struct label *vplabel, struct image_params *imgp, 2595ef5def59SRobert Watson struct label *execlabel) 2596d8a7b7a3SRobert Watson { 2597ef5def59SRobert Watson struct mac_mls *subj, *obj, *exec; 2598ef5def59SRobert Watson int error; 2599ef5def59SRobert Watson 2600ef5def59SRobert Watson if (execlabel != NULL) { 2601ef5def59SRobert Watson /* 2602ef5def59SRobert Watson * We currently don't permit labels to be changed at 26033f1a7a90SRobert Watson * exec-time as part of MLS, so disallow non-NULL MLS label 26043f1a7a90SRobert Watson * elements in the execlabel. 2605ef5def59SRobert Watson */ 2606ef5def59SRobert Watson exec = SLOT(execlabel); 2607ef5def59SRobert Watson error = mls_atmostflags(exec, 0); 2608ef5def59SRobert Watson if (error) 2609ef5def59SRobert Watson return (error); 2610ef5def59SRobert Watson } 2611d8a7b7a3SRobert Watson 26123f1a7a90SRobert Watson if (!mls_enabled) 2613d8a7b7a3SRobert Watson return (0); 2614d8a7b7a3SRobert Watson 2615eca8a663SRobert Watson subj = SLOT(cred->cr_label); 261678007886SRobert Watson obj = SLOT(vplabel); 2617d8a7b7a3SRobert Watson 26183f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2619d8a7b7a3SRobert Watson return (EACCES); 2620d8a7b7a3SRobert Watson 2621d8a7b7a3SRobert Watson return (0); 2622d8a7b7a3SRobert Watson } 2623d8a7b7a3SRobert Watson 2624d8a7b7a3SRobert Watson static int 26253f1a7a90SRobert Watson mls_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 262678007886SRobert Watson struct label *vplabel, acl_type_t type) 2627d8a7b7a3SRobert Watson { 2628d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2629d8a7b7a3SRobert Watson 26303f1a7a90SRobert Watson if (!mls_enabled) 2631d8a7b7a3SRobert Watson return (0); 2632d8a7b7a3SRobert Watson 2633eca8a663SRobert Watson subj = SLOT(cred->cr_label); 263478007886SRobert Watson obj = SLOT(vplabel); 2635d8a7b7a3SRobert Watson 26363f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2637d8a7b7a3SRobert Watson return (EACCES); 2638d8a7b7a3SRobert Watson 2639d8a7b7a3SRobert Watson return (0); 2640d8a7b7a3SRobert Watson } 2641d8a7b7a3SRobert Watson 2642d8a7b7a3SRobert Watson static int 26433f1a7a90SRobert Watson mls_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 2644fefd0ac8SRobert Watson struct label *vplabel, int attrnamespace, const char *name) 2645d8a7b7a3SRobert Watson { 2646d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2647d8a7b7a3SRobert Watson 26483f1a7a90SRobert Watson if (!mls_enabled) 2649d8a7b7a3SRobert Watson return (0); 2650d8a7b7a3SRobert Watson 2651eca8a663SRobert Watson subj = SLOT(cred->cr_label); 265278007886SRobert Watson obj = SLOT(vplabel); 2653d8a7b7a3SRobert Watson 26543f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2655d8a7b7a3SRobert Watson return (EACCES); 2656d8a7b7a3SRobert Watson 2657d8a7b7a3SRobert Watson return (0); 2658d8a7b7a3SRobert Watson } 2659d8a7b7a3SRobert Watson 2660d8a7b7a3SRobert Watson static int 26613f1a7a90SRobert Watson mls_vnode_check_link(struct ucred *cred, struct vnode *dvp, 266278007886SRobert Watson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2663c27b50f5SRobert Watson struct componentname *cnp) 2664c27b50f5SRobert Watson { 2665c27b50f5SRobert Watson struct mac_mls *subj, *obj; 2666c27b50f5SRobert Watson 26673f1a7a90SRobert Watson if (!mls_enabled) 2668c27b50f5SRobert Watson return (0); 2669c27b50f5SRobert Watson 2670eca8a663SRobert Watson subj = SLOT(cred->cr_label); 267178007886SRobert Watson obj = SLOT(dvplabel); 2672c27b50f5SRobert Watson 26733f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2674c27b50f5SRobert Watson return (EACCES); 2675c27b50f5SRobert Watson 26767bb9c8a0SRobert Watson obj = SLOT(vplabel); 26773f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2678c27b50f5SRobert Watson return (EACCES); 2679c27b50f5SRobert Watson 2680c27b50f5SRobert Watson return (0); 2681c27b50f5SRobert Watson } 2682c27b50f5SRobert Watson 2683c27b50f5SRobert Watson static int 26843f1a7a90SRobert Watson mls_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 268578007886SRobert Watson struct label *vplabel, int attrnamespace) 268654e2c147SRobert Watson { 268754e2c147SRobert Watson 268854e2c147SRobert Watson struct mac_mls *subj, *obj; 268954e2c147SRobert Watson 26903f1a7a90SRobert Watson if (!mls_enabled) 269154e2c147SRobert Watson return (0); 269254e2c147SRobert Watson 2693eca8a663SRobert Watson subj = SLOT(cred->cr_label); 269478007886SRobert Watson obj = SLOT(vplabel); 269554e2c147SRobert Watson 26963f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 269754e2c147SRobert Watson return (EACCES); 269854e2c147SRobert Watson 269954e2c147SRobert Watson return (0); 270054e2c147SRobert Watson } 270154e2c147SRobert Watson 270254e2c147SRobert Watson static int 27033f1a7a90SRobert Watson mls_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 270478007886SRobert Watson struct label *dvplabel, struct componentname *cnp) 2705d8a7b7a3SRobert Watson { 2706d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2707d8a7b7a3SRobert Watson 27083f1a7a90SRobert Watson if (!mls_enabled) 2709d8a7b7a3SRobert Watson return (0); 2710d8a7b7a3SRobert Watson 2711eca8a663SRobert Watson subj = SLOT(cred->cr_label); 271278007886SRobert Watson obj = SLOT(dvplabel); 2713d8a7b7a3SRobert Watson 27143f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2715d8a7b7a3SRobert Watson return (EACCES); 2716d8a7b7a3SRobert Watson 2717d8a7b7a3SRobert Watson return (0); 2718d8a7b7a3SRobert Watson } 2719d8a7b7a3SRobert Watson 2720d8a7b7a3SRobert Watson static int 27213f1a7a90SRobert Watson mls_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 272278007886SRobert Watson struct label *vplabel, int prot, int flags) 2723e183f80eSRobert Watson { 2724e183f80eSRobert Watson struct mac_mls *subj, *obj; 2725e183f80eSRobert Watson 2726e183f80eSRobert Watson /* 2727e183f80eSRobert Watson * Rely on the use of open()-time protections to handle 2728e183f80eSRobert Watson * non-revocation cases. 2729e183f80eSRobert Watson */ 27303f1a7a90SRobert Watson if (!mls_enabled || !revocation_enabled) 2731e183f80eSRobert Watson return (0); 2732e183f80eSRobert Watson 2733eca8a663SRobert Watson subj = SLOT(cred->cr_label); 273478007886SRobert Watson obj = SLOT(vplabel); 2735e183f80eSRobert Watson 2736e183f80eSRobert Watson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 27373f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2738e183f80eSRobert Watson return (EACCES); 2739e183f80eSRobert Watson } 2740c92163dcSChristian S.J. Peron if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 27413f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2742e183f80eSRobert Watson return (EACCES); 2743e183f80eSRobert Watson } 2744e183f80eSRobert Watson 2745e183f80eSRobert Watson return (0); 2746e183f80eSRobert Watson } 2747e183f80eSRobert Watson 2748e183f80eSRobert Watson static int 27493f1a7a90SRobert Watson mls_vnode_check_open(struct ucred *cred, struct vnode *vp, 275015bc6b2bSEdward Tomasz Napierala struct label *vplabel, accmode_t accmode) 2751d8a7b7a3SRobert Watson { 2752d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2753d8a7b7a3SRobert Watson 27543f1a7a90SRobert Watson if (!mls_enabled) 2755d8a7b7a3SRobert Watson return (0); 2756d8a7b7a3SRobert Watson 2757eca8a663SRobert Watson subj = SLOT(cred->cr_label); 275878007886SRobert Watson obj = SLOT(vplabel); 2759d8a7b7a3SRobert Watson 2760d8a7b7a3SRobert Watson /* XXX privilege override for admin? */ 27616180d318SEdward Tomasz Napierala if (accmode & (VREAD | VEXEC | VSTAT_PERMS)) { 27623f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2763d8a7b7a3SRobert Watson return (EACCES); 2764d8a7b7a3SRobert Watson } 27656180d318SEdward Tomasz Napierala if (accmode & VMODIFY_PERMS) { 27663f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2767d8a7b7a3SRobert Watson return (EACCES); 2768d8a7b7a3SRobert Watson } 2769d8a7b7a3SRobert Watson 2770d8a7b7a3SRobert Watson return (0); 2771d8a7b7a3SRobert Watson } 2772d8a7b7a3SRobert Watson 2773d8a7b7a3SRobert Watson static int 27743f1a7a90SRobert Watson mls_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 277578007886SRobert Watson struct vnode *vp, struct label *vplabel) 27767f724f8bSRobert Watson { 27777f724f8bSRobert Watson struct mac_mls *subj, *obj; 27787f724f8bSRobert Watson 27793f1a7a90SRobert Watson if (!mls_enabled || !revocation_enabled) 27807f724f8bSRobert Watson return (0); 27817f724f8bSRobert Watson 2782eca8a663SRobert Watson subj = SLOT(active_cred->cr_label); 278378007886SRobert Watson obj = SLOT(vplabel); 27847f724f8bSRobert Watson 27853f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 27867f724f8bSRobert Watson return (EACCES); 27877f724f8bSRobert Watson 27887f724f8bSRobert Watson return (0); 27897f724f8bSRobert Watson } 27907f724f8bSRobert Watson 27917f724f8bSRobert Watson static int 27923f1a7a90SRobert Watson mls_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 279378007886SRobert Watson struct vnode *vp, struct label *vplabel) 27947f724f8bSRobert Watson { 27957f724f8bSRobert Watson struct mac_mls *subj, *obj; 27967f724f8bSRobert Watson 27973f1a7a90SRobert Watson if (!mls_enabled || !revocation_enabled) 27987f724f8bSRobert Watson return (0); 27997f724f8bSRobert Watson 2800eca8a663SRobert Watson subj = SLOT(active_cred->cr_label); 280178007886SRobert Watson obj = SLOT(vplabel); 28027f724f8bSRobert Watson 28033f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 28047f724f8bSRobert Watson return (EACCES); 28057f724f8bSRobert Watson 28067f724f8bSRobert Watson return (0); 28077f724f8bSRobert Watson } 28087f724f8bSRobert Watson 28097f724f8bSRobert Watson static int 28103f1a7a90SRobert Watson mls_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 281178007886SRobert Watson struct label *dvplabel) 2812d8a7b7a3SRobert Watson { 2813d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2814d8a7b7a3SRobert Watson 28153f1a7a90SRobert Watson if (!mls_enabled) 2816d8a7b7a3SRobert Watson return (0); 2817d8a7b7a3SRobert Watson 2818eca8a663SRobert Watson subj = SLOT(cred->cr_label); 281978007886SRobert Watson obj = SLOT(dvplabel); 2820d8a7b7a3SRobert Watson 28213f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2822d8a7b7a3SRobert Watson return (EACCES); 2823d8a7b7a3SRobert Watson 2824d8a7b7a3SRobert Watson return (0); 2825d8a7b7a3SRobert Watson } 2826d8a7b7a3SRobert Watson 2827d8a7b7a3SRobert Watson static int 28283f1a7a90SRobert Watson mls_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 282978007886SRobert Watson struct label *vplabel) 2830d8a7b7a3SRobert Watson { 2831d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2832d8a7b7a3SRobert Watson 28333f1a7a90SRobert Watson if (!mls_enabled) 2834d8a7b7a3SRobert Watson return (0); 2835d8a7b7a3SRobert Watson 2836eca8a663SRobert Watson subj = SLOT(cred->cr_label); 283778007886SRobert Watson obj = SLOT(vplabel); 2838d8a7b7a3SRobert Watson 28393f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 2840d8a7b7a3SRobert Watson return (EACCES); 2841d8a7b7a3SRobert Watson 2842d8a7b7a3SRobert Watson return (0); 2843d8a7b7a3SRobert Watson } 2844d8a7b7a3SRobert Watson 2845d8a7b7a3SRobert Watson static int 28463f1a7a90SRobert Watson mls_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 284778007886SRobert Watson struct label *vplabel, struct label *newlabel) 2848d8a7b7a3SRobert Watson { 2849d8a7b7a3SRobert Watson struct mac_mls *old, *new, *subj; 2850b5f072b5SRobert Watson int error; 2851d8a7b7a3SRobert Watson 285278007886SRobert Watson old = SLOT(vplabel); 2853d8a7b7a3SRobert Watson new = SLOT(newlabel); 2854eca8a663SRobert Watson subj = SLOT(cred->cr_label); 2855d8a7b7a3SRobert Watson 2856b5f072b5SRobert Watson /* 2857b5f072b5SRobert Watson * If there is an MLS label update for the vnode, it must be a 2858dee57980SRobert Watson * effective label. 2859b5f072b5SRobert Watson */ 2860dee57980SRobert Watson error = mls_atmostflags(new, MAC_MLS_FLAG_EFFECTIVE); 2861b5f072b5SRobert Watson if (error) 2862b5f072b5SRobert Watson return (error); 2863d8a7b7a3SRobert Watson 2864d8a7b7a3SRobert Watson /* 2865b5f072b5SRobert Watson * To perform a relabel of the vnode (MLS label or not), MLS must 2866b5f072b5SRobert Watson * authorize the relabel. 2867d8a7b7a3SRobert Watson */ 28683f1a7a90SRobert Watson if (!mls_effective_in_range(old, subj)) 2869d8a7b7a3SRobert Watson return (EPERM); 2870d8a7b7a3SRobert Watson 2871d8a7b7a3SRobert Watson /* 2872b5f072b5SRobert Watson * If the MLS label is to be changed, authorize as appropriate. 2873b5f072b5SRobert Watson */ 2874dee57980SRobert Watson if (new->mm_flags & MAC_MLS_FLAG_EFFECTIVE) { 2875b5f072b5SRobert Watson /* 2876b5f072b5SRobert Watson * To change the MLS label on a vnode, the new vnode label 2877b5f072b5SRobert Watson * must be in the subject range. 2878d8a7b7a3SRobert Watson */ 28793f1a7a90SRobert Watson if (!mls_effective_in_range(new, subj)) 2880d8a7b7a3SRobert Watson return (EPERM); 2881d8a7b7a3SRobert Watson 2882d8a7b7a3SRobert Watson /* 28833f1a7a90SRobert Watson * To change the MLS label on the vnode to be EQUAL, the 28843f1a7a90SRobert Watson * subject must have appropriate privilege. 2885d8a7b7a3SRobert Watson */ 28863f1a7a90SRobert Watson if (mls_contains_equal(new)) { 28873f1a7a90SRobert Watson error = mls_subject_privileged(subj); 2888b5f072b5SRobert Watson if (error) 2889b5f072b5SRobert Watson return (error); 2890b5f072b5SRobert Watson } 2891b5f072b5SRobert Watson } 2892d8a7b7a3SRobert Watson 2893b5f072b5SRobert Watson return (0); 2894d8a7b7a3SRobert Watson } 2895d8a7b7a3SRobert Watson 2896d8a7b7a3SRobert Watson static int 28973f1a7a90SRobert Watson mls_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 289878007886SRobert Watson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2899d8a7b7a3SRobert Watson struct componentname *cnp) 2900d8a7b7a3SRobert Watson { 2901d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2902d8a7b7a3SRobert Watson 29033f1a7a90SRobert Watson if (!mls_enabled) 2904d8a7b7a3SRobert Watson return (0); 2905d8a7b7a3SRobert Watson 2906eca8a663SRobert Watson subj = SLOT(cred->cr_label); 290778007886SRobert Watson obj = SLOT(dvplabel); 2908d8a7b7a3SRobert Watson 29093f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2910d8a7b7a3SRobert Watson return (EACCES); 2911d8a7b7a3SRobert Watson 291278007886SRobert Watson obj = SLOT(vplabel); 2913d8a7b7a3SRobert Watson 29143f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2915d8a7b7a3SRobert Watson return (EACCES); 2916d8a7b7a3SRobert Watson 2917d8a7b7a3SRobert Watson return (0); 2918d8a7b7a3SRobert Watson } 2919d8a7b7a3SRobert Watson 2920d8a7b7a3SRobert Watson static int 29213f1a7a90SRobert Watson mls_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 292278007886SRobert Watson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 292378007886SRobert Watson int samedir, struct componentname *cnp) 2924d8a7b7a3SRobert Watson { 2925d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2926d8a7b7a3SRobert Watson 29273f1a7a90SRobert Watson if (!mls_enabled) 2928d8a7b7a3SRobert Watson return (0); 2929d8a7b7a3SRobert Watson 2930eca8a663SRobert Watson subj = SLOT(cred->cr_label); 293178007886SRobert Watson obj = SLOT(dvplabel); 2932d8a7b7a3SRobert Watson 29333f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2934d8a7b7a3SRobert Watson return (EACCES); 2935d8a7b7a3SRobert Watson 2936d8a7b7a3SRobert Watson if (vp != NULL) { 293778007886SRobert Watson obj = SLOT(vplabel); 2938d8a7b7a3SRobert Watson 29393f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2940d8a7b7a3SRobert Watson return (EACCES); 2941d8a7b7a3SRobert Watson } 2942d8a7b7a3SRobert Watson 2943d8a7b7a3SRobert Watson return (0); 2944d8a7b7a3SRobert Watson } 2945d8a7b7a3SRobert Watson 2946d8a7b7a3SRobert Watson static int 29473f1a7a90SRobert Watson mls_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 294878007886SRobert Watson struct label *vplabel) 2949d8a7b7a3SRobert Watson { 2950d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2951d8a7b7a3SRobert Watson 29523f1a7a90SRobert Watson if (!mls_enabled) 2953d8a7b7a3SRobert Watson return (0); 2954d8a7b7a3SRobert Watson 2955eca8a663SRobert Watson subj = SLOT(cred->cr_label); 295678007886SRobert Watson obj = SLOT(vplabel); 2957d8a7b7a3SRobert Watson 29583f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2959d8a7b7a3SRobert Watson return (EACCES); 2960d8a7b7a3SRobert Watson 2961d8a7b7a3SRobert Watson return (0); 2962d8a7b7a3SRobert Watson } 2963d8a7b7a3SRobert Watson 2964d8a7b7a3SRobert Watson static int 29653f1a7a90SRobert Watson mls_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 296678007886SRobert Watson struct label *vplabel, acl_type_t type, struct acl *acl) 2967d8a7b7a3SRobert Watson { 2968d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2969d8a7b7a3SRobert Watson 29703f1a7a90SRobert Watson if (!mls_enabled) 2971d8a7b7a3SRobert Watson return (0); 2972d8a7b7a3SRobert Watson 2973eca8a663SRobert Watson subj = SLOT(cred->cr_label); 297478007886SRobert Watson obj = SLOT(vplabel); 2975d8a7b7a3SRobert Watson 29763f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2977d8a7b7a3SRobert Watson return (EACCES); 2978d8a7b7a3SRobert Watson 2979d8a7b7a3SRobert Watson return (0); 2980d8a7b7a3SRobert Watson } 2981d8a7b7a3SRobert Watson 2982d8a7b7a3SRobert Watson static int 29833f1a7a90SRobert Watson mls_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2984fefd0ac8SRobert Watson struct label *vplabel, int attrnamespace, const char *name) 2985d8a7b7a3SRobert Watson { 2986d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 2987d8a7b7a3SRobert Watson 29883f1a7a90SRobert Watson if (!mls_enabled) 2989d8a7b7a3SRobert Watson return (0); 2990d8a7b7a3SRobert Watson 2991eca8a663SRobert Watson subj = SLOT(cred->cr_label); 299278007886SRobert Watson obj = SLOT(vplabel); 2993d8a7b7a3SRobert Watson 29943f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 2995d8a7b7a3SRobert Watson return (EACCES); 2996d8a7b7a3SRobert Watson 2997d8a7b7a3SRobert Watson /* XXX: protect the MAC EA in a special way? */ 2998d8a7b7a3SRobert Watson 2999d8a7b7a3SRobert Watson return (0); 3000d8a7b7a3SRobert Watson } 3001d8a7b7a3SRobert Watson 3002d8a7b7a3SRobert Watson static int 30033f1a7a90SRobert Watson mls_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 300478007886SRobert Watson struct label *vplabel, u_long flags) 3005d8a7b7a3SRobert Watson { 3006d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 3007d8a7b7a3SRobert Watson 30083f1a7a90SRobert Watson if (!mls_enabled) 3009d8a7b7a3SRobert Watson return (0); 3010d8a7b7a3SRobert Watson 3011eca8a663SRobert Watson subj = SLOT(cred->cr_label); 301278007886SRobert Watson obj = SLOT(vplabel); 3013d8a7b7a3SRobert Watson 30143f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 3015d8a7b7a3SRobert Watson return (EACCES); 3016d8a7b7a3SRobert Watson 3017d8a7b7a3SRobert Watson return (0); 3018d8a7b7a3SRobert Watson } 3019d8a7b7a3SRobert Watson 3020d8a7b7a3SRobert Watson static int 30213f1a7a90SRobert Watson mls_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 302278007886SRobert Watson struct label *vplabel, mode_t mode) 3023d8a7b7a3SRobert Watson { 3024d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 3025d8a7b7a3SRobert Watson 30263f1a7a90SRobert Watson if (!mls_enabled) 3027d8a7b7a3SRobert Watson return (0); 3028d8a7b7a3SRobert Watson 3029eca8a663SRobert Watson subj = SLOT(cred->cr_label); 303078007886SRobert Watson obj = SLOT(vplabel); 3031d8a7b7a3SRobert Watson 30323f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 3033d8a7b7a3SRobert Watson return (EACCES); 3034d8a7b7a3SRobert Watson 3035d8a7b7a3SRobert Watson return (0); 3036d8a7b7a3SRobert Watson } 3037d8a7b7a3SRobert Watson 3038d8a7b7a3SRobert Watson static int 30393f1a7a90SRobert Watson mls_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 304078007886SRobert Watson struct label *vplabel, uid_t uid, gid_t gid) 3041d8a7b7a3SRobert Watson { 3042d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 3043d8a7b7a3SRobert Watson 30443f1a7a90SRobert Watson if (!mls_enabled) 3045d8a7b7a3SRobert Watson return (0); 3046d8a7b7a3SRobert Watson 3047eca8a663SRobert Watson subj = SLOT(cred->cr_label); 304878007886SRobert Watson obj = SLOT(vplabel); 3049d8a7b7a3SRobert Watson 30503f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 3051d8a7b7a3SRobert Watson return (EACCES); 3052d8a7b7a3SRobert Watson 3053d8a7b7a3SRobert Watson return (0); 3054d8a7b7a3SRobert Watson } 3055d8a7b7a3SRobert Watson 3056d8a7b7a3SRobert Watson static int 30573f1a7a90SRobert Watson mls_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 305878007886SRobert Watson struct label *vplabel, struct timespec atime, struct timespec mtime) 3059d8a7b7a3SRobert Watson { 3060d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 3061d8a7b7a3SRobert Watson 30623f1a7a90SRobert Watson if (!mls_enabled) 3063d8a7b7a3SRobert Watson return (0); 3064d8a7b7a3SRobert Watson 3065eca8a663SRobert Watson subj = SLOT(cred->cr_label); 306678007886SRobert Watson obj = SLOT(vplabel); 3067d8a7b7a3SRobert Watson 30683f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 3069d8a7b7a3SRobert Watson return (EACCES); 3070d8a7b7a3SRobert Watson 3071d8a7b7a3SRobert Watson return (0); 3072d8a7b7a3SRobert Watson } 3073d8a7b7a3SRobert Watson 3074d8a7b7a3SRobert Watson static int 30753f1a7a90SRobert Watson mls_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 307678007886SRobert Watson struct vnode *vp, struct label *vplabel) 3077d8a7b7a3SRobert Watson { 3078d8a7b7a3SRobert Watson struct mac_mls *subj, *obj; 3079d8a7b7a3SRobert Watson 30803f1a7a90SRobert Watson if (!mls_enabled) 3081d8a7b7a3SRobert Watson return (0); 3082d8a7b7a3SRobert Watson 3083eca8a663SRobert Watson subj = SLOT(active_cred->cr_label); 308478007886SRobert Watson obj = SLOT(vplabel); 3085d8a7b7a3SRobert Watson 30863f1a7a90SRobert Watson if (!mls_dominate_effective(subj, obj)) 3087d8a7b7a3SRobert Watson return (EACCES); 3088d8a7b7a3SRobert Watson 3089d8a7b7a3SRobert Watson return (0); 3090d8a7b7a3SRobert Watson } 3091d8a7b7a3SRobert Watson 30927f724f8bSRobert Watson static int 30933f1a7a90SRobert Watson mls_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 309445e0f3d6SRobert Watson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 309545e0f3d6SRobert Watson struct componentname *cnp) 309645e0f3d6SRobert Watson { 309745e0f3d6SRobert Watson struct mac_mls *subj, *obj; 309845e0f3d6SRobert Watson 30993f1a7a90SRobert Watson if (!mls_enabled) 310045e0f3d6SRobert Watson return (0); 310145e0f3d6SRobert Watson 310245e0f3d6SRobert Watson subj = SLOT(cred->cr_label); 310345e0f3d6SRobert Watson obj = SLOT(dvplabel); 310445e0f3d6SRobert Watson 31053f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 310645e0f3d6SRobert Watson return (EACCES); 310745e0f3d6SRobert Watson 310845e0f3d6SRobert Watson obj = SLOT(vplabel); 310945e0f3d6SRobert Watson 31103f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 311145e0f3d6SRobert Watson return (EACCES); 311245e0f3d6SRobert Watson 311345e0f3d6SRobert Watson return (0); 311445e0f3d6SRobert Watson } 311545e0f3d6SRobert Watson 311645e0f3d6SRobert Watson static int 31173f1a7a90SRobert Watson mls_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred, 311878007886SRobert Watson struct vnode *vp, struct label *vplabel) 31197f724f8bSRobert Watson { 31207f724f8bSRobert Watson struct mac_mls *subj, *obj; 31217f724f8bSRobert Watson 31223f1a7a90SRobert Watson if (!mls_enabled || !revocation_enabled) 31237f724f8bSRobert Watson return (0); 31247f724f8bSRobert Watson 3125eca8a663SRobert Watson subj = SLOT(active_cred->cr_label); 312678007886SRobert Watson obj = SLOT(vplabel); 31277f724f8bSRobert Watson 31283f1a7a90SRobert Watson if (!mls_dominate_effective(obj, subj)) 31297f724f8bSRobert Watson return (EACCES); 31307f724f8bSRobert Watson 31317f724f8bSRobert Watson return (0); 31327f724f8bSRobert Watson } 31337f724f8bSRobert Watson 3134eb320b0eSRobert Watson static int 3135eb320b0eSRobert Watson mls_vnode_create_extattr(struct ucred *cred, struct mount *mp, 3136eb320b0eSRobert Watson struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 3137eb320b0eSRobert Watson struct vnode *vp, struct label *vplabel, struct componentname *cnp) 3138eb320b0eSRobert Watson { 3139eb320b0eSRobert Watson struct mac_mls *source, *dest, mm_temp; 3140eb320b0eSRobert Watson size_t buflen; 3141eb320b0eSRobert Watson int error; 3142eb320b0eSRobert Watson 3143eb320b0eSRobert Watson buflen = sizeof(mm_temp); 3144eb320b0eSRobert Watson bzero(&mm_temp, buflen); 3145eb320b0eSRobert Watson 3146eb320b0eSRobert Watson source = SLOT(cred->cr_label); 3147eb320b0eSRobert Watson dest = SLOT(vplabel); 3148eb320b0eSRobert Watson mls_copy_effective(source, &mm_temp); 3149eb320b0eSRobert Watson 3150eb320b0eSRobert Watson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 3151eb320b0eSRobert Watson MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 3152eb320b0eSRobert Watson if (error == 0) 3153eb320b0eSRobert Watson mls_copy_effective(source, dest); 3154eb320b0eSRobert Watson return (error); 3155eb320b0eSRobert Watson } 3156eb320b0eSRobert Watson 3157eb320b0eSRobert Watson static void 3158eb320b0eSRobert Watson mls_vnode_relabel(struct ucred *cred, struct vnode *vp, 3159eb320b0eSRobert Watson struct label *vplabel, struct label *label) 3160eb320b0eSRobert Watson { 3161eb320b0eSRobert Watson struct mac_mls *source, *dest; 3162eb320b0eSRobert Watson 3163eb320b0eSRobert Watson source = SLOT(label); 3164eb320b0eSRobert Watson dest = SLOT(vplabel); 3165eb320b0eSRobert Watson 3166eb320b0eSRobert Watson mls_copy(source, dest); 3167eb320b0eSRobert Watson } 3168eb320b0eSRobert Watson 3169eb320b0eSRobert Watson static int 3170eb320b0eSRobert Watson mls_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 3171eb320b0eSRobert Watson struct label *vplabel, struct label *intlabel) 3172eb320b0eSRobert Watson { 3173eb320b0eSRobert Watson struct mac_mls *source, mm_temp; 3174eb320b0eSRobert Watson size_t buflen; 3175eb320b0eSRobert Watson int error; 3176eb320b0eSRobert Watson 3177eb320b0eSRobert Watson buflen = sizeof(mm_temp); 3178eb320b0eSRobert Watson bzero(&mm_temp, buflen); 3179eb320b0eSRobert Watson 3180eb320b0eSRobert Watson source = SLOT(intlabel); 3181eb320b0eSRobert Watson if ((source->mm_flags & MAC_MLS_FLAG_EFFECTIVE) == 0) 3182eb320b0eSRobert Watson return (0); 3183eb320b0eSRobert Watson 3184eb320b0eSRobert Watson mls_copy_effective(source, &mm_temp); 3185eb320b0eSRobert Watson 3186eb320b0eSRobert Watson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE, 3187eb320b0eSRobert Watson MAC_MLS_EXTATTR_NAME, buflen, (char *) &mm_temp, curthread); 3188eb320b0eSRobert Watson return (error); 3189eb320b0eSRobert Watson } 3190eb320b0eSRobert Watson 31913f1a7a90SRobert Watson static struct mac_policy_ops mls_ops = 3192d8a7b7a3SRobert Watson { 31933f1a7a90SRobert Watson .mpo_init = mls_init, 3194eb320b0eSRobert Watson 3195eb320b0eSRobert Watson .mpo_bpfdesc_check_receive = mls_bpfdesc_check_receive, 3196eb320b0eSRobert Watson .mpo_bpfdesc_create = mls_bpfdesc_create, 3197eb320b0eSRobert Watson .mpo_bpfdesc_create_mbuf = mls_bpfdesc_create_mbuf, 31983f1a7a90SRobert Watson .mpo_bpfdesc_destroy_label = mls_destroy_label, 3199eb320b0eSRobert Watson .mpo_bpfdesc_init_label = mls_init_label, 3200eb320b0eSRobert Watson 3201212ab0cfSRobert Watson .mpo_cred_associate_nfsd = mls_cred_associate_nfsd, 3202eb320b0eSRobert Watson .mpo_cred_check_relabel = mls_cred_check_relabel, 3203eb320b0eSRobert Watson .mpo_cred_check_visible = mls_cred_check_visible, 32043f1a7a90SRobert Watson .mpo_cred_copy_label = mls_copy_label, 3205212ab0cfSRobert Watson .mpo_cred_create_init = mls_cred_create_init, 3206212ab0cfSRobert Watson .mpo_cred_create_swapper = mls_cred_create_swapper, 3207eb320b0eSRobert Watson .mpo_cred_destroy_label = mls_destroy_label, 32083f1a7a90SRobert Watson .mpo_cred_externalize_label = mls_externalize_label, 3209eb320b0eSRobert Watson .mpo_cred_init_label = mls_init_label, 32103f1a7a90SRobert Watson .mpo_cred_internalize_label = mls_internalize_label, 3211eb320b0eSRobert Watson .mpo_cred_relabel = mls_cred_relabel, 3212eb320b0eSRobert Watson 32133f1a7a90SRobert Watson .mpo_devfs_create_device = mls_devfs_create_device, 32143f1a7a90SRobert Watson .mpo_devfs_create_directory = mls_devfs_create_directory, 32153f1a7a90SRobert Watson .mpo_devfs_create_symlink = mls_devfs_create_symlink, 3216eb320b0eSRobert Watson .mpo_devfs_destroy_label = mls_destroy_label, 3217eb320b0eSRobert Watson .mpo_devfs_init_label = mls_init_label, 32183f1a7a90SRobert Watson .mpo_devfs_update = mls_devfs_update, 32193f1a7a90SRobert Watson .mpo_devfs_vnode_associate = mls_devfs_vnode_associate, 3220eb320b0eSRobert Watson 32213f1a7a90SRobert Watson .mpo_ifnet_check_relabel = mls_ifnet_check_relabel, 32223f1a7a90SRobert Watson .mpo_ifnet_check_transmit = mls_ifnet_check_transmit, 3223eb320b0eSRobert Watson .mpo_ifnet_copy_label = mls_copy_label, 3224eb320b0eSRobert Watson .mpo_ifnet_create = mls_ifnet_create, 3225eb320b0eSRobert Watson .mpo_ifnet_create_mbuf = mls_ifnet_create_mbuf, 3226eb320b0eSRobert Watson .mpo_ifnet_destroy_label = mls_destroy_label, 3227eb320b0eSRobert Watson .mpo_ifnet_externalize_label = mls_externalize_label, 3228eb320b0eSRobert Watson .mpo_ifnet_init_label = mls_init_label, 3229eb320b0eSRobert Watson .mpo_ifnet_internalize_label = mls_internalize_label, 3230eb320b0eSRobert Watson .mpo_ifnet_relabel = mls_ifnet_relabel, 3231eb320b0eSRobert Watson 32323f1a7a90SRobert Watson .mpo_inpcb_check_deliver = mls_inpcb_check_deliver, 32337fb179baSBjoern A. Zeeb .mpo_inpcb_check_visible = mls_inpcb_check_visible, 3234eb320b0eSRobert Watson .mpo_inpcb_create = mls_inpcb_create, 3235eb320b0eSRobert Watson .mpo_inpcb_create_mbuf = mls_inpcb_create_mbuf, 3236eb320b0eSRobert Watson .mpo_inpcb_destroy_label = mls_destroy_label, 3237eb320b0eSRobert Watson .mpo_inpcb_init_label = mls_init_label_waitcheck, 3238eb320b0eSRobert Watson .mpo_inpcb_sosetlabel = mls_inpcb_sosetlabel, 3239eb320b0eSRobert Watson 3240048e1287SRobert Watson .mpo_ip6q_create = mls_ip6q_create, 3241048e1287SRobert Watson .mpo_ip6q_destroy_label = mls_destroy_label, 3242048e1287SRobert Watson .mpo_ip6q_init_label = mls_init_label_waitcheck, 3243048e1287SRobert Watson .mpo_ip6q_match = mls_ip6q_match, 3244048e1287SRobert Watson .mpo_ip6q_reassemble = mls_ip6q_reassemble, 3245048e1287SRobert Watson .mpo_ip6q_update = mls_ip6q_update, 3246048e1287SRobert Watson 3247eb320b0eSRobert Watson .mpo_ipq_create = mls_ipq_create, 3248eb320b0eSRobert Watson .mpo_ipq_destroy_label = mls_destroy_label, 3249eb320b0eSRobert Watson .mpo_ipq_init_label = mls_init_label_waitcheck, 3250eb320b0eSRobert Watson .mpo_ipq_match = mls_ipq_match, 3251eb320b0eSRobert Watson .mpo_ipq_reassemble = mls_ipq_reassemble, 3252eb320b0eSRobert Watson .mpo_ipq_update = mls_ipq_update, 3253eb320b0eSRobert Watson 3254eb320b0eSRobert Watson .mpo_mbuf_copy_label = mls_copy_label, 3255eb320b0eSRobert Watson .mpo_mbuf_destroy_label = mls_destroy_label, 3256eb320b0eSRobert Watson .mpo_mbuf_init_label = mls_init_label_waitcheck, 3257eb320b0eSRobert Watson 32583f1a7a90SRobert Watson .mpo_mount_check_stat = mls_mount_check_stat, 3259eb320b0eSRobert Watson .mpo_mount_create = mls_mount_create, 3260eb320b0eSRobert Watson .mpo_mount_destroy_label = mls_destroy_label, 3261eb320b0eSRobert Watson .mpo_mount_init_label = mls_init_label, 3262eb320b0eSRobert Watson 3263eb320b0eSRobert Watson .mpo_netinet_arp_send = mls_netinet_arp_send, 3264eb320b0eSRobert Watson .mpo_netinet_firewall_reply = mls_netinet_firewall_reply, 3265eb320b0eSRobert Watson .mpo_netinet_firewall_send = mls_netinet_firewall_send, 3266eb320b0eSRobert Watson .mpo_netinet_fragment = mls_netinet_fragment, 3267eb320b0eSRobert Watson .mpo_netinet_icmp_reply = mls_netinet_icmp_reply, 3268eb320b0eSRobert Watson .mpo_netinet_igmp_send = mls_netinet_igmp_send, 3269eb320b0eSRobert Watson 3270eb320b0eSRobert Watson .mpo_netinet6_nd6_send = mls_netinet6_nd6_send, 3271eb320b0eSRobert Watson 32723f1a7a90SRobert Watson .mpo_pipe_check_ioctl = mls_pipe_check_ioctl, 32733f1a7a90SRobert Watson .mpo_pipe_check_poll = mls_pipe_check_poll, 32743f1a7a90SRobert Watson .mpo_pipe_check_read = mls_pipe_check_read, 32753f1a7a90SRobert Watson .mpo_pipe_check_relabel = mls_pipe_check_relabel, 32763f1a7a90SRobert Watson .mpo_pipe_check_stat = mls_pipe_check_stat, 32773f1a7a90SRobert Watson .mpo_pipe_check_write = mls_pipe_check_write, 3278eb320b0eSRobert Watson .mpo_pipe_copy_label = mls_copy_label, 3279eb320b0eSRobert Watson .mpo_pipe_create = mls_pipe_create, 3280eb320b0eSRobert Watson .mpo_pipe_destroy_label = mls_destroy_label, 3281eb320b0eSRobert Watson .mpo_pipe_externalize_label = mls_externalize_label, 3282eb320b0eSRobert Watson .mpo_pipe_init_label = mls_init_label, 3283eb320b0eSRobert Watson .mpo_pipe_internalize_label = mls_internalize_label, 3284eb320b0eSRobert Watson .mpo_pipe_relabel = mls_pipe_relabel, 3285eb320b0eSRobert Watson 32863f1a7a90SRobert Watson .mpo_posixsem_check_getvalue = mls_posixsem_check_rdonly, 32876bc1e9cdSJohn Baldwin .mpo_posixsem_check_open = mls_posixsem_check_openunlink, 32883f1a7a90SRobert Watson .mpo_posixsem_check_post = mls_posixsem_check_write, 32899b6dd12eSRobert Watson .mpo_posixsem_check_setmode = mls_posixsem_check_setmode, 32909b6dd12eSRobert Watson .mpo_posixsem_check_setowner = mls_posixsem_check_setowner, 32916bc1e9cdSJohn Baldwin .mpo_posixsem_check_stat = mls_posixsem_check_rdonly, 32926bc1e9cdSJohn Baldwin .mpo_posixsem_check_unlink = mls_posixsem_check_openunlink, 32933f1a7a90SRobert Watson .mpo_posixsem_check_wait = mls_posixsem_check_write, 3294eb320b0eSRobert Watson .mpo_posixsem_create = mls_posixsem_create, 3295eb320b0eSRobert Watson .mpo_posixsem_destroy_label = mls_destroy_label, 3296eb320b0eSRobert Watson .mpo_posixsem_init_label = mls_init_label, 3297eb320b0eSRobert Watson 32989b6dd12eSRobert Watson .mpo_posixshm_check_mmap = mls_posixshm_check_mmap, 32999b6dd12eSRobert Watson .mpo_posixshm_check_open = mls_posixshm_check_open, 3300940cb0e2SKonstantin Belousov .mpo_posixshm_check_read = mls_posixshm_check_read, 33019b6dd12eSRobert Watson .mpo_posixshm_check_setmode = mls_posixshm_check_setmode, 33029b6dd12eSRobert Watson .mpo_posixshm_check_setowner = mls_posixshm_check_setowner, 33039b6dd12eSRobert Watson .mpo_posixshm_check_stat = mls_posixshm_check_stat, 33049b6dd12eSRobert Watson .mpo_posixshm_check_truncate = mls_posixshm_check_truncate, 33059b6dd12eSRobert Watson .mpo_posixshm_check_unlink = mls_posixshm_check_unlink, 3306940cb0e2SKonstantin Belousov .mpo_posixshm_check_write = mls_posixshm_check_write, 33079b6dd12eSRobert Watson .mpo_posixshm_create = mls_posixshm_create, 33089b6dd12eSRobert Watson .mpo_posixshm_destroy_label = mls_destroy_label, 33099b6dd12eSRobert Watson .mpo_posixshm_init_label = mls_init_label, 33109b6dd12eSRobert Watson 33113f1a7a90SRobert Watson .mpo_proc_check_debug = mls_proc_check_debug, 33123f1a7a90SRobert Watson .mpo_proc_check_sched = mls_proc_check_sched, 33133f1a7a90SRobert Watson .mpo_proc_check_signal = mls_proc_check_signal, 3314eb320b0eSRobert Watson 33153f1a7a90SRobert Watson .mpo_socket_check_deliver = mls_socket_check_deliver, 33163f1a7a90SRobert Watson .mpo_socket_check_relabel = mls_socket_check_relabel, 33173f1a7a90SRobert Watson .mpo_socket_check_visible = mls_socket_check_visible, 3318eb320b0eSRobert Watson .mpo_socket_copy_label = mls_copy_label, 3319eb320b0eSRobert Watson .mpo_socket_create = mls_socket_create, 3320eb320b0eSRobert Watson .mpo_socket_create_mbuf = mls_socket_create_mbuf, 3321eb320b0eSRobert Watson .mpo_socket_destroy_label = mls_destroy_label, 3322eb320b0eSRobert Watson .mpo_socket_externalize_label = mls_externalize_label, 3323eb320b0eSRobert Watson .mpo_socket_init_label = mls_init_label_waitcheck, 3324eb320b0eSRobert Watson .mpo_socket_internalize_label = mls_internalize_label, 3325eb320b0eSRobert Watson .mpo_socket_newconn = mls_socket_newconn, 3326eb320b0eSRobert Watson .mpo_socket_relabel = mls_socket_relabel, 3327eb320b0eSRobert Watson 3328eb320b0eSRobert Watson .mpo_socketpeer_destroy_label = mls_destroy_label, 3329eb320b0eSRobert Watson .mpo_socketpeer_externalize_label = mls_externalize_label, 3330eb320b0eSRobert Watson .mpo_socketpeer_init_label = mls_init_label_waitcheck, 3331eb320b0eSRobert Watson .mpo_socketpeer_set_from_mbuf = mls_socketpeer_set_from_mbuf, 3332eb320b0eSRobert Watson .mpo_socketpeer_set_from_socket = mls_socketpeer_set_from_socket, 3333eb320b0eSRobert Watson 3334eb320b0eSRobert Watson .mpo_syncache_create = mls_syncache_create, 3335eb320b0eSRobert Watson .mpo_syncache_create_mbuf = mls_syncache_create_mbuf, 3336eb320b0eSRobert Watson .mpo_syncache_destroy_label = mls_destroy_label, 3337eb320b0eSRobert Watson .mpo_syncache_init_label = mls_init_label_waitcheck, 3338eb320b0eSRobert Watson 3339eb320b0eSRobert Watson .mpo_sysvmsg_cleanup = mls_sysvmsg_cleanup, 3340eb320b0eSRobert Watson .mpo_sysvmsg_create = mls_sysvmsg_create, 3341eb320b0eSRobert Watson .mpo_sysvmsg_destroy_label = mls_destroy_label, 3342eb320b0eSRobert Watson .mpo_sysvmsg_init_label = mls_init_label, 3343eb320b0eSRobert Watson 3344eb320b0eSRobert Watson .mpo_sysvmsq_check_msgrcv = mls_sysvmsq_check_msgrcv, 3345eb320b0eSRobert Watson .mpo_sysvmsq_check_msgrmid = mls_sysvmsq_check_msgrmid, 3346eb320b0eSRobert Watson .mpo_sysvmsq_check_msqget = mls_sysvmsq_check_msqget, 3347eb320b0eSRobert Watson .mpo_sysvmsq_check_msqsnd = mls_sysvmsq_check_msqsnd, 3348eb320b0eSRobert Watson .mpo_sysvmsq_check_msqrcv = mls_sysvmsq_check_msqrcv, 3349eb320b0eSRobert Watson .mpo_sysvmsq_check_msqctl = mls_sysvmsq_check_msqctl, 3350eb320b0eSRobert Watson .mpo_sysvmsq_cleanup = mls_sysvmsq_cleanup, 3351eb320b0eSRobert Watson .mpo_sysvmsq_destroy_label = mls_destroy_label, 3352eb320b0eSRobert Watson .mpo_sysvmsq_init_label = mls_init_label, 3353eb320b0eSRobert Watson .mpo_sysvmsq_create = mls_sysvmsq_create, 3354eb320b0eSRobert Watson 3355eb320b0eSRobert Watson .mpo_sysvsem_check_semctl = mls_sysvsem_check_semctl, 3356eb320b0eSRobert Watson .mpo_sysvsem_check_semget = mls_sysvsem_check_semget, 3357eb320b0eSRobert Watson .mpo_sysvsem_check_semop = mls_sysvsem_check_semop, 3358eb320b0eSRobert Watson .mpo_sysvsem_cleanup = mls_sysvsem_cleanup, 3359eb320b0eSRobert Watson .mpo_sysvsem_create = mls_sysvsem_create, 3360eb320b0eSRobert Watson .mpo_sysvsem_destroy_label = mls_destroy_label, 3361eb320b0eSRobert Watson .mpo_sysvsem_init_label = mls_init_label, 3362eb320b0eSRobert Watson 3363eb320b0eSRobert Watson .mpo_sysvshm_check_shmat = mls_sysvshm_check_shmat, 3364eb320b0eSRobert Watson .mpo_sysvshm_check_shmctl = mls_sysvshm_check_shmctl, 3365eb320b0eSRobert Watson .mpo_sysvshm_check_shmget = mls_sysvshm_check_shmget, 3366eb320b0eSRobert Watson .mpo_sysvshm_cleanup = mls_sysvshm_cleanup, 3367eb320b0eSRobert Watson .mpo_sysvshm_create = mls_sysvshm_create, 3368eb320b0eSRobert Watson .mpo_sysvshm_destroy_label = mls_destroy_label, 3369eb320b0eSRobert Watson .mpo_sysvshm_init_label = mls_init_label, 3370eb320b0eSRobert Watson 33713f1a7a90SRobert Watson .mpo_system_check_acct = mls_system_check_acct, 33723f1a7a90SRobert Watson .mpo_system_check_auditctl = mls_system_check_auditctl, 33733f1a7a90SRobert Watson .mpo_system_check_swapon = mls_system_check_swapon, 3374eb320b0eSRobert Watson 3375eb320b0eSRobert Watson .mpo_vnode_associate_extattr = mls_vnode_associate_extattr, 3376eb320b0eSRobert Watson .mpo_vnode_associate_singlelabel = mls_vnode_associate_singlelabel, 33773f1a7a90SRobert Watson .mpo_vnode_check_access = mls_vnode_check_open, 33783f1a7a90SRobert Watson .mpo_vnode_check_chdir = mls_vnode_check_chdir, 33793f1a7a90SRobert Watson .mpo_vnode_check_chroot = mls_vnode_check_chroot, 33803f1a7a90SRobert Watson .mpo_vnode_check_create = mls_vnode_check_create, 33813f1a7a90SRobert Watson .mpo_vnode_check_deleteacl = mls_vnode_check_deleteacl, 33823f1a7a90SRobert Watson .mpo_vnode_check_deleteextattr = mls_vnode_check_deleteextattr, 33833f1a7a90SRobert Watson .mpo_vnode_check_exec = mls_vnode_check_exec, 33843f1a7a90SRobert Watson .mpo_vnode_check_getacl = mls_vnode_check_getacl, 33853f1a7a90SRobert Watson .mpo_vnode_check_getextattr = mls_vnode_check_getextattr, 33863f1a7a90SRobert Watson .mpo_vnode_check_link = mls_vnode_check_link, 33873f1a7a90SRobert Watson .mpo_vnode_check_listextattr = mls_vnode_check_listextattr, 33883f1a7a90SRobert Watson .mpo_vnode_check_lookup = mls_vnode_check_lookup, 33893f1a7a90SRobert Watson .mpo_vnode_check_mmap = mls_vnode_check_mmap, 33903f1a7a90SRobert Watson .mpo_vnode_check_open = mls_vnode_check_open, 33913f1a7a90SRobert Watson .mpo_vnode_check_poll = mls_vnode_check_poll, 33923f1a7a90SRobert Watson .mpo_vnode_check_read = mls_vnode_check_read, 33933f1a7a90SRobert Watson .mpo_vnode_check_readdir = mls_vnode_check_readdir, 33943f1a7a90SRobert Watson .mpo_vnode_check_readlink = mls_vnode_check_readlink, 33953f1a7a90SRobert Watson .mpo_vnode_check_relabel = mls_vnode_check_relabel, 33963f1a7a90SRobert Watson .mpo_vnode_check_rename_from = mls_vnode_check_rename_from, 33973f1a7a90SRobert Watson .mpo_vnode_check_rename_to = mls_vnode_check_rename_to, 33983f1a7a90SRobert Watson .mpo_vnode_check_revoke = mls_vnode_check_revoke, 33993f1a7a90SRobert Watson .mpo_vnode_check_setacl = mls_vnode_check_setacl, 34003f1a7a90SRobert Watson .mpo_vnode_check_setextattr = mls_vnode_check_setextattr, 34013f1a7a90SRobert Watson .mpo_vnode_check_setflags = mls_vnode_check_setflags, 34023f1a7a90SRobert Watson .mpo_vnode_check_setmode = mls_vnode_check_setmode, 34033f1a7a90SRobert Watson .mpo_vnode_check_setowner = mls_vnode_check_setowner, 34043f1a7a90SRobert Watson .mpo_vnode_check_setutimes = mls_vnode_check_setutimes, 34053f1a7a90SRobert Watson .mpo_vnode_check_stat = mls_vnode_check_stat, 34063f1a7a90SRobert Watson .mpo_vnode_check_unlink = mls_vnode_check_unlink, 34073f1a7a90SRobert Watson .mpo_vnode_check_write = mls_vnode_check_write, 3408eb320b0eSRobert Watson .mpo_vnode_copy_label = mls_copy_label, 3409eb320b0eSRobert Watson .mpo_vnode_create_extattr = mls_vnode_create_extattr, 3410eb320b0eSRobert Watson .mpo_vnode_destroy_label = mls_destroy_label, 3411eb320b0eSRobert Watson .mpo_vnode_externalize_label = mls_externalize_label, 3412eb320b0eSRobert Watson .mpo_vnode_init_label = mls_init_label, 3413eb320b0eSRobert Watson .mpo_vnode_internalize_label = mls_internalize_label, 3414eb320b0eSRobert Watson .mpo_vnode_relabel = mls_vnode_relabel, 3415eb320b0eSRobert Watson .mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr, 3416d8a7b7a3SRobert Watson }; 3417d8a7b7a3SRobert Watson 34183f1a7a90SRobert Watson MAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS", 34199162f64bSRobert Watson MPC_LOADTIME_FLAG_NOTLATE, &mls_slot); 3420