mac_biba.c revision 110351
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 110351 2003-02-04 21:28:46Z 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 88107731Srwatsonstatic int mac_biba_enabled = 1; 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 508109623Salfred SLOT(label) = biba_alloc(0); 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; 1130110350Srwatson int len, type; 1131101099Srwatson 1132101099Srwatson dest = SLOT(ifnetlabel); 1133101099Srwatson 1134101099Srwatson if (ifnet->if_type == IFT_LOOP) { 1135110350Srwatson type = MAC_BIBA_TYPE_EQUAL; 1136101099Srwatson goto set; 1137101099Srwatson } 1138101099Srwatson 1139101099Srwatson if (trust_all_interfaces) { 1140110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1141101099Srwatson goto set; 1142101099Srwatson } 1143101099Srwatson 1144110350Srwatson type = 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) { 1164110350Srwatson type = 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: 1179110350Srwatson mac_biba_set_single(dest, type, 0, NULL); 1180110350Srwatson mac_biba_set_range(dest, type, 0, NULL, type, 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 /* 1425110351Srwatson * If the change request modifies both the Biba label 1426110351Srwatson * single and range, check that the new single will be 1427110351Srwatson * in the new range. 1428110351Srwatson */ 1429110351Srwatson if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1430110351Srwatson MAC_BIBA_FLAGS_BOTH && 1431110351Srwatson !mac_biba_single_in_range(new, new)) 1432110351Srwatson return (EINVAL); 1433110351Srwatson 1434110351Srwatson /* 1435105634Srwatson * To change the Biba single label on a credential, the 1436105634Srwatson * new single label must be in the current range. 1437105634Srwatson */ 1438105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1439105634Srwatson !mac_biba_single_in_range(new, subj)) 1440105634Srwatson return (EPERM); 1441101099Srwatson 1442105634Srwatson /* 1443105634Srwatson * To change the Biba range on a credential, the new 1444105634Srwatson * range label must be in the current range. 1445105634Srwatson */ 1446105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1447105634Srwatson !mac_biba_range_in_range(new, subj)) 1448105634Srwatson return (EPERM); 1449101099Srwatson 1450105634Srwatson /* 1451105634Srwatson * To have EQUAL in any component of the new credential 1452105634Srwatson * Biba label, the subject must already have EQUAL in 1453105634Srwatson * their label. 1454105634Srwatson */ 1455105634Srwatson if (mac_biba_contains_equal(new)) { 1456106090Srwatson error = mac_biba_subject_privileged(subj); 1457105634Srwatson if (error) 1458105634Srwatson return (error); 1459105634Srwatson } 1460105634Srwatson } 1461105634Srwatson 1462101099Srwatson return (0); 1463101099Srwatson} 1464101099Srwatson 1465101099Srwatsonstatic int 1466101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1467101099Srwatson{ 1468101099Srwatson struct mac_biba *subj, *obj; 1469101099Srwatson 1470101099Srwatson if (!mac_biba_enabled) 1471101099Srwatson return (0); 1472101099Srwatson 1473101099Srwatson subj = SLOT(&u1->cr_label); 1474101099Srwatson obj = SLOT(&u2->cr_label); 1475101099Srwatson 1476101099Srwatson /* XXX: range */ 1477101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1478101099Srwatson return (ESRCH); 1479101099Srwatson 1480101099Srwatson return (0); 1481101099Srwatson} 1482101099Srwatson 1483101099Srwatsonstatic int 1484101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1485101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1486101099Srwatson{ 1487101099Srwatson struct mac_biba *subj, *new; 1488105634Srwatson int error; 1489101099Srwatson 1490101099Srwatson subj = SLOT(&cred->cr_label); 1491101099Srwatson new = SLOT(newlabel); 1492101099Srwatson 1493105634Srwatson /* 1494105634Srwatson * If there is a Biba label update for the interface, it may 1495105634Srwatson * be an update of the single, range, or both. 1496105634Srwatson */ 1497105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1498105634Srwatson if (error) 1499105634Srwatson return (error); 1500101099Srwatson 1501105634Srwatson /* 1502106160Srwatson * Relabling network interfaces requires Biba privilege. 1503106160Srwatson */ 1504106160Srwatson error = mac_biba_subject_privileged(subj); 1505106160Srwatson if (error) 1506106160Srwatson return (error); 1507106160Srwatson 1508106160Srwatson /* 1509105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1510105634Srwatson */ 1511105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1512105634Srwatson /* 1513105634Srwatson * Rely on the traditional superuser status for the Biba 1514105634Srwatson * interface relabel requirements. XXXMAC: This will go 1515105634Srwatson * away. 1516105634Srwatson */ 1517105634Srwatson error = suser_cred(cred, 0); 1518105634Srwatson if (error) 1519105634Srwatson return (EPERM); 1520105634Srwatson 1521105634Srwatson /* 1522105634Srwatson * XXXMAC: Additional consistency tests regarding the single 1523105634Srwatson * and the range of the new label might be performed here. 1524105634Srwatson */ 1525105634Srwatson } 1526105634Srwatson 1527105634Srwatson return (0); 1528101099Srwatson} 1529101099Srwatson 1530103759Srwatsonstatic int 1531101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1532101099Srwatson struct mbuf *m, struct label *mbuflabel) 1533101099Srwatson{ 1534101099Srwatson struct mac_biba *p, *i; 1535103761Srwatson 1536101099Srwatson if (!mac_biba_enabled) 1537101099Srwatson return (0); 1538101099Srwatson 1539101099Srwatson p = SLOT(mbuflabel); 1540101099Srwatson i = SLOT(ifnetlabel); 1541103759Srwatson 1542101099Srwatson return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1543101099Srwatson} 1544101099Srwatson 1545101099Srwatsonstatic int 1546101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1547101099Srwatson struct label *mntlabel) 1548101099Srwatson{ 1549101099Srwatson struct mac_biba *subj, *obj; 1550101099Srwatson 1551101099Srwatson if (!mac_biba_enabled) 1552101099Srwatson return (0); 1553101099Srwatson 1554101099Srwatson subj = SLOT(&cred->cr_label); 1555101099Srwatson obj = SLOT(mntlabel); 1556101099Srwatson 1557101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1558101099Srwatson return (EACCES); 1559101099Srwatson 1560101099Srwatson return (0); 1561101099Srwatson} 1562101099Srwatson 1563101099Srwatsonstatic int 1564101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1565101099Srwatson struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1566101099Srwatson{ 1567103759Srwatson 1568101099Srwatson if(!mac_biba_enabled) 1569101099Srwatson return (0); 1570101099Srwatson 1571101099Srwatson /* XXX: This will be implemented soon... */ 1572101099Srwatson 1573101099Srwatson return (0); 1574101099Srwatson} 1575101099Srwatson 1576101099Srwatsonstatic int 1577102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1578102115Srwatson struct label *pipelabel) 1579101099Srwatson{ 1580101099Srwatson struct mac_biba *subj, *obj; 1581101099Srwatson 1582101099Srwatson if (!mac_biba_enabled) 1583101099Srwatson return (0); 1584101099Srwatson 1585101099Srwatson subj = SLOT(&cred->cr_label); 1586101099Srwatson obj = SLOT((pipelabel)); 1587101099Srwatson 1588102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1589102115Srwatson return (EACCES); 1590101099Srwatson 1591101099Srwatson return (0); 1592101099Srwatson} 1593101099Srwatson 1594101099Srwatsonstatic int 1595102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1596102115Srwatson struct label *pipelabel) 1597102115Srwatson{ 1598102115Srwatson struct mac_biba *subj, *obj; 1599102115Srwatson 1600102115Srwatson if (!mac_biba_enabled) 1601102115Srwatson return (0); 1602102115Srwatson 1603102115Srwatson subj = SLOT(&cred->cr_label); 1604102115Srwatson obj = SLOT((pipelabel)); 1605102115Srwatson 1606102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1607102115Srwatson return (EACCES); 1608102115Srwatson 1609102115Srwatson return (0); 1610102115Srwatson} 1611102115Srwatson 1612102115Srwatsonstatic int 1613101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1614101099Srwatson struct label *pipelabel, struct label *newlabel) 1615101099Srwatson{ 1616101099Srwatson struct mac_biba *subj, *obj, *new; 1617105634Srwatson int error; 1618101099Srwatson 1619101099Srwatson new = SLOT(newlabel); 1620101099Srwatson subj = SLOT(&cred->cr_label); 1621101099Srwatson obj = SLOT(pipelabel); 1622101099Srwatson 1623101099Srwatson /* 1624105634Srwatson * If there is a Biba label update for a pipe, it must be a 1625105634Srwatson * single update. 1626101099Srwatson */ 1627105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1628105634Srwatson if (error) 1629105634Srwatson return (error); 1630101099Srwatson 1631101099Srwatson /* 1632105634Srwatson * To perform a relabel of a pipe (Biba label or not), Biba must 1633105634Srwatson * authorize the relabel. 1634101099Srwatson */ 1635105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1636101099Srwatson return (EPERM); 1637101099Srwatson 1638101099Srwatson /* 1639105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1640101099Srwatson */ 1641105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1642105634Srwatson /* 1643105634Srwatson * To change the Biba label on a pipe, the new pipe label 1644105634Srwatson * must be in the subject range. 1645105634Srwatson */ 1646105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1647105634Srwatson return (EPERM); 1648101099Srwatson 1649105634Srwatson /* 1650105634Srwatson * To change the Biba label on a pipe to be EQUAL, the 1651105634Srwatson * subject must have appropriate privilege. 1652105634Srwatson */ 1653105634Srwatson if (mac_biba_contains_equal(new)) { 1654106090Srwatson error = mac_biba_subject_privileged(subj); 1655105634Srwatson if (error) 1656105634Srwatson return (error); 1657105634Srwatson } 1658105634Srwatson } 1659105634Srwatson 1660101099Srwatson return (0); 1661101099Srwatson} 1662101099Srwatson 1663101099Srwatsonstatic int 1664102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1665102115Srwatson struct label *pipelabel) 1666102115Srwatson{ 1667102115Srwatson struct mac_biba *subj, *obj; 1668102115Srwatson 1669102115Srwatson if (!mac_biba_enabled) 1670102115Srwatson return (0); 1671102115Srwatson 1672102115Srwatson subj = SLOT(&cred->cr_label); 1673102115Srwatson obj = SLOT((pipelabel)); 1674102115Srwatson 1675102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1676102115Srwatson return (EACCES); 1677102115Srwatson 1678102115Srwatson return (0); 1679102115Srwatson} 1680102115Srwatson 1681102115Srwatsonstatic int 1682102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1683102115Srwatson struct label *pipelabel) 1684102115Srwatson{ 1685102115Srwatson struct mac_biba *subj, *obj; 1686102115Srwatson 1687102115Srwatson if (!mac_biba_enabled) 1688102115Srwatson return (0); 1689102115Srwatson 1690102115Srwatson subj = SLOT(&cred->cr_label); 1691102115Srwatson obj = SLOT((pipelabel)); 1692102115Srwatson 1693102115Srwatson if (!mac_biba_dominate_single(subj, obj)) 1694102115Srwatson return (EACCES); 1695102115Srwatson 1696102115Srwatson return (0); 1697102115Srwatson} 1698102115Srwatson 1699102115Srwatsonstatic int 1700101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1701101099Srwatson{ 1702101099Srwatson struct mac_biba *subj, *obj; 1703101099Srwatson 1704101099Srwatson if (!mac_biba_enabled) 1705101099Srwatson return (0); 1706101099Srwatson 1707101099Srwatson subj = SLOT(&cred->cr_label); 1708101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1709101099Srwatson 1710101099Srwatson /* XXX: range checks */ 1711101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1712101099Srwatson return (ESRCH); 1713101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1714101099Srwatson return (EACCES); 1715101099Srwatson 1716101099Srwatson return (0); 1717101099Srwatson} 1718101099Srwatson 1719101099Srwatsonstatic int 1720101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1721101099Srwatson{ 1722101099Srwatson struct mac_biba *subj, *obj; 1723103759Srwatson 1724101099Srwatson if (!mac_biba_enabled) 1725101099Srwatson return (0); 1726101099Srwatson 1727101099Srwatson subj = SLOT(&cred->cr_label); 1728101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1729103759Srwatson 1730101099Srwatson /* XXX: range checks */ 1731101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1732101099Srwatson return (ESRCH); 1733101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1734101099Srwatson return (EACCES); 1735101099Srwatson 1736101099Srwatson return (0); 1737101099Srwatson} 1738101099Srwatson 1739101099Srwatsonstatic int 1740101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1741101099Srwatson{ 1742101099Srwatson struct mac_biba *subj, *obj; 1743103759Srwatson 1744101099Srwatson if (!mac_biba_enabled) 1745101099Srwatson return (0); 1746101099Srwatson 1747101099Srwatson subj = SLOT(&cred->cr_label); 1748101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1749103759Srwatson 1750101099Srwatson /* XXX: range checks */ 1751101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1752101099Srwatson return (ESRCH); 1753101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1754101099Srwatson return (EACCES); 1755101099Srwatson 1756101099Srwatson return (0); 1757101099Srwatson} 1758101099Srwatson 1759101099Srwatsonstatic int 1760101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1761101099Srwatson struct mbuf *m, struct label *mbuflabel) 1762101099Srwatson{ 1763101099Srwatson struct mac_biba *p, *s; 1764101099Srwatson 1765101099Srwatson if (!mac_biba_enabled) 1766101099Srwatson return (0); 1767101099Srwatson 1768101099Srwatson p = SLOT(mbuflabel); 1769101099Srwatson s = SLOT(socketlabel); 1770101099Srwatson 1771101099Srwatson return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1772101099Srwatson} 1773101099Srwatson 1774101099Srwatsonstatic int 1775106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1776101099Srwatson struct label *socketlabel, struct label *newlabel) 1777101099Srwatson{ 1778101099Srwatson struct mac_biba *subj, *obj, *new; 1779105634Srwatson int error; 1780101099Srwatson 1781101099Srwatson new = SLOT(newlabel); 1782101099Srwatson subj = SLOT(&cred->cr_label); 1783101099Srwatson obj = SLOT(socketlabel); 1784101099Srwatson 1785101099Srwatson /* 1786105634Srwatson * If there is a Biba label update for the socket, it may be 1787105634Srwatson * an update of single. 1788101099Srwatson */ 1789105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1790105634Srwatson if (error) 1791105634Srwatson return (error); 1792101099Srwatson 1793101099Srwatson /* 1794105634Srwatson * To relabel a socket, the old socket single must be in the subject 1795101099Srwatson * range. 1796101099Srwatson */ 1797105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1798101099Srwatson return (EPERM); 1799101099Srwatson 1800101099Srwatson /* 1801105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1802101099Srwatson */ 1803105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1804105634Srwatson /* 1805105634Srwatson * To relabel a socket, the new socket single must be in 1806105634Srwatson * the subject range. 1807105634Srwatson */ 1808105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1809105634Srwatson return (EPERM); 1810101099Srwatson 1811105634Srwatson /* 1812105634Srwatson * To change the Biba label on the socket to contain EQUAL, 1813105634Srwatson * the subject must have appropriate privilege. 1814105634Srwatson */ 1815105634Srwatson if (mac_biba_contains_equal(new)) { 1816106090Srwatson error = mac_biba_subject_privileged(subj); 1817105634Srwatson if (error) 1818105634Srwatson return (error); 1819105634Srwatson } 1820105634Srwatson } 1821105634Srwatson 1822101099Srwatson return (0); 1823101099Srwatson} 1824101099Srwatson 1825101099Srwatsonstatic int 1826101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1827101099Srwatson struct label *socketlabel) 1828101099Srwatson{ 1829101099Srwatson struct mac_biba *subj, *obj; 1830101099Srwatson 1831105722Srwatson if (!mac_biba_enabled) 1832105722Srwatson return (0); 1833105722Srwatson 1834101099Srwatson subj = SLOT(&cred->cr_label); 1835101099Srwatson obj = SLOT(socketlabel); 1836101099Srwatson 1837101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1838101099Srwatson return (ENOENT); 1839101099Srwatson 1840101099Srwatson return (0); 1841101099Srwatson} 1842101099Srwatson 1843101099Srwatsonstatic int 1844106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1845106418Srwatson struct label *label) 1846106418Srwatson{ 1847106418Srwatson struct mac_biba *subj, *obj; 1848106418Srwatson int error; 1849106418Srwatson 1850106418Srwatson if (!mac_biba_enabled) 1851106418Srwatson return (0); 1852106418Srwatson 1853106418Srwatson subj = SLOT(&cred->cr_label); 1854106418Srwatson 1855106418Srwatson error = mac_biba_subject_privileged(subj); 1856106418Srwatson if (error) 1857106418Srwatson return (error); 1858106418Srwatson 1859106418Srwatson if (label == NULL) 1860106418Srwatson return (0); 1861106418Srwatson 1862106418Srwatson obj = SLOT(label); 1863106418Srwatson if (!mac_biba_high_single(obj)) 1864106418Srwatson return (EACCES); 1865106418Srwatson 1866106418Srwatson return (0); 1867106418Srwatson} 1868106418Srwatson 1869106418Srwatsonstatic int 1870106418Srwatsonmac_biba_check_system_settime(struct ucred *cred) 1871106418Srwatson{ 1872106418Srwatson struct mac_biba *subj; 1873106418Srwatson int error; 1874106418Srwatson 1875106418Srwatson if (!mac_biba_enabled) 1876106418Srwatson return (0); 1877106418Srwatson 1878106418Srwatson subj = SLOT(&cred->cr_label); 1879106418Srwatson 1880106418Srwatson error = mac_biba_subject_privileged(subj); 1881106418Srwatson if (error) 1882106418Srwatson return (error); 1883106418Srwatson 1884106418Srwatson return (0); 1885106418Srwatson} 1886106418Srwatson 1887106418Srwatsonstatic int 1888106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1889106161Srwatson struct label *label) 1890106161Srwatson{ 1891106161Srwatson struct mac_biba *subj, *obj; 1892106416Srwatson int error; 1893106161Srwatson 1894106161Srwatson if (!mac_biba_enabled) 1895106161Srwatson return (0); 1896106161Srwatson 1897106161Srwatson subj = SLOT(&cred->cr_label); 1898106161Srwatson obj = SLOT(label); 1899106161Srwatson 1900106416Srwatson error = mac_biba_subject_privileged(subj); 1901106416Srwatson if (error) 1902106416Srwatson return (error); 1903106161Srwatson 1904106161Srwatson if (!mac_biba_high_single(obj)) 1905106161Srwatson return (EACCES); 1906106161Srwatson 1907106161Srwatson return (0); 1908106161Srwatson} 1909106161Srwatson 1910106161Srwatsonstatic int 1911106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1912106161Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1913106161Srwatson{ 1914106161Srwatson struct mac_biba *subj; 1915106161Srwatson int error; 1916106161Srwatson 1917106161Srwatson if (!mac_biba_enabled) 1918106161Srwatson return (0); 1919106161Srwatson 1920106161Srwatson subj = SLOT(&cred->cr_label); 1921106161Srwatson 1922106161Srwatson /* 1923106161Srwatson * In general, treat sysctl variables as biba/high, but also 1924106161Srwatson * require privilege to change them, since they are a 1925106161Srwatson * communications channel between grades. Exempt MIB 1926106161Srwatson * queries from this due to undocmented sysctl magic. 1927106161Srwatson * XXXMAC: This probably requires some more review. 1928106161Srwatson */ 1929106161Srwatson if (new != NULL) { 1930106161Srwatson if (namelen > 0 && name[0] == 0) 1931106161Srwatson return (0); 1932106161Srwatson 1933106161Srwatson if (!mac_biba_subject_dominate_high(subj)) 1934106161Srwatson return (EACCES); 1935106161Srwatson 1936106161Srwatson error = mac_biba_subject_privileged(subj); 1937106161Srwatson if (error) 1938106161Srwatson return (error); 1939106161Srwatson } 1940106161Srwatson 1941106161Srwatson return (0); 1942106161Srwatson} 1943106161Srwatson 1944106161Srwatsonstatic int 1945101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1946101099Srwatson struct label *dlabel) 1947101099Srwatson{ 1948101099Srwatson struct mac_biba *subj, *obj; 1949101099Srwatson 1950101099Srwatson if (!mac_biba_enabled) 1951101099Srwatson return (0); 1952101099Srwatson 1953101099Srwatson subj = SLOT(&cred->cr_label); 1954101099Srwatson obj = SLOT(dlabel); 1955101099Srwatson 1956101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1957101099Srwatson return (EACCES); 1958101099Srwatson 1959101099Srwatson return (0); 1960101099Srwatson} 1961101099Srwatson 1962101099Srwatsonstatic int 1963101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1964101099Srwatson struct label *dlabel) 1965101099Srwatson{ 1966101099Srwatson struct mac_biba *subj, *obj; 1967101099Srwatson 1968101099Srwatson if (!mac_biba_enabled) 1969101099Srwatson return (0); 1970101099Srwatson 1971101099Srwatson subj = SLOT(&cred->cr_label); 1972101099Srwatson obj = SLOT(dlabel); 1973101099Srwatson 1974101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1975101099Srwatson return (EACCES); 1976101099Srwatson 1977101099Srwatson return (0); 1978101099Srwatson} 1979101099Srwatson 1980101099Srwatsonstatic int 1981101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1982101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1983101099Srwatson{ 1984101099Srwatson struct mac_biba *subj, *obj; 1985101099Srwatson 1986101099Srwatson if (!mac_biba_enabled) 1987101099Srwatson return (0); 1988101099Srwatson 1989101099Srwatson subj = SLOT(&cred->cr_label); 1990101099Srwatson obj = SLOT(dlabel); 1991101099Srwatson 1992101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1993101099Srwatson return (EACCES); 1994101099Srwatson 1995101099Srwatson return (0); 1996101099Srwatson} 1997101099Srwatson 1998101099Srwatsonstatic int 1999101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2000101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2001101099Srwatson struct componentname *cnp) 2002101099Srwatson{ 2003101099Srwatson struct mac_biba *subj, *obj; 2004101099Srwatson 2005101099Srwatson if (!mac_biba_enabled) 2006101099Srwatson return (0); 2007101099Srwatson 2008101099Srwatson subj = SLOT(&cred->cr_label); 2009101099Srwatson obj = SLOT(dlabel); 2010101099Srwatson 2011101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2012101099Srwatson return (EACCES); 2013101099Srwatson 2014101099Srwatson obj = SLOT(label); 2015101099Srwatson 2016101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2017101099Srwatson return (EACCES); 2018101099Srwatson 2019101099Srwatson return (0); 2020101099Srwatson} 2021101099Srwatson 2022101099Srwatsonstatic int 2023101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2024101099Srwatson struct label *label, acl_type_t type) 2025101099Srwatson{ 2026101099Srwatson struct mac_biba *subj, *obj; 2027101099Srwatson 2028101099Srwatson if (!mac_biba_enabled) 2029101099Srwatson return (0); 2030101099Srwatson 2031101099Srwatson subj = SLOT(&cred->cr_label); 2032101099Srwatson obj = SLOT(label); 2033101099Srwatson 2034101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2035101099Srwatson return (EACCES); 2036101099Srwatson 2037101099Srwatson return (0); 2038101099Srwatson} 2039101099Srwatson 2040101099Srwatsonstatic int 2041101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2042106648Srwatson struct label *label, struct image_params *imgp, 2043106648Srwatson struct label *execlabel) 2044101099Srwatson{ 2045106648Srwatson struct mac_biba *subj, *obj, *exec; 2046106648Srwatson int error; 2047101099Srwatson 2048106648Srwatson if (execlabel != NULL) { 2049106648Srwatson /* 2050106648Srwatson * We currently don't permit labels to be changed at 2051106648Srwatson * exec-time as part of Biba, so disallow non-NULL 2052106648Srwatson * Biba label elements in the execlabel. 2053106648Srwatson */ 2054106648Srwatson exec = SLOT(execlabel); 2055106648Srwatson error = biba_atmostflags(exec, 0); 2056106648Srwatson if (error) 2057106648Srwatson return (error); 2058106648Srwatson } 2059106648Srwatson 2060101099Srwatson if (!mac_biba_enabled) 2061101099Srwatson return (0); 2062101099Srwatson 2063101099Srwatson subj = SLOT(&cred->cr_label); 2064101099Srwatson obj = SLOT(label); 2065101099Srwatson 2066101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2067101099Srwatson return (EACCES); 2068101099Srwatson 2069101099Srwatson return (0); 2070101099Srwatson} 2071101099Srwatson 2072101099Srwatsonstatic int 2073101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2074101099Srwatson struct label *label, acl_type_t type) 2075101099Srwatson{ 2076101099Srwatson struct mac_biba *subj, *obj; 2077101099Srwatson 2078101099Srwatson if (!mac_biba_enabled) 2079101099Srwatson return (0); 2080101099Srwatson 2081101099Srwatson subj = SLOT(&cred->cr_label); 2082101099Srwatson obj = SLOT(label); 2083101099Srwatson 2084101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2085101099Srwatson return (EACCES); 2086101099Srwatson 2087101099Srwatson return (0); 2088101099Srwatson} 2089101099Srwatson 2090101099Srwatsonstatic int 2091101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2092101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 2093101099Srwatson{ 2094101099Srwatson struct mac_biba *subj, *obj; 2095101099Srwatson 2096101099Srwatson if (!mac_biba_enabled) 2097101099Srwatson return (0); 2098101099Srwatson 2099101099Srwatson subj = SLOT(&cred->cr_label); 2100101099Srwatson obj = SLOT(label); 2101101099Srwatson 2102101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2103101099Srwatson return (EACCES); 2104101099Srwatson 2105101099Srwatson return (0); 2106101099Srwatson} 2107101099Srwatson 2108101099Srwatsonstatic int 2109104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2110104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2111104530Srwatson struct componentname *cnp) 2112104530Srwatson{ 2113104530Srwatson struct mac_biba *subj, *obj; 2114104530Srwatson 2115104530Srwatson if (!mac_biba_enabled) 2116104530Srwatson return (0); 2117104530Srwatson 2118104530Srwatson subj = SLOT(&cred->cr_label); 2119104530Srwatson obj = SLOT(dlabel); 2120104530Srwatson 2121104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2122104530Srwatson return (EACCES); 2123104530Srwatson 2124104530Srwatson obj = SLOT(label); 2125104530Srwatson 2126104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2127104530Srwatson return (EACCES); 2128104530Srwatson 2129104530Srwatson return (0); 2130104530Srwatson} 2131104530Srwatson 2132104530Srwatsonstatic int 2133103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2134101099Srwatson struct label *dlabel, struct componentname *cnp) 2135101099Srwatson{ 2136101099Srwatson struct mac_biba *subj, *obj; 2137103759Srwatson 2138101099Srwatson if (!mac_biba_enabled) 2139101099Srwatson return (0); 2140103759Srwatson 2141101099Srwatson subj = SLOT(&cred->cr_label); 2142101099Srwatson obj = SLOT(dlabel); 2143103759Srwatson 2144101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2145101099Srwatson return (EACCES); 2146101099Srwatson 2147103759Srwatson return (0); 2148101099Srwatson} 2149101099Srwatson 2150101099Srwatsonstatic int 2151104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2152104546Srwatson struct label *label, int prot) 2153104546Srwatson{ 2154104546Srwatson struct mac_biba *subj, *obj; 2155104546Srwatson 2156104546Srwatson /* 2157104546Srwatson * Rely on the use of open()-time protections to handle 2158104546Srwatson * non-revocation cases. 2159104546Srwatson */ 2160105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2161104546Srwatson return (0); 2162104546Srwatson 2163104546Srwatson subj = SLOT(&cred->cr_label); 2164104546Srwatson obj = SLOT(label); 2165104546Srwatson 2166104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2167104546Srwatson if (!mac_biba_dominate_single(obj, subj)) 2168104546Srwatson return (EACCES); 2169104546Srwatson } 2170104546Srwatson if (prot & VM_PROT_WRITE) { 2171104546Srwatson if (!mac_biba_dominate_single(subj, obj)) 2172104546Srwatson return (EACCES); 2173104546Srwatson } 2174104546Srwatson 2175104569Srwatson return (0); 2176104546Srwatson} 2177104546Srwatson 2178104546Srwatsonstatic int 2179101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2180106212Srwatson struct label *vnodelabel, int acc_mode) 2181101099Srwatson{ 2182101099Srwatson struct mac_biba *subj, *obj; 2183101099Srwatson 2184101099Srwatson if (!mac_biba_enabled) 2185101099Srwatson return (0); 2186101099Srwatson 2187101099Srwatson subj = SLOT(&cred->cr_label); 2188101099Srwatson obj = SLOT(vnodelabel); 2189101099Srwatson 2190101099Srwatson /* XXX privilege override for admin? */ 2191101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2192101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2193101099Srwatson return (EACCES); 2194101099Srwatson } 2195101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2196101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2197101099Srwatson return (EACCES); 2198101099Srwatson } 2199101099Srwatson 2200101099Srwatson return (0); 2201101099Srwatson} 2202101099Srwatson 2203101099Srwatsonstatic int 2204102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2205102129Srwatson struct vnode *vp, struct label *label) 2206102112Srwatson{ 2207102112Srwatson struct mac_biba *subj, *obj; 2208102112Srwatson 2209105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2210102112Srwatson return (0); 2211102112Srwatson 2212102129Srwatson subj = SLOT(&active_cred->cr_label); 2213102112Srwatson obj = SLOT(label); 2214102112Srwatson 2215102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2216102112Srwatson return (EACCES); 2217102112Srwatson 2218102112Srwatson return (0); 2219102112Srwatson} 2220102112Srwatson 2221102112Srwatsonstatic int 2222102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2223102129Srwatson struct vnode *vp, struct label *label) 2224102112Srwatson{ 2225102112Srwatson struct mac_biba *subj, *obj; 2226102112Srwatson 2227105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2228102112Srwatson return (0); 2229102112Srwatson 2230102129Srwatson subj = SLOT(&active_cred->cr_label); 2231102112Srwatson obj = SLOT(label); 2232102112Srwatson 2233102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2234102112Srwatson return (EACCES); 2235102112Srwatson 2236102112Srwatson return (0); 2237102112Srwatson} 2238102112Srwatson 2239102112Srwatsonstatic int 2240101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2241101099Srwatson struct label *dlabel) 2242101099Srwatson{ 2243101099Srwatson struct mac_biba *subj, *obj; 2244101099Srwatson 2245101099Srwatson if (!mac_biba_enabled) 2246101099Srwatson return (0); 2247101099Srwatson 2248101099Srwatson subj = SLOT(&cred->cr_label); 2249101099Srwatson obj = SLOT(dlabel); 2250101099Srwatson 2251101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2252101099Srwatson return (EACCES); 2253101099Srwatson 2254101099Srwatson return (0); 2255101099Srwatson} 2256101099Srwatson 2257101099Srwatsonstatic int 2258101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2259101099Srwatson struct label *label) 2260101099Srwatson{ 2261101099Srwatson struct mac_biba *subj, *obj; 2262101099Srwatson 2263101099Srwatson if (!mac_biba_enabled) 2264101099Srwatson return (0); 2265101099Srwatson 2266101099Srwatson subj = SLOT(&cred->cr_label); 2267101099Srwatson obj = SLOT(label); 2268101099Srwatson 2269101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2270101099Srwatson return (EACCES); 2271101099Srwatson 2272101099Srwatson return (0); 2273101099Srwatson} 2274101099Srwatson 2275101099Srwatsonstatic int 2276101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2277101099Srwatson struct label *vnodelabel, struct label *newlabel) 2278101099Srwatson{ 2279101099Srwatson struct mac_biba *old, *new, *subj; 2280105634Srwatson int error; 2281101099Srwatson 2282101099Srwatson old = SLOT(vnodelabel); 2283101099Srwatson new = SLOT(newlabel); 2284101099Srwatson subj = SLOT(&cred->cr_label); 2285101099Srwatson 2286101099Srwatson /* 2287105634Srwatson * If there is a Biba label update for the vnode, it must be a 2288105634Srwatson * single label. 2289101099Srwatson */ 2290105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2291105634Srwatson if (error) 2292105634Srwatson return (error); 2293101099Srwatson 2294101099Srwatson /* 2295105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2296105634Srwatson * authorize the relabel. 2297101099Srwatson */ 2298105634Srwatson if (!mac_biba_single_in_range(old, subj)) 2299101099Srwatson return (EPERM); 2300101099Srwatson 2301101099Srwatson /* 2302105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2303101099Srwatson */ 2304105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2305105634Srwatson /* 2306105634Srwatson * To change the Biba label on a vnode, the new vnode label 2307105634Srwatson * must be in the subject range. 2308105634Srwatson */ 2309105634Srwatson if (!mac_biba_single_in_range(new, subj)) 2310105634Srwatson return (EPERM); 2311101099Srwatson 2312105634Srwatson /* 2313105634Srwatson * To change the Biba label on the vnode to be EQUAL, 2314105634Srwatson * the subject must have appropriate privilege. 2315105634Srwatson */ 2316105634Srwatson if (mac_biba_contains_equal(new)) { 2317106090Srwatson error = mac_biba_subject_privileged(subj); 2318105634Srwatson if (error) 2319105634Srwatson return (error); 2320105634Srwatson } 2321105634Srwatson } 2322105634Srwatson 2323105634Srwatson return (0); 2324101099Srwatson} 2325101099Srwatson 2326101099Srwatsonstatic int 2327101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2328101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2329101099Srwatson struct componentname *cnp) 2330101099Srwatson{ 2331101099Srwatson struct mac_biba *subj, *obj; 2332101099Srwatson 2333101099Srwatson if (!mac_biba_enabled) 2334101099Srwatson return (0); 2335101099Srwatson 2336101099Srwatson subj = SLOT(&cred->cr_label); 2337101099Srwatson obj = SLOT(dlabel); 2338101099Srwatson 2339101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2340101099Srwatson return (EACCES); 2341101099Srwatson 2342101099Srwatson obj = SLOT(label); 2343101099Srwatson 2344101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2345101099Srwatson return (EACCES); 2346101099Srwatson 2347101099Srwatson return (0); 2348101099Srwatson} 2349101099Srwatson 2350101099Srwatsonstatic int 2351101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2352101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2353101099Srwatson struct componentname *cnp) 2354101099Srwatson{ 2355101099Srwatson struct mac_biba *subj, *obj; 2356101099Srwatson 2357101099Srwatson if (!mac_biba_enabled) 2358101099Srwatson return (0); 2359101099Srwatson 2360101099Srwatson subj = SLOT(&cred->cr_label); 2361101099Srwatson obj = SLOT(dlabel); 2362101099Srwatson 2363101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2364101099Srwatson return (EACCES); 2365101099Srwatson 2366101099Srwatson if (vp != NULL) { 2367101099Srwatson obj = SLOT(label); 2368101099Srwatson 2369101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2370101099Srwatson return (EACCES); 2371101099Srwatson } 2372101099Srwatson 2373101099Srwatson return (0); 2374101099Srwatson} 2375101099Srwatson 2376101099Srwatsonstatic int 2377101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2378101099Srwatson struct label *label) 2379101099Srwatson{ 2380101099Srwatson struct mac_biba *subj, *obj; 2381101099Srwatson 2382101099Srwatson if (!mac_biba_enabled) 2383101099Srwatson return (0); 2384101099Srwatson 2385101099Srwatson subj = SLOT(&cred->cr_label); 2386101099Srwatson obj = SLOT(label); 2387101099Srwatson 2388101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2389101099Srwatson return (EACCES); 2390101099Srwatson 2391101099Srwatson return (0); 2392101099Srwatson} 2393101099Srwatson 2394101099Srwatsonstatic int 2395101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2396101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 2397101099Srwatson{ 2398101099Srwatson struct mac_biba *subj, *obj; 2399101099Srwatson 2400101099Srwatson if (!mac_biba_enabled) 2401101099Srwatson return (0); 2402101099Srwatson 2403101099Srwatson subj = SLOT(&cred->cr_label); 2404101099Srwatson obj = SLOT(label); 2405101099Srwatson 2406101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2407101099Srwatson return (EACCES); 2408101099Srwatson 2409101099Srwatson return (0); 2410101099Srwatson} 2411101099Srwatson 2412101099Srwatsonstatic int 2413101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2414101099Srwatson struct label *vnodelabel, int attrnamespace, const char *name, 2415101099Srwatson struct uio *uio) 2416101099Srwatson{ 2417101099Srwatson struct mac_biba *subj, *obj; 2418101099Srwatson 2419101099Srwatson if (!mac_biba_enabled) 2420101099Srwatson return (0); 2421101099Srwatson 2422101099Srwatson subj = SLOT(&cred->cr_label); 2423101099Srwatson obj = SLOT(vnodelabel); 2424101099Srwatson 2425101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2426101099Srwatson return (EACCES); 2427101099Srwatson 2428101099Srwatson /* XXX: protect the MAC EA in a special way? */ 2429101099Srwatson 2430101099Srwatson return (0); 2431101099Srwatson} 2432101099Srwatson 2433101099Srwatsonstatic int 2434101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2435101099Srwatson struct label *vnodelabel, u_long flags) 2436101099Srwatson{ 2437101099Srwatson struct mac_biba *subj, *obj; 2438101099Srwatson 2439101099Srwatson if (!mac_biba_enabled) 2440101099Srwatson return (0); 2441101099Srwatson 2442101099Srwatson subj = SLOT(&cred->cr_label); 2443101099Srwatson obj = SLOT(vnodelabel); 2444101099Srwatson 2445101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2446101099Srwatson return (EACCES); 2447101099Srwatson 2448101099Srwatson return (0); 2449101099Srwatson} 2450101099Srwatson 2451101099Srwatsonstatic int 2452101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2453101099Srwatson struct label *vnodelabel, mode_t mode) 2454101099Srwatson{ 2455101099Srwatson struct mac_biba *subj, *obj; 2456101099Srwatson 2457101099Srwatson if (!mac_biba_enabled) 2458101099Srwatson return (0); 2459101099Srwatson 2460101099Srwatson subj = SLOT(&cred->cr_label); 2461101099Srwatson obj = SLOT(vnodelabel); 2462101099Srwatson 2463101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2464101099Srwatson return (EACCES); 2465101099Srwatson 2466101099Srwatson return (0); 2467101099Srwatson} 2468101099Srwatson 2469101099Srwatsonstatic int 2470101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2471101099Srwatson struct label *vnodelabel, uid_t uid, gid_t gid) 2472101099Srwatson{ 2473101099Srwatson struct mac_biba *subj, *obj; 2474101099Srwatson 2475101099Srwatson if (!mac_biba_enabled) 2476101099Srwatson return (0); 2477101099Srwatson 2478101099Srwatson subj = SLOT(&cred->cr_label); 2479101099Srwatson obj = SLOT(vnodelabel); 2480101099Srwatson 2481101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2482101099Srwatson return (EACCES); 2483101099Srwatson 2484101099Srwatson return (0); 2485101099Srwatson} 2486101099Srwatson 2487101099Srwatsonstatic int 2488101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2489101099Srwatson struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2490101099Srwatson{ 2491101099Srwatson struct mac_biba *subj, *obj; 2492101099Srwatson 2493101099Srwatson if (!mac_biba_enabled) 2494101099Srwatson return (0); 2495101099Srwatson 2496101099Srwatson subj = SLOT(&cred->cr_label); 2497101099Srwatson obj = SLOT(vnodelabel); 2498101099Srwatson 2499101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2500101099Srwatson return (EACCES); 2501101099Srwatson 2502101099Srwatson return (0); 2503101099Srwatson} 2504101099Srwatson 2505101099Srwatsonstatic int 2506102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2507102129Srwatson struct vnode *vp, struct label *vnodelabel) 2508101099Srwatson{ 2509101099Srwatson struct mac_biba *subj, *obj; 2510101099Srwatson 2511101099Srwatson if (!mac_biba_enabled) 2512101099Srwatson return (0); 2513101099Srwatson 2514102129Srwatson subj = SLOT(&active_cred->cr_label); 2515101099Srwatson obj = SLOT(vnodelabel); 2516101099Srwatson 2517101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2518101099Srwatson return (EACCES); 2519101099Srwatson 2520101099Srwatson return (0); 2521101099Srwatson} 2522101099Srwatson 2523102112Srwatsonstatic int 2524102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred, 2525102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 2526102112Srwatson{ 2527102112Srwatson struct mac_biba *subj, *obj; 2528102112Srwatson 2529105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2530102112Srwatson return (0); 2531102112Srwatson 2532102129Srwatson subj = SLOT(&active_cred->cr_label); 2533102112Srwatson obj = SLOT(label); 2534102112Srwatson 2535102112Srwatson if (!mac_biba_dominate_single(subj, obj)) 2536102112Srwatson return (EACCES); 2537102112Srwatson 2538102112Srwatson return (0); 2539102112Srwatson} 2540102112Srwatson 2541106217Srwatsonstatic struct mac_policy_ops mac_biba_ops = 2542101099Srwatson{ 2543106217Srwatson .mpo_destroy = mac_biba_destroy, 2544106217Srwatson .mpo_init = mac_biba_init, 2545106217Srwatson .mpo_init_bpfdesc_label = mac_biba_init_label, 2546106217Srwatson .mpo_init_cred_label = mac_biba_init_label, 2547106217Srwatson .mpo_init_devfsdirent_label = mac_biba_init_label, 2548106217Srwatson .mpo_init_ifnet_label = mac_biba_init_label, 2549106217Srwatson .mpo_init_ipq_label = mac_biba_init_label, 2550106217Srwatson .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2551106217Srwatson .mpo_init_mount_label = mac_biba_init_label, 2552106217Srwatson .mpo_init_mount_fs_label = mac_biba_init_label, 2553106217Srwatson .mpo_init_pipe_label = mac_biba_init_label, 2554106217Srwatson .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2555106217Srwatson .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2556106217Srwatson .mpo_init_vnode_label = mac_biba_init_label, 2557106217Srwatson .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2558106217Srwatson .mpo_destroy_cred_label = mac_biba_destroy_label, 2559106217Srwatson .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2560106217Srwatson .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2561106217Srwatson .mpo_destroy_ipq_label = mac_biba_destroy_label, 2562106217Srwatson .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2563106217Srwatson .mpo_destroy_mount_label = mac_biba_destroy_label, 2564106217Srwatson .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2565106217Srwatson .mpo_destroy_pipe_label = mac_biba_destroy_label, 2566106217Srwatson .mpo_destroy_socket_label = mac_biba_destroy_label, 2567106217Srwatson .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2568106217Srwatson .mpo_destroy_vnode_label = mac_biba_destroy_label, 2569106217Srwatson .mpo_copy_pipe_label = mac_biba_copy_label, 2570106217Srwatson .mpo_copy_vnode_label = mac_biba_copy_label, 2571106217Srwatson .mpo_externalize_cred_label = mac_biba_externalize_label, 2572106217Srwatson .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2573106217Srwatson .mpo_externalize_pipe_label = mac_biba_externalize_label, 2574106217Srwatson .mpo_externalize_socket_label = mac_biba_externalize_label, 2575106217Srwatson .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2576106217Srwatson .mpo_externalize_vnode_label = mac_biba_externalize_label, 2577106217Srwatson .mpo_internalize_cred_label = mac_biba_internalize_label, 2578106217Srwatson .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2579106217Srwatson .mpo_internalize_pipe_label = mac_biba_internalize_label, 2580106217Srwatson .mpo_internalize_socket_label = mac_biba_internalize_label, 2581106217Srwatson .mpo_internalize_vnode_label = mac_biba_internalize_label, 2582106217Srwatson .mpo_create_devfs_device = mac_biba_create_devfs_device, 2583106217Srwatson .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2584106217Srwatson .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2585106217Srwatson .mpo_create_mount = mac_biba_create_mount, 2586106217Srwatson .mpo_create_root_mount = mac_biba_create_root_mount, 2587106217Srwatson .mpo_relabel_vnode = mac_biba_relabel_vnode, 2588106217Srwatson .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2589106217Srwatson .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2590106217Srwatson .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2591106217Srwatson .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2592106217Srwatson .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2593106217Srwatson .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2594106217Srwatson .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2595106217Srwatson .mpo_create_pipe = mac_biba_create_pipe, 2596106217Srwatson .mpo_create_socket = mac_biba_create_socket, 2597106217Srwatson .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2598106217Srwatson .mpo_relabel_pipe = mac_biba_relabel_pipe, 2599106217Srwatson .mpo_relabel_socket = mac_biba_relabel_socket, 2600106217Srwatson .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2601106217Srwatson .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2602106217Srwatson .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2603106217Srwatson .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2604106217Srwatson .mpo_create_fragment = mac_biba_create_fragment, 2605106217Srwatson .mpo_create_ifnet = mac_biba_create_ifnet, 2606106217Srwatson .mpo_create_ipq = mac_biba_create_ipq, 2607106217Srwatson .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2608106217Srwatson .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2609106217Srwatson .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2610106217Srwatson .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2611106217Srwatson .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2612106217Srwatson .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2613106217Srwatson .mpo_fragment_match = mac_biba_fragment_match, 2614106217Srwatson .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2615106217Srwatson .mpo_update_ipq = mac_biba_update_ipq, 2616106217Srwatson .mpo_create_cred = mac_biba_create_cred, 2617106217Srwatson .mpo_create_proc0 = mac_biba_create_proc0, 2618106217Srwatson .mpo_create_proc1 = mac_biba_create_proc1, 2619106217Srwatson .mpo_relabel_cred = mac_biba_relabel_cred, 2620106217Srwatson .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2621106217Srwatson .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2622106217Srwatson .mpo_check_cred_visible = mac_biba_check_cred_visible, 2623106217Srwatson .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2624106217Srwatson .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2625106217Srwatson .mpo_check_mount_stat = mac_biba_check_mount_stat, 2626106217Srwatson .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2627106217Srwatson .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2628106217Srwatson .mpo_check_pipe_read = mac_biba_check_pipe_read, 2629106217Srwatson .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2630106217Srwatson .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2631106217Srwatson .mpo_check_pipe_write = mac_biba_check_pipe_write, 2632106217Srwatson .mpo_check_proc_debug = mac_biba_check_proc_debug, 2633106217Srwatson .mpo_check_proc_sched = mac_biba_check_proc_sched, 2634106217Srwatson .mpo_check_proc_signal = mac_biba_check_proc_signal, 2635106217Srwatson .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2636106217Srwatson .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2637106217Srwatson .mpo_check_socket_visible = mac_biba_check_socket_visible, 2638106418Srwatson .mpo_check_system_acct = mac_biba_check_system_acct, 2639106418Srwatson .mpo_check_system_settime = mac_biba_check_system_settime, 2640106217Srwatson .mpo_check_system_swapon = mac_biba_check_system_swapon, 2641106217Srwatson .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2642106217Srwatson .mpo_check_vnode_access = mac_biba_check_vnode_open, 2643106217Srwatson .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2644106217Srwatson .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2645106217Srwatson .mpo_check_vnode_create = mac_biba_check_vnode_create, 2646106217Srwatson .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2647106217Srwatson .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2648106217Srwatson .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2649106217Srwatson .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2650106217Srwatson .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2651106217Srwatson .mpo_check_vnode_link = mac_biba_check_vnode_link, 2652106217Srwatson .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2653106217Srwatson .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2654106217Srwatson .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2655106217Srwatson .mpo_check_vnode_open = mac_biba_check_vnode_open, 2656106217Srwatson .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2657106217Srwatson .mpo_check_vnode_read = mac_biba_check_vnode_read, 2658106217Srwatson .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2659106217Srwatson .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2660106217Srwatson .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2661106217Srwatson .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2662106217Srwatson .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2663106217Srwatson .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2664106217Srwatson .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2665106217Srwatson .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2666106217Srwatson .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2667106217Srwatson .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2668106217Srwatson .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2669106217Srwatson .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2670106217Srwatson .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2671106217Srwatson .mpo_check_vnode_write = mac_biba_check_vnode_write, 2672101099Srwatson}; 2673101099Srwatson 2674106217SrwatsonMAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2675101099Srwatson MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot); 2676