mac_biba.c revision 107698
1101099Srwatson/*- 2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3101099Srwatson * Copyright (c) 2001, 2002 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 107698 2002-12-09 03:44:28Z 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> 52101099Srwatson#include <sys/systm.h> 53101099Srwatson#include <sys/sysproto.h> 54101099Srwatson#include <sys/sysent.h> 55105696Srwatson#include <sys/systm.h> 56101099Srwatson#include <sys/vnode.h> 57101099Srwatson#include <sys/file.h> 58101099Srwatson#include <sys/socket.h> 59101099Srwatson#include <sys/socketvar.h> 60101099Srwatson#include <sys/pipe.h> 61101099Srwatson#include <sys/sysctl.h> 62101099Srwatson 63101099Srwatson#include <fs/devfs/devfs.h> 64101099Srwatson 65101099Srwatson#include <net/bpfdesc.h> 66101099Srwatson#include <net/if.h> 67101099Srwatson#include <net/if_types.h> 68101099Srwatson#include <net/if_var.h> 69101099Srwatson 70101099Srwatson#include <netinet/in.h> 71101099Srwatson#include <netinet/ip_var.h> 72101099Srwatson 73101099Srwatson#include <vm/vm.h> 74101099Srwatson 75101099Srwatson#include <sys/mac_policy.h> 76101099Srwatson 77101099Srwatson#include <security/mac_biba/mac_biba.h> 78101099Srwatson 79101099SrwatsonSYSCTL_DECL(_security_mac); 80101099Srwatson 81101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 82101099Srwatson "TrustedBSD mac_biba policy controls"); 83101099Srwatson 84105988Srwatsonstatic int mac_biba_label_size = sizeof(struct mac_biba); 85105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 86105988Srwatson &mac_biba_label_size, 0, "Size of struct mac_biba"); 87105988Srwatson 88101099Srwatsonstatic int mac_biba_enabled = 0; 89101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 90101099Srwatson &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 91102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 92101099Srwatson 93101099Srwatsonstatic int destroyed_not_inited; 94101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 95101099Srwatson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 96101099Srwatson 97101099Srwatsonstatic int trust_all_interfaces = 0; 98101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 99101099Srwatson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 100101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 101101099Srwatson 102101099Srwatsonstatic char trusted_interfaces[128]; 103101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 104101099Srwatson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 105101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 106101099Srwatson sizeof(trusted_interfaces)); 107101099Srwatson 108105643Srwatsonstatic int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 109105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 110105643Srwatson &max_compartments, 0, "Maximum supported compartments"); 111105643Srwatson 112105606Srwatsonstatic int ptys_equal = 0; 113105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 114105606Srwatson &ptys_equal, 0, "Label pty devices as biba/equal on create"); 115105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 116105606Srwatson 117105637Srwatsonstatic int revocation_enabled = 0; 118101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 119105637Srwatson &revocation_enabled, 0, "Revoke access to objects on relabel"); 120105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 121101099Srwatson 122101099Srwatsonstatic int mac_biba_slot; 123101099Srwatson#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 124101099Srwatson 125101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels"); 126101099Srwatson 127105643Srwatsonstatic __inline int 128105643Srwatsonbiba_bit_set_empty(u_char *set) { 129105643Srwatson int i; 130105643Srwatson 131105643Srwatson for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 132105643Srwatson if (set[i] != 0) 133105643Srwatson return (0); 134105643Srwatson return (1); 135105643Srwatson} 136105643Srwatson 137101099Srwatsonstatic struct mac_biba * 138104514Srwatsonbiba_alloc(int flag) 139101099Srwatson{ 140101099Srwatson struct mac_biba *mac_biba; 141101099Srwatson 142104514Srwatson mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag); 143101099Srwatson 144101099Srwatson return (mac_biba); 145101099Srwatson} 146101099Srwatson 147101099Srwatsonstatic void 148101099Srwatsonbiba_free(struct mac_biba *mac_biba) 149101099Srwatson{ 150101099Srwatson 151101099Srwatson if (mac_biba != NULL) 152101099Srwatson free(mac_biba, M_MACBIBA); 153101099Srwatson else 154101099Srwatson atomic_add_int(&destroyed_not_inited, 1); 155101099Srwatson} 156101099Srwatson 157101099Srwatsonstatic int 158105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags) 159105634Srwatson{ 160105634Srwatson 161105634Srwatson if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 162105634Srwatson return (EINVAL); 163105634Srwatson return (0); 164105634Srwatson} 165105634Srwatson 166105634Srwatsonstatic int 167101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a, 168101099Srwatson struct mac_biba_element *b) 169101099Srwatson{ 170105643Srwatson int bit; 171101099Srwatson 172105736Srwatson switch (a->mbe_type) { 173101099Srwatson case MAC_BIBA_TYPE_EQUAL: 174101099Srwatson case MAC_BIBA_TYPE_HIGH: 175101099Srwatson return (1); 176101099Srwatson 177101099Srwatson case MAC_BIBA_TYPE_LOW: 178101099Srwatson switch (b->mbe_type) { 179101099Srwatson case MAC_BIBA_TYPE_GRADE: 180101099Srwatson case MAC_BIBA_TYPE_HIGH: 181101099Srwatson return (0); 182101099Srwatson 183101099Srwatson case MAC_BIBA_TYPE_EQUAL: 184101099Srwatson case MAC_BIBA_TYPE_LOW: 185101099Srwatson return (1); 186101099Srwatson 187101099Srwatson default: 188101099Srwatson panic("mac_biba_dominate_element: b->mbe_type invalid"); 189101099Srwatson } 190101099Srwatson 191101099Srwatson case MAC_BIBA_TYPE_GRADE: 192101099Srwatson switch (b->mbe_type) { 193101099Srwatson case MAC_BIBA_TYPE_EQUAL: 194101099Srwatson case MAC_BIBA_TYPE_LOW: 195101099Srwatson return (1); 196101099Srwatson 197101099Srwatson case MAC_BIBA_TYPE_HIGH: 198101099Srwatson return (0); 199101099Srwatson 200101099Srwatson case MAC_BIBA_TYPE_GRADE: 201105643Srwatson for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 202105643Srwatson if (!MAC_BIBA_BIT_TEST(bit, 203105643Srwatson a->mbe_compartments) && 204105643Srwatson MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 205105643Srwatson return (0); 206101099Srwatson return (a->mbe_grade >= b->mbe_grade); 207101099Srwatson 208101099Srwatson default: 209101099Srwatson panic("mac_biba_dominate_element: b->mbe_type invalid"); 210101099Srwatson } 211101099Srwatson 212101099Srwatson default: 213101099Srwatson panic("mac_biba_dominate_element: a->mbe_type invalid"); 214101099Srwatson } 215101099Srwatson 216101099Srwatson return (0); 217101099Srwatson} 218101099Srwatson 219101099Srwatsonstatic int 220105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba) 221105988Srwatson{ 222105988Srwatson struct mac_biba_element *element; 223105988Srwatson 224106174Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 225105988Srwatson ("mac_biba_single_in_range: mac_biba not single")); 226105988Srwatson element = &mac_biba->mb_single; 227105988Srwatson 228105988Srwatson return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 229105988Srwatson element->mbe_type == MAC_BIBA_TYPE_HIGH); 230105988Srwatson} 231105988Srwatson 232105988Srwatsonstatic int 233101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 234101099Srwatson{ 235101099Srwatson 236101099Srwatson return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 237101099Srwatson &rangea->mb_rangehigh) && 238101099Srwatson mac_biba_dominate_element(&rangea->mb_rangelow, 239101099Srwatson &rangeb->mb_rangelow)); 240101099Srwatson} 241101099Srwatson 242101099Srwatsonstatic int 243101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range) 244101099Srwatson{ 245101099Srwatson 246103750Srwatson KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 247101099Srwatson ("mac_biba_single_in_range: a not single")); 248103750Srwatson KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 249101099Srwatson ("mac_biba_single_in_range: b not range")); 250101099Srwatson 251101099Srwatson return (mac_biba_dominate_element(&range->mb_rangehigh, 252101099Srwatson &single->mb_single) && 253101099Srwatson mac_biba_dominate_element(&single->mb_single, 254101099Srwatson &range->mb_rangelow)); 255101099Srwatson 256101099Srwatson return (1); 257101099Srwatson} 258101099Srwatson 259101099Srwatsonstatic int 260101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b) 261101099Srwatson{ 262101099Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 263101099Srwatson ("mac_biba_dominate_single: a not single")); 264101099Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 265101099Srwatson ("mac_biba_dominate_single: b not single")); 266101099Srwatson 267101099Srwatson return (mac_biba_dominate_element(&a->mb_single, &b->mb_single)); 268101099Srwatson} 269101099Srwatson 270101099Srwatsonstatic int 271101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 272101099Srwatson{ 273101099Srwatson 274101099Srwatson if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 275101099Srwatson b->mbe_type == MAC_BIBA_TYPE_EQUAL) 276101099Srwatson return (1); 277101099Srwatson 278101099Srwatson return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 279101099Srwatson} 280101099Srwatson 281101099Srwatsonstatic int 282101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b) 283101099Srwatson{ 284101099Srwatson 285101099Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 286101099Srwatson ("mac_biba_equal_single: a not single")); 287101099Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 288101099Srwatson ("mac_biba_equal_single: b not single")); 289101099Srwatson 290101099Srwatson return (mac_biba_equal_element(&a->mb_single, &b->mb_single)); 291101099Srwatson} 292101099Srwatson 293101099Srwatsonstatic int 294105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba) 295105634Srwatson{ 296105634Srwatson 297105634Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) 298105634Srwatson if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 299105634Srwatson return (1); 300105634Srwatson 301105634Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 302105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 303105634Srwatson return (1); 304105634Srwatson if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 305105637Srwatson return (1); 306105634Srwatson } 307105634Srwatson 308105634Srwatson return (0); 309105634Srwatson} 310105634Srwatson 311105634Srwatsonstatic int 312106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba) 313105634Srwatson{ 314105634Srwatson 315105634Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 316105634Srwatson MAC_BIBA_FLAGS_BOTH, 317106090Srwatson ("mac_biba_subject_privileged: subject doesn't have both labels")); 318105634Srwatson 319105634Srwatson /* If the single is EQUAL, it's ok. */ 320105634Srwatson if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 321105634Srwatson return (0); 322105634Srwatson 323105634Srwatson /* If either range endpoint is EQUAL, it's ok. */ 324105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 325105634Srwatson mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 326105634Srwatson return (0); 327105634Srwatson 328105634Srwatson /* If the range is low-high, it's ok. */ 329105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 330105634Srwatson mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 331105634Srwatson return (0); 332105634Srwatson 333105634Srwatson /* It's not ok. */ 334105634Srwatson return (EPERM); 335105634Srwatson} 336105634Srwatson 337106091Srwatsonstatic int 338105988Srwatsonmac_biba_high_single(struct mac_biba *mac_biba) 339105988Srwatson{ 340105988Srwatson 341105988Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 342105988Srwatson ("mac_biba_equal_single: mac_biba not single")); 343105988Srwatson 344105988Srwatson return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH); 345105988Srwatson} 346105988Srwatson 347105634Srwatsonstatic int 348101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba) 349101099Srwatson{ 350101099Srwatson 351101099Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 352101099Srwatson switch (mac_biba->mb_single.mbe_type) { 353101099Srwatson case MAC_BIBA_TYPE_GRADE: 354101099Srwatson break; 355101099Srwatson 356101099Srwatson case MAC_BIBA_TYPE_EQUAL: 357101099Srwatson case MAC_BIBA_TYPE_HIGH: 358101099Srwatson case MAC_BIBA_TYPE_LOW: 359105643Srwatson if (mac_biba->mb_single.mbe_grade != 0 || 360105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 361105643Srwatson mac_biba->mb_single.mbe_compartments)) 362101099Srwatson return (EINVAL); 363101099Srwatson break; 364101099Srwatson 365101099Srwatson default: 366101099Srwatson return (EINVAL); 367101099Srwatson } 368101099Srwatson } else { 369101099Srwatson if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 370101099Srwatson return (EINVAL); 371101099Srwatson } 372101099Srwatson 373101099Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 374101099Srwatson switch (mac_biba->mb_rangelow.mbe_type) { 375101099Srwatson case MAC_BIBA_TYPE_GRADE: 376101099Srwatson break; 377101099Srwatson 378101099Srwatson case MAC_BIBA_TYPE_EQUAL: 379101099Srwatson case MAC_BIBA_TYPE_HIGH: 380101099Srwatson case MAC_BIBA_TYPE_LOW: 381105643Srwatson if (mac_biba->mb_rangelow.mbe_grade != 0 || 382105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 383105643Srwatson mac_biba->mb_rangelow.mbe_compartments)) 384101099Srwatson return (EINVAL); 385101099Srwatson break; 386101099Srwatson 387101099Srwatson default: 388101099Srwatson return (EINVAL); 389101099Srwatson } 390101099Srwatson 391101099Srwatson switch (mac_biba->mb_rangehigh.mbe_type) { 392101099Srwatson case MAC_BIBA_TYPE_GRADE: 393101099Srwatson break; 394101099Srwatson 395101099Srwatson case MAC_BIBA_TYPE_EQUAL: 396101099Srwatson case MAC_BIBA_TYPE_HIGH: 397101099Srwatson case MAC_BIBA_TYPE_LOW: 398105643Srwatson if (mac_biba->mb_rangehigh.mbe_grade != 0 || 399105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 400105643Srwatson mac_biba->mb_rangehigh.mbe_compartments)) 401101099Srwatson return (EINVAL); 402101099Srwatson break; 403101099Srwatson 404101099Srwatson default: 405101099Srwatson return (EINVAL); 406101099Srwatson } 407101099Srwatson if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 408101099Srwatson &mac_biba->mb_rangelow)) 409101099Srwatson return (EINVAL); 410101099Srwatson } else { 411101099Srwatson if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 412101099Srwatson mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 413101099Srwatson return (EINVAL); 414101099Srwatson } 415101099Srwatson 416101099Srwatson return (0); 417101099Srwatson} 418101099Srwatson 419101099Srwatsonstatic void 420101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 421105643Srwatson u_short gradelow, u_char *compartmentslow, u_short typehigh, 422105643Srwatson u_short gradehigh, u_char *compartmentshigh) 423101099Srwatson{ 424101099Srwatson 425101099Srwatson mac_biba->mb_rangelow.mbe_type = typelow; 426101099Srwatson mac_biba->mb_rangelow.mbe_grade = gradelow; 427105643Srwatson if (compartmentslow != NULL) 428105643Srwatson memcpy(mac_biba->mb_rangelow.mbe_compartments, 429105643Srwatson compartmentslow, 430105643Srwatson sizeof(mac_biba->mb_rangelow.mbe_compartments)); 431101099Srwatson mac_biba->mb_rangehigh.mbe_type = typehigh; 432101099Srwatson mac_biba->mb_rangehigh.mbe_grade = gradehigh; 433105643Srwatson if (compartmentshigh != NULL) 434105643Srwatson memcpy(mac_biba->mb_rangehigh.mbe_compartments, 435105643Srwatson compartmentshigh, 436105643Srwatson sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 437101099Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 438101099Srwatson} 439101099Srwatson 440101099Srwatsonstatic void 441105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 442105643Srwatson u_char *compartments) 443101099Srwatson{ 444101099Srwatson 445101099Srwatson mac_biba->mb_single.mbe_type = type; 446101099Srwatson mac_biba->mb_single.mbe_grade = grade; 447105643Srwatson if (compartments != NULL) 448105643Srwatson memcpy(mac_biba->mb_single.mbe_compartments, compartments, 449105643Srwatson sizeof(mac_biba->mb_single.mbe_compartments)); 450101099Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 451101099Srwatson} 452101099Srwatson 453101099Srwatsonstatic void 454101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 455101099Srwatson{ 456105643Srwatson 457101099Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 458101099Srwatson ("mac_biba_copy_range: labelfrom not range")); 459101099Srwatson 460101099Srwatson labelto->mb_rangelow = labelfrom->mb_rangelow; 461101099Srwatson labelto->mb_rangehigh = labelfrom->mb_rangehigh; 462101099Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 463101099Srwatson} 464101099Srwatson 465101099Srwatsonstatic void 466101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 467101099Srwatson{ 468101099Srwatson 469101099Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 470101099Srwatson ("mac_biba_copy_single: labelfrom not single")); 471101099Srwatson 472101099Srwatson labelto->mb_single = labelfrom->mb_single; 473101099Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 474101099Srwatson} 475101099Srwatson 476105656Srwatsonstatic void 477105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 478105656Srwatson{ 479105656Srwatson 480105656Srwatson if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 481105656Srwatson mac_biba_copy_single(source, dest); 482105656Srwatson if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 483105656Srwatson mac_biba_copy_range(source, dest); 484105656Srwatson} 485105656Srwatson 486101099Srwatson/* 487101099Srwatson * Policy module operations. 488101099Srwatson */ 489101099Srwatsonstatic void 490101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf) 491101099Srwatson{ 492101099Srwatson 493101099Srwatson} 494101099Srwatson 495101099Srwatsonstatic void 496101099Srwatsonmac_biba_init(struct mac_policy_conf *conf) 497101099Srwatson{ 498101099Srwatson 499101099Srwatson} 500101099Srwatson 501101099Srwatson/* 502101099Srwatson * Label operations. 503101099Srwatson */ 504101099Srwatsonstatic void 505104514Srwatsonmac_biba_init_label(struct label *label) 506101099Srwatson{ 507101099Srwatson 508101099Srwatson SLOT(label) = biba_alloc(M_WAITOK); 509101099Srwatson} 510101099Srwatson 511101099Srwatsonstatic int 512104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag) 513101099Srwatson{ 514101099Srwatson 515104514Srwatson SLOT(label) = biba_alloc(flag); 516101099Srwatson if (SLOT(label) == NULL) 517101099Srwatson return (ENOMEM); 518101099Srwatson 519101099Srwatson return (0); 520101099Srwatson} 521101099Srwatson 522101099Srwatsonstatic void 523104514Srwatsonmac_biba_destroy_label(struct label *label) 524101099Srwatson{ 525101099Srwatson 526101099Srwatson biba_free(SLOT(label)); 527101099Srwatson SLOT(label) = NULL; 528101099Srwatson} 529101099Srwatson 530105696Srwatson/* 531105696Srwatson * mac_biba_element_to_string() is basically an snprintf wrapper with 532105696Srwatson * the same properties as snprintf(). It returns the length it would 533105696Srwatson * have added to the string in the event the string is too short. 534105696Srwatson */ 535105696Srwatsonstatic size_t 536105696Srwatsonmac_biba_element_to_string(char *string, size_t size, 537105696Srwatson struct mac_biba_element *element) 538105696Srwatson{ 539105696Srwatson int pos, bit = 1; 540105696Srwatson 541105696Srwatson switch (element->mbe_type) { 542105696Srwatson case MAC_BIBA_TYPE_HIGH: 543105696Srwatson return (snprintf(string, size, "high")); 544105696Srwatson 545105696Srwatson case MAC_BIBA_TYPE_LOW: 546105696Srwatson return (snprintf(string, size, "low")); 547105696Srwatson 548105696Srwatson case MAC_BIBA_TYPE_EQUAL: 549105696Srwatson return (snprintf(string, size, "equal")); 550105696Srwatson 551105696Srwatson case MAC_BIBA_TYPE_GRADE: 552105696Srwatson pos = snprintf(string, size, "%d:", element->mbe_grade); 553105696Srwatson for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) { 554105696Srwatson if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments)) 555105696Srwatson pos += snprintf(string + pos, size - pos, 556105696Srwatson "%d+", bit); 557105696Srwatson } 558105696Srwatson if (string[pos - 1] == '+' || string[pos - 1] == ':') 559106214Srwatson string[--pos] = '\0'; 560105696Srwatson return (pos); 561105696Srwatson 562105696Srwatson default: 563105696Srwatson panic("mac_biba_element_to_string: invalid type (%d)", 564105696Srwatson element->mbe_type); 565105696Srwatson } 566105696Srwatson} 567105696Srwatson 568101099Srwatsonstatic int 569105696Srwatsonmac_biba_to_string(char *string, size_t size, size_t *caller_len, 570105696Srwatson struct mac_biba *mac_biba) 571101099Srwatson{ 572105696Srwatson size_t left, len; 573105696Srwatson char *curptr; 574105696Srwatson 575105696Srwatson bzero(string, size); 576105696Srwatson curptr = string; 577105696Srwatson left = size; 578105696Srwatson 579105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 580105696Srwatson len = mac_biba_element_to_string(curptr, left, 581105696Srwatson &mac_biba->mb_single); 582105696Srwatson if (len >= left) 583105696Srwatson return (EINVAL); 584105696Srwatson left -= len; 585105696Srwatson curptr += len; 586105696Srwatson } 587105696Srwatson 588105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 589105696Srwatson len = snprintf(curptr, left, "("); 590105696Srwatson if (len >= left) 591105696Srwatson return (EINVAL); 592105696Srwatson left -= len; 593105696Srwatson curptr += len; 594105696Srwatson 595105696Srwatson len = mac_biba_element_to_string(curptr, left, 596105696Srwatson &mac_biba->mb_rangelow); 597105696Srwatson if (len >= left) 598105696Srwatson return (EINVAL); 599105696Srwatson left -= len; 600105696Srwatson curptr += len; 601105696Srwatson 602105696Srwatson len = snprintf(curptr, left, "-"); 603105696Srwatson if (len >= left) 604105696Srwatson return (EINVAL); 605105696Srwatson left -= len; 606105696Srwatson curptr += len; 607105696Srwatson 608105696Srwatson len = mac_biba_element_to_string(curptr, left, 609105696Srwatson &mac_biba->mb_rangehigh); 610105696Srwatson if (len >= left) 611105696Srwatson return (EINVAL); 612105696Srwatson left -= len; 613105696Srwatson curptr += len; 614105696Srwatson 615105696Srwatson len = snprintf(curptr, left, ")"); 616105696Srwatson if (len >= left) 617105696Srwatson return (EINVAL); 618105696Srwatson left -= len; 619105696Srwatson curptr += len; 620105696Srwatson } 621105696Srwatson 622105696Srwatson *caller_len = strlen(string); 623105696Srwatson return (0); 624105696Srwatson} 625105696Srwatson 626105696Srwatsonstatic int 627105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name, 628105696Srwatson char *element_data, size_t size, size_t *len, int *claimed) 629105696Srwatson{ 630101099Srwatson struct mac_biba *mac_biba; 631105696Srwatson int error; 632101099Srwatson 633105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 634105696Srwatson return (0); 635105696Srwatson 636105696Srwatson (*claimed)++; 637105696Srwatson 638101099Srwatson mac_biba = SLOT(label); 639105696Srwatson error = mac_biba_to_string(element_data, size, len, mac_biba); 640105696Srwatson if (error) 641105696Srwatson return (error); 642101099Srwatson 643105696Srwatson *len = strlen(element_data); 644105696Srwatson return (0); 645105696Srwatson} 646105696Srwatson 647105696Srwatsonstatic int 648105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string) 649101099Srwatson{ 650105696Srwatson 651105696Srwatson if (strcmp(string, "high") == 0 || 652105696Srwatson strcmp(string, "hi") == 0) { 653105696Srwatson element->mbe_type = MAC_BIBA_TYPE_HIGH; 654105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 655105696Srwatson } else if (strcmp(string, "low") == 0 || 656105696Srwatson strcmp(string, "lo") == 0) { 657105696Srwatson element->mbe_type = MAC_BIBA_TYPE_LOW; 658105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 659105696Srwatson } else if (strcmp(string, "equal") == 0 || 660105696Srwatson strcmp(string, "eq") == 0) { 661105696Srwatson element->mbe_type = MAC_BIBA_TYPE_EQUAL; 662105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 663105696Srwatson } else { 664105696Srwatson char *p0, *p1; 665105696Srwatson int d; 666105696Srwatson 667105696Srwatson p0 = string; 668105696Srwatson d = strtol(p0, &p1, 10); 669105696Srwatson 670105696Srwatson if (d < 0 || d > 65535) 671105696Srwatson return (EINVAL); 672105696Srwatson element->mbe_type = MAC_BIBA_TYPE_GRADE; 673105696Srwatson element->mbe_grade = d; 674105696Srwatson 675105696Srwatson if (*p1 != ':') { 676105696Srwatson if (p1 == p0 || *p1 != '\0') 677105696Srwatson return (EINVAL); 678105696Srwatson else 679105696Srwatson return (0); 680105696Srwatson } 681105696Srwatson else 682105696Srwatson if (*(p1 + 1) == '\0') 683105696Srwatson return (0); 684105696Srwatson 685105696Srwatson while ((p0 = ++p1)) { 686105696Srwatson d = strtol(p0, &p1, 10); 687105696Srwatson if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS) 688105696Srwatson return (EINVAL); 689105696Srwatson 690105696Srwatson MAC_BIBA_BIT_SET(d, element->mbe_compartments); 691105696Srwatson 692105696Srwatson if (*p1 == '\0') 693105696Srwatson break; 694105696Srwatson if (p1 == p0 || *p1 != '+') 695105696Srwatson return (EINVAL); 696105696Srwatson } 697105696Srwatson } 698105696Srwatson 699105696Srwatson return (0); 700105696Srwatson} 701105696Srwatson 702105696Srwatson/* 703105696Srwatson * Note: destructively consumes the string, make a local copy before 704105696Srwatson * calling if that's a problem. 705105696Srwatson */ 706105696Srwatsonstatic int 707105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string) 708105696Srwatson{ 709105696Srwatson char *range, *rangeend, *rangehigh, *rangelow, *single; 710101099Srwatson int error; 711101099Srwatson 712105696Srwatson /* Do we have a range? */ 713105696Srwatson single = string; 714105696Srwatson range = index(string, '('); 715105696Srwatson if (range == single) 716105696Srwatson single = NULL; 717105696Srwatson rangelow = rangehigh = NULL; 718105696Srwatson if (range != NULL) { 719105696Srwatson /* Nul terminate the end of the single string. */ 720105696Srwatson *range = '\0'; 721105696Srwatson range++; 722105696Srwatson rangelow = range; 723105696Srwatson rangehigh = index(rangelow, '-'); 724105696Srwatson if (rangehigh == NULL) 725105696Srwatson return (EINVAL); 726105696Srwatson rangehigh++; 727105696Srwatson if (*rangelow == '\0' || *rangehigh == '\0') 728105696Srwatson return (EINVAL); 729105696Srwatson rangeend = index(rangehigh, ')'); 730105696Srwatson if (rangeend == NULL) 731105696Srwatson return (EINVAL); 732105696Srwatson if (*(rangeend + 1) != '\0') 733105696Srwatson return (EINVAL); 734105696Srwatson /* Nul terminate the ends of the ranges. */ 735105696Srwatson *(rangehigh - 1) = '\0'; 736105696Srwatson *rangeend = '\0'; 737105696Srwatson } 738105696Srwatson KASSERT((rangelow != NULL && rangehigh != NULL) || 739105696Srwatson (rangelow == NULL && rangehigh == NULL), 740105696Srwatson ("mac_biba_internalize_label: range mismatch")); 741101099Srwatson 742105696Srwatson bzero(mac_biba, sizeof(*mac_biba)); 743105696Srwatson if (single != NULL) { 744105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_single, single); 745105696Srwatson if (error) 746105696Srwatson return (error); 747105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 748105696Srwatson } 749105696Srwatson 750105696Srwatson if (rangelow != NULL) { 751105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangelow, 752105696Srwatson rangelow); 753105696Srwatson if (error) 754105696Srwatson return (error); 755105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 756105696Srwatson rangehigh); 757105696Srwatson if (error) 758105696Srwatson return (error); 759105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 760105696Srwatson } 761105696Srwatson 762101099Srwatson error = mac_biba_valid(mac_biba); 763101099Srwatson if (error) 764101099Srwatson return (error); 765101099Srwatson 766105696Srwatson return (0); 767105696Srwatson} 768101099Srwatson 769105696Srwatsonstatic int 770105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name, 771105696Srwatson char *element_data, int *claimed) 772105696Srwatson{ 773105696Srwatson struct mac_biba *mac_biba, mac_biba_temp; 774105696Srwatson int error; 775105696Srwatson 776105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 777105696Srwatson return (0); 778105696Srwatson 779105696Srwatson (*claimed)++; 780105696Srwatson 781105696Srwatson error = mac_biba_parse(&mac_biba_temp, element_data); 782105696Srwatson if (error) 783105696Srwatson return (error); 784105696Srwatson 785105696Srwatson mac_biba = SLOT(label); 786105696Srwatson *mac_biba = mac_biba_temp; 787105696Srwatson 788101099Srwatson return (0); 789101099Srwatson} 790101099Srwatson 791105696Srwatsonstatic void 792105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest) 793105696Srwatson{ 794105696Srwatson 795105696Srwatson *SLOT(dest) = *SLOT(src); 796105696Srwatson} 797105696Srwatson 798101099Srwatson/* 799101099Srwatson * Labeling event operations: file system objects, and things that look 800101099Srwatson * a lot like file system objects. 801101099Srwatson */ 802101099Srwatsonstatic void 803107698Srwatsonmac_biba_create_devfs_device(struct mount *mp, dev_t dev, 804107698Srwatson struct devfs_dirent *devfs_dirent, struct label *label) 805101099Srwatson{ 806101099Srwatson struct mac_biba *mac_biba; 807101099Srwatson int biba_type; 808101099Srwatson 809101099Srwatson mac_biba = SLOT(label); 810101099Srwatson if (strcmp(dev->si_name, "null") == 0 || 811101099Srwatson strcmp(dev->si_name, "zero") == 0 || 812101099Srwatson strcmp(dev->si_name, "random") == 0 || 813101099Srwatson strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 814101099Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 815105606Srwatson else if (ptys_equal && 816105606Srwatson (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 817105606Srwatson strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 818105606Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 819101099Srwatson else 820101099Srwatson biba_type = MAC_BIBA_TYPE_HIGH; 821105643Srwatson mac_biba_set_single(mac_biba, biba_type, 0, NULL); 822101099Srwatson} 823101099Srwatson 824101099Srwatsonstatic void 825107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname, 826107698Srwatson int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 827101099Srwatson{ 828101099Srwatson struct mac_biba *mac_biba; 829101099Srwatson 830101099Srwatson mac_biba = SLOT(label); 831105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 832101099Srwatson} 833101099Srwatson 834101099Srwatsonstatic void 835107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp, 836107698Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 837107698Srwatson struct label *delabel) 838104535Srwatson{ 839104535Srwatson struct mac_biba *source, *dest; 840104535Srwatson 841104535Srwatson source = SLOT(&cred->cr_label); 842104535Srwatson dest = SLOT(delabel); 843104535Srwatson 844104535Srwatson mac_biba_copy_single(source, dest); 845104535Srwatson} 846104535Srwatson 847104535Srwatsonstatic void 848101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp, 849101099Srwatson struct label *mntlabel, struct label *fslabel) 850101099Srwatson{ 851101099Srwatson struct mac_biba *source, *dest; 852101099Srwatson 853101099Srwatson source = SLOT(&cred->cr_label); 854101099Srwatson dest = SLOT(mntlabel); 855101099Srwatson mac_biba_copy_single(source, dest); 856101099Srwatson dest = SLOT(fslabel); 857101099Srwatson mac_biba_copy_single(source, dest); 858101099Srwatson} 859101099Srwatson 860101099Srwatsonstatic void 861101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 862101099Srwatson struct label *mntlabel, struct label *fslabel) 863101099Srwatson{ 864101099Srwatson struct mac_biba *mac_biba; 865101099Srwatson 866101099Srwatson /* Always mount root as high integrity. */ 867101099Srwatson mac_biba = SLOT(fslabel); 868105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 869101099Srwatson mac_biba = SLOT(mntlabel); 870105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 871101099Srwatson} 872101099Srwatson 873101099Srwatsonstatic void 874101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 875101099Srwatson struct label *vnodelabel, struct label *label) 876101099Srwatson{ 877101099Srwatson struct mac_biba *source, *dest; 878101099Srwatson 879101099Srwatson source = SLOT(label); 880101099Srwatson dest = SLOT(vnodelabel); 881101099Srwatson 882105656Srwatson mac_biba_copy(source, dest); 883101099Srwatson} 884101099Srwatson 885101099Srwatsonstatic void 886107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp, 887107698Srwatson struct devfs_dirent *devfs_dirent, struct label *direntlabel, 888107698Srwatson struct vnode *vp, struct label *vnodelabel) 889101099Srwatson{ 890101099Srwatson struct mac_biba *source, *dest; 891101099Srwatson 892101099Srwatson source = SLOT(vnodelabel); 893101099Srwatson dest = SLOT(direntlabel); 894101099Srwatson 895105656Srwatson mac_biba_copy(source, dest); 896101099Srwatson} 897101099Srwatson 898101099Srwatsonstatic void 899105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 900105988Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 901105988Srwatson struct label *vlabel) 902101099Srwatson{ 903101099Srwatson struct mac_biba *source, *dest; 904101099Srwatson 905105988Srwatson source = SLOT(delabel); 906105988Srwatson dest = SLOT(vlabel); 907101099Srwatson 908101099Srwatson mac_biba_copy_single(source, dest); 909101099Srwatson} 910101099Srwatson 911101099Srwatsonstatic int 912105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 913105988Srwatson struct vnode *vp, struct label *vlabel) 914101099Srwatson{ 915105988Srwatson struct mac_biba temp, *source, *dest; 916106354Smux int buflen, error; 917101099Srwatson 918105988Srwatson source = SLOT(fslabel); 919105988Srwatson dest = SLOT(vlabel); 920101099Srwatson 921105988Srwatson buflen = sizeof(temp); 922105988Srwatson bzero(&temp, buflen); 923105988Srwatson 924105988Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 925105988Srwatson MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 926105988Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 927105988Srwatson /* Fall back to the fslabel. */ 928105988Srwatson mac_biba_copy_single(source, dest); 929105988Srwatson return (0); 930105988Srwatson } else if (error) 931101099Srwatson return (error); 932101099Srwatson 933105988Srwatson if (buflen != sizeof(temp)) { 934105988Srwatson printf("mac_biba_associate_vnode_extattr: bad size %d\n", 935105988Srwatson buflen); 936105988Srwatson return (EPERM); 937105988Srwatson } 938105988Srwatson if (mac_biba_valid(&temp) != 0) { 939105988Srwatson printf("mac_biba_associate_vnode_extattr: invalid\n"); 940105988Srwatson return (EPERM); 941105988Srwatson } 942105988Srwatson if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 943105988Srwatson printf("mac_biba_associate_vnode_extattr: not single\n"); 944105988Srwatson return (EPERM); 945105988Srwatson } 946101099Srwatson 947105988Srwatson mac_biba_copy_single(&temp, dest); 948101099Srwatson return (0); 949101099Srwatson} 950101099Srwatson 951101099Srwatsonstatic void 952105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp, 953105988Srwatson struct label *fslabel, struct vnode *vp, struct label *vlabel) 954101099Srwatson{ 955101099Srwatson struct mac_biba *source, *dest; 956101099Srwatson 957101099Srwatson source = SLOT(fslabel); 958105988Srwatson dest = SLOT(vlabel); 959101099Srwatson 960101099Srwatson mac_biba_copy_single(source, dest); 961101099Srwatson} 962101099Srwatson 963105988Srwatsonstatic int 964105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 965105988Srwatson struct label *fslabel, struct vnode *dvp, struct label *dlabel, 966105988Srwatson struct vnode *vp, struct label *vlabel, struct componentname *cnp) 967105988Srwatson{ 968105988Srwatson struct mac_biba *source, *dest, temp; 969105988Srwatson size_t buflen; 970105988Srwatson int error; 971105988Srwatson 972105988Srwatson buflen = sizeof(temp); 973105988Srwatson bzero(&temp, buflen); 974105988Srwatson 975105988Srwatson source = SLOT(&cred->cr_label); 976105988Srwatson dest = SLOT(vlabel); 977105988Srwatson mac_biba_copy_single(source, &temp); 978105988Srwatson 979105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 980105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 981105988Srwatson if (error == 0) 982105988Srwatson mac_biba_copy_single(source, dest); 983105988Srwatson return (error); 984105988Srwatson} 985105988Srwatson 986105988Srwatsonstatic int 987105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 988105988Srwatson struct label *vlabel, struct label *intlabel) 989105988Srwatson{ 990105988Srwatson struct mac_biba *source, temp; 991105988Srwatson size_t buflen; 992105988Srwatson int error; 993105988Srwatson 994105988Srwatson buflen = sizeof(temp); 995105988Srwatson bzero(&temp, buflen); 996105988Srwatson 997105988Srwatson source = SLOT(intlabel); 998105988Srwatson if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 999105988Srwatson return (0); 1000105988Srwatson 1001105988Srwatson mac_biba_copy_single(source, &temp); 1002105988Srwatson 1003105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 1004105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 1005105988Srwatson return (error); 1006105988Srwatson} 1007105988Srwatson 1008101099Srwatson/* 1009101099Srwatson * Labeling event operations: IPC object. 1010101099Srwatson */ 1011101099Srwatsonstatic void 1012101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1013101099Srwatson struct mbuf *m, struct label *mbuflabel) 1014101099Srwatson{ 1015101099Srwatson struct mac_biba *source, *dest; 1016101099Srwatson 1017101099Srwatson source = SLOT(socketlabel); 1018101099Srwatson dest = SLOT(mbuflabel); 1019101099Srwatson 1020101099Srwatson mac_biba_copy_single(source, dest); 1021101099Srwatson} 1022101099Srwatson 1023101099Srwatsonstatic void 1024101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket, 1025101099Srwatson struct label *socketlabel) 1026101099Srwatson{ 1027101099Srwatson struct mac_biba *source, *dest; 1028101099Srwatson 1029101099Srwatson source = SLOT(&cred->cr_label); 1030101099Srwatson dest = SLOT(socketlabel); 1031101099Srwatson 1032101099Srwatson mac_biba_copy_single(source, dest); 1033101099Srwatson} 1034101099Srwatson 1035101099Srwatsonstatic void 1036101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1037101099Srwatson struct label *pipelabel) 1038101099Srwatson{ 1039101099Srwatson struct mac_biba *source, *dest; 1040101099Srwatson 1041101099Srwatson source = SLOT(&cred->cr_label); 1042101099Srwatson dest = SLOT(pipelabel); 1043101099Srwatson 1044101099Srwatson mac_biba_copy_single(source, dest); 1045101099Srwatson} 1046101099Srwatson 1047101099Srwatsonstatic void 1048101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket, 1049101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1050101099Srwatson struct label *newsocketlabel) 1051101099Srwatson{ 1052101099Srwatson struct mac_biba *source, *dest; 1053101099Srwatson 1054101099Srwatson source = SLOT(oldsocketlabel); 1055101099Srwatson dest = SLOT(newsocketlabel); 1056101099Srwatson 1057101099Srwatson mac_biba_copy_single(source, dest); 1058101099Srwatson} 1059101099Srwatson 1060101099Srwatsonstatic void 1061101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1062101099Srwatson struct label *socketlabel, struct label *newlabel) 1063101099Srwatson{ 1064101099Srwatson struct mac_biba *source, *dest; 1065101099Srwatson 1066101099Srwatson source = SLOT(newlabel); 1067101099Srwatson dest = SLOT(socketlabel); 1068101099Srwatson 1069105656Srwatson mac_biba_copy(source, dest); 1070101099Srwatson} 1071101099Srwatson 1072101099Srwatsonstatic void 1073101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1074101099Srwatson struct label *pipelabel, struct label *newlabel) 1075101099Srwatson{ 1076101099Srwatson struct mac_biba *source, *dest; 1077101099Srwatson 1078101099Srwatson source = SLOT(newlabel); 1079101099Srwatson dest = SLOT(pipelabel); 1080101099Srwatson 1081105656Srwatson mac_biba_copy(source, dest); 1082101099Srwatson} 1083101099Srwatson 1084101099Srwatsonstatic void 1085101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1086101099Srwatson struct socket *socket, struct label *socketpeerlabel) 1087101099Srwatson{ 1088101099Srwatson struct mac_biba *source, *dest; 1089101099Srwatson 1090101099Srwatson source = SLOT(mbuflabel); 1091101099Srwatson dest = SLOT(socketpeerlabel); 1092101099Srwatson 1093101099Srwatson mac_biba_copy_single(source, dest); 1094101099Srwatson} 1095101099Srwatson 1096101099Srwatson/* 1097101099Srwatson * Labeling event operations: network objects. 1098101099Srwatson */ 1099101099Srwatsonstatic void 1100101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1101101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1102101099Srwatson struct label *newsocketpeerlabel) 1103101099Srwatson{ 1104101099Srwatson struct mac_biba *source, *dest; 1105101099Srwatson 1106101099Srwatson source = SLOT(oldsocketlabel); 1107101099Srwatson dest = SLOT(newsocketpeerlabel); 1108101099Srwatson 1109101099Srwatson mac_biba_copy_single(source, dest); 1110101099Srwatson} 1111101099Srwatson 1112101099Srwatsonstatic void 1113101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1114101099Srwatson struct label *bpflabel) 1115101099Srwatson{ 1116101099Srwatson struct mac_biba *source, *dest; 1117101099Srwatson 1118101099Srwatson source = SLOT(&cred->cr_label); 1119101099Srwatson dest = SLOT(bpflabel); 1120101099Srwatson 1121101099Srwatson mac_biba_copy_single(source, dest); 1122101099Srwatson} 1123101099Srwatson 1124101099Srwatsonstatic void 1125101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1126101099Srwatson{ 1127101099Srwatson char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1128101099Srwatson char tiflist[sizeof(trusted_interfaces)]; 1129101099Srwatson struct mac_biba *dest; 1130101099Srwatson int len, grade; 1131101099Srwatson 1132101099Srwatson dest = SLOT(ifnetlabel); 1133101099Srwatson 1134101099Srwatson if (ifnet->if_type == IFT_LOOP) { 1135101099Srwatson grade = MAC_BIBA_TYPE_EQUAL; 1136101099Srwatson goto set; 1137101099Srwatson } 1138101099Srwatson 1139101099Srwatson if (trust_all_interfaces) { 1140101099Srwatson grade = MAC_BIBA_TYPE_HIGH; 1141101099Srwatson goto set; 1142101099Srwatson } 1143101099Srwatson 1144101099Srwatson grade = MAC_BIBA_TYPE_LOW; 1145101099Srwatson 1146101099Srwatson if (trusted_interfaces[0] == '\0' || 1147101099Srwatson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1148101099Srwatson goto set; 1149101099Srwatson 1150106089Srwatson bzero(tiflist, sizeof(tiflist)); 1151101099Srwatson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1152101099Srwatson if(*p != ' ' && *p != '\t') 1153101099Srwatson *q = *p; 1154101099Srwatson 1155101099Srwatson snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1156101099Srwatson 1157101099Srwatson for (p = q = tiflist;; p++) { 1158101099Srwatson if (*p == ',' || *p == '\0') { 1159101099Srwatson len = p - q; 1160101099Srwatson if (len < IFNAMSIZ) { 1161101099Srwatson bzero(tifname, sizeof(tifname)); 1162101099Srwatson bcopy(q, tifname, len); 1163101099Srwatson if (strcmp(tifname, ifname) == 0) { 1164101099Srwatson grade = MAC_BIBA_TYPE_HIGH; 1165101099Srwatson break; 1166101099Srwatson } 1167106089Srwatson } else { 1168106089Srwatson *p = '\0'; 1169106089Srwatson printf("mac_biba warning: interface name " 1170106089Srwatson "\"%s\" is too long (must be < %d)\n", 1171106089Srwatson q, IFNAMSIZ); 1172101099Srwatson } 1173101099Srwatson if (*p == '\0') 1174101099Srwatson break; 1175101099Srwatson q = p + 1; 1176101099Srwatson } 1177101099Srwatson } 1178101099Srwatsonset: 1179105643Srwatson mac_biba_set_single(dest, grade, 0, NULL); 1180105643Srwatson mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL); 1181101099Srwatson} 1182101099Srwatson 1183101099Srwatsonstatic void 1184101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1185101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1186101099Srwatson{ 1187101099Srwatson struct mac_biba *source, *dest; 1188101099Srwatson 1189101099Srwatson source = SLOT(fragmentlabel); 1190101099Srwatson dest = SLOT(ipqlabel); 1191101099Srwatson 1192101099Srwatson mac_biba_copy_single(source, dest); 1193101099Srwatson} 1194101099Srwatson 1195101099Srwatsonstatic void 1196101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1197101099Srwatson struct mbuf *datagram, struct label *datagramlabel) 1198101099Srwatson{ 1199101099Srwatson struct mac_biba *source, *dest; 1200101099Srwatson 1201101099Srwatson source = SLOT(ipqlabel); 1202101099Srwatson dest = SLOT(datagramlabel); 1203101099Srwatson 1204101099Srwatson /* Just use the head, since we require them all to match. */ 1205101099Srwatson mac_biba_copy_single(source, dest); 1206101099Srwatson} 1207101099Srwatson 1208101099Srwatsonstatic void 1209101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1210101099Srwatson struct mbuf *fragment, struct label *fragmentlabel) 1211101099Srwatson{ 1212101099Srwatson struct mac_biba *source, *dest; 1213101099Srwatson 1214101099Srwatson source = SLOT(datagramlabel); 1215101099Srwatson dest = SLOT(fragmentlabel); 1216101099Srwatson 1217101099Srwatson mac_biba_copy_single(source, dest); 1218101099Srwatson} 1219101099Srwatson 1220101099Srwatsonstatic void 1221101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1222101099Srwatson struct label *oldmbuflabel, struct mbuf *newmbuf, 1223101099Srwatson struct label *newmbuflabel) 1224101099Srwatson{ 1225101099Srwatson struct mac_biba *source, *dest; 1226101099Srwatson 1227101099Srwatson source = SLOT(oldmbuflabel); 1228101099Srwatson dest = SLOT(newmbuflabel); 1229101099Srwatson 1230105656Srwatson /* 1231105656Srwatson * Because the source mbuf may not yet have been "created", 1232105696Srwatson * just initialized, we do a conditional copy. Since we don't 1233105656Srwatson * allow mbufs to have ranges, do a KASSERT to make sure that 1234105656Srwatson * doesn't happen. 1235105656Srwatson */ 1236105656Srwatson KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1237105656Srwatson ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1238105656Srwatson mac_biba_copy(source, dest); 1239101099Srwatson} 1240101099Srwatson 1241101099Srwatsonstatic void 1242101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1243101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1244101099Srwatson{ 1245101099Srwatson struct mac_biba *dest; 1246101099Srwatson 1247101099Srwatson dest = SLOT(mbuflabel); 1248101099Srwatson 1249105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1250101099Srwatson} 1251101099Srwatson 1252101099Srwatsonstatic void 1253101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1254101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1255101099Srwatson{ 1256101099Srwatson struct mac_biba *source, *dest; 1257101099Srwatson 1258101099Srwatson source = SLOT(bpflabel); 1259101099Srwatson dest = SLOT(mbuflabel); 1260101099Srwatson 1261101099Srwatson mac_biba_copy_single(source, dest); 1262101099Srwatson} 1263101099Srwatson 1264101099Srwatsonstatic void 1265101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1266101099Srwatson struct mbuf *m, struct label *mbuflabel) 1267101099Srwatson{ 1268101099Srwatson struct mac_biba *source, *dest; 1269101099Srwatson 1270101099Srwatson source = SLOT(ifnetlabel); 1271101099Srwatson dest = SLOT(mbuflabel); 1272101099Srwatson 1273101099Srwatson mac_biba_copy_single(source, dest); 1274101099Srwatson} 1275101099Srwatson 1276101099Srwatsonstatic void 1277101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1278101099Srwatson struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1279101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1280101099Srwatson{ 1281101099Srwatson struct mac_biba *source, *dest; 1282101099Srwatson 1283101099Srwatson source = SLOT(oldmbuflabel); 1284101099Srwatson dest = SLOT(newmbuflabel); 1285101099Srwatson 1286101099Srwatson mac_biba_copy_single(source, dest); 1287101099Srwatson} 1288101099Srwatson 1289101099Srwatsonstatic void 1290101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1291101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1292101099Srwatson{ 1293101099Srwatson struct mac_biba *source, *dest; 1294101099Srwatson 1295101099Srwatson source = SLOT(oldmbuflabel); 1296101099Srwatson dest = SLOT(newmbuflabel); 1297101099Srwatson 1298101099Srwatson mac_biba_copy_single(source, dest); 1299101099Srwatson} 1300101099Srwatson 1301101099Srwatsonstatic int 1302101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1303101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1304101099Srwatson{ 1305101099Srwatson struct mac_biba *a, *b; 1306101099Srwatson 1307101099Srwatson a = SLOT(ipqlabel); 1308101099Srwatson b = SLOT(fragmentlabel); 1309101099Srwatson 1310101099Srwatson return (mac_biba_equal_single(a, b)); 1311101099Srwatson} 1312101099Srwatson 1313101099Srwatsonstatic void 1314101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1315101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1316101099Srwatson{ 1317101099Srwatson struct mac_biba *source, *dest; 1318101099Srwatson 1319101099Srwatson source = SLOT(newlabel); 1320101099Srwatson dest = SLOT(ifnetlabel); 1321101099Srwatson 1322105656Srwatson mac_biba_copy(source, dest); 1323101099Srwatson} 1324101099Srwatson 1325101099Srwatsonstatic void 1326101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1327101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1328101099Srwatson{ 1329101099Srwatson 1330101099Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1331101099Srwatson} 1332101099Srwatson 1333101099Srwatson/* 1334101099Srwatson * Labeling event operations: processes. 1335101099Srwatson */ 1336101099Srwatsonstatic void 1337101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1338101099Srwatson{ 1339101099Srwatson struct mac_biba *source, *dest; 1340101099Srwatson 1341101099Srwatson source = SLOT(&cred_parent->cr_label); 1342101099Srwatson dest = SLOT(&cred_child->cr_label); 1343101099Srwatson 1344101099Srwatson mac_biba_copy_single(source, dest); 1345101099Srwatson mac_biba_copy_range(source, dest); 1346101099Srwatson} 1347101099Srwatson 1348101099Srwatsonstatic void 1349101099Srwatsonmac_biba_create_proc0(struct ucred *cred) 1350101099Srwatson{ 1351101099Srwatson struct mac_biba *dest; 1352101099Srwatson 1353101099Srwatson dest = SLOT(&cred->cr_label); 1354101099Srwatson 1355105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1356105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1357105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1358101099Srwatson} 1359101099Srwatson 1360101099Srwatsonstatic void 1361101099Srwatsonmac_biba_create_proc1(struct ucred *cred) 1362101099Srwatson{ 1363101099Srwatson struct mac_biba *dest; 1364101099Srwatson 1365101099Srwatson dest = SLOT(&cred->cr_label); 1366101099Srwatson 1367105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1368105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1369105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1370101099Srwatson} 1371101099Srwatson 1372101099Srwatsonstatic void 1373101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1374101099Srwatson{ 1375101099Srwatson struct mac_biba *source, *dest; 1376101099Srwatson 1377101099Srwatson source = SLOT(newlabel); 1378101099Srwatson dest = SLOT(&cred->cr_label); 1379101099Srwatson 1380105656Srwatson mac_biba_copy(source, dest); 1381101099Srwatson} 1382101099Srwatson 1383101099Srwatson/* 1384101099Srwatson * Access control checks. 1385101099Srwatson */ 1386101099Srwatsonstatic int 1387101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1388101099Srwatson struct ifnet *ifnet, struct label *ifnetlabel) 1389101099Srwatson{ 1390101099Srwatson struct mac_biba *a, *b; 1391101099Srwatson 1392101099Srwatson if (!mac_biba_enabled) 1393101099Srwatson return (0); 1394101099Srwatson 1395101099Srwatson a = SLOT(bpflabel); 1396101099Srwatson b = SLOT(ifnetlabel); 1397101099Srwatson 1398101099Srwatson if (mac_biba_equal_single(a, b)) 1399101099Srwatson return (0); 1400101099Srwatson return (EACCES); 1401101099Srwatson} 1402101099Srwatson 1403101099Srwatsonstatic int 1404101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1405101099Srwatson{ 1406101099Srwatson struct mac_biba *subj, *new; 1407105634Srwatson int error; 1408101099Srwatson 1409101099Srwatson subj = SLOT(&cred->cr_label); 1410101099Srwatson new = SLOT(newlabel); 1411101099Srwatson 1412101099Srwatson /* 1413105634Srwatson * If there is a Biba label update for the credential, it may 1414105634Srwatson * be an update of the single, range, or both. 1415101099Srwatson */ 1416105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1417105634Srwatson if (error) 1418105634Srwatson return (error); 1419101099Srwatson 1420101099Srwatson /* 1421105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1422101099Srwatson */ 1423105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1424105634Srwatson /* 1425105634Srwatson * To change the Biba single label on a credential, the 1426105634Srwatson * new single label must be in the current range. 1427105634Srwatson */ 1428105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1429105634Srwatson !mac_biba_single_in_range(new, subj)) 1430105634Srwatson return (EPERM); 1431101099Srwatson 1432105634Srwatson /* 1433105634Srwatson * To change the Biba range on a credential, the new 1434105634Srwatson * range label must be in the current range. 1435105634Srwatson */ 1436105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1437105634Srwatson !mac_biba_range_in_range(new, subj)) 1438105634Srwatson return (EPERM); 1439101099Srwatson 1440105634Srwatson /* 1441105634Srwatson * To have EQUAL in any component of the new credential 1442105634Srwatson * Biba label, the subject must already have EQUAL in 1443105634Srwatson * their label. 1444105634Srwatson */ 1445105634Srwatson if (mac_biba_contains_equal(new)) { 1446106090Srwatson error = mac_biba_subject_privileged(subj); 1447105634Srwatson if (error) 1448105634Srwatson return (error); 1449105634Srwatson } 1450101099Srwatson 1451105634Srwatson /* 1452105634Srwatson * XXXMAC: Additional consistency tests regarding the 1453105634Srwatson * single and range of the new label might be performed 1454105634Srwatson * here. 1455105634Srwatson */ 1456105634Srwatson } 1457105634Srwatson 1458101099Srwatson return (0); 1459101099Srwatson} 1460101099Srwatson 1461101099Srwatsonstatic int 1462101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1463101099Srwatson{ 1464101099Srwatson struct mac_biba *subj, *obj; 1465101099Srwatson 1466101099Srwatson if (!mac_biba_enabled) 1467101099Srwatson return (0); 1468101099Srwatson 1469101099Srwatson subj = SLOT(&u1->cr_label); 1470101099Srwatson obj = SLOT(&u2->cr_label); 1471101099Srwatson 1472101099Srwatson /* XXX: range */ 1473101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1474101099Srwatson return (ESRCH); 1475101099Srwatson 1476101099Srwatson return (0); 1477101099Srwatson} 1478101099Srwatson 1479101099Srwatsonstatic int 1480101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1481101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1482101099Srwatson{ 1483101099Srwatson struct mac_biba *subj, *new; 1484105634Srwatson int error; 1485101099Srwatson 1486101099Srwatson subj = SLOT(&cred->cr_label); 1487101099Srwatson new = SLOT(newlabel); 1488101099Srwatson 1489105634Srwatson /* 1490105634Srwatson * If there is a Biba label update for the interface, it may 1491105634Srwatson * be an update of the single, range, or both. 1492105634Srwatson */ 1493105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1494105634Srwatson if (error) 1495105634Srwatson return (error); 1496101099Srwatson 1497105634Srwatson /* 1498106160Srwatson * Relabling network interfaces requires Biba privilege. 1499106160Srwatson */ 1500106160Srwatson error = mac_biba_subject_privileged(subj); 1501106160Srwatson if (error) 1502106160Srwatson return (error); 1503106160Srwatson 1504106160Srwatson /* 1505105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1506105634Srwatson */ 1507105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1508105634Srwatson /* 1509105634Srwatson * Rely on the traditional superuser status for the Biba 1510105634Srwatson * interface relabel requirements. XXXMAC: This will go 1511105634Srwatson * away. 1512105634Srwatson */ 1513105634Srwatson error = suser_cred(cred, 0); 1514105634Srwatson if (error) 1515105634Srwatson return (EPERM); 1516105634Srwatson 1517105634Srwatson /* 1518105634Srwatson * XXXMAC: Additional consistency tests regarding the single 1519105634Srwatson * and the range of the new label might be performed here. 1520105634Srwatson */ 1521105634Srwatson } 1522105634Srwatson 1523105634Srwatson return (0); 1524101099Srwatson} 1525101099Srwatson 1526103759Srwatsonstatic int 1527101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1528101099Srwatson struct mbuf *m, struct label *mbuflabel) 1529101099Srwatson{ 1530101099Srwatson struct mac_biba *p, *i; 1531103761Srwatson 1532101099Srwatson if (!mac_biba_enabled) 1533101099Srwatson return (0); 1534101099Srwatson 1535101099Srwatson p = SLOT(mbuflabel); 1536101099Srwatson i = SLOT(ifnetlabel); 1537103759Srwatson 1538101099Srwatson return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1539101099Srwatson} 1540101099Srwatson 1541101099Srwatsonstatic int 1542101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1543101099Srwatson struct label *mntlabel) 1544101099Srwatson{ 1545101099Srwatson struct mac_biba *subj, *obj; 1546101099Srwatson 1547101099Srwatson if (!mac_biba_enabled) 1548101099Srwatson return (0); 1549101099Srwatson 1550101099Srwatson subj = SLOT(&cred->cr_label); 1551101099Srwatson obj = SLOT(mntlabel); 1552101099Srwatson 1553101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1554101099Srwatson return (EACCES); 1555101099Srwatson 1556101099Srwatson return (0); 1557101099Srwatson} 1558101099Srwatson 1559101099Srwatsonstatic int 1560101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1561101099Srwatson struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1562101099Srwatson{ 1563103759Srwatson 1564101099Srwatson if(!mac_biba_enabled) 1565101099Srwatson return (0); 1566101099Srwatson 1567101099Srwatson /* XXX: This will be implemented soon... */ 1568101099Srwatson 1569101099Srwatson return (0); 1570101099Srwatson} 1571101099Srwatson 1572101099Srwatsonstatic int 1573102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1574102115Srwatson struct label *pipelabel) 1575101099Srwatson{ 1576101099Srwatson struct mac_biba *subj, *obj; 1577101099Srwatson 1578101099Srwatson if (!mac_biba_enabled) 1579101099Srwatson return (0); 1580101099Srwatson 1581101099Srwatson subj = SLOT(&cred->cr_label); 1582101099Srwatson obj = SLOT((pipelabel)); 1583101099Srwatson 1584102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1585102115Srwatson return (EACCES); 1586101099Srwatson 1587101099Srwatson return (0); 1588101099Srwatson} 1589101099Srwatson 1590101099Srwatsonstatic int 1591102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1592102115Srwatson struct label *pipelabel) 1593102115Srwatson{ 1594102115Srwatson struct mac_biba *subj, *obj; 1595102115Srwatson 1596102115Srwatson if (!mac_biba_enabled) 1597102115Srwatson return (0); 1598102115Srwatson 1599102115Srwatson subj = SLOT(&cred->cr_label); 1600102115Srwatson obj = SLOT((pipelabel)); 1601102115Srwatson 1602102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1603102115Srwatson return (EACCES); 1604102115Srwatson 1605102115Srwatson return (0); 1606102115Srwatson} 1607102115Srwatson 1608102115Srwatsonstatic int 1609101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1610101099Srwatson struct label *pipelabel, struct label *newlabel) 1611101099Srwatson{ 1612101099Srwatson struct mac_biba *subj, *obj, *new; 1613105634Srwatson int error; 1614101099Srwatson 1615101099Srwatson new = SLOT(newlabel); 1616101099Srwatson subj = SLOT(&cred->cr_label); 1617101099Srwatson obj = SLOT(pipelabel); 1618101099Srwatson 1619101099Srwatson /* 1620105634Srwatson * If there is a Biba label update for a pipe, it must be a 1621105634Srwatson * single update. 1622101099Srwatson */ 1623105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1624105634Srwatson if (error) 1625105634Srwatson return (error); 1626101099Srwatson 1627101099Srwatson /* 1628105634Srwatson * To perform a relabel of a pipe (Biba label or not), Biba must 1629105634Srwatson * authorize the relabel. 1630101099Srwatson */ 1631105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1632101099Srwatson return (EPERM); 1633101099Srwatson 1634101099Srwatson /* 1635105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1636101099Srwatson */ 1637105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1638105634Srwatson /* 1639105634Srwatson * To change the Biba label on a pipe, the new pipe label 1640105634Srwatson * must be in the subject range. 1641105634Srwatson */ 1642105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1643105634Srwatson return (EPERM); 1644101099Srwatson 1645105634Srwatson /* 1646105634Srwatson * To change the Biba label on a pipe to be EQUAL, the 1647105634Srwatson * subject must have appropriate privilege. 1648105634Srwatson */ 1649105634Srwatson if (mac_biba_contains_equal(new)) { 1650106090Srwatson error = mac_biba_subject_privileged(subj); 1651105634Srwatson if (error) 1652105634Srwatson return (error); 1653105634Srwatson } 1654105634Srwatson } 1655105634Srwatson 1656101099Srwatson return (0); 1657101099Srwatson} 1658101099Srwatson 1659101099Srwatsonstatic int 1660102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1661102115Srwatson struct label *pipelabel) 1662102115Srwatson{ 1663102115Srwatson struct mac_biba *subj, *obj; 1664102115Srwatson 1665102115Srwatson if (!mac_biba_enabled) 1666102115Srwatson return (0); 1667102115Srwatson 1668102115Srwatson subj = SLOT(&cred->cr_label); 1669102115Srwatson obj = SLOT((pipelabel)); 1670102115Srwatson 1671102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1672102115Srwatson return (EACCES); 1673102115Srwatson 1674102115Srwatson return (0); 1675102115Srwatson} 1676102115Srwatson 1677102115Srwatsonstatic int 1678102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1679102115Srwatson struct label *pipelabel) 1680102115Srwatson{ 1681102115Srwatson struct mac_biba *subj, *obj; 1682102115Srwatson 1683102115Srwatson if (!mac_biba_enabled) 1684102115Srwatson return (0); 1685102115Srwatson 1686102115Srwatson subj = SLOT(&cred->cr_label); 1687102115Srwatson obj = SLOT((pipelabel)); 1688102115Srwatson 1689102115Srwatson if (!mac_biba_dominate_single(subj, obj)) 1690102115Srwatson return (EACCES); 1691102115Srwatson 1692102115Srwatson return (0); 1693102115Srwatson} 1694102115Srwatson 1695102115Srwatsonstatic int 1696101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1697101099Srwatson{ 1698101099Srwatson struct mac_biba *subj, *obj; 1699101099Srwatson 1700101099Srwatson if (!mac_biba_enabled) 1701101099Srwatson return (0); 1702101099Srwatson 1703101099Srwatson subj = SLOT(&cred->cr_label); 1704101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1705101099Srwatson 1706101099Srwatson /* XXX: range checks */ 1707101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1708101099Srwatson return (ESRCH); 1709101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1710101099Srwatson return (EACCES); 1711101099Srwatson 1712101099Srwatson return (0); 1713101099Srwatson} 1714101099Srwatson 1715101099Srwatsonstatic int 1716101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1717101099Srwatson{ 1718101099Srwatson struct mac_biba *subj, *obj; 1719103759Srwatson 1720101099Srwatson if (!mac_biba_enabled) 1721101099Srwatson return (0); 1722101099Srwatson 1723101099Srwatson subj = SLOT(&cred->cr_label); 1724101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1725103759Srwatson 1726101099Srwatson /* XXX: range checks */ 1727101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1728101099Srwatson return (ESRCH); 1729101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1730101099Srwatson return (EACCES); 1731101099Srwatson 1732101099Srwatson return (0); 1733101099Srwatson} 1734101099Srwatson 1735101099Srwatsonstatic int 1736101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1737101099Srwatson{ 1738101099Srwatson struct mac_biba *subj, *obj; 1739103759Srwatson 1740101099Srwatson if (!mac_biba_enabled) 1741101099Srwatson return (0); 1742101099Srwatson 1743101099Srwatson subj = SLOT(&cred->cr_label); 1744101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1745103759Srwatson 1746101099Srwatson /* XXX: range checks */ 1747101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1748101099Srwatson return (ESRCH); 1749101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1750101099Srwatson return (EACCES); 1751101099Srwatson 1752101099Srwatson return (0); 1753101099Srwatson} 1754101099Srwatson 1755101099Srwatsonstatic int 1756101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1757101099Srwatson struct mbuf *m, struct label *mbuflabel) 1758101099Srwatson{ 1759101099Srwatson struct mac_biba *p, *s; 1760101099Srwatson 1761101099Srwatson if (!mac_biba_enabled) 1762101099Srwatson return (0); 1763101099Srwatson 1764101099Srwatson p = SLOT(mbuflabel); 1765101099Srwatson s = SLOT(socketlabel); 1766101099Srwatson 1767101099Srwatson return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1768101099Srwatson} 1769101099Srwatson 1770101099Srwatsonstatic int 1771106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1772101099Srwatson struct label *socketlabel, struct label *newlabel) 1773101099Srwatson{ 1774101099Srwatson struct mac_biba *subj, *obj, *new; 1775105634Srwatson int error; 1776101099Srwatson 1777101099Srwatson new = SLOT(newlabel); 1778101099Srwatson subj = SLOT(&cred->cr_label); 1779101099Srwatson obj = SLOT(socketlabel); 1780101099Srwatson 1781101099Srwatson /* 1782105634Srwatson * If there is a Biba label update for the socket, it may be 1783105634Srwatson * an update of single. 1784101099Srwatson */ 1785105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1786105634Srwatson if (error) 1787105634Srwatson return (error); 1788101099Srwatson 1789101099Srwatson /* 1790105634Srwatson * To relabel a socket, the old socket single must be in the subject 1791101099Srwatson * range. 1792101099Srwatson */ 1793105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1794101099Srwatson return (EPERM); 1795101099Srwatson 1796101099Srwatson /* 1797105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1798101099Srwatson */ 1799105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1800105634Srwatson /* 1801105634Srwatson * To relabel a socket, the new socket single must be in 1802105634Srwatson * the subject range. 1803105634Srwatson */ 1804105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1805105634Srwatson return (EPERM); 1806101099Srwatson 1807105634Srwatson /* 1808105634Srwatson * To change the Biba label on the socket to contain EQUAL, 1809105634Srwatson * the subject must have appropriate privilege. 1810105634Srwatson */ 1811105634Srwatson if (mac_biba_contains_equal(new)) { 1812106090Srwatson error = mac_biba_subject_privileged(subj); 1813105634Srwatson if (error) 1814105634Srwatson return (error); 1815105634Srwatson } 1816105634Srwatson } 1817105634Srwatson 1818101099Srwatson return (0); 1819101099Srwatson} 1820101099Srwatson 1821101099Srwatsonstatic int 1822101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1823101099Srwatson struct label *socketlabel) 1824101099Srwatson{ 1825101099Srwatson struct mac_biba *subj, *obj; 1826101099Srwatson 1827105722Srwatson if (!mac_biba_enabled) 1828105722Srwatson return (0); 1829105722Srwatson 1830101099Srwatson subj = SLOT(&cred->cr_label); 1831101099Srwatson obj = SLOT(socketlabel); 1832101099Srwatson 1833101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1834101099Srwatson return (ENOENT); 1835101099Srwatson 1836101099Srwatson return (0); 1837101099Srwatson} 1838101099Srwatson 1839101099Srwatsonstatic int 1840106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1841106418Srwatson struct label *label) 1842106418Srwatson{ 1843106418Srwatson struct mac_biba *subj, *obj; 1844106418Srwatson int error; 1845106418Srwatson 1846106418Srwatson if (!mac_biba_enabled) 1847106418Srwatson return (0); 1848106418Srwatson 1849106418Srwatson subj = SLOT(&cred->cr_label); 1850106418Srwatson 1851106418Srwatson error = mac_biba_subject_privileged(subj); 1852106418Srwatson if (error) 1853106418Srwatson return (error); 1854106418Srwatson 1855106418Srwatson if (label == NULL) 1856106418Srwatson return (0); 1857106418Srwatson 1858106418Srwatson obj = SLOT(label); 1859106418Srwatson if (!mac_biba_high_single(obj)) 1860106418Srwatson return (EACCES); 1861106418Srwatson 1862106418Srwatson return (0); 1863106418Srwatson} 1864106418Srwatson 1865106418Srwatsonstatic int 1866106418Srwatsonmac_biba_check_system_settime(struct ucred *cred) 1867106418Srwatson{ 1868106418Srwatson struct mac_biba *subj; 1869106418Srwatson int error; 1870106418Srwatson 1871106418Srwatson if (!mac_biba_enabled) 1872106418Srwatson return (0); 1873106418Srwatson 1874106418Srwatson subj = SLOT(&cred->cr_label); 1875106418Srwatson 1876106418Srwatson error = mac_biba_subject_privileged(subj); 1877106418Srwatson if (error) 1878106418Srwatson return (error); 1879106418Srwatson 1880106418Srwatson return (0); 1881106418Srwatson} 1882106418Srwatson 1883106418Srwatsonstatic int 1884106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1885106161Srwatson struct label *label) 1886106161Srwatson{ 1887106161Srwatson struct mac_biba *subj, *obj; 1888106416Srwatson int error; 1889106161Srwatson 1890106161Srwatson if (!mac_biba_enabled) 1891106161Srwatson return (0); 1892106161Srwatson 1893106161Srwatson subj = SLOT(&cred->cr_label); 1894106161Srwatson obj = SLOT(label); 1895106161Srwatson 1896106416Srwatson error = mac_biba_subject_privileged(subj); 1897106416Srwatson if (error) 1898106416Srwatson return (error); 1899106161Srwatson 1900106161Srwatson if (!mac_biba_high_single(obj)) 1901106161Srwatson return (EACCES); 1902106161Srwatson 1903106161Srwatson return (0); 1904106161Srwatson} 1905106161Srwatson 1906106161Srwatsonstatic int 1907106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1908106161Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1909106161Srwatson{ 1910106161Srwatson struct mac_biba *subj; 1911106161Srwatson int error; 1912106161Srwatson 1913106161Srwatson if (!mac_biba_enabled) 1914106161Srwatson return (0); 1915106161Srwatson 1916106161Srwatson subj = SLOT(&cred->cr_label); 1917106161Srwatson 1918106161Srwatson /* 1919106161Srwatson * In general, treat sysctl variables as biba/high, but also 1920106161Srwatson * require privilege to change them, since they are a 1921106161Srwatson * communications channel between grades. Exempt MIB 1922106161Srwatson * queries from this due to undocmented sysctl magic. 1923106161Srwatson * XXXMAC: This probably requires some more review. 1924106161Srwatson */ 1925106161Srwatson if (new != NULL) { 1926106161Srwatson if (namelen > 0 && name[0] == 0) 1927106161Srwatson return (0); 1928106161Srwatson 1929106161Srwatson if (!mac_biba_subject_dominate_high(subj)) 1930106161Srwatson return (EACCES); 1931106161Srwatson 1932106161Srwatson error = mac_biba_subject_privileged(subj); 1933106161Srwatson if (error) 1934106161Srwatson return (error); 1935106161Srwatson } 1936106161Srwatson 1937106161Srwatson return (0); 1938106161Srwatson} 1939106161Srwatson 1940106161Srwatsonstatic int 1941101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1942101099Srwatson struct label *dlabel) 1943101099Srwatson{ 1944101099Srwatson struct mac_biba *subj, *obj; 1945101099Srwatson 1946101099Srwatson if (!mac_biba_enabled) 1947101099Srwatson return (0); 1948101099Srwatson 1949101099Srwatson subj = SLOT(&cred->cr_label); 1950101099Srwatson obj = SLOT(dlabel); 1951101099Srwatson 1952101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1953101099Srwatson return (EACCES); 1954101099Srwatson 1955101099Srwatson return (0); 1956101099Srwatson} 1957101099Srwatson 1958101099Srwatsonstatic int 1959101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1960101099Srwatson struct label *dlabel) 1961101099Srwatson{ 1962101099Srwatson struct mac_biba *subj, *obj; 1963101099Srwatson 1964101099Srwatson if (!mac_biba_enabled) 1965101099Srwatson return (0); 1966101099Srwatson 1967101099Srwatson subj = SLOT(&cred->cr_label); 1968101099Srwatson obj = SLOT(dlabel); 1969101099Srwatson 1970101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1971101099Srwatson return (EACCES); 1972101099Srwatson 1973101099Srwatson return (0); 1974101099Srwatson} 1975101099Srwatson 1976101099Srwatsonstatic int 1977101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1978101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1979101099Srwatson{ 1980101099Srwatson struct mac_biba *subj, *obj; 1981101099Srwatson 1982101099Srwatson if (!mac_biba_enabled) 1983101099Srwatson return (0); 1984101099Srwatson 1985101099Srwatson subj = SLOT(&cred->cr_label); 1986101099Srwatson obj = SLOT(dlabel); 1987101099Srwatson 1988101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1989101099Srwatson return (EACCES); 1990101099Srwatson 1991101099Srwatson return (0); 1992101099Srwatson} 1993101099Srwatson 1994101099Srwatsonstatic int 1995101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1996101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 1997101099Srwatson struct componentname *cnp) 1998101099Srwatson{ 1999101099Srwatson struct mac_biba *subj, *obj; 2000101099Srwatson 2001101099Srwatson if (!mac_biba_enabled) 2002101099Srwatson return (0); 2003101099Srwatson 2004101099Srwatson subj = SLOT(&cred->cr_label); 2005101099Srwatson obj = SLOT(dlabel); 2006101099Srwatson 2007101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2008101099Srwatson return (EACCES); 2009101099Srwatson 2010101099Srwatson obj = SLOT(label); 2011101099Srwatson 2012101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2013101099Srwatson return (EACCES); 2014101099Srwatson 2015101099Srwatson return (0); 2016101099Srwatson} 2017101099Srwatson 2018101099Srwatsonstatic int 2019101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2020101099Srwatson struct label *label, acl_type_t type) 2021101099Srwatson{ 2022101099Srwatson struct mac_biba *subj, *obj; 2023101099Srwatson 2024101099Srwatson if (!mac_biba_enabled) 2025101099Srwatson return (0); 2026101099Srwatson 2027101099Srwatson subj = SLOT(&cred->cr_label); 2028101099Srwatson obj = SLOT(label); 2029101099Srwatson 2030101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2031101099Srwatson return (EACCES); 2032101099Srwatson 2033101099Srwatson return (0); 2034101099Srwatson} 2035101099Srwatson 2036101099Srwatsonstatic int 2037101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2038106648Srwatson struct label *label, struct image_params *imgp, 2039106648Srwatson struct label *execlabel) 2040101099Srwatson{ 2041106648Srwatson struct mac_biba *subj, *obj, *exec; 2042106648Srwatson int error; 2043101099Srwatson 2044106648Srwatson if (execlabel != NULL) { 2045106648Srwatson /* 2046106648Srwatson * We currently don't permit labels to be changed at 2047106648Srwatson * exec-time as part of Biba, so disallow non-NULL 2048106648Srwatson * Biba label elements in the execlabel. 2049106648Srwatson */ 2050106648Srwatson exec = SLOT(execlabel); 2051106648Srwatson error = biba_atmostflags(exec, 0); 2052106648Srwatson if (error) 2053106648Srwatson return (error); 2054106648Srwatson } 2055106648Srwatson 2056101099Srwatson if (!mac_biba_enabled) 2057101099Srwatson return (0); 2058101099Srwatson 2059101099Srwatson subj = SLOT(&cred->cr_label); 2060101099Srwatson obj = SLOT(label); 2061101099Srwatson 2062101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2063101099Srwatson return (EACCES); 2064101099Srwatson 2065101099Srwatson return (0); 2066101099Srwatson} 2067101099Srwatson 2068101099Srwatsonstatic int 2069101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2070101099Srwatson struct label *label, acl_type_t type) 2071101099Srwatson{ 2072101099Srwatson struct mac_biba *subj, *obj; 2073101099Srwatson 2074101099Srwatson if (!mac_biba_enabled) 2075101099Srwatson return (0); 2076101099Srwatson 2077101099Srwatson subj = SLOT(&cred->cr_label); 2078101099Srwatson obj = SLOT(label); 2079101099Srwatson 2080101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2081101099Srwatson return (EACCES); 2082101099Srwatson 2083101099Srwatson return (0); 2084101099Srwatson} 2085101099Srwatson 2086101099Srwatsonstatic int 2087101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2088101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 2089101099Srwatson{ 2090101099Srwatson struct mac_biba *subj, *obj; 2091101099Srwatson 2092101099Srwatson if (!mac_biba_enabled) 2093101099Srwatson return (0); 2094101099Srwatson 2095101099Srwatson subj = SLOT(&cred->cr_label); 2096101099Srwatson obj = SLOT(label); 2097101099Srwatson 2098101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2099101099Srwatson return (EACCES); 2100101099Srwatson 2101101099Srwatson return (0); 2102101099Srwatson} 2103101099Srwatson 2104101099Srwatsonstatic int 2105104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2106104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2107104530Srwatson struct componentname *cnp) 2108104530Srwatson{ 2109104530Srwatson struct mac_biba *subj, *obj; 2110104530Srwatson 2111104530Srwatson if (!mac_biba_enabled) 2112104530Srwatson return (0); 2113104530Srwatson 2114104530Srwatson subj = SLOT(&cred->cr_label); 2115104530Srwatson obj = SLOT(dlabel); 2116104530Srwatson 2117104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2118104530Srwatson return (EACCES); 2119104530Srwatson 2120104530Srwatson obj = SLOT(label); 2121104530Srwatson 2122104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2123104530Srwatson return (EACCES); 2124104530Srwatson 2125104530Srwatson return (0); 2126104530Srwatson} 2127104530Srwatson 2128104530Srwatsonstatic int 2129103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2130101099Srwatson struct label *dlabel, struct componentname *cnp) 2131101099Srwatson{ 2132101099Srwatson struct mac_biba *subj, *obj; 2133103759Srwatson 2134101099Srwatson if (!mac_biba_enabled) 2135101099Srwatson return (0); 2136103759Srwatson 2137101099Srwatson subj = SLOT(&cred->cr_label); 2138101099Srwatson obj = SLOT(dlabel); 2139103759Srwatson 2140101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2141101099Srwatson return (EACCES); 2142101099Srwatson 2143103759Srwatson return (0); 2144101099Srwatson} 2145101099Srwatson 2146101099Srwatsonstatic int 2147104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2148104546Srwatson struct label *label, int prot) 2149104546Srwatson{ 2150104546Srwatson struct mac_biba *subj, *obj; 2151104546Srwatson 2152104546Srwatson /* 2153104546Srwatson * Rely on the use of open()-time protections to handle 2154104546Srwatson * non-revocation cases. 2155104546Srwatson */ 2156105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2157104546Srwatson return (0); 2158104546Srwatson 2159104546Srwatson subj = SLOT(&cred->cr_label); 2160104546Srwatson obj = SLOT(label); 2161104546Srwatson 2162104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2163104546Srwatson if (!mac_biba_dominate_single(obj, subj)) 2164104546Srwatson return (EACCES); 2165104546Srwatson } 2166104546Srwatson if (prot & VM_PROT_WRITE) { 2167104546Srwatson if (!mac_biba_dominate_single(subj, obj)) 2168104546Srwatson return (EACCES); 2169104546Srwatson } 2170104546Srwatson 2171104569Srwatson return (0); 2172104546Srwatson} 2173104546Srwatson 2174104546Srwatsonstatic int 2175101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2176106212Srwatson struct label *vnodelabel, int acc_mode) 2177101099Srwatson{ 2178101099Srwatson struct mac_biba *subj, *obj; 2179101099Srwatson 2180101099Srwatson if (!mac_biba_enabled) 2181101099Srwatson return (0); 2182101099Srwatson 2183101099Srwatson subj = SLOT(&cred->cr_label); 2184101099Srwatson obj = SLOT(vnodelabel); 2185101099Srwatson 2186101099Srwatson /* XXX privilege override for admin? */ 2187101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2188101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2189101099Srwatson return (EACCES); 2190101099Srwatson } 2191101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2192101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2193101099Srwatson return (EACCES); 2194101099Srwatson } 2195101099Srwatson 2196101099Srwatson return (0); 2197101099Srwatson} 2198101099Srwatson 2199101099Srwatsonstatic int 2200102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2201102129Srwatson struct vnode *vp, struct label *label) 2202102112Srwatson{ 2203102112Srwatson struct mac_biba *subj, *obj; 2204102112Srwatson 2205105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2206102112Srwatson return (0); 2207102112Srwatson 2208102129Srwatson subj = SLOT(&active_cred->cr_label); 2209102112Srwatson obj = SLOT(label); 2210102112Srwatson 2211102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2212102112Srwatson return (EACCES); 2213102112Srwatson 2214102112Srwatson return (0); 2215102112Srwatson} 2216102112Srwatson 2217102112Srwatsonstatic int 2218102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2219102129Srwatson struct vnode *vp, struct label *label) 2220102112Srwatson{ 2221102112Srwatson struct mac_biba *subj, *obj; 2222102112Srwatson 2223105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2224102112Srwatson return (0); 2225102112Srwatson 2226102129Srwatson subj = SLOT(&active_cred->cr_label); 2227102112Srwatson obj = SLOT(label); 2228102112Srwatson 2229102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2230102112Srwatson return (EACCES); 2231102112Srwatson 2232102112Srwatson return (0); 2233102112Srwatson} 2234102112Srwatson 2235102112Srwatsonstatic int 2236101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2237101099Srwatson struct label *dlabel) 2238101099Srwatson{ 2239101099Srwatson struct mac_biba *subj, *obj; 2240101099Srwatson 2241101099Srwatson if (!mac_biba_enabled) 2242101099Srwatson return (0); 2243101099Srwatson 2244101099Srwatson subj = SLOT(&cred->cr_label); 2245101099Srwatson obj = SLOT(dlabel); 2246101099Srwatson 2247101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2248101099Srwatson return (EACCES); 2249101099Srwatson 2250101099Srwatson return (0); 2251101099Srwatson} 2252101099Srwatson 2253101099Srwatsonstatic int 2254101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2255101099Srwatson struct label *label) 2256101099Srwatson{ 2257101099Srwatson struct mac_biba *subj, *obj; 2258101099Srwatson 2259101099Srwatson if (!mac_biba_enabled) 2260101099Srwatson return (0); 2261101099Srwatson 2262101099Srwatson subj = SLOT(&cred->cr_label); 2263101099Srwatson obj = SLOT(label); 2264101099Srwatson 2265101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2266101099Srwatson return (EACCES); 2267101099Srwatson 2268101099Srwatson return (0); 2269101099Srwatson} 2270101099Srwatson 2271101099Srwatsonstatic int 2272101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2273101099Srwatson struct label *vnodelabel, struct label *newlabel) 2274101099Srwatson{ 2275101099Srwatson struct mac_biba *old, *new, *subj; 2276105634Srwatson int error; 2277101099Srwatson 2278101099Srwatson old = SLOT(vnodelabel); 2279101099Srwatson new = SLOT(newlabel); 2280101099Srwatson subj = SLOT(&cred->cr_label); 2281101099Srwatson 2282101099Srwatson /* 2283105634Srwatson * If there is a Biba label update for the vnode, it must be a 2284105634Srwatson * single label. 2285101099Srwatson */ 2286105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2287105634Srwatson if (error) 2288105634Srwatson return (error); 2289101099Srwatson 2290101099Srwatson /* 2291105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2292105634Srwatson * authorize the relabel. 2293101099Srwatson */ 2294105634Srwatson if (!mac_biba_single_in_range(old, subj)) 2295101099Srwatson return (EPERM); 2296101099Srwatson 2297101099Srwatson /* 2298105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2299101099Srwatson */ 2300105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2301105634Srwatson /* 2302105634Srwatson * To change the Biba label on a vnode, the new vnode label 2303105634Srwatson * must be in the subject range. 2304105634Srwatson */ 2305105634Srwatson if (!mac_biba_single_in_range(new, subj)) 2306105634Srwatson return (EPERM); 2307101099Srwatson 2308105634Srwatson /* 2309105634Srwatson * To change the Biba label on the vnode to be EQUAL, 2310105634Srwatson * the subject must have appropriate privilege. 2311105634Srwatson */ 2312105634Srwatson if (mac_biba_contains_equal(new)) { 2313106090Srwatson error = mac_biba_subject_privileged(subj); 2314105634Srwatson if (error) 2315105634Srwatson return (error); 2316105634Srwatson } 2317105634Srwatson } 2318105634Srwatson 2319105634Srwatson return (0); 2320101099Srwatson} 2321101099Srwatson 2322101099Srwatsonstatic int 2323101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2324101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2325101099Srwatson struct componentname *cnp) 2326101099Srwatson{ 2327101099Srwatson struct mac_biba *subj, *obj; 2328101099Srwatson 2329101099Srwatson if (!mac_biba_enabled) 2330101099Srwatson return (0); 2331101099Srwatson 2332101099Srwatson subj = SLOT(&cred->cr_label); 2333101099Srwatson obj = SLOT(dlabel); 2334101099Srwatson 2335101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2336101099Srwatson return (EACCES); 2337101099Srwatson 2338101099Srwatson obj = SLOT(label); 2339101099Srwatson 2340101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2341101099Srwatson return (EACCES); 2342101099Srwatson 2343101099Srwatson return (0); 2344101099Srwatson} 2345101099Srwatson 2346101099Srwatsonstatic int 2347101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2348101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2349101099Srwatson struct componentname *cnp) 2350101099Srwatson{ 2351101099Srwatson struct mac_biba *subj, *obj; 2352101099Srwatson 2353101099Srwatson if (!mac_biba_enabled) 2354101099Srwatson return (0); 2355101099Srwatson 2356101099Srwatson subj = SLOT(&cred->cr_label); 2357101099Srwatson obj = SLOT(dlabel); 2358101099Srwatson 2359101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2360101099Srwatson return (EACCES); 2361101099Srwatson 2362101099Srwatson if (vp != NULL) { 2363101099Srwatson obj = SLOT(label); 2364101099Srwatson 2365101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2366101099Srwatson return (EACCES); 2367101099Srwatson } 2368101099Srwatson 2369101099Srwatson return (0); 2370101099Srwatson} 2371101099Srwatson 2372101099Srwatsonstatic int 2373101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2374101099Srwatson struct label *label) 2375101099Srwatson{ 2376101099Srwatson struct mac_biba *subj, *obj; 2377101099Srwatson 2378101099Srwatson if (!mac_biba_enabled) 2379101099Srwatson return (0); 2380101099Srwatson 2381101099Srwatson subj = SLOT(&cred->cr_label); 2382101099Srwatson obj = SLOT(label); 2383101099Srwatson 2384101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2385101099Srwatson return (EACCES); 2386101099Srwatson 2387101099Srwatson return (0); 2388101099Srwatson} 2389101099Srwatson 2390101099Srwatsonstatic int 2391101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2392101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 2393101099Srwatson{ 2394101099Srwatson struct mac_biba *subj, *obj; 2395101099Srwatson 2396101099Srwatson if (!mac_biba_enabled) 2397101099Srwatson return (0); 2398101099Srwatson 2399101099Srwatson subj = SLOT(&cred->cr_label); 2400101099Srwatson obj = SLOT(label); 2401101099Srwatson 2402101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2403101099Srwatson return (EACCES); 2404101099Srwatson 2405101099Srwatson return (0); 2406101099Srwatson} 2407101099Srwatson 2408101099Srwatsonstatic int 2409101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2410101099Srwatson struct label *vnodelabel, int attrnamespace, const char *name, 2411101099Srwatson struct uio *uio) 2412101099Srwatson{ 2413101099Srwatson struct mac_biba *subj, *obj; 2414101099Srwatson 2415101099Srwatson if (!mac_biba_enabled) 2416101099Srwatson return (0); 2417101099Srwatson 2418101099Srwatson subj = SLOT(&cred->cr_label); 2419101099Srwatson obj = SLOT(vnodelabel); 2420101099Srwatson 2421101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2422101099Srwatson return (EACCES); 2423101099Srwatson 2424101099Srwatson /* XXX: protect the MAC EA in a special way? */ 2425101099Srwatson 2426101099Srwatson return (0); 2427101099Srwatson} 2428101099Srwatson 2429101099Srwatsonstatic int 2430101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2431101099Srwatson struct label *vnodelabel, u_long flags) 2432101099Srwatson{ 2433101099Srwatson struct mac_biba *subj, *obj; 2434101099Srwatson 2435101099Srwatson if (!mac_biba_enabled) 2436101099Srwatson return (0); 2437101099Srwatson 2438101099Srwatson subj = SLOT(&cred->cr_label); 2439101099Srwatson obj = SLOT(vnodelabel); 2440101099Srwatson 2441101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2442101099Srwatson return (EACCES); 2443101099Srwatson 2444101099Srwatson return (0); 2445101099Srwatson} 2446101099Srwatson 2447101099Srwatsonstatic int 2448101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2449101099Srwatson struct label *vnodelabel, mode_t mode) 2450101099Srwatson{ 2451101099Srwatson struct mac_biba *subj, *obj; 2452101099Srwatson 2453101099Srwatson if (!mac_biba_enabled) 2454101099Srwatson return (0); 2455101099Srwatson 2456101099Srwatson subj = SLOT(&cred->cr_label); 2457101099Srwatson obj = SLOT(vnodelabel); 2458101099Srwatson 2459101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2460101099Srwatson return (EACCES); 2461101099Srwatson 2462101099Srwatson return (0); 2463101099Srwatson} 2464101099Srwatson 2465101099Srwatsonstatic int 2466101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2467101099Srwatson struct label *vnodelabel, uid_t uid, gid_t gid) 2468101099Srwatson{ 2469101099Srwatson struct mac_biba *subj, *obj; 2470101099Srwatson 2471101099Srwatson if (!mac_biba_enabled) 2472101099Srwatson return (0); 2473101099Srwatson 2474101099Srwatson subj = SLOT(&cred->cr_label); 2475101099Srwatson obj = SLOT(vnodelabel); 2476101099Srwatson 2477101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2478101099Srwatson return (EACCES); 2479101099Srwatson 2480101099Srwatson return (0); 2481101099Srwatson} 2482101099Srwatson 2483101099Srwatsonstatic int 2484101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2485101099Srwatson struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2486101099Srwatson{ 2487101099Srwatson struct mac_biba *subj, *obj; 2488101099Srwatson 2489101099Srwatson if (!mac_biba_enabled) 2490101099Srwatson return (0); 2491101099Srwatson 2492101099Srwatson subj = SLOT(&cred->cr_label); 2493101099Srwatson obj = SLOT(vnodelabel); 2494101099Srwatson 2495101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2496101099Srwatson return (EACCES); 2497101099Srwatson 2498101099Srwatson return (0); 2499101099Srwatson} 2500101099Srwatson 2501101099Srwatsonstatic int 2502102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2503102129Srwatson struct vnode *vp, struct label *vnodelabel) 2504101099Srwatson{ 2505101099Srwatson struct mac_biba *subj, *obj; 2506101099Srwatson 2507101099Srwatson if (!mac_biba_enabled) 2508101099Srwatson return (0); 2509101099Srwatson 2510102129Srwatson subj = SLOT(&active_cred->cr_label); 2511101099Srwatson obj = SLOT(vnodelabel); 2512101099Srwatson 2513101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2514101099Srwatson return (EACCES); 2515101099Srwatson 2516101099Srwatson return (0); 2517101099Srwatson} 2518101099Srwatson 2519102112Srwatsonstatic int 2520102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred, 2521102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 2522102112Srwatson{ 2523102112Srwatson struct mac_biba *subj, *obj; 2524102112Srwatson 2525105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2526102112Srwatson return (0); 2527102112Srwatson 2528102129Srwatson subj = SLOT(&active_cred->cr_label); 2529102112Srwatson obj = SLOT(label); 2530102112Srwatson 2531102112Srwatson if (!mac_biba_dominate_single(subj, obj)) 2532102112Srwatson return (EACCES); 2533102112Srwatson 2534102112Srwatson return (0); 2535102112Srwatson} 2536102112Srwatson 2537106217Srwatsonstatic struct mac_policy_ops mac_biba_ops = 2538101099Srwatson{ 2539106217Srwatson .mpo_destroy = mac_biba_destroy, 2540106217Srwatson .mpo_init = mac_biba_init, 2541106217Srwatson .mpo_init_bpfdesc_label = mac_biba_init_label, 2542106217Srwatson .mpo_init_cred_label = mac_biba_init_label, 2543106217Srwatson .mpo_init_devfsdirent_label = mac_biba_init_label, 2544106217Srwatson .mpo_init_ifnet_label = mac_biba_init_label, 2545106217Srwatson .mpo_init_ipq_label = mac_biba_init_label, 2546106217Srwatson .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2547106217Srwatson .mpo_init_mount_label = mac_biba_init_label, 2548106217Srwatson .mpo_init_mount_fs_label = mac_biba_init_label, 2549106217Srwatson .mpo_init_pipe_label = mac_biba_init_label, 2550106217Srwatson .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2551106217Srwatson .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2552106217Srwatson .mpo_init_vnode_label = mac_biba_init_label, 2553106217Srwatson .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2554106217Srwatson .mpo_destroy_cred_label = mac_biba_destroy_label, 2555106217Srwatson .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2556106217Srwatson .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2557106217Srwatson .mpo_destroy_ipq_label = mac_biba_destroy_label, 2558106217Srwatson .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2559106217Srwatson .mpo_destroy_mount_label = mac_biba_destroy_label, 2560106217Srwatson .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2561106217Srwatson .mpo_destroy_pipe_label = mac_biba_destroy_label, 2562106217Srwatson .mpo_destroy_socket_label = mac_biba_destroy_label, 2563106217Srwatson .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2564106217Srwatson .mpo_destroy_vnode_label = mac_biba_destroy_label, 2565106217Srwatson .mpo_copy_pipe_label = mac_biba_copy_label, 2566106217Srwatson .mpo_copy_vnode_label = mac_biba_copy_label, 2567106217Srwatson .mpo_externalize_cred_label = mac_biba_externalize_label, 2568106217Srwatson .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2569106217Srwatson .mpo_externalize_pipe_label = mac_biba_externalize_label, 2570106217Srwatson .mpo_externalize_socket_label = mac_biba_externalize_label, 2571106217Srwatson .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2572106217Srwatson .mpo_externalize_vnode_label = mac_biba_externalize_label, 2573106217Srwatson .mpo_internalize_cred_label = mac_biba_internalize_label, 2574106217Srwatson .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2575106217Srwatson .mpo_internalize_pipe_label = mac_biba_internalize_label, 2576106217Srwatson .mpo_internalize_socket_label = mac_biba_internalize_label, 2577106217Srwatson .mpo_internalize_vnode_label = mac_biba_internalize_label, 2578106217Srwatson .mpo_create_devfs_device = mac_biba_create_devfs_device, 2579106217Srwatson .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2580106217Srwatson .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2581106217Srwatson .mpo_create_mount = mac_biba_create_mount, 2582106217Srwatson .mpo_create_root_mount = mac_biba_create_root_mount, 2583106217Srwatson .mpo_relabel_vnode = mac_biba_relabel_vnode, 2584106217Srwatson .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2585106217Srwatson .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2586106217Srwatson .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2587106217Srwatson .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2588106217Srwatson .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2589106217Srwatson .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2590106217Srwatson .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2591106217Srwatson .mpo_create_pipe = mac_biba_create_pipe, 2592106217Srwatson .mpo_create_socket = mac_biba_create_socket, 2593106217Srwatson .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2594106217Srwatson .mpo_relabel_pipe = mac_biba_relabel_pipe, 2595106217Srwatson .mpo_relabel_socket = mac_biba_relabel_socket, 2596106217Srwatson .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2597106217Srwatson .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2598106217Srwatson .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2599106217Srwatson .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2600106217Srwatson .mpo_create_fragment = mac_biba_create_fragment, 2601106217Srwatson .mpo_create_ifnet = mac_biba_create_ifnet, 2602106217Srwatson .mpo_create_ipq = mac_biba_create_ipq, 2603106217Srwatson .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2604106217Srwatson .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2605106217Srwatson .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2606106217Srwatson .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2607106217Srwatson .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2608106217Srwatson .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2609106217Srwatson .mpo_fragment_match = mac_biba_fragment_match, 2610106217Srwatson .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2611106217Srwatson .mpo_update_ipq = mac_biba_update_ipq, 2612106217Srwatson .mpo_create_cred = mac_biba_create_cred, 2613106217Srwatson .mpo_create_proc0 = mac_biba_create_proc0, 2614106217Srwatson .mpo_create_proc1 = mac_biba_create_proc1, 2615106217Srwatson .mpo_relabel_cred = mac_biba_relabel_cred, 2616106217Srwatson .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2617106217Srwatson .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2618106217Srwatson .mpo_check_cred_visible = mac_biba_check_cred_visible, 2619106217Srwatson .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2620106217Srwatson .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2621106217Srwatson .mpo_check_mount_stat = mac_biba_check_mount_stat, 2622106217Srwatson .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2623106217Srwatson .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2624106217Srwatson .mpo_check_pipe_read = mac_biba_check_pipe_read, 2625106217Srwatson .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2626106217Srwatson .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2627106217Srwatson .mpo_check_pipe_write = mac_biba_check_pipe_write, 2628106217Srwatson .mpo_check_proc_debug = mac_biba_check_proc_debug, 2629106217Srwatson .mpo_check_proc_sched = mac_biba_check_proc_sched, 2630106217Srwatson .mpo_check_proc_signal = mac_biba_check_proc_signal, 2631106217Srwatson .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2632106217Srwatson .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2633106217Srwatson .mpo_check_socket_visible = mac_biba_check_socket_visible, 2634106418Srwatson .mpo_check_system_acct = mac_biba_check_system_acct, 2635106418Srwatson .mpo_check_system_settime = mac_biba_check_system_settime, 2636106217Srwatson .mpo_check_system_swapon = mac_biba_check_system_swapon, 2637106217Srwatson .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2638106217Srwatson .mpo_check_vnode_access = mac_biba_check_vnode_open, 2639106217Srwatson .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2640106217Srwatson .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2641106217Srwatson .mpo_check_vnode_create = mac_biba_check_vnode_create, 2642106217Srwatson .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2643106217Srwatson .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2644106217Srwatson .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2645106217Srwatson .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2646106217Srwatson .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2647106217Srwatson .mpo_check_vnode_link = mac_biba_check_vnode_link, 2648106217Srwatson .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2649106217Srwatson .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2650106217Srwatson .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2651106217Srwatson .mpo_check_vnode_open = mac_biba_check_vnode_open, 2652106217Srwatson .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2653106217Srwatson .mpo_check_vnode_read = mac_biba_check_vnode_read, 2654106217Srwatson .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2655106217Srwatson .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2656106217Srwatson .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2657106217Srwatson .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2658106217Srwatson .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2659106217Srwatson .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2660106217Srwatson .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2661106217Srwatson .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2662106217Srwatson .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2663106217Srwatson .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2664106217Srwatson .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2665106217Srwatson .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2666106217Srwatson .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2667106217Srwatson .mpo_check_vnode_write = mac_biba_check_vnode_write, 2668101099Srwatson}; 2669101099Srwatson 2670106217SrwatsonMAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2671101099Srwatson MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot); 2672