mac_biba.c revision 122563
1101099Srwatson/*- 2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3115497Srwatson * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. 4101099Srwatson * All rights reserved. 5101099Srwatson * 6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 7101099Srwatson * 8106393Srwatson * This software was developed for the FreeBSD Project in part by Network 9106393Srwatson * Associates Laboratories, the Security Research Division of Network 10106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 11106393Srwatson * as part of the DARPA CHATS research program. 12101099Srwatson * 13101099Srwatson * Redistribution and use in source and binary forms, with or without 14101099Srwatson * modification, are permitted provided that the following conditions 15101099Srwatson * are met: 16101099Srwatson * 1. Redistributions of source code must retain the above copyright 17101099Srwatson * notice, this list of conditions and the following disclaimer. 18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright 19101099Srwatson * notice, this list of conditions and the following disclaimer in the 20101099Srwatson * documentation and/or other materials provided with the distribution. 21101099Srwatson * 22101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32101099Srwatson * SUCH DAMAGE. 33101099Srwatson * 34101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 122563 2003-11-12 15:09:39Z rwatson $ 35101099Srwatson */ 36101099Srwatson 37101099Srwatson/* 38101099Srwatson * Developed by the TrustedBSD Project. 39101099Srwatson * Biba fixed label mandatory integrity policy. 40101099Srwatson */ 41101099Srwatson 42101099Srwatson#include <sys/types.h> 43101099Srwatson#include <sys/param.h> 44101099Srwatson#include <sys/acl.h> 45101099Srwatson#include <sys/conf.h> 46105988Srwatson#include <sys/extattr.h> 47101099Srwatson#include <sys/kernel.h> 48101099Srwatson#include <sys/mac.h> 49103183Sbde#include <sys/malloc.h> 50101099Srwatson#include <sys/mount.h> 51101099Srwatson#include <sys/proc.h> 52115497Srwatson#include <sys/sbuf.h> 53101099Srwatson#include <sys/systm.h> 54101099Srwatson#include <sys/sysproto.h> 55101099Srwatson#include <sys/sysent.h> 56105696Srwatson#include <sys/systm.h> 57101099Srwatson#include <sys/vnode.h> 58101099Srwatson#include <sys/file.h> 59101099Srwatson#include <sys/socket.h> 60101099Srwatson#include <sys/socketvar.h> 61101099Srwatson#include <sys/pipe.h> 62101099Srwatson#include <sys/sysctl.h> 63101099Srwatson 64101099Srwatson#include <fs/devfs/devfs.h> 65101099Srwatson 66101099Srwatson#include <net/bpfdesc.h> 67101099Srwatson#include <net/if.h> 68101099Srwatson#include <net/if_types.h> 69101099Srwatson#include <net/if_var.h> 70101099Srwatson 71101099Srwatson#include <netinet/in.h> 72101099Srwatson#include <netinet/ip_var.h> 73101099Srwatson 74101099Srwatson#include <vm/vm.h> 75101099Srwatson 76101099Srwatson#include <sys/mac_policy.h> 77101099Srwatson 78101099Srwatson#include <security/mac_biba/mac_biba.h> 79101099Srwatson 80101099SrwatsonSYSCTL_DECL(_security_mac); 81101099Srwatson 82101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 83101099Srwatson "TrustedBSD mac_biba policy controls"); 84101099Srwatson 85105988Srwatsonstatic int mac_biba_label_size = sizeof(struct mac_biba); 86105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 87105988Srwatson &mac_biba_label_size, 0, "Size of struct mac_biba"); 88105988Srwatson 89107731Srwatsonstatic int mac_biba_enabled = 1; 90101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 91101099Srwatson &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 92102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 93101099Srwatson 94101099Srwatsonstatic int destroyed_not_inited; 95101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 96101099Srwatson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 97101099Srwatson 98101099Srwatsonstatic int trust_all_interfaces = 0; 99101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 100101099Srwatson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 101101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 102101099Srwatson 103101099Srwatsonstatic char trusted_interfaces[128]; 104101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 105101099Srwatson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 106101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 107101099Srwatson sizeof(trusted_interfaces)); 108101099Srwatson 109105643Srwatsonstatic int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 110105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 111105643Srwatson &max_compartments, 0, "Maximum supported compartments"); 112105643Srwatson 113105606Srwatsonstatic int ptys_equal = 0; 114105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 115105606Srwatson &ptys_equal, 0, "Label pty devices as biba/equal on create"); 116105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 117105606Srwatson 118105637Srwatsonstatic int revocation_enabled = 0; 119101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 120105637Srwatson &revocation_enabled, 0, "Revoke access to objects on relabel"); 121105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 122101099Srwatson 123101099Srwatsonstatic int mac_biba_slot; 124101099Srwatson#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 125101099Srwatson 126101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels"); 127101099Srwatson 128105643Srwatsonstatic __inline int 129105643Srwatsonbiba_bit_set_empty(u_char *set) { 130105643Srwatson int i; 131105643Srwatson 132105643Srwatson for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 133105643Srwatson if (set[i] != 0) 134105643Srwatson return (0); 135105643Srwatson return (1); 136105643Srwatson} 137105643Srwatson 138101099Srwatsonstatic struct mac_biba * 139104514Srwatsonbiba_alloc(int flag) 140101099Srwatson{ 141101099Srwatson struct mac_biba *mac_biba; 142101099Srwatson 143104514Srwatson mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag); 144101099Srwatson 145101099Srwatson return (mac_biba); 146101099Srwatson} 147101099Srwatson 148101099Srwatsonstatic void 149101099Srwatsonbiba_free(struct mac_biba *mac_biba) 150101099Srwatson{ 151101099Srwatson 152101099Srwatson if (mac_biba != NULL) 153101099Srwatson free(mac_biba, M_MACBIBA); 154101099Srwatson else 155101099Srwatson atomic_add_int(&destroyed_not_inited, 1); 156101099Srwatson} 157101099Srwatson 158101099Srwatsonstatic int 159105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags) 160105634Srwatson{ 161105634Srwatson 162105634Srwatson if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 163105634Srwatson return (EINVAL); 164105634Srwatson return (0); 165105634Srwatson} 166105634Srwatson 167105634Srwatsonstatic int 168101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a, 169101099Srwatson struct mac_biba_element *b) 170101099Srwatson{ 171105643Srwatson int bit; 172101099Srwatson 173105736Srwatson switch (a->mbe_type) { 174101099Srwatson case MAC_BIBA_TYPE_EQUAL: 175101099Srwatson case MAC_BIBA_TYPE_HIGH: 176101099Srwatson return (1); 177101099Srwatson 178101099Srwatson case MAC_BIBA_TYPE_LOW: 179101099Srwatson switch (b->mbe_type) { 180101099Srwatson case MAC_BIBA_TYPE_GRADE: 181101099Srwatson case MAC_BIBA_TYPE_HIGH: 182101099Srwatson return (0); 183101099Srwatson 184101099Srwatson case MAC_BIBA_TYPE_EQUAL: 185101099Srwatson case MAC_BIBA_TYPE_LOW: 186101099Srwatson return (1); 187101099Srwatson 188101099Srwatson default: 189101099Srwatson panic("mac_biba_dominate_element: b->mbe_type invalid"); 190101099Srwatson } 191101099Srwatson 192101099Srwatson case MAC_BIBA_TYPE_GRADE: 193101099Srwatson switch (b->mbe_type) { 194101099Srwatson case MAC_BIBA_TYPE_EQUAL: 195101099Srwatson case MAC_BIBA_TYPE_LOW: 196101099Srwatson return (1); 197101099Srwatson 198101099Srwatson case MAC_BIBA_TYPE_HIGH: 199101099Srwatson return (0); 200101099Srwatson 201101099Srwatson case MAC_BIBA_TYPE_GRADE: 202105643Srwatson for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 203105643Srwatson if (!MAC_BIBA_BIT_TEST(bit, 204105643Srwatson a->mbe_compartments) && 205105643Srwatson MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 206105643Srwatson return (0); 207101099Srwatson return (a->mbe_grade >= b->mbe_grade); 208101099Srwatson 209101099Srwatson default: 210101099Srwatson panic("mac_biba_dominate_element: b->mbe_type invalid"); 211101099Srwatson } 212101099Srwatson 213101099Srwatson default: 214101099Srwatson panic("mac_biba_dominate_element: a->mbe_type invalid"); 215101099Srwatson } 216101099Srwatson 217101099Srwatson return (0); 218101099Srwatson} 219101099Srwatson 220101099Srwatsonstatic int 221105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba) 222105988Srwatson{ 223105988Srwatson struct mac_biba_element *element; 224105988Srwatson 225106174Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 226105988Srwatson ("mac_biba_single_in_range: mac_biba not single")); 227105988Srwatson element = &mac_biba->mb_single; 228105988Srwatson 229105988Srwatson return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 230105988Srwatson element->mbe_type == MAC_BIBA_TYPE_HIGH); 231105988Srwatson} 232105988Srwatson 233105988Srwatsonstatic int 234101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 235101099Srwatson{ 236101099Srwatson 237101099Srwatson return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 238101099Srwatson &rangea->mb_rangehigh) && 239101099Srwatson mac_biba_dominate_element(&rangea->mb_rangelow, 240101099Srwatson &rangeb->mb_rangelow)); 241101099Srwatson} 242101099Srwatson 243101099Srwatsonstatic int 244101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range) 245101099Srwatson{ 246101099Srwatson 247103750Srwatson KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 248101099Srwatson ("mac_biba_single_in_range: a not single")); 249103750Srwatson KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 250101099Srwatson ("mac_biba_single_in_range: b not range")); 251101099Srwatson 252101099Srwatson return (mac_biba_dominate_element(&range->mb_rangehigh, 253101099Srwatson &single->mb_single) && 254101099Srwatson mac_biba_dominate_element(&single->mb_single, 255101099Srwatson &range->mb_rangelow)); 256101099Srwatson 257101099Srwatson return (1); 258101099Srwatson} 259101099Srwatson 260101099Srwatsonstatic int 261101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b) 262101099Srwatson{ 263101099Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 264101099Srwatson ("mac_biba_dominate_single: a not single")); 265101099Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 266101099Srwatson ("mac_biba_dominate_single: b not single")); 267101099Srwatson 268101099Srwatson return (mac_biba_dominate_element(&a->mb_single, &b->mb_single)); 269101099Srwatson} 270101099Srwatson 271101099Srwatsonstatic int 272101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 273101099Srwatson{ 274101099Srwatson 275101099Srwatson if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 276101099Srwatson b->mbe_type == MAC_BIBA_TYPE_EQUAL) 277101099Srwatson return (1); 278101099Srwatson 279101099Srwatson return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 280101099Srwatson} 281101099Srwatson 282101099Srwatsonstatic int 283101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b) 284101099Srwatson{ 285101099Srwatson 286101099Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 287101099Srwatson ("mac_biba_equal_single: a not single")); 288101099Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 289101099Srwatson ("mac_biba_equal_single: b not single")); 290101099Srwatson 291101099Srwatson return (mac_biba_equal_element(&a->mb_single, &b->mb_single)); 292101099Srwatson} 293101099Srwatson 294101099Srwatsonstatic int 295105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba) 296105634Srwatson{ 297105634Srwatson 298105634Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) 299105634Srwatson if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 300105634Srwatson return (1); 301105634Srwatson 302105634Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 303105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 304105634Srwatson return (1); 305105634Srwatson if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 306105637Srwatson return (1); 307105634Srwatson } 308105634Srwatson 309105634Srwatson return (0); 310105634Srwatson} 311105634Srwatson 312105634Srwatsonstatic int 313106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba) 314105634Srwatson{ 315105634Srwatson 316105634Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 317105634Srwatson MAC_BIBA_FLAGS_BOTH, 318106090Srwatson ("mac_biba_subject_privileged: subject doesn't have both labels")); 319105634Srwatson 320105634Srwatson /* If the single is EQUAL, it's ok. */ 321105634Srwatson if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 322105634Srwatson return (0); 323105634Srwatson 324105634Srwatson /* If either range endpoint is EQUAL, it's ok. */ 325105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 326105634Srwatson mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 327105634Srwatson return (0); 328105634Srwatson 329105634Srwatson /* If the range is low-high, it's ok. */ 330105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 331105634Srwatson mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 332105634Srwatson return (0); 333105634Srwatson 334105634Srwatson /* It's not ok. */ 335105634Srwatson return (EPERM); 336105634Srwatson} 337105634Srwatson 338106091Srwatsonstatic int 339105988Srwatsonmac_biba_high_single(struct mac_biba *mac_biba) 340105988Srwatson{ 341105988Srwatson 342105988Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 343105988Srwatson ("mac_biba_equal_single: mac_biba not single")); 344105988Srwatson 345105988Srwatson return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH); 346105988Srwatson} 347105988Srwatson 348105634Srwatsonstatic int 349101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba) 350101099Srwatson{ 351101099Srwatson 352101099Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 353101099Srwatson switch (mac_biba->mb_single.mbe_type) { 354101099Srwatson case MAC_BIBA_TYPE_GRADE: 355101099Srwatson break; 356101099Srwatson 357101099Srwatson case MAC_BIBA_TYPE_EQUAL: 358101099Srwatson case MAC_BIBA_TYPE_HIGH: 359101099Srwatson case MAC_BIBA_TYPE_LOW: 360105643Srwatson if (mac_biba->mb_single.mbe_grade != 0 || 361105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 362105643Srwatson mac_biba->mb_single.mbe_compartments)) 363101099Srwatson return (EINVAL); 364101099Srwatson break; 365101099Srwatson 366101099Srwatson default: 367101099Srwatson return (EINVAL); 368101099Srwatson } 369101099Srwatson } else { 370101099Srwatson if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 371101099Srwatson return (EINVAL); 372101099Srwatson } 373101099Srwatson 374101099Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 375101099Srwatson switch (mac_biba->mb_rangelow.mbe_type) { 376101099Srwatson case MAC_BIBA_TYPE_GRADE: 377101099Srwatson break; 378101099Srwatson 379101099Srwatson case MAC_BIBA_TYPE_EQUAL: 380101099Srwatson case MAC_BIBA_TYPE_HIGH: 381101099Srwatson case MAC_BIBA_TYPE_LOW: 382105643Srwatson if (mac_biba->mb_rangelow.mbe_grade != 0 || 383105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 384105643Srwatson mac_biba->mb_rangelow.mbe_compartments)) 385101099Srwatson return (EINVAL); 386101099Srwatson break; 387101099Srwatson 388101099Srwatson default: 389101099Srwatson return (EINVAL); 390101099Srwatson } 391101099Srwatson 392101099Srwatson switch (mac_biba->mb_rangehigh.mbe_type) { 393101099Srwatson case MAC_BIBA_TYPE_GRADE: 394101099Srwatson break; 395101099Srwatson 396101099Srwatson case MAC_BIBA_TYPE_EQUAL: 397101099Srwatson case MAC_BIBA_TYPE_HIGH: 398101099Srwatson case MAC_BIBA_TYPE_LOW: 399105643Srwatson if (mac_biba->mb_rangehigh.mbe_grade != 0 || 400105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 401105643Srwatson mac_biba->mb_rangehigh.mbe_compartments)) 402101099Srwatson return (EINVAL); 403101099Srwatson break; 404101099Srwatson 405101099Srwatson default: 406101099Srwatson return (EINVAL); 407101099Srwatson } 408101099Srwatson if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 409101099Srwatson &mac_biba->mb_rangelow)) 410101099Srwatson return (EINVAL); 411101099Srwatson } else { 412101099Srwatson if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 413101099Srwatson mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 414101099Srwatson return (EINVAL); 415101099Srwatson } 416101099Srwatson 417101099Srwatson return (0); 418101099Srwatson} 419101099Srwatson 420101099Srwatsonstatic void 421101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 422105643Srwatson u_short gradelow, u_char *compartmentslow, u_short typehigh, 423105643Srwatson u_short gradehigh, u_char *compartmentshigh) 424101099Srwatson{ 425101099Srwatson 426101099Srwatson mac_biba->mb_rangelow.mbe_type = typelow; 427101099Srwatson mac_biba->mb_rangelow.mbe_grade = gradelow; 428105643Srwatson if (compartmentslow != NULL) 429105643Srwatson memcpy(mac_biba->mb_rangelow.mbe_compartments, 430105643Srwatson compartmentslow, 431105643Srwatson sizeof(mac_biba->mb_rangelow.mbe_compartments)); 432101099Srwatson mac_biba->mb_rangehigh.mbe_type = typehigh; 433101099Srwatson mac_biba->mb_rangehigh.mbe_grade = gradehigh; 434105643Srwatson if (compartmentshigh != NULL) 435105643Srwatson memcpy(mac_biba->mb_rangehigh.mbe_compartments, 436105643Srwatson compartmentshigh, 437105643Srwatson sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 438101099Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 439101099Srwatson} 440101099Srwatson 441101099Srwatsonstatic void 442105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 443105643Srwatson u_char *compartments) 444101099Srwatson{ 445101099Srwatson 446101099Srwatson mac_biba->mb_single.mbe_type = type; 447101099Srwatson mac_biba->mb_single.mbe_grade = grade; 448105643Srwatson if (compartments != NULL) 449105643Srwatson memcpy(mac_biba->mb_single.mbe_compartments, compartments, 450105643Srwatson sizeof(mac_biba->mb_single.mbe_compartments)); 451101099Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 452101099Srwatson} 453101099Srwatson 454101099Srwatsonstatic void 455101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 456101099Srwatson{ 457105643Srwatson 458101099Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 459101099Srwatson ("mac_biba_copy_range: labelfrom not range")); 460101099Srwatson 461101099Srwatson labelto->mb_rangelow = labelfrom->mb_rangelow; 462101099Srwatson labelto->mb_rangehigh = labelfrom->mb_rangehigh; 463101099Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 464101099Srwatson} 465101099Srwatson 466101099Srwatsonstatic void 467101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 468101099Srwatson{ 469101099Srwatson 470101099Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 471101099Srwatson ("mac_biba_copy_single: labelfrom not single")); 472101099Srwatson 473101099Srwatson labelto->mb_single = labelfrom->mb_single; 474101099Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 475101099Srwatson} 476101099Srwatson 477105656Srwatsonstatic void 478105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 479105656Srwatson{ 480105656Srwatson 481105656Srwatson if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 482105656Srwatson mac_biba_copy_single(source, dest); 483105656Srwatson if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 484105656Srwatson mac_biba_copy_range(source, dest); 485105656Srwatson} 486105656Srwatson 487101099Srwatson/* 488101099Srwatson * Policy module operations. 489101099Srwatson */ 490101099Srwatsonstatic void 491101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf) 492101099Srwatson{ 493101099Srwatson 494101099Srwatson} 495101099Srwatson 496101099Srwatsonstatic void 497101099Srwatsonmac_biba_init(struct mac_policy_conf *conf) 498101099Srwatson{ 499101099Srwatson 500101099Srwatson} 501101099Srwatson 502101099Srwatson/* 503101099Srwatson * Label operations. 504101099Srwatson */ 505101099Srwatsonstatic void 506104514Srwatsonmac_biba_init_label(struct label *label) 507101099Srwatson{ 508101099Srwatson 509111119Simp SLOT(label) = biba_alloc(M_WAITOK); 510101099Srwatson} 511101099Srwatson 512101099Srwatsonstatic int 513104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag) 514101099Srwatson{ 515101099Srwatson 516104514Srwatson SLOT(label) = biba_alloc(flag); 517101099Srwatson if (SLOT(label) == NULL) 518101099Srwatson return (ENOMEM); 519101099Srwatson 520101099Srwatson return (0); 521101099Srwatson} 522101099Srwatson 523101099Srwatsonstatic void 524104514Srwatsonmac_biba_destroy_label(struct label *label) 525101099Srwatson{ 526101099Srwatson 527101099Srwatson biba_free(SLOT(label)); 528101099Srwatson SLOT(label) = NULL; 529101099Srwatson} 530101099Srwatson 531105696Srwatson/* 532115497Srwatson * mac_biba_element_to_string() accepts an sbuf and Biba element. It 533115497Srwatson * converts the Biba element to a string and stores the result in the 534115497Srwatson * sbuf; if there isn't space in the sbuf, -1 is returned. 535105696Srwatson */ 536115497Srwatsonstatic int 537115497Srwatsonmac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element) 538105696Srwatson{ 539115497Srwatson int i, first; 540105696Srwatson 541105696Srwatson switch (element->mbe_type) { 542105696Srwatson case MAC_BIBA_TYPE_HIGH: 543115497Srwatson return (sbuf_printf(sb, "high")); 544105696Srwatson 545105696Srwatson case MAC_BIBA_TYPE_LOW: 546115497Srwatson return (sbuf_printf(sb, "low")); 547105696Srwatson 548105696Srwatson case MAC_BIBA_TYPE_EQUAL: 549115497Srwatson return (sbuf_printf(sb, "equal")); 550105696Srwatson 551105696Srwatson case MAC_BIBA_TYPE_GRADE: 552115497Srwatson if (sbuf_printf(sb, "%d", element->mbe_grade) == -1) 553115497Srwatson return (-1); 554115497Srwatson 555115497Srwatson first = 1; 556115497Srwatson for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) { 557115497Srwatson if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) { 558115497Srwatson if (first) { 559115497Srwatson if (sbuf_putc(sb, ':') == -1) 560115497Srwatson return (-1); 561115497Srwatson if (sbuf_printf(sb, "%d", i) == -1) 562115497Srwatson return (-1); 563115497Srwatson first = 0; 564115497Srwatson } else { 565115497Srwatson if (sbuf_printf(sb, "+%d", i) == -1) 566115497Srwatson return (-1); 567115497Srwatson } 568115497Srwatson } 569105696Srwatson } 570115497Srwatson return (0); 571105696Srwatson 572105696Srwatson default: 573105696Srwatson panic("mac_biba_element_to_string: invalid type (%d)", 574105696Srwatson element->mbe_type); 575105696Srwatson } 576105696Srwatson} 577105696Srwatson 578115497Srwatson/* 579116701Srwatson * mac_biba_to_string() converts a Biba label to a string, and places 580116701Srwatson * the results in the passed sbuf. It returns 0 on success, or EINVAL 581116701Srwatson * if there isn't room in the sbuf. Note: the sbuf will be modified 582116701Srwatson * even in a failure case, so the caller may need to revert the sbuf 583116701Srwatson * by restoring the offset if that's undesired. 584115497Srwatson */ 585101099Srwatsonstatic int 586116701Srwatsonmac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba) 587101099Srwatson{ 588105696Srwatson 589105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 590116701Srwatson if (mac_biba_element_to_string(sb, &mac_biba->mb_single) 591115497Srwatson == -1) 592105696Srwatson return (EINVAL); 593105696Srwatson } 594105696Srwatson 595105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 596116701Srwatson if (sbuf_putc(sb, '(') == -1) 597105696Srwatson return (EINVAL); 598105696Srwatson 599116701Srwatson if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow) 600115497Srwatson == -1) 601105696Srwatson return (EINVAL); 602105696Srwatson 603116701Srwatson if (sbuf_putc(sb, '-') == -1) 604105696Srwatson return (EINVAL); 605105696Srwatson 606116701Srwatson if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh) 607115497Srwatson == -1) 608105696Srwatson return (EINVAL); 609105696Srwatson 610116701Srwatson if (sbuf_putc(sb, ')') == -1) 611105696Srwatson return (EINVAL); 612105696Srwatson } 613105696Srwatson 614105696Srwatson return (0); 615105696Srwatson} 616105696Srwatson 617105696Srwatsonstatic int 618105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name, 619116701Srwatson struct sbuf *sb, int *claimed) 620105696Srwatson{ 621101099Srwatson struct mac_biba *mac_biba; 622101099Srwatson 623105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 624105696Srwatson return (0); 625105696Srwatson 626105696Srwatson (*claimed)++; 627105696Srwatson 628101099Srwatson mac_biba = SLOT(label); 629116701Srwatson return (mac_biba_to_string(sb, mac_biba)); 630105696Srwatson} 631105696Srwatson 632105696Srwatsonstatic int 633105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string) 634101099Srwatson{ 635115395Srwatson char *compartment, *end, *grade; 636115395Srwatson int value; 637105696Srwatson 638105696Srwatson if (strcmp(string, "high") == 0 || 639105696Srwatson strcmp(string, "hi") == 0) { 640105696Srwatson element->mbe_type = MAC_BIBA_TYPE_HIGH; 641105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 642105696Srwatson } else if (strcmp(string, "low") == 0 || 643105696Srwatson strcmp(string, "lo") == 0) { 644105696Srwatson element->mbe_type = MAC_BIBA_TYPE_LOW; 645105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 646105696Srwatson } else if (strcmp(string, "equal") == 0 || 647105696Srwatson strcmp(string, "eq") == 0) { 648105696Srwatson element->mbe_type = MAC_BIBA_TYPE_EQUAL; 649105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 650105696Srwatson } else { 651115395Srwatson element->mbe_type = MAC_BIBA_TYPE_GRADE; 652105696Srwatson 653115395Srwatson /* 654115395Srwatson * Numeric grade piece of the element. 655115395Srwatson */ 656115395Srwatson grade = strsep(&string, ":"); 657115395Srwatson value = strtol(grade, &end, 10); 658115395Srwatson if (end == grade || *end != '\0') 659105696Srwatson return (EINVAL); 660115395Srwatson if (value < 0 || value > 65535) 661115395Srwatson return (EINVAL); 662115395Srwatson element->mbe_grade = value; 663105696Srwatson 664115395Srwatson /* 665115395Srwatson * Optional compartment piece of the element. If none 666115395Srwatson * are included, we assume that the label has no 667115395Srwatson * compartments. 668115395Srwatson */ 669115395Srwatson if (string == NULL) 670115395Srwatson return (0); 671115395Srwatson if (*string == '\0') 672115395Srwatson return (0); 673105696Srwatson 674115395Srwatson while ((compartment = strsep(&string, "+")) != NULL) { 675115395Srwatson value = strtol(compartment, &end, 10); 676115395Srwatson if (compartment == end || *end != '\0') 677105696Srwatson return (EINVAL); 678115395Srwatson if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 679105696Srwatson return (EINVAL); 680115395Srwatson MAC_BIBA_BIT_SET(value, element->mbe_compartments); 681105696Srwatson } 682105696Srwatson } 683105696Srwatson 684105696Srwatson return (0); 685105696Srwatson} 686105696Srwatson 687105696Srwatson/* 688105696Srwatson * Note: destructively consumes the string, make a local copy before 689105696Srwatson * calling if that's a problem. 690105696Srwatson */ 691105696Srwatsonstatic int 692105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string) 693105696Srwatson{ 694115395Srwatson char *rangehigh, *rangelow, *single; 695101099Srwatson int error; 696101099Srwatson 697115395Srwatson single = strsep(&string, "("); 698115395Srwatson if (*single == '\0') 699105696Srwatson single = NULL; 700115395Srwatson 701115395Srwatson if (string != NULL) { 702115395Srwatson rangelow = strsep(&string, "-"); 703115395Srwatson if (string == NULL) 704105696Srwatson return (EINVAL); 705115395Srwatson rangehigh = strsep(&string, ")"); 706115395Srwatson if (string == NULL) 707105696Srwatson return (EINVAL); 708115395Srwatson if (*string != '\0') 709105696Srwatson return (EINVAL); 710115395Srwatson } else { 711115395Srwatson rangelow = NULL; 712115395Srwatson rangehigh = NULL; 713105696Srwatson } 714115395Srwatson 715105696Srwatson KASSERT((rangelow != NULL && rangehigh != NULL) || 716105696Srwatson (rangelow == NULL && rangehigh == NULL), 717115395Srwatson ("mac_biba_parse: range mismatch")); 718101099Srwatson 719105696Srwatson bzero(mac_biba, sizeof(*mac_biba)); 720105696Srwatson if (single != NULL) { 721105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_single, single); 722105696Srwatson if (error) 723105696Srwatson return (error); 724105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 725105696Srwatson } 726105696Srwatson 727105696Srwatson if (rangelow != NULL) { 728105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangelow, 729105696Srwatson rangelow); 730105696Srwatson if (error) 731105696Srwatson return (error); 732105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 733105696Srwatson rangehigh); 734105696Srwatson if (error) 735105696Srwatson return (error); 736105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 737105696Srwatson } 738105696Srwatson 739101099Srwatson error = mac_biba_valid(mac_biba); 740101099Srwatson if (error) 741101099Srwatson return (error); 742101099Srwatson 743105696Srwatson return (0); 744105696Srwatson} 745101099Srwatson 746105696Srwatsonstatic int 747105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name, 748105696Srwatson char *element_data, int *claimed) 749105696Srwatson{ 750105696Srwatson struct mac_biba *mac_biba, mac_biba_temp; 751105696Srwatson int error; 752105696Srwatson 753105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 754105696Srwatson return (0); 755105696Srwatson 756105696Srwatson (*claimed)++; 757105696Srwatson 758105696Srwatson error = mac_biba_parse(&mac_biba_temp, element_data); 759105696Srwatson if (error) 760105696Srwatson return (error); 761105696Srwatson 762105696Srwatson mac_biba = SLOT(label); 763105696Srwatson *mac_biba = mac_biba_temp; 764105696Srwatson 765101099Srwatson return (0); 766101099Srwatson} 767101099Srwatson 768105696Srwatsonstatic void 769105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest) 770105696Srwatson{ 771105696Srwatson 772105696Srwatson *SLOT(dest) = *SLOT(src); 773105696Srwatson} 774105696Srwatson 775101099Srwatson/* 776101099Srwatson * Labeling event operations: file system objects, and things that look 777101099Srwatson * a lot like file system objects. 778101099Srwatson */ 779101099Srwatsonstatic void 780107698Srwatsonmac_biba_create_devfs_device(struct mount *mp, dev_t dev, 781107698Srwatson struct devfs_dirent *devfs_dirent, struct label *label) 782101099Srwatson{ 783101099Srwatson struct mac_biba *mac_biba; 784101099Srwatson int biba_type; 785101099Srwatson 786101099Srwatson mac_biba = SLOT(label); 787101099Srwatson if (strcmp(dev->si_name, "null") == 0 || 788101099Srwatson strcmp(dev->si_name, "zero") == 0 || 789101099Srwatson strcmp(dev->si_name, "random") == 0 || 790101099Srwatson strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 791101099Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 792105606Srwatson else if (ptys_equal && 793105606Srwatson (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 794105606Srwatson strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 795105606Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 796101099Srwatson else 797101099Srwatson biba_type = MAC_BIBA_TYPE_HIGH; 798105643Srwatson mac_biba_set_single(mac_biba, biba_type, 0, NULL); 799101099Srwatson} 800101099Srwatson 801101099Srwatsonstatic void 802107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname, 803107698Srwatson int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 804101099Srwatson{ 805101099Srwatson struct mac_biba *mac_biba; 806101099Srwatson 807101099Srwatson mac_biba = SLOT(label); 808105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 809101099Srwatson} 810101099Srwatson 811101099Srwatsonstatic void 812107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp, 813107698Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 814122563Srwatson struct label *delabel) 815104535Srwatson{ 816104535Srwatson struct mac_biba *source, *dest; 817104535Srwatson 818122524Srwatson source = SLOT(cred->cr_label); 819104535Srwatson dest = SLOT(delabel); 820104535Srwatson 821104535Srwatson mac_biba_copy_single(source, dest); 822104535Srwatson} 823104535Srwatson 824104535Srwatsonstatic void 825101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp, 826101099Srwatson struct label *mntlabel, struct label *fslabel) 827101099Srwatson{ 828101099Srwatson struct mac_biba *source, *dest; 829101099Srwatson 830122524Srwatson source = SLOT(cred->cr_label); 831101099Srwatson dest = SLOT(mntlabel); 832101099Srwatson mac_biba_copy_single(source, dest); 833101099Srwatson dest = SLOT(fslabel); 834101099Srwatson mac_biba_copy_single(source, dest); 835101099Srwatson} 836101099Srwatson 837101099Srwatsonstatic void 838101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 839101099Srwatson struct label *mntlabel, struct label *fslabel) 840101099Srwatson{ 841101099Srwatson struct mac_biba *mac_biba; 842101099Srwatson 843101099Srwatson /* Always mount root as high integrity. */ 844101099Srwatson mac_biba = SLOT(fslabel); 845105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 846101099Srwatson mac_biba = SLOT(mntlabel); 847105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 848101099Srwatson} 849101099Srwatson 850101099Srwatsonstatic void 851101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 852101099Srwatson struct label *vnodelabel, struct label *label) 853101099Srwatson{ 854101099Srwatson struct mac_biba *source, *dest; 855101099Srwatson 856101099Srwatson source = SLOT(label); 857101099Srwatson dest = SLOT(vnodelabel); 858101099Srwatson 859105656Srwatson mac_biba_copy(source, dest); 860101099Srwatson} 861101099Srwatson 862101099Srwatsonstatic void 863107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp, 864107698Srwatson struct devfs_dirent *devfs_dirent, struct label *direntlabel, 865107698Srwatson struct vnode *vp, struct label *vnodelabel) 866101099Srwatson{ 867101099Srwatson struct mac_biba *source, *dest; 868101099Srwatson 869101099Srwatson source = SLOT(vnodelabel); 870101099Srwatson dest = SLOT(direntlabel); 871101099Srwatson 872105656Srwatson mac_biba_copy(source, dest); 873101099Srwatson} 874101099Srwatson 875101099Srwatsonstatic void 876105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 877105988Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 878105988Srwatson struct label *vlabel) 879101099Srwatson{ 880101099Srwatson struct mac_biba *source, *dest; 881101099Srwatson 882105988Srwatson source = SLOT(delabel); 883105988Srwatson dest = SLOT(vlabel); 884101099Srwatson 885101099Srwatson mac_biba_copy_single(source, dest); 886101099Srwatson} 887101099Srwatson 888101099Srwatsonstatic int 889105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 890105988Srwatson struct vnode *vp, struct label *vlabel) 891101099Srwatson{ 892105988Srwatson struct mac_biba temp, *source, *dest; 893106354Smux int buflen, error; 894101099Srwatson 895105988Srwatson source = SLOT(fslabel); 896105988Srwatson dest = SLOT(vlabel); 897101099Srwatson 898105988Srwatson buflen = sizeof(temp); 899105988Srwatson bzero(&temp, buflen); 900105988Srwatson 901105988Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 902105988Srwatson MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 903105988Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 904105988Srwatson /* Fall back to the fslabel. */ 905105988Srwatson mac_biba_copy_single(source, dest); 906105988Srwatson return (0); 907105988Srwatson } else if (error) 908101099Srwatson return (error); 909101099Srwatson 910105988Srwatson if (buflen != sizeof(temp)) { 911105988Srwatson printf("mac_biba_associate_vnode_extattr: bad size %d\n", 912105988Srwatson buflen); 913105988Srwatson return (EPERM); 914105988Srwatson } 915105988Srwatson if (mac_biba_valid(&temp) != 0) { 916105988Srwatson printf("mac_biba_associate_vnode_extattr: invalid\n"); 917105988Srwatson return (EPERM); 918105988Srwatson } 919105988Srwatson if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 920105988Srwatson printf("mac_biba_associate_vnode_extattr: not single\n"); 921105988Srwatson return (EPERM); 922105988Srwatson } 923101099Srwatson 924105988Srwatson mac_biba_copy_single(&temp, dest); 925101099Srwatson return (0); 926101099Srwatson} 927101099Srwatson 928101099Srwatsonstatic void 929105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp, 930105988Srwatson struct label *fslabel, struct vnode *vp, struct label *vlabel) 931101099Srwatson{ 932101099Srwatson struct mac_biba *source, *dest; 933101099Srwatson 934101099Srwatson source = SLOT(fslabel); 935105988Srwatson dest = SLOT(vlabel); 936101099Srwatson 937101099Srwatson mac_biba_copy_single(source, dest); 938101099Srwatson} 939101099Srwatson 940105988Srwatsonstatic int 941105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 942105988Srwatson struct label *fslabel, struct vnode *dvp, struct label *dlabel, 943105988Srwatson struct vnode *vp, struct label *vlabel, struct componentname *cnp) 944105988Srwatson{ 945105988Srwatson struct mac_biba *source, *dest, temp; 946105988Srwatson size_t buflen; 947105988Srwatson int error; 948105988Srwatson 949105988Srwatson buflen = sizeof(temp); 950105988Srwatson bzero(&temp, buflen); 951105988Srwatson 952122524Srwatson source = SLOT(cred->cr_label); 953105988Srwatson dest = SLOT(vlabel); 954105988Srwatson mac_biba_copy_single(source, &temp); 955105988Srwatson 956105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 957105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 958105988Srwatson if (error == 0) 959105988Srwatson mac_biba_copy_single(source, dest); 960105988Srwatson return (error); 961105988Srwatson} 962105988Srwatson 963105988Srwatsonstatic int 964105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 965105988Srwatson struct label *vlabel, struct label *intlabel) 966105988Srwatson{ 967105988Srwatson struct mac_biba *source, temp; 968105988Srwatson size_t buflen; 969105988Srwatson int error; 970105988Srwatson 971105988Srwatson buflen = sizeof(temp); 972105988Srwatson bzero(&temp, buflen); 973105988Srwatson 974105988Srwatson source = SLOT(intlabel); 975105988Srwatson if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 976105988Srwatson return (0); 977105988Srwatson 978105988Srwatson mac_biba_copy_single(source, &temp); 979105988Srwatson 980105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 981105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 982105988Srwatson return (error); 983105988Srwatson} 984105988Srwatson 985101099Srwatson/* 986101099Srwatson * Labeling event operations: IPC object. 987101099Srwatson */ 988101099Srwatsonstatic void 989101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 990101099Srwatson struct mbuf *m, struct label *mbuflabel) 991101099Srwatson{ 992101099Srwatson struct mac_biba *source, *dest; 993101099Srwatson 994101099Srwatson source = SLOT(socketlabel); 995101099Srwatson dest = SLOT(mbuflabel); 996101099Srwatson 997101099Srwatson mac_biba_copy_single(source, dest); 998101099Srwatson} 999101099Srwatson 1000101099Srwatsonstatic void 1001101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket, 1002101099Srwatson struct label *socketlabel) 1003101099Srwatson{ 1004101099Srwatson struct mac_biba *source, *dest; 1005101099Srwatson 1006122524Srwatson source = SLOT(cred->cr_label); 1007101099Srwatson dest = SLOT(socketlabel); 1008101099Srwatson 1009101099Srwatson mac_biba_copy_single(source, dest); 1010101099Srwatson} 1011101099Srwatson 1012101099Srwatsonstatic void 1013101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1014101099Srwatson struct label *pipelabel) 1015101099Srwatson{ 1016101099Srwatson struct mac_biba *source, *dest; 1017101099Srwatson 1018122524Srwatson source = SLOT(cred->cr_label); 1019101099Srwatson dest = SLOT(pipelabel); 1020101099Srwatson 1021101099Srwatson mac_biba_copy_single(source, dest); 1022101099Srwatson} 1023101099Srwatson 1024101099Srwatsonstatic void 1025101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket, 1026101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1027101099Srwatson struct label *newsocketlabel) 1028101099Srwatson{ 1029101099Srwatson struct mac_biba *source, *dest; 1030101099Srwatson 1031101099Srwatson source = SLOT(oldsocketlabel); 1032101099Srwatson dest = SLOT(newsocketlabel); 1033101099Srwatson 1034101099Srwatson mac_biba_copy_single(source, dest); 1035101099Srwatson} 1036101099Srwatson 1037101099Srwatsonstatic void 1038101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1039101099Srwatson struct label *socketlabel, struct label *newlabel) 1040101099Srwatson{ 1041101099Srwatson struct mac_biba *source, *dest; 1042101099Srwatson 1043101099Srwatson source = SLOT(newlabel); 1044101099Srwatson dest = SLOT(socketlabel); 1045101099Srwatson 1046105656Srwatson mac_biba_copy(source, dest); 1047101099Srwatson} 1048101099Srwatson 1049101099Srwatsonstatic void 1050101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1051101099Srwatson struct label *pipelabel, struct label *newlabel) 1052101099Srwatson{ 1053101099Srwatson struct mac_biba *source, *dest; 1054101099Srwatson 1055101099Srwatson source = SLOT(newlabel); 1056101099Srwatson dest = SLOT(pipelabel); 1057101099Srwatson 1058105656Srwatson mac_biba_copy(source, dest); 1059101099Srwatson} 1060101099Srwatson 1061101099Srwatsonstatic void 1062101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1063101099Srwatson struct socket *socket, struct label *socketpeerlabel) 1064101099Srwatson{ 1065101099Srwatson struct mac_biba *source, *dest; 1066101099Srwatson 1067101099Srwatson source = SLOT(mbuflabel); 1068101099Srwatson dest = SLOT(socketpeerlabel); 1069101099Srwatson 1070101099Srwatson mac_biba_copy_single(source, dest); 1071101099Srwatson} 1072101099Srwatson 1073101099Srwatson/* 1074101099Srwatson * Labeling event operations: network objects. 1075101099Srwatson */ 1076101099Srwatsonstatic void 1077101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1078101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1079101099Srwatson struct label *newsocketpeerlabel) 1080101099Srwatson{ 1081101099Srwatson struct mac_biba *source, *dest; 1082101099Srwatson 1083101099Srwatson source = SLOT(oldsocketlabel); 1084101099Srwatson dest = SLOT(newsocketpeerlabel); 1085101099Srwatson 1086101099Srwatson mac_biba_copy_single(source, dest); 1087101099Srwatson} 1088101099Srwatson 1089101099Srwatsonstatic void 1090101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1091101099Srwatson struct label *bpflabel) 1092101099Srwatson{ 1093101099Srwatson struct mac_biba *source, *dest; 1094101099Srwatson 1095122524Srwatson source = SLOT(cred->cr_label); 1096101099Srwatson dest = SLOT(bpflabel); 1097101099Srwatson 1098101099Srwatson mac_biba_copy_single(source, dest); 1099101099Srwatson} 1100101099Srwatson 1101101099Srwatsonstatic void 1102101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1103101099Srwatson{ 1104121816Sbrooks char tifname[IFNAMSIZ], *p, *q; 1105101099Srwatson char tiflist[sizeof(trusted_interfaces)]; 1106101099Srwatson struct mac_biba *dest; 1107110350Srwatson int len, type; 1108101099Srwatson 1109101099Srwatson dest = SLOT(ifnetlabel); 1110101099Srwatson 1111101099Srwatson if (ifnet->if_type == IFT_LOOP) { 1112110350Srwatson type = MAC_BIBA_TYPE_EQUAL; 1113101099Srwatson goto set; 1114101099Srwatson } 1115101099Srwatson 1116101099Srwatson if (trust_all_interfaces) { 1117110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1118101099Srwatson goto set; 1119101099Srwatson } 1120101099Srwatson 1121110350Srwatson type = MAC_BIBA_TYPE_LOW; 1122101099Srwatson 1123101099Srwatson if (trusted_interfaces[0] == '\0' || 1124101099Srwatson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1125101099Srwatson goto set; 1126101099Srwatson 1127106089Srwatson bzero(tiflist, sizeof(tiflist)); 1128101099Srwatson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1129101099Srwatson if(*p != ' ' && *p != '\t') 1130101099Srwatson *q = *p; 1131101099Srwatson 1132101099Srwatson for (p = q = tiflist;; p++) { 1133101099Srwatson if (*p == ',' || *p == '\0') { 1134101099Srwatson len = p - q; 1135101099Srwatson if (len < IFNAMSIZ) { 1136101099Srwatson bzero(tifname, sizeof(tifname)); 1137101099Srwatson bcopy(q, tifname, len); 1138121816Sbrooks if (strcmp(tifname, ifnet->if_xname) == 0) { 1139110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1140101099Srwatson break; 1141101099Srwatson } 1142106089Srwatson } else { 1143106089Srwatson *p = '\0'; 1144106089Srwatson printf("mac_biba warning: interface name " 1145106089Srwatson "\"%s\" is too long (must be < %d)\n", 1146106089Srwatson q, IFNAMSIZ); 1147101099Srwatson } 1148101099Srwatson if (*p == '\0') 1149101099Srwatson break; 1150101099Srwatson q = p + 1; 1151101099Srwatson } 1152101099Srwatson } 1153101099Srwatsonset: 1154110350Srwatson mac_biba_set_single(dest, type, 0, NULL); 1155110350Srwatson mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1156101099Srwatson} 1157101099Srwatson 1158101099Srwatsonstatic void 1159101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1160101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1161101099Srwatson{ 1162101099Srwatson struct mac_biba *source, *dest; 1163101099Srwatson 1164101099Srwatson source = SLOT(fragmentlabel); 1165101099Srwatson dest = SLOT(ipqlabel); 1166101099Srwatson 1167101099Srwatson mac_biba_copy_single(source, dest); 1168101099Srwatson} 1169101099Srwatson 1170101099Srwatsonstatic void 1171101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1172101099Srwatson struct mbuf *datagram, struct label *datagramlabel) 1173101099Srwatson{ 1174101099Srwatson struct mac_biba *source, *dest; 1175101099Srwatson 1176101099Srwatson source = SLOT(ipqlabel); 1177101099Srwatson dest = SLOT(datagramlabel); 1178101099Srwatson 1179101099Srwatson /* Just use the head, since we require them all to match. */ 1180101099Srwatson mac_biba_copy_single(source, dest); 1181101099Srwatson} 1182101099Srwatson 1183101099Srwatsonstatic void 1184101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1185101099Srwatson struct mbuf *fragment, struct label *fragmentlabel) 1186101099Srwatson{ 1187101099Srwatson struct mac_biba *source, *dest; 1188101099Srwatson 1189101099Srwatson source = SLOT(datagramlabel); 1190101099Srwatson dest = SLOT(fragmentlabel); 1191101099Srwatson 1192101099Srwatson mac_biba_copy_single(source, dest); 1193101099Srwatson} 1194101099Srwatson 1195101099Srwatsonstatic void 1196101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1197101099Srwatson struct label *oldmbuflabel, struct mbuf *newmbuf, 1198101099Srwatson struct label *newmbuflabel) 1199101099Srwatson{ 1200101099Srwatson struct mac_biba *source, *dest; 1201101099Srwatson 1202101099Srwatson source = SLOT(oldmbuflabel); 1203101099Srwatson dest = SLOT(newmbuflabel); 1204101099Srwatson 1205105656Srwatson /* 1206105656Srwatson * Because the source mbuf may not yet have been "created", 1207105696Srwatson * just initialized, we do a conditional copy. Since we don't 1208105656Srwatson * allow mbufs to have ranges, do a KASSERT to make sure that 1209105656Srwatson * doesn't happen. 1210105656Srwatson */ 1211105656Srwatson KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1212105656Srwatson ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1213105656Srwatson mac_biba_copy(source, dest); 1214101099Srwatson} 1215101099Srwatson 1216101099Srwatsonstatic void 1217101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1218101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1219101099Srwatson{ 1220101099Srwatson struct mac_biba *dest; 1221101099Srwatson 1222101099Srwatson dest = SLOT(mbuflabel); 1223101099Srwatson 1224105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1225101099Srwatson} 1226101099Srwatson 1227101099Srwatsonstatic void 1228101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1229101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1230101099Srwatson{ 1231101099Srwatson struct mac_biba *source, *dest; 1232101099Srwatson 1233101099Srwatson source = SLOT(bpflabel); 1234101099Srwatson dest = SLOT(mbuflabel); 1235101099Srwatson 1236101099Srwatson mac_biba_copy_single(source, dest); 1237101099Srwatson} 1238101099Srwatson 1239101099Srwatsonstatic void 1240101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1241101099Srwatson struct mbuf *m, struct label *mbuflabel) 1242101099Srwatson{ 1243101099Srwatson struct mac_biba *source, *dest; 1244101099Srwatson 1245101099Srwatson source = SLOT(ifnetlabel); 1246101099Srwatson dest = SLOT(mbuflabel); 1247101099Srwatson 1248101099Srwatson mac_biba_copy_single(source, dest); 1249101099Srwatson} 1250101099Srwatson 1251101099Srwatsonstatic void 1252101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1253101099Srwatson struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1254101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1255101099Srwatson{ 1256101099Srwatson struct mac_biba *source, *dest; 1257101099Srwatson 1258101099Srwatson source = SLOT(oldmbuflabel); 1259101099Srwatson dest = SLOT(newmbuflabel); 1260101099Srwatson 1261101099Srwatson mac_biba_copy_single(source, dest); 1262101099Srwatson} 1263101099Srwatson 1264101099Srwatsonstatic void 1265101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1266101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1267101099Srwatson{ 1268101099Srwatson struct mac_biba *source, *dest; 1269101099Srwatson 1270101099Srwatson source = SLOT(oldmbuflabel); 1271101099Srwatson dest = SLOT(newmbuflabel); 1272101099Srwatson 1273101099Srwatson mac_biba_copy_single(source, dest); 1274101099Srwatson} 1275101099Srwatson 1276101099Srwatsonstatic int 1277101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1278101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1279101099Srwatson{ 1280101099Srwatson struct mac_biba *a, *b; 1281101099Srwatson 1282101099Srwatson a = SLOT(ipqlabel); 1283101099Srwatson b = SLOT(fragmentlabel); 1284101099Srwatson 1285101099Srwatson return (mac_biba_equal_single(a, b)); 1286101099Srwatson} 1287101099Srwatson 1288101099Srwatsonstatic void 1289101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1290101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1291101099Srwatson{ 1292101099Srwatson struct mac_biba *source, *dest; 1293101099Srwatson 1294101099Srwatson source = SLOT(newlabel); 1295101099Srwatson dest = SLOT(ifnetlabel); 1296101099Srwatson 1297105656Srwatson mac_biba_copy(source, dest); 1298101099Srwatson} 1299101099Srwatson 1300101099Srwatsonstatic void 1301101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1302101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1303101099Srwatson{ 1304101099Srwatson 1305101099Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1306101099Srwatson} 1307101099Srwatson 1308101099Srwatson/* 1309101099Srwatson * Labeling event operations: processes. 1310101099Srwatson */ 1311101099Srwatsonstatic void 1312101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1313101099Srwatson{ 1314101099Srwatson struct mac_biba *source, *dest; 1315101099Srwatson 1316122524Srwatson source = SLOT(cred_parent->cr_label); 1317122524Srwatson dest = SLOT(cred_child->cr_label); 1318101099Srwatson 1319101099Srwatson mac_biba_copy_single(source, dest); 1320101099Srwatson mac_biba_copy_range(source, dest); 1321101099Srwatson} 1322101099Srwatson 1323101099Srwatsonstatic void 1324101099Srwatsonmac_biba_create_proc0(struct ucred *cred) 1325101099Srwatson{ 1326101099Srwatson struct mac_biba *dest; 1327101099Srwatson 1328122524Srwatson dest = SLOT(cred->cr_label); 1329101099Srwatson 1330105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1331105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1332105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1333101099Srwatson} 1334101099Srwatson 1335101099Srwatsonstatic void 1336101099Srwatsonmac_biba_create_proc1(struct ucred *cred) 1337101099Srwatson{ 1338101099Srwatson struct mac_biba *dest; 1339101099Srwatson 1340122524Srwatson dest = SLOT(cred->cr_label); 1341101099Srwatson 1342105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1343105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1344105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1345101099Srwatson} 1346101099Srwatson 1347101099Srwatsonstatic void 1348101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1349101099Srwatson{ 1350101099Srwatson struct mac_biba *source, *dest; 1351101099Srwatson 1352101099Srwatson source = SLOT(newlabel); 1353122524Srwatson dest = SLOT(cred->cr_label); 1354101099Srwatson 1355105656Srwatson mac_biba_copy(source, dest); 1356101099Srwatson} 1357101099Srwatson 1358101099Srwatson/* 1359101099Srwatson * Access control checks. 1360101099Srwatson */ 1361101099Srwatsonstatic int 1362101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1363101099Srwatson struct ifnet *ifnet, struct label *ifnetlabel) 1364101099Srwatson{ 1365101099Srwatson struct mac_biba *a, *b; 1366101099Srwatson 1367101099Srwatson if (!mac_biba_enabled) 1368101099Srwatson return (0); 1369101099Srwatson 1370101099Srwatson a = SLOT(bpflabel); 1371101099Srwatson b = SLOT(ifnetlabel); 1372101099Srwatson 1373101099Srwatson if (mac_biba_equal_single(a, b)) 1374101099Srwatson return (0); 1375101099Srwatson return (EACCES); 1376101099Srwatson} 1377101099Srwatson 1378101099Srwatsonstatic int 1379101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1380101099Srwatson{ 1381101099Srwatson struct mac_biba *subj, *new; 1382105634Srwatson int error; 1383101099Srwatson 1384122524Srwatson subj = SLOT(cred->cr_label); 1385101099Srwatson new = SLOT(newlabel); 1386101099Srwatson 1387101099Srwatson /* 1388105634Srwatson * If there is a Biba label update for the credential, it may 1389105634Srwatson * be an update of the single, range, or both. 1390101099Srwatson */ 1391105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1392105634Srwatson if (error) 1393105634Srwatson return (error); 1394101099Srwatson 1395101099Srwatson /* 1396105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1397101099Srwatson */ 1398105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1399105634Srwatson /* 1400110351Srwatson * If the change request modifies both the Biba label 1401110351Srwatson * single and range, check that the new single will be 1402110351Srwatson * in the new range. 1403110351Srwatson */ 1404110351Srwatson if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1405110351Srwatson MAC_BIBA_FLAGS_BOTH && 1406110351Srwatson !mac_biba_single_in_range(new, new)) 1407110351Srwatson return (EINVAL); 1408110351Srwatson 1409110351Srwatson /* 1410105634Srwatson * To change the Biba single label on a credential, the 1411105634Srwatson * new single label must be in the current range. 1412105634Srwatson */ 1413105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1414105634Srwatson !mac_biba_single_in_range(new, subj)) 1415105634Srwatson return (EPERM); 1416101099Srwatson 1417105634Srwatson /* 1418105634Srwatson * To change the Biba range on a credential, the new 1419105634Srwatson * range label must be in the current range. 1420105634Srwatson */ 1421105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1422105634Srwatson !mac_biba_range_in_range(new, subj)) 1423105634Srwatson return (EPERM); 1424101099Srwatson 1425105634Srwatson /* 1426105634Srwatson * To have EQUAL in any component of the new credential 1427105634Srwatson * Biba label, the subject must already have EQUAL in 1428105634Srwatson * their label. 1429105634Srwatson */ 1430105634Srwatson if (mac_biba_contains_equal(new)) { 1431106090Srwatson error = mac_biba_subject_privileged(subj); 1432105634Srwatson if (error) 1433105634Srwatson return (error); 1434105634Srwatson } 1435105634Srwatson } 1436105634Srwatson 1437101099Srwatson return (0); 1438101099Srwatson} 1439101099Srwatson 1440101099Srwatsonstatic int 1441101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1442101099Srwatson{ 1443101099Srwatson struct mac_biba *subj, *obj; 1444101099Srwatson 1445101099Srwatson if (!mac_biba_enabled) 1446101099Srwatson return (0); 1447101099Srwatson 1448122524Srwatson subj = SLOT(u1->cr_label); 1449122524Srwatson obj = SLOT(u2->cr_label); 1450101099Srwatson 1451101099Srwatson /* XXX: range */ 1452101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1453101099Srwatson return (ESRCH); 1454101099Srwatson 1455101099Srwatson return (0); 1456101099Srwatson} 1457101099Srwatson 1458101099Srwatsonstatic int 1459101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1460101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1461101099Srwatson{ 1462101099Srwatson struct mac_biba *subj, *new; 1463105634Srwatson int error; 1464101099Srwatson 1465122524Srwatson subj = SLOT(cred->cr_label); 1466101099Srwatson new = SLOT(newlabel); 1467101099Srwatson 1468105634Srwatson /* 1469105634Srwatson * If there is a Biba label update for the interface, it may 1470105634Srwatson * be an update of the single, range, or both. 1471105634Srwatson */ 1472105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1473105634Srwatson if (error) 1474105634Srwatson return (error); 1475101099Srwatson 1476105634Srwatson /* 1477106160Srwatson * Relabling network interfaces requires Biba privilege. 1478106160Srwatson */ 1479106160Srwatson error = mac_biba_subject_privileged(subj); 1480106160Srwatson if (error) 1481106160Srwatson return (error); 1482106160Srwatson 1483105634Srwatson return (0); 1484101099Srwatson} 1485101099Srwatson 1486103759Srwatsonstatic int 1487101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1488101099Srwatson struct mbuf *m, struct label *mbuflabel) 1489101099Srwatson{ 1490101099Srwatson struct mac_biba *p, *i; 1491103761Srwatson 1492101099Srwatson if (!mac_biba_enabled) 1493101099Srwatson return (0); 1494101099Srwatson 1495101099Srwatson p = SLOT(mbuflabel); 1496101099Srwatson i = SLOT(ifnetlabel); 1497103759Srwatson 1498101099Srwatson return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1499101099Srwatson} 1500101099Srwatson 1501101099Srwatsonstatic int 1502110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1503110354Srwatson struct label *label) 1504110354Srwatson{ 1505110354Srwatson struct mac_biba *subj, *obj; 1506110354Srwatson int error; 1507110354Srwatson 1508110354Srwatson if (!mac_biba_enabled) 1509110354Srwatson return (0); 1510110354Srwatson 1511122524Srwatson subj = SLOT(cred->cr_label); 1512110354Srwatson 1513110354Srwatson error = mac_biba_subject_privileged(subj); 1514110354Srwatson if (error) 1515110354Srwatson return (error); 1516110354Srwatson 1517110354Srwatson obj = SLOT(label); 1518110354Srwatson if (!mac_biba_high_single(obj)) 1519110354Srwatson return (EACCES); 1520110354Srwatson 1521110354Srwatson return (0); 1522110354Srwatson} 1523110354Srwatson 1524110354Srwatson 1525110354Srwatsonstatic int 1526110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred) 1527110354Srwatson{ 1528110354Srwatson struct mac_biba *subj; 1529110354Srwatson 1530110354Srwatson if (!mac_biba_enabled) 1531110354Srwatson return (0); 1532110354Srwatson 1533122524Srwatson subj = SLOT(cred->cr_label); 1534110354Srwatson 1535110354Srwatson return (mac_biba_subject_privileged(subj)); 1536110354Srwatson} 1537110354Srwatson 1538110354Srwatsonstatic int 1539101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1540101099Srwatson struct label *mntlabel) 1541101099Srwatson{ 1542101099Srwatson struct mac_biba *subj, *obj; 1543101099Srwatson 1544101099Srwatson if (!mac_biba_enabled) 1545101099Srwatson return (0); 1546101099Srwatson 1547122524Srwatson subj = SLOT(cred->cr_label); 1548101099Srwatson obj = SLOT(mntlabel); 1549101099Srwatson 1550101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1551101099Srwatson return (EACCES); 1552101099Srwatson 1553101099Srwatson return (0); 1554101099Srwatson} 1555101099Srwatson 1556101099Srwatsonstatic int 1557101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1558101099Srwatson struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1559101099Srwatson{ 1560103759Srwatson 1561101099Srwatson if(!mac_biba_enabled) 1562101099Srwatson return (0); 1563101099Srwatson 1564101099Srwatson /* XXX: This will be implemented soon... */ 1565101099Srwatson 1566101099Srwatson return (0); 1567101099Srwatson} 1568101099Srwatson 1569101099Srwatsonstatic int 1570102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1571102115Srwatson struct label *pipelabel) 1572101099Srwatson{ 1573101099Srwatson struct mac_biba *subj, *obj; 1574101099Srwatson 1575101099Srwatson if (!mac_biba_enabled) 1576101099Srwatson return (0); 1577101099Srwatson 1578122524Srwatson subj = SLOT(cred->cr_label); 1579101099Srwatson obj = SLOT((pipelabel)); 1580101099Srwatson 1581102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1582102115Srwatson return (EACCES); 1583101099Srwatson 1584101099Srwatson return (0); 1585101099Srwatson} 1586101099Srwatson 1587101099Srwatsonstatic int 1588102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1589102115Srwatson struct label *pipelabel) 1590102115Srwatson{ 1591102115Srwatson struct mac_biba *subj, *obj; 1592102115Srwatson 1593102115Srwatson if (!mac_biba_enabled) 1594102115Srwatson return (0); 1595102115Srwatson 1596122524Srwatson subj = SLOT(cred->cr_label); 1597102115Srwatson obj = SLOT((pipelabel)); 1598102115Srwatson 1599102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1600102115Srwatson return (EACCES); 1601102115Srwatson 1602102115Srwatson return (0); 1603102115Srwatson} 1604102115Srwatson 1605102115Srwatsonstatic int 1606101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1607101099Srwatson struct label *pipelabel, struct label *newlabel) 1608101099Srwatson{ 1609101099Srwatson struct mac_biba *subj, *obj, *new; 1610105634Srwatson int error; 1611101099Srwatson 1612101099Srwatson new = SLOT(newlabel); 1613122524Srwatson subj = SLOT(cred->cr_label); 1614101099Srwatson obj = SLOT(pipelabel); 1615101099Srwatson 1616101099Srwatson /* 1617105634Srwatson * If there is a Biba label update for a pipe, it must be a 1618105634Srwatson * single update. 1619101099Srwatson */ 1620105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1621105634Srwatson if (error) 1622105634Srwatson return (error); 1623101099Srwatson 1624101099Srwatson /* 1625105634Srwatson * To perform a relabel of a pipe (Biba label or not), Biba must 1626105634Srwatson * authorize the relabel. 1627101099Srwatson */ 1628105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1629101099Srwatson return (EPERM); 1630101099Srwatson 1631101099Srwatson /* 1632105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1633101099Srwatson */ 1634105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1635105634Srwatson /* 1636105634Srwatson * To change the Biba label on a pipe, the new pipe label 1637105634Srwatson * must be in the subject range. 1638105634Srwatson */ 1639105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1640105634Srwatson return (EPERM); 1641101099Srwatson 1642105634Srwatson /* 1643105634Srwatson * To change the Biba label on a pipe to be EQUAL, the 1644105634Srwatson * subject must have appropriate privilege. 1645105634Srwatson */ 1646105634Srwatson if (mac_biba_contains_equal(new)) { 1647106090Srwatson error = mac_biba_subject_privileged(subj); 1648105634Srwatson if (error) 1649105634Srwatson return (error); 1650105634Srwatson } 1651105634Srwatson } 1652105634Srwatson 1653101099Srwatson return (0); 1654101099Srwatson} 1655101099Srwatson 1656101099Srwatsonstatic int 1657102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1658102115Srwatson struct label *pipelabel) 1659102115Srwatson{ 1660102115Srwatson struct mac_biba *subj, *obj; 1661102115Srwatson 1662102115Srwatson if (!mac_biba_enabled) 1663102115Srwatson return (0); 1664102115Srwatson 1665122524Srwatson subj = SLOT(cred->cr_label); 1666102115Srwatson obj = SLOT((pipelabel)); 1667102115Srwatson 1668102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1669102115Srwatson return (EACCES); 1670102115Srwatson 1671102115Srwatson return (0); 1672102115Srwatson} 1673102115Srwatson 1674102115Srwatsonstatic int 1675102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1676102115Srwatson struct label *pipelabel) 1677102115Srwatson{ 1678102115Srwatson struct mac_biba *subj, *obj; 1679102115Srwatson 1680102115Srwatson if (!mac_biba_enabled) 1681102115Srwatson return (0); 1682102115Srwatson 1683122524Srwatson subj = SLOT(cred->cr_label); 1684102115Srwatson obj = SLOT((pipelabel)); 1685102115Srwatson 1686102115Srwatson if (!mac_biba_dominate_single(subj, obj)) 1687102115Srwatson return (EACCES); 1688102115Srwatson 1689102115Srwatson return (0); 1690102115Srwatson} 1691102115Srwatson 1692102115Srwatsonstatic int 1693101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1694101099Srwatson{ 1695101099Srwatson struct mac_biba *subj, *obj; 1696101099Srwatson 1697101099Srwatson if (!mac_biba_enabled) 1698101099Srwatson return (0); 1699101099Srwatson 1700122524Srwatson subj = SLOT(cred->cr_label); 1701122524Srwatson obj = SLOT(proc->p_ucred->cr_label); 1702101099Srwatson 1703101099Srwatson /* XXX: range checks */ 1704101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1705101099Srwatson return (ESRCH); 1706101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1707101099Srwatson return (EACCES); 1708101099Srwatson 1709101099Srwatson return (0); 1710101099Srwatson} 1711101099Srwatson 1712101099Srwatsonstatic int 1713101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1714101099Srwatson{ 1715101099Srwatson struct mac_biba *subj, *obj; 1716103759Srwatson 1717101099Srwatson if (!mac_biba_enabled) 1718101099Srwatson return (0); 1719101099Srwatson 1720122524Srwatson subj = SLOT(cred->cr_label); 1721122524Srwatson obj = SLOT(proc->p_ucred->cr_label); 1722103759Srwatson 1723101099Srwatson /* XXX: range checks */ 1724101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1725101099Srwatson return (ESRCH); 1726101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1727101099Srwatson return (EACCES); 1728101099Srwatson 1729101099Srwatson return (0); 1730101099Srwatson} 1731101099Srwatson 1732101099Srwatsonstatic int 1733101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1734101099Srwatson{ 1735101099Srwatson struct mac_biba *subj, *obj; 1736103759Srwatson 1737101099Srwatson if (!mac_biba_enabled) 1738101099Srwatson return (0); 1739101099Srwatson 1740122524Srwatson subj = SLOT(cred->cr_label); 1741122524Srwatson obj = SLOT(proc->p_ucred->cr_label); 1742103759Srwatson 1743101099Srwatson /* XXX: range checks */ 1744101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1745101099Srwatson return (ESRCH); 1746101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1747101099Srwatson return (EACCES); 1748101099Srwatson 1749101099Srwatson return (0); 1750101099Srwatson} 1751101099Srwatson 1752101099Srwatsonstatic int 1753101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1754101099Srwatson struct mbuf *m, struct label *mbuflabel) 1755101099Srwatson{ 1756101099Srwatson struct mac_biba *p, *s; 1757101099Srwatson 1758101099Srwatson if (!mac_biba_enabled) 1759101099Srwatson return (0); 1760101099Srwatson 1761101099Srwatson p = SLOT(mbuflabel); 1762101099Srwatson s = SLOT(socketlabel); 1763101099Srwatson 1764101099Srwatson return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1765101099Srwatson} 1766101099Srwatson 1767101099Srwatsonstatic int 1768106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1769101099Srwatson struct label *socketlabel, struct label *newlabel) 1770101099Srwatson{ 1771101099Srwatson struct mac_biba *subj, *obj, *new; 1772105634Srwatson int error; 1773101099Srwatson 1774101099Srwatson new = SLOT(newlabel); 1775122524Srwatson subj = SLOT(cred->cr_label); 1776101099Srwatson obj = SLOT(socketlabel); 1777101099Srwatson 1778101099Srwatson /* 1779105634Srwatson * If there is a Biba label update for the socket, it may be 1780105634Srwatson * an update of single. 1781101099Srwatson */ 1782105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1783105634Srwatson if (error) 1784105634Srwatson return (error); 1785101099Srwatson 1786101099Srwatson /* 1787105634Srwatson * To relabel a socket, the old socket single must be in the subject 1788101099Srwatson * range. 1789101099Srwatson */ 1790105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1791101099Srwatson return (EPERM); 1792101099Srwatson 1793101099Srwatson /* 1794105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1795101099Srwatson */ 1796105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1797105634Srwatson /* 1798105634Srwatson * To relabel a socket, the new socket single must be in 1799105634Srwatson * the subject range. 1800105634Srwatson */ 1801105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1802105634Srwatson return (EPERM); 1803101099Srwatson 1804105634Srwatson /* 1805105634Srwatson * To change the Biba label on the socket to contain EQUAL, 1806105634Srwatson * the subject must have appropriate privilege. 1807105634Srwatson */ 1808105634Srwatson if (mac_biba_contains_equal(new)) { 1809106090Srwatson error = mac_biba_subject_privileged(subj); 1810105634Srwatson if (error) 1811105634Srwatson return (error); 1812105634Srwatson } 1813105634Srwatson } 1814105634Srwatson 1815101099Srwatson return (0); 1816101099Srwatson} 1817101099Srwatson 1818101099Srwatsonstatic int 1819101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1820101099Srwatson struct label *socketlabel) 1821101099Srwatson{ 1822101099Srwatson struct mac_biba *subj, *obj; 1823101099Srwatson 1824105722Srwatson if (!mac_biba_enabled) 1825105722Srwatson return (0); 1826105722Srwatson 1827122524Srwatson subj = SLOT(cred->cr_label); 1828101099Srwatson obj = SLOT(socketlabel); 1829101099Srwatson 1830101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1831101099Srwatson return (ENOENT); 1832101099Srwatson 1833101099Srwatson return (0); 1834101099Srwatson} 1835101099Srwatson 1836101099Srwatsonstatic int 1837112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred) 1838112574Srwatson{ 1839112574Srwatson struct mac_biba *subj; 1840112574Srwatson int error; 1841112574Srwatson 1842112574Srwatson if (!mac_biba_enabled) 1843112574Srwatson return (0); 1844112574Srwatson 1845122524Srwatson subj = SLOT(cred->cr_label); 1846112574Srwatson 1847112574Srwatson error = mac_biba_subject_privileged(subj); 1848112574Srwatson if (error) 1849112574Srwatson return (error); 1850112574Srwatson 1851112574Srwatson return (0); 1852112574Srwatson} 1853112574Srwatson 1854112574Srwatsonstatic int 1855106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1856106418Srwatson struct label *label) 1857106418Srwatson{ 1858106418Srwatson struct mac_biba *subj, *obj; 1859106418Srwatson int error; 1860106418Srwatson 1861106418Srwatson if (!mac_biba_enabled) 1862106418Srwatson return (0); 1863106418Srwatson 1864122524Srwatson subj = SLOT(cred->cr_label); 1865106418Srwatson 1866106418Srwatson error = mac_biba_subject_privileged(subj); 1867106418Srwatson if (error) 1868106418Srwatson return (error); 1869106418Srwatson 1870106418Srwatson if (label == NULL) 1871106418Srwatson return (0); 1872106418Srwatson 1873106418Srwatson obj = SLOT(label); 1874106418Srwatson if (!mac_biba_high_single(obj)) 1875106418Srwatson return (EACCES); 1876106418Srwatson 1877106418Srwatson return (0); 1878106418Srwatson} 1879106418Srwatson 1880106418Srwatsonstatic int 1881106418Srwatsonmac_biba_check_system_settime(struct ucred *cred) 1882106418Srwatson{ 1883106418Srwatson struct mac_biba *subj; 1884106418Srwatson int error; 1885106418Srwatson 1886106418Srwatson if (!mac_biba_enabled) 1887106418Srwatson return (0); 1888106418Srwatson 1889122524Srwatson subj = SLOT(cred->cr_label); 1890106418Srwatson 1891106418Srwatson error = mac_biba_subject_privileged(subj); 1892106418Srwatson if (error) 1893106418Srwatson return (error); 1894106418Srwatson 1895106418Srwatson return (0); 1896106418Srwatson} 1897106418Srwatson 1898106418Srwatsonstatic int 1899106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1900106161Srwatson struct label *label) 1901106161Srwatson{ 1902106161Srwatson struct mac_biba *subj, *obj; 1903106416Srwatson int error; 1904106161Srwatson 1905106161Srwatson if (!mac_biba_enabled) 1906106161Srwatson return (0); 1907106161Srwatson 1908122524Srwatson subj = SLOT(cred->cr_label); 1909106161Srwatson obj = SLOT(label); 1910106161Srwatson 1911106416Srwatson error = mac_biba_subject_privileged(subj); 1912106416Srwatson if (error) 1913106416Srwatson return (error); 1914106161Srwatson 1915106161Srwatson if (!mac_biba_high_single(obj)) 1916106161Srwatson return (EACCES); 1917106161Srwatson 1918106161Srwatson return (0); 1919106161Srwatson} 1920106161Srwatson 1921106161Srwatsonstatic int 1922112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 1923112574Srwatson struct label *label) 1924112574Srwatson{ 1925112574Srwatson struct mac_biba *subj, *obj; 1926112574Srwatson int error; 1927112574Srwatson 1928112574Srwatson if (!mac_biba_enabled) 1929112574Srwatson return (0); 1930112574Srwatson 1931122524Srwatson subj = SLOT(cred->cr_label); 1932112574Srwatson obj = SLOT(label); 1933112574Srwatson 1934112574Srwatson error = mac_biba_subject_privileged(subj); 1935112574Srwatson if (error) 1936112574Srwatson return (error); 1937112574Srwatson 1938112574Srwatson return (0); 1939112574Srwatson} 1940112574Srwatson 1941112574Srwatsonstatic int 1942106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1943106161Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1944106161Srwatson{ 1945106161Srwatson struct mac_biba *subj; 1946106161Srwatson int error; 1947106161Srwatson 1948106161Srwatson if (!mac_biba_enabled) 1949106161Srwatson return (0); 1950106161Srwatson 1951122524Srwatson subj = SLOT(cred->cr_label); 1952106161Srwatson 1953106161Srwatson /* 1954106161Srwatson * In general, treat sysctl variables as biba/high, but also 1955106161Srwatson * require privilege to change them, since they are a 1956106161Srwatson * communications channel between grades. Exempt MIB 1957106161Srwatson * queries from this due to undocmented sysctl magic. 1958106161Srwatson * XXXMAC: This probably requires some more review. 1959106161Srwatson */ 1960106161Srwatson if (new != NULL) { 1961106161Srwatson if (namelen > 0 && name[0] == 0) 1962106161Srwatson return (0); 1963106161Srwatson 1964106161Srwatson if (!mac_biba_subject_dominate_high(subj)) 1965106161Srwatson return (EACCES); 1966106161Srwatson 1967106161Srwatson error = mac_biba_subject_privileged(subj); 1968106161Srwatson if (error) 1969106161Srwatson return (error); 1970106161Srwatson } 1971106161Srwatson 1972106161Srwatson return (0); 1973106161Srwatson} 1974106161Srwatson 1975106161Srwatsonstatic int 1976101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1977101099Srwatson struct label *dlabel) 1978101099Srwatson{ 1979101099Srwatson struct mac_biba *subj, *obj; 1980101099Srwatson 1981101099Srwatson if (!mac_biba_enabled) 1982101099Srwatson return (0); 1983101099Srwatson 1984122524Srwatson subj = SLOT(cred->cr_label); 1985101099Srwatson obj = SLOT(dlabel); 1986101099Srwatson 1987101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1988101099Srwatson return (EACCES); 1989101099Srwatson 1990101099Srwatson return (0); 1991101099Srwatson} 1992101099Srwatson 1993101099Srwatsonstatic int 1994101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1995101099Srwatson struct label *dlabel) 1996101099Srwatson{ 1997101099Srwatson struct mac_biba *subj, *obj; 1998101099Srwatson 1999101099Srwatson if (!mac_biba_enabled) 2000101099Srwatson return (0); 2001101099Srwatson 2002122524Srwatson subj = SLOT(cred->cr_label); 2003101099Srwatson obj = SLOT(dlabel); 2004101099Srwatson 2005101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2006101099Srwatson return (EACCES); 2007101099Srwatson 2008101099Srwatson return (0); 2009101099Srwatson} 2010101099Srwatson 2011101099Srwatsonstatic int 2012101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2013101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2014101099Srwatson{ 2015101099Srwatson struct mac_biba *subj, *obj; 2016101099Srwatson 2017101099Srwatson if (!mac_biba_enabled) 2018101099Srwatson return (0); 2019101099Srwatson 2020122524Srwatson subj = SLOT(cred->cr_label); 2021101099Srwatson obj = SLOT(dlabel); 2022101099Srwatson 2023101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2024101099Srwatson return (EACCES); 2025101099Srwatson 2026101099Srwatson return (0); 2027101099Srwatson} 2028101099Srwatson 2029101099Srwatsonstatic int 2030101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2031101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2032101099Srwatson struct componentname *cnp) 2033101099Srwatson{ 2034101099Srwatson struct mac_biba *subj, *obj; 2035101099Srwatson 2036101099Srwatson if (!mac_biba_enabled) 2037101099Srwatson return (0); 2038101099Srwatson 2039122524Srwatson subj = SLOT(cred->cr_label); 2040101099Srwatson obj = SLOT(dlabel); 2041101099Srwatson 2042101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2043101099Srwatson return (EACCES); 2044101099Srwatson 2045101099Srwatson obj = SLOT(label); 2046101099Srwatson 2047101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2048101099Srwatson return (EACCES); 2049101099Srwatson 2050101099Srwatson return (0); 2051101099Srwatson} 2052101099Srwatson 2053101099Srwatsonstatic int 2054101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2055101099Srwatson struct label *label, acl_type_t type) 2056101099Srwatson{ 2057101099Srwatson struct mac_biba *subj, *obj; 2058101099Srwatson 2059101099Srwatson if (!mac_biba_enabled) 2060101099Srwatson return (0); 2061101099Srwatson 2062122524Srwatson subj = SLOT(cred->cr_label); 2063101099Srwatson obj = SLOT(label); 2064101099Srwatson 2065101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2066101099Srwatson return (EACCES); 2067101099Srwatson 2068101099Srwatson return (0); 2069101099Srwatson} 2070101099Srwatson 2071101099Srwatsonstatic int 2072119202Srwatsonmac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2073119202Srwatson struct label *label, int attrnamespace, const char *name) 2074119202Srwatson{ 2075119202Srwatson struct mac_biba *subj, *obj; 2076119202Srwatson 2077119202Srwatson if (!mac_biba_enabled) 2078119202Srwatson return (0); 2079119202Srwatson 2080122524Srwatson subj = SLOT(cred->cr_label); 2081119202Srwatson obj = SLOT(label); 2082119202Srwatson 2083119202Srwatson if (!mac_biba_dominate_single(subj, obj)) 2084119202Srwatson return (EACCES); 2085119202Srwatson 2086119202Srwatson return (0); 2087119202Srwatson} 2088119202Srwatson 2089119202Srwatsonstatic int 2090101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2091106648Srwatson struct label *label, struct image_params *imgp, 2092106648Srwatson struct label *execlabel) 2093101099Srwatson{ 2094106648Srwatson struct mac_biba *subj, *obj, *exec; 2095106648Srwatson int error; 2096101099Srwatson 2097106648Srwatson if (execlabel != NULL) { 2098106648Srwatson /* 2099106648Srwatson * We currently don't permit labels to be changed at 2100106648Srwatson * exec-time as part of Biba, so disallow non-NULL 2101106648Srwatson * Biba label elements in the execlabel. 2102106648Srwatson */ 2103106648Srwatson exec = SLOT(execlabel); 2104106648Srwatson error = biba_atmostflags(exec, 0); 2105106648Srwatson if (error) 2106106648Srwatson return (error); 2107106648Srwatson } 2108106648Srwatson 2109101099Srwatson if (!mac_biba_enabled) 2110101099Srwatson return (0); 2111101099Srwatson 2112122524Srwatson subj = SLOT(cred->cr_label); 2113101099Srwatson obj = SLOT(label); 2114101099Srwatson 2115101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2116101099Srwatson return (EACCES); 2117101099Srwatson 2118101099Srwatson return (0); 2119101099Srwatson} 2120101099Srwatson 2121101099Srwatsonstatic int 2122101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2123101099Srwatson struct label *label, acl_type_t type) 2124101099Srwatson{ 2125101099Srwatson struct mac_biba *subj, *obj; 2126101099Srwatson 2127101099Srwatson if (!mac_biba_enabled) 2128101099Srwatson return (0); 2129101099Srwatson 2130122524Srwatson subj = SLOT(cred->cr_label); 2131101099Srwatson obj = SLOT(label); 2132101099Srwatson 2133101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2134101099Srwatson return (EACCES); 2135101099Srwatson 2136101099Srwatson return (0); 2137101099Srwatson} 2138101099Srwatson 2139101099Srwatsonstatic int 2140101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2141101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 2142101099Srwatson{ 2143101099Srwatson struct mac_biba *subj, *obj; 2144101099Srwatson 2145101099Srwatson if (!mac_biba_enabled) 2146101099Srwatson return (0); 2147101099Srwatson 2148122524Srwatson subj = SLOT(cred->cr_label); 2149101099Srwatson obj = SLOT(label); 2150101099Srwatson 2151101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2152101099Srwatson return (EACCES); 2153101099Srwatson 2154101099Srwatson return (0); 2155101099Srwatson} 2156101099Srwatson 2157101099Srwatsonstatic int 2158104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2159104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2160104530Srwatson struct componentname *cnp) 2161104530Srwatson{ 2162104530Srwatson struct mac_biba *subj, *obj; 2163104530Srwatson 2164104530Srwatson if (!mac_biba_enabled) 2165104530Srwatson return (0); 2166104530Srwatson 2167122524Srwatson subj = SLOT(cred->cr_label); 2168104530Srwatson obj = SLOT(dlabel); 2169104530Srwatson 2170104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2171104530Srwatson return (EACCES); 2172104530Srwatson 2173104530Srwatson obj = SLOT(label); 2174104530Srwatson 2175104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2176104530Srwatson return (EACCES); 2177104530Srwatson 2178104530Srwatson return (0); 2179104530Srwatson} 2180104530Srwatson 2181104530Srwatsonstatic int 2182119202Srwatsonmac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2183119202Srwatson struct label *label, int attrnamespace) 2184119202Srwatson{ 2185119202Srwatson struct mac_biba *subj, *obj; 2186119202Srwatson 2187119202Srwatson if (!mac_biba_enabled) 2188119202Srwatson return (0); 2189119202Srwatson 2190122524Srwatson subj = SLOT(cred->cr_label); 2191119202Srwatson obj = SLOT(label); 2192119202Srwatson 2193119202Srwatson if (!mac_biba_dominate_single(obj, subj)) 2194119202Srwatson return (EACCES); 2195119202Srwatson 2196119202Srwatson return (0); 2197119202Srwatson} 2198119202Srwatson 2199119202Srwatsonstatic int 2200103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2201101099Srwatson struct label *dlabel, struct componentname *cnp) 2202101099Srwatson{ 2203101099Srwatson struct mac_biba *subj, *obj; 2204103759Srwatson 2205101099Srwatson if (!mac_biba_enabled) 2206101099Srwatson return (0); 2207103759Srwatson 2208122524Srwatson subj = SLOT(cred->cr_label); 2209101099Srwatson obj = SLOT(dlabel); 2210103759Srwatson 2211101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2212101099Srwatson return (EACCES); 2213101099Srwatson 2214103759Srwatson return (0); 2215101099Srwatson} 2216101099Srwatson 2217101099Srwatsonstatic int 2218104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2219104546Srwatson struct label *label, int prot) 2220104546Srwatson{ 2221104546Srwatson struct mac_biba *subj, *obj; 2222104546Srwatson 2223104546Srwatson /* 2224104546Srwatson * Rely on the use of open()-time protections to handle 2225104546Srwatson * non-revocation cases. 2226104546Srwatson */ 2227105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2228104546Srwatson return (0); 2229104546Srwatson 2230122524Srwatson subj = SLOT(cred->cr_label); 2231104546Srwatson obj = SLOT(label); 2232104546Srwatson 2233104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2234104546Srwatson if (!mac_biba_dominate_single(obj, subj)) 2235104546Srwatson return (EACCES); 2236104546Srwatson } 2237104546Srwatson if (prot & VM_PROT_WRITE) { 2238104546Srwatson if (!mac_biba_dominate_single(subj, obj)) 2239104546Srwatson return (EACCES); 2240104546Srwatson } 2241104546Srwatson 2242104569Srwatson return (0); 2243104546Srwatson} 2244104546Srwatson 2245104546Srwatsonstatic int 2246101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2247106212Srwatson struct label *vnodelabel, int acc_mode) 2248101099Srwatson{ 2249101099Srwatson struct mac_biba *subj, *obj; 2250101099Srwatson 2251101099Srwatson if (!mac_biba_enabled) 2252101099Srwatson return (0); 2253101099Srwatson 2254122524Srwatson subj = SLOT(cred->cr_label); 2255101099Srwatson obj = SLOT(vnodelabel); 2256101099Srwatson 2257101099Srwatson /* XXX privilege override for admin? */ 2258101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2259101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2260101099Srwatson return (EACCES); 2261101099Srwatson } 2262101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2263101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2264101099Srwatson return (EACCES); 2265101099Srwatson } 2266101099Srwatson 2267101099Srwatson return (0); 2268101099Srwatson} 2269101099Srwatson 2270101099Srwatsonstatic int 2271102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2272102129Srwatson struct vnode *vp, struct label *label) 2273102112Srwatson{ 2274102112Srwatson struct mac_biba *subj, *obj; 2275102112Srwatson 2276105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2277102112Srwatson return (0); 2278102112Srwatson 2279122524Srwatson subj = SLOT(active_cred->cr_label); 2280102112Srwatson obj = SLOT(label); 2281102112Srwatson 2282102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2283102112Srwatson return (EACCES); 2284102112Srwatson 2285102112Srwatson return (0); 2286102112Srwatson} 2287102112Srwatson 2288102112Srwatsonstatic int 2289102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2290102129Srwatson struct vnode *vp, struct label *label) 2291102112Srwatson{ 2292102112Srwatson struct mac_biba *subj, *obj; 2293102112Srwatson 2294105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2295102112Srwatson return (0); 2296102112Srwatson 2297122524Srwatson subj = SLOT(active_cred->cr_label); 2298102112Srwatson obj = SLOT(label); 2299102112Srwatson 2300102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2301102112Srwatson return (EACCES); 2302102112Srwatson 2303102112Srwatson return (0); 2304102112Srwatson} 2305102112Srwatson 2306102112Srwatsonstatic int 2307101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2308101099Srwatson struct label *dlabel) 2309101099Srwatson{ 2310101099Srwatson struct mac_biba *subj, *obj; 2311101099Srwatson 2312101099Srwatson if (!mac_biba_enabled) 2313101099Srwatson return (0); 2314101099Srwatson 2315122524Srwatson subj = SLOT(cred->cr_label); 2316101099Srwatson obj = SLOT(dlabel); 2317101099Srwatson 2318101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2319101099Srwatson return (EACCES); 2320101099Srwatson 2321101099Srwatson return (0); 2322101099Srwatson} 2323101099Srwatson 2324101099Srwatsonstatic int 2325101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2326101099Srwatson struct label *label) 2327101099Srwatson{ 2328101099Srwatson struct mac_biba *subj, *obj; 2329101099Srwatson 2330101099Srwatson if (!mac_biba_enabled) 2331101099Srwatson return (0); 2332101099Srwatson 2333122524Srwatson subj = SLOT(cred->cr_label); 2334101099Srwatson obj = SLOT(label); 2335101099Srwatson 2336101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2337101099Srwatson return (EACCES); 2338101099Srwatson 2339101099Srwatson return (0); 2340101099Srwatson} 2341101099Srwatson 2342101099Srwatsonstatic int 2343101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2344101099Srwatson struct label *vnodelabel, struct label *newlabel) 2345101099Srwatson{ 2346101099Srwatson struct mac_biba *old, *new, *subj; 2347105634Srwatson int error; 2348101099Srwatson 2349101099Srwatson old = SLOT(vnodelabel); 2350101099Srwatson new = SLOT(newlabel); 2351122524Srwatson subj = SLOT(cred->cr_label); 2352101099Srwatson 2353101099Srwatson /* 2354105634Srwatson * If there is a Biba label update for the vnode, it must be a 2355105634Srwatson * single label. 2356101099Srwatson */ 2357105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2358105634Srwatson if (error) 2359105634Srwatson return (error); 2360101099Srwatson 2361101099Srwatson /* 2362105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2363105634Srwatson * authorize the relabel. 2364101099Srwatson */ 2365105634Srwatson if (!mac_biba_single_in_range(old, subj)) 2366101099Srwatson return (EPERM); 2367101099Srwatson 2368101099Srwatson /* 2369105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2370101099Srwatson */ 2371105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2372105634Srwatson /* 2373105634Srwatson * To change the Biba label on a vnode, the new vnode label 2374105634Srwatson * must be in the subject range. 2375105634Srwatson */ 2376105634Srwatson if (!mac_biba_single_in_range(new, subj)) 2377105634Srwatson return (EPERM); 2378101099Srwatson 2379105634Srwatson /* 2380105634Srwatson * To change the Biba label on the vnode to be EQUAL, 2381105634Srwatson * the subject must have appropriate privilege. 2382105634Srwatson */ 2383105634Srwatson if (mac_biba_contains_equal(new)) { 2384106090Srwatson error = mac_biba_subject_privileged(subj); 2385105634Srwatson if (error) 2386105634Srwatson return (error); 2387105634Srwatson } 2388105634Srwatson } 2389105634Srwatson 2390105634Srwatson return (0); 2391101099Srwatson} 2392101099Srwatson 2393101099Srwatsonstatic int 2394101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2395101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2396101099Srwatson struct componentname *cnp) 2397101099Srwatson{ 2398101099Srwatson struct mac_biba *subj, *obj; 2399101099Srwatson 2400101099Srwatson if (!mac_biba_enabled) 2401101099Srwatson return (0); 2402101099Srwatson 2403122524Srwatson subj = SLOT(cred->cr_label); 2404101099Srwatson obj = SLOT(dlabel); 2405101099Srwatson 2406101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2407101099Srwatson return (EACCES); 2408101099Srwatson 2409101099Srwatson obj = SLOT(label); 2410101099Srwatson 2411101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2412101099Srwatson return (EACCES); 2413101099Srwatson 2414101099Srwatson return (0); 2415101099Srwatson} 2416101099Srwatson 2417101099Srwatsonstatic int 2418101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2419101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2420101099Srwatson struct componentname *cnp) 2421101099Srwatson{ 2422101099Srwatson struct mac_biba *subj, *obj; 2423101099Srwatson 2424101099Srwatson if (!mac_biba_enabled) 2425101099Srwatson return (0); 2426101099Srwatson 2427122524Srwatson subj = SLOT(cred->cr_label); 2428101099Srwatson obj = SLOT(dlabel); 2429101099Srwatson 2430101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2431101099Srwatson return (EACCES); 2432101099Srwatson 2433101099Srwatson if (vp != NULL) { 2434101099Srwatson obj = SLOT(label); 2435101099Srwatson 2436101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2437101099Srwatson return (EACCES); 2438101099Srwatson } 2439101099Srwatson 2440101099Srwatson return (0); 2441101099Srwatson} 2442101099Srwatson 2443101099Srwatsonstatic int 2444101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2445101099Srwatson struct label *label) 2446101099Srwatson{ 2447101099Srwatson struct mac_biba *subj, *obj; 2448101099Srwatson 2449101099Srwatson if (!mac_biba_enabled) 2450101099Srwatson return (0); 2451101099Srwatson 2452122524Srwatson subj = SLOT(cred->cr_label); 2453101099Srwatson obj = SLOT(label); 2454101099Srwatson 2455101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2456101099Srwatson return (EACCES); 2457101099Srwatson 2458101099Srwatson return (0); 2459101099Srwatson} 2460101099Srwatson 2461101099Srwatsonstatic int 2462101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2463101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 2464101099Srwatson{ 2465101099Srwatson struct mac_biba *subj, *obj; 2466101099Srwatson 2467101099Srwatson if (!mac_biba_enabled) 2468101099Srwatson return (0); 2469101099Srwatson 2470122524Srwatson subj = SLOT(cred->cr_label); 2471101099Srwatson obj = SLOT(label); 2472101099Srwatson 2473101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2474101099Srwatson return (EACCES); 2475101099Srwatson 2476101099Srwatson return (0); 2477101099Srwatson} 2478101099Srwatson 2479101099Srwatsonstatic int 2480101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2481101099Srwatson struct label *vnodelabel, int attrnamespace, const char *name, 2482101099Srwatson struct uio *uio) 2483101099Srwatson{ 2484101099Srwatson struct mac_biba *subj, *obj; 2485101099Srwatson 2486101099Srwatson if (!mac_biba_enabled) 2487101099Srwatson return (0); 2488101099Srwatson 2489122524Srwatson subj = SLOT(cred->cr_label); 2490101099Srwatson obj = SLOT(vnodelabel); 2491101099Srwatson 2492101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2493101099Srwatson return (EACCES); 2494101099Srwatson 2495101099Srwatson /* XXX: protect the MAC EA in a special way? */ 2496101099Srwatson 2497101099Srwatson return (0); 2498101099Srwatson} 2499101099Srwatson 2500101099Srwatsonstatic int 2501101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2502101099Srwatson struct label *vnodelabel, u_long flags) 2503101099Srwatson{ 2504101099Srwatson struct mac_biba *subj, *obj; 2505101099Srwatson 2506101099Srwatson if (!mac_biba_enabled) 2507101099Srwatson return (0); 2508101099Srwatson 2509122524Srwatson subj = SLOT(cred->cr_label); 2510101099Srwatson obj = SLOT(vnodelabel); 2511101099Srwatson 2512101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2513101099Srwatson return (EACCES); 2514101099Srwatson 2515101099Srwatson return (0); 2516101099Srwatson} 2517101099Srwatson 2518101099Srwatsonstatic int 2519101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2520101099Srwatson struct label *vnodelabel, mode_t mode) 2521101099Srwatson{ 2522101099Srwatson struct mac_biba *subj, *obj; 2523101099Srwatson 2524101099Srwatson if (!mac_biba_enabled) 2525101099Srwatson return (0); 2526101099Srwatson 2527122524Srwatson subj = SLOT(cred->cr_label); 2528101099Srwatson obj = SLOT(vnodelabel); 2529101099Srwatson 2530101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2531101099Srwatson return (EACCES); 2532101099Srwatson 2533101099Srwatson return (0); 2534101099Srwatson} 2535101099Srwatson 2536101099Srwatsonstatic int 2537101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2538101099Srwatson struct label *vnodelabel, uid_t uid, gid_t gid) 2539101099Srwatson{ 2540101099Srwatson struct mac_biba *subj, *obj; 2541101099Srwatson 2542101099Srwatson if (!mac_biba_enabled) 2543101099Srwatson return (0); 2544101099Srwatson 2545122524Srwatson subj = SLOT(cred->cr_label); 2546101099Srwatson obj = SLOT(vnodelabel); 2547101099Srwatson 2548101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2549101099Srwatson return (EACCES); 2550101099Srwatson 2551101099Srwatson return (0); 2552101099Srwatson} 2553101099Srwatson 2554101099Srwatsonstatic int 2555101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2556101099Srwatson struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2557101099Srwatson{ 2558101099Srwatson struct mac_biba *subj, *obj; 2559101099Srwatson 2560101099Srwatson if (!mac_biba_enabled) 2561101099Srwatson return (0); 2562101099Srwatson 2563122524Srwatson subj = SLOT(cred->cr_label); 2564101099Srwatson obj = SLOT(vnodelabel); 2565101099Srwatson 2566101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2567101099Srwatson return (EACCES); 2568101099Srwatson 2569101099Srwatson return (0); 2570101099Srwatson} 2571101099Srwatson 2572101099Srwatsonstatic int 2573102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2574102129Srwatson struct vnode *vp, struct label *vnodelabel) 2575101099Srwatson{ 2576101099Srwatson struct mac_biba *subj, *obj; 2577101099Srwatson 2578101099Srwatson if (!mac_biba_enabled) 2579101099Srwatson return (0); 2580101099Srwatson 2581122524Srwatson subj = SLOT(active_cred->cr_label); 2582101099Srwatson obj = SLOT(vnodelabel); 2583101099Srwatson 2584101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2585101099Srwatson return (EACCES); 2586101099Srwatson 2587101099Srwatson return (0); 2588101099Srwatson} 2589101099Srwatson 2590102112Srwatsonstatic int 2591102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred, 2592102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 2593102112Srwatson{ 2594102112Srwatson struct mac_biba *subj, *obj; 2595102112Srwatson 2596105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2597102112Srwatson return (0); 2598102112Srwatson 2599122524Srwatson subj = SLOT(active_cred->cr_label); 2600102112Srwatson obj = SLOT(label); 2601102112Srwatson 2602102112Srwatson if (!mac_biba_dominate_single(subj, obj)) 2603102112Srwatson return (EACCES); 2604102112Srwatson 2605102112Srwatson return (0); 2606102112Srwatson} 2607102112Srwatson 2608106217Srwatsonstatic struct mac_policy_ops mac_biba_ops = 2609101099Srwatson{ 2610106217Srwatson .mpo_destroy = mac_biba_destroy, 2611106217Srwatson .mpo_init = mac_biba_init, 2612106217Srwatson .mpo_init_bpfdesc_label = mac_biba_init_label, 2613106217Srwatson .mpo_init_cred_label = mac_biba_init_label, 2614106217Srwatson .mpo_init_devfsdirent_label = mac_biba_init_label, 2615106217Srwatson .mpo_init_ifnet_label = mac_biba_init_label, 2616112675Srwatson .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 2617106217Srwatson .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2618106217Srwatson .mpo_init_mount_label = mac_biba_init_label, 2619106217Srwatson .mpo_init_mount_fs_label = mac_biba_init_label, 2620106217Srwatson .mpo_init_pipe_label = mac_biba_init_label, 2621106217Srwatson .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2622106217Srwatson .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2623106217Srwatson .mpo_init_vnode_label = mac_biba_init_label, 2624106217Srwatson .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2625106217Srwatson .mpo_destroy_cred_label = mac_biba_destroy_label, 2626106217Srwatson .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2627106217Srwatson .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2628106217Srwatson .mpo_destroy_ipq_label = mac_biba_destroy_label, 2629106217Srwatson .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2630106217Srwatson .mpo_destroy_mount_label = mac_biba_destroy_label, 2631106217Srwatson .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2632106217Srwatson .mpo_destroy_pipe_label = mac_biba_destroy_label, 2633106217Srwatson .mpo_destroy_socket_label = mac_biba_destroy_label, 2634106217Srwatson .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2635106217Srwatson .mpo_destroy_vnode_label = mac_biba_destroy_label, 2636115707Srwatson .mpo_copy_mbuf_label = mac_biba_copy_label, 2637106217Srwatson .mpo_copy_pipe_label = mac_biba_copy_label, 2638106217Srwatson .mpo_copy_vnode_label = mac_biba_copy_label, 2639106217Srwatson .mpo_externalize_cred_label = mac_biba_externalize_label, 2640106217Srwatson .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2641106217Srwatson .mpo_externalize_pipe_label = mac_biba_externalize_label, 2642106217Srwatson .mpo_externalize_socket_label = mac_biba_externalize_label, 2643106217Srwatson .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2644106217Srwatson .mpo_externalize_vnode_label = mac_biba_externalize_label, 2645106217Srwatson .mpo_internalize_cred_label = mac_biba_internalize_label, 2646106217Srwatson .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2647106217Srwatson .mpo_internalize_pipe_label = mac_biba_internalize_label, 2648106217Srwatson .mpo_internalize_socket_label = mac_biba_internalize_label, 2649106217Srwatson .mpo_internalize_vnode_label = mac_biba_internalize_label, 2650106217Srwatson .mpo_create_devfs_device = mac_biba_create_devfs_device, 2651106217Srwatson .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2652106217Srwatson .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2653106217Srwatson .mpo_create_mount = mac_biba_create_mount, 2654106217Srwatson .mpo_create_root_mount = mac_biba_create_root_mount, 2655106217Srwatson .mpo_relabel_vnode = mac_biba_relabel_vnode, 2656106217Srwatson .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2657106217Srwatson .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2658106217Srwatson .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2659106217Srwatson .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2660106217Srwatson .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2661106217Srwatson .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2662106217Srwatson .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2663106217Srwatson .mpo_create_pipe = mac_biba_create_pipe, 2664106217Srwatson .mpo_create_socket = mac_biba_create_socket, 2665106217Srwatson .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2666106217Srwatson .mpo_relabel_pipe = mac_biba_relabel_pipe, 2667106217Srwatson .mpo_relabel_socket = mac_biba_relabel_socket, 2668106217Srwatson .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2669106217Srwatson .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2670106217Srwatson .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2671106217Srwatson .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2672106217Srwatson .mpo_create_fragment = mac_biba_create_fragment, 2673106217Srwatson .mpo_create_ifnet = mac_biba_create_ifnet, 2674106217Srwatson .mpo_create_ipq = mac_biba_create_ipq, 2675106217Srwatson .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2676106217Srwatson .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2677106217Srwatson .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2678106217Srwatson .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2679106217Srwatson .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2680106217Srwatson .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2681106217Srwatson .mpo_fragment_match = mac_biba_fragment_match, 2682106217Srwatson .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2683106217Srwatson .mpo_update_ipq = mac_biba_update_ipq, 2684106217Srwatson .mpo_create_cred = mac_biba_create_cred, 2685106217Srwatson .mpo_create_proc0 = mac_biba_create_proc0, 2686106217Srwatson .mpo_create_proc1 = mac_biba_create_proc1, 2687106217Srwatson .mpo_relabel_cred = mac_biba_relabel_cred, 2688106217Srwatson .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2689106217Srwatson .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2690106217Srwatson .mpo_check_cred_visible = mac_biba_check_cred_visible, 2691106217Srwatson .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2692106217Srwatson .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2693110354Srwatson .mpo_check_kld_load = mac_biba_check_kld_load, 2694110354Srwatson .mpo_check_kld_unload = mac_biba_check_kld_unload, 2695106217Srwatson .mpo_check_mount_stat = mac_biba_check_mount_stat, 2696106217Srwatson .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2697106217Srwatson .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2698106217Srwatson .mpo_check_pipe_read = mac_biba_check_pipe_read, 2699106217Srwatson .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2700106217Srwatson .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2701106217Srwatson .mpo_check_pipe_write = mac_biba_check_pipe_write, 2702106217Srwatson .mpo_check_proc_debug = mac_biba_check_proc_debug, 2703106217Srwatson .mpo_check_proc_sched = mac_biba_check_proc_sched, 2704106217Srwatson .mpo_check_proc_signal = mac_biba_check_proc_signal, 2705106217Srwatson .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2706106217Srwatson .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2707106217Srwatson .mpo_check_socket_visible = mac_biba_check_socket_visible, 2708112574Srwatson .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 2709106418Srwatson .mpo_check_system_acct = mac_biba_check_system_acct, 2710106418Srwatson .mpo_check_system_settime = mac_biba_check_system_settime, 2711106217Srwatson .mpo_check_system_swapon = mac_biba_check_system_swapon, 2712112574Srwatson .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 2713106217Srwatson .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2714106217Srwatson .mpo_check_vnode_access = mac_biba_check_vnode_open, 2715106217Srwatson .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2716106217Srwatson .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2717106217Srwatson .mpo_check_vnode_create = mac_biba_check_vnode_create, 2718106217Srwatson .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2719106217Srwatson .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2720119202Srwatson .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr, 2721106217Srwatson .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2722106217Srwatson .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2723106217Srwatson .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2724106217Srwatson .mpo_check_vnode_link = mac_biba_check_vnode_link, 2725119202Srwatson .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr, 2726106217Srwatson .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2727106217Srwatson .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2728106217Srwatson .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2729106217Srwatson .mpo_check_vnode_open = mac_biba_check_vnode_open, 2730106217Srwatson .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2731106217Srwatson .mpo_check_vnode_read = mac_biba_check_vnode_read, 2732106217Srwatson .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2733106217Srwatson .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2734106217Srwatson .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2735106217Srwatson .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2736106217Srwatson .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2737106217Srwatson .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2738106217Srwatson .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2739106217Srwatson .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2740106217Srwatson .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2741106217Srwatson .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2742106217Srwatson .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2743106217Srwatson .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2744106217Srwatson .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2745106217Srwatson .mpo_check_vnode_write = mac_biba_check_vnode_write, 2746101099Srwatson}; 2747101099Srwatson 2748112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 2749113531Srwatson MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot); 2750