mac_biba.c revision 123173
1101099Srwatson/*- 2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3115497Srwatson * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. 4101099Srwatson * All rights reserved. 5101099Srwatson * 6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 7101099Srwatson * 8106393Srwatson * This software was developed for the FreeBSD Project in part by Network 9106393Srwatson * Associates Laboratories, the Security Research Division of Network 10106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 11106393Srwatson * as part of the DARPA CHATS research program. 12101099Srwatson * 13101099Srwatson * Redistribution and use in source and binary forms, with or without 14101099Srwatson * modification, are permitted provided that the following conditions 15101099Srwatson * are met: 16101099Srwatson * 1. Redistributions of source code must retain the above copyright 17101099Srwatson * notice, this list of conditions and the following disclaimer. 18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright 19101099Srwatson * notice, this list of conditions and the following disclaimer in the 20101099Srwatson * documentation and/or other materials provided with the distribution. 21101099Srwatson * 22101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32101099Srwatson * SUCH DAMAGE. 33101099Srwatson * 34101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 123173 2003-12-06 21:48:03Z rwatson $ 35101099Srwatson */ 36101099Srwatson 37101099Srwatson/* 38101099Srwatson * Developed by the TrustedBSD Project. 39101099Srwatson * Biba fixed label mandatory integrity policy. 40101099Srwatson */ 41101099Srwatson 42101099Srwatson#include <sys/types.h> 43101099Srwatson#include <sys/param.h> 44101099Srwatson#include <sys/acl.h> 45101099Srwatson#include <sys/conf.h> 46105988Srwatson#include <sys/extattr.h> 47101099Srwatson#include <sys/kernel.h> 48101099Srwatson#include <sys/mac.h> 49103183Sbde#include <sys/malloc.h> 50101099Srwatson#include <sys/mount.h> 51101099Srwatson#include <sys/proc.h> 52115497Srwatson#include <sys/sbuf.h> 53101099Srwatson#include <sys/systm.h> 54101099Srwatson#include <sys/sysproto.h> 55101099Srwatson#include <sys/sysent.h> 56105696Srwatson#include <sys/systm.h> 57101099Srwatson#include <sys/vnode.h> 58101099Srwatson#include <sys/file.h> 59101099Srwatson#include <sys/socket.h> 60101099Srwatson#include <sys/socketvar.h> 61101099Srwatson#include <sys/pipe.h> 62101099Srwatson#include <sys/sysctl.h> 63101099Srwatson 64101099Srwatson#include <fs/devfs/devfs.h> 65101099Srwatson 66101099Srwatson#include <net/bpfdesc.h> 67101099Srwatson#include <net/if.h> 68101099Srwatson#include <net/if_types.h> 69101099Srwatson#include <net/if_var.h> 70101099Srwatson 71101099Srwatson#include <netinet/in.h> 72122875Srwatson#include <netinet/in_pcb.h> 73101099Srwatson#include <netinet/ip_var.h> 74101099Srwatson 75122879Srwatson#include <vm/uma.h> 76101099Srwatson#include <vm/vm.h> 77101099Srwatson 78101099Srwatson#include <sys/mac_policy.h> 79101099Srwatson 80101099Srwatson#include <security/mac_biba/mac_biba.h> 81101099Srwatson 82101099SrwatsonSYSCTL_DECL(_security_mac); 83101099Srwatson 84101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 85101099Srwatson "TrustedBSD mac_biba policy controls"); 86101099Srwatson 87105988Srwatsonstatic int mac_biba_label_size = sizeof(struct mac_biba); 88105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 89105988Srwatson &mac_biba_label_size, 0, "Size of struct mac_biba"); 90105988Srwatson 91107731Srwatsonstatic int mac_biba_enabled = 1; 92101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 93101099Srwatson &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 94102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 95101099Srwatson 96101099Srwatsonstatic int destroyed_not_inited; 97101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 98101099Srwatson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 99101099Srwatson 100101099Srwatsonstatic int trust_all_interfaces = 0; 101101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 102101099Srwatson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 103101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 104101099Srwatson 105101099Srwatsonstatic char trusted_interfaces[128]; 106101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 107101099Srwatson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 108101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 109101099Srwatson sizeof(trusted_interfaces)); 110101099Srwatson 111105643Srwatsonstatic int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 112105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 113105643Srwatson &max_compartments, 0, "Maximum supported compartments"); 114105643Srwatson 115105606Srwatsonstatic int ptys_equal = 0; 116105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 117105606Srwatson &ptys_equal, 0, "Label pty devices as biba/equal on create"); 118105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 119105606Srwatson 120105637Srwatsonstatic int revocation_enabled = 0; 121101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 122105637Srwatson &revocation_enabled, 0, "Revoke access to objects on relabel"); 123105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 124101099Srwatson 125101099Srwatsonstatic int mac_biba_slot; 126101099Srwatson#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 127101099Srwatson 128122879Srwatsonstatic uma_zone_t zone_biba; 129101099Srwatson 130105643Srwatsonstatic __inline int 131105643Srwatsonbiba_bit_set_empty(u_char *set) { 132105643Srwatson int i; 133105643Srwatson 134105643Srwatson for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 135105643Srwatson if (set[i] != 0) 136105643Srwatson return (0); 137105643Srwatson return (1); 138105643Srwatson} 139105643Srwatson 140101099Srwatsonstatic struct mac_biba * 141104514Srwatsonbiba_alloc(int flag) 142101099Srwatson{ 143101099Srwatson 144122879Srwatson return (uma_zalloc(zone_biba, flag | M_ZERO)); 145101099Srwatson} 146101099Srwatson 147101099Srwatsonstatic void 148101099Srwatsonbiba_free(struct mac_biba *mac_biba) 149101099Srwatson{ 150101099Srwatson 151101099Srwatson if (mac_biba != NULL) 152122879Srwatson uma_zfree(zone_biba, mac_biba); 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_init(struct mac_policy_conf *conf) 491101099Srwatson{ 492101099Srwatson 493122879Srwatson zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL, 494122879Srwatson NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 495101099Srwatson} 496101099Srwatson 497101099Srwatson/* 498101099Srwatson * Label operations. 499101099Srwatson */ 500101099Srwatsonstatic void 501104514Srwatsonmac_biba_init_label(struct label *label) 502101099Srwatson{ 503101099Srwatson 504111119Simp SLOT(label) = biba_alloc(M_WAITOK); 505101099Srwatson} 506101099Srwatson 507101099Srwatsonstatic int 508104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag) 509101099Srwatson{ 510101099Srwatson 511104514Srwatson SLOT(label) = biba_alloc(flag); 512101099Srwatson if (SLOT(label) == NULL) 513101099Srwatson return (ENOMEM); 514101099Srwatson 515101099Srwatson return (0); 516101099Srwatson} 517101099Srwatson 518101099Srwatsonstatic void 519104514Srwatsonmac_biba_destroy_label(struct label *label) 520101099Srwatson{ 521101099Srwatson 522101099Srwatson biba_free(SLOT(label)); 523101099Srwatson SLOT(label) = NULL; 524101099Srwatson} 525101099Srwatson 526105696Srwatson/* 527115497Srwatson * mac_biba_element_to_string() accepts an sbuf and Biba element. It 528115497Srwatson * converts the Biba element to a string and stores the result in the 529115497Srwatson * sbuf; if there isn't space in the sbuf, -1 is returned. 530105696Srwatson */ 531115497Srwatsonstatic int 532115497Srwatsonmac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element) 533105696Srwatson{ 534115497Srwatson int i, first; 535105696Srwatson 536105696Srwatson switch (element->mbe_type) { 537105696Srwatson case MAC_BIBA_TYPE_HIGH: 538115497Srwatson return (sbuf_printf(sb, "high")); 539105696Srwatson 540105696Srwatson case MAC_BIBA_TYPE_LOW: 541115497Srwatson return (sbuf_printf(sb, "low")); 542105696Srwatson 543105696Srwatson case MAC_BIBA_TYPE_EQUAL: 544115497Srwatson return (sbuf_printf(sb, "equal")); 545105696Srwatson 546105696Srwatson case MAC_BIBA_TYPE_GRADE: 547115497Srwatson if (sbuf_printf(sb, "%d", element->mbe_grade) == -1) 548115497Srwatson return (-1); 549115497Srwatson 550115497Srwatson first = 1; 551115497Srwatson for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) { 552115497Srwatson if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) { 553115497Srwatson if (first) { 554115497Srwatson if (sbuf_putc(sb, ':') == -1) 555115497Srwatson return (-1); 556115497Srwatson if (sbuf_printf(sb, "%d", i) == -1) 557115497Srwatson return (-1); 558115497Srwatson first = 0; 559115497Srwatson } else { 560115497Srwatson if (sbuf_printf(sb, "+%d", i) == -1) 561115497Srwatson return (-1); 562115497Srwatson } 563115497Srwatson } 564105696Srwatson } 565115497Srwatson return (0); 566105696Srwatson 567105696Srwatson default: 568105696Srwatson panic("mac_biba_element_to_string: invalid type (%d)", 569105696Srwatson element->mbe_type); 570105696Srwatson } 571105696Srwatson} 572105696Srwatson 573115497Srwatson/* 574116701Srwatson * mac_biba_to_string() converts a Biba label to a string, and places 575116701Srwatson * the results in the passed sbuf. It returns 0 on success, or EINVAL 576116701Srwatson * if there isn't room in the sbuf. Note: the sbuf will be modified 577116701Srwatson * even in a failure case, so the caller may need to revert the sbuf 578116701Srwatson * by restoring the offset if that's undesired. 579115497Srwatson */ 580101099Srwatsonstatic int 581116701Srwatsonmac_biba_to_string(struct sbuf *sb, struct mac_biba *mac_biba) 582101099Srwatson{ 583105696Srwatson 584105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 585116701Srwatson if (mac_biba_element_to_string(sb, &mac_biba->mb_single) 586115497Srwatson == -1) 587105696Srwatson return (EINVAL); 588105696Srwatson } 589105696Srwatson 590105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 591116701Srwatson if (sbuf_putc(sb, '(') == -1) 592105696Srwatson return (EINVAL); 593105696Srwatson 594116701Srwatson if (mac_biba_element_to_string(sb, &mac_biba->mb_rangelow) 595115497Srwatson == -1) 596105696Srwatson return (EINVAL); 597105696Srwatson 598116701Srwatson if (sbuf_putc(sb, '-') == -1) 599105696Srwatson return (EINVAL); 600105696Srwatson 601116701Srwatson if (mac_biba_element_to_string(sb, &mac_biba->mb_rangehigh) 602115497Srwatson == -1) 603105696Srwatson return (EINVAL); 604105696Srwatson 605116701Srwatson if (sbuf_putc(sb, ')') == -1) 606105696Srwatson return (EINVAL); 607105696Srwatson } 608105696Srwatson 609105696Srwatson return (0); 610105696Srwatson} 611105696Srwatson 612105696Srwatsonstatic int 613105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name, 614116701Srwatson struct sbuf *sb, int *claimed) 615105696Srwatson{ 616101099Srwatson struct mac_biba *mac_biba; 617101099Srwatson 618105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 619105696Srwatson return (0); 620105696Srwatson 621105696Srwatson (*claimed)++; 622105696Srwatson 623101099Srwatson mac_biba = SLOT(label); 624116701Srwatson return (mac_biba_to_string(sb, mac_biba)); 625105696Srwatson} 626105696Srwatson 627105696Srwatsonstatic int 628105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string) 629101099Srwatson{ 630115395Srwatson char *compartment, *end, *grade; 631115395Srwatson int value; 632105696Srwatson 633105696Srwatson if (strcmp(string, "high") == 0 || 634105696Srwatson strcmp(string, "hi") == 0) { 635105696Srwatson element->mbe_type = MAC_BIBA_TYPE_HIGH; 636105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 637105696Srwatson } else if (strcmp(string, "low") == 0 || 638105696Srwatson strcmp(string, "lo") == 0) { 639105696Srwatson element->mbe_type = MAC_BIBA_TYPE_LOW; 640105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 641105696Srwatson } else if (strcmp(string, "equal") == 0 || 642105696Srwatson strcmp(string, "eq") == 0) { 643105696Srwatson element->mbe_type = MAC_BIBA_TYPE_EQUAL; 644105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 645105696Srwatson } else { 646115395Srwatson element->mbe_type = MAC_BIBA_TYPE_GRADE; 647105696Srwatson 648115395Srwatson /* 649115395Srwatson * Numeric grade piece of the element. 650115395Srwatson */ 651115395Srwatson grade = strsep(&string, ":"); 652115395Srwatson value = strtol(grade, &end, 10); 653115395Srwatson if (end == grade || *end != '\0') 654105696Srwatson return (EINVAL); 655115395Srwatson if (value < 0 || value > 65535) 656115395Srwatson return (EINVAL); 657115395Srwatson element->mbe_grade = value; 658105696Srwatson 659115395Srwatson /* 660115395Srwatson * Optional compartment piece of the element. If none 661115395Srwatson * are included, we assume that the label has no 662115395Srwatson * compartments. 663115395Srwatson */ 664115395Srwatson if (string == NULL) 665115395Srwatson return (0); 666115395Srwatson if (*string == '\0') 667115395Srwatson return (0); 668105696Srwatson 669115395Srwatson while ((compartment = strsep(&string, "+")) != NULL) { 670115395Srwatson value = strtol(compartment, &end, 10); 671115395Srwatson if (compartment == end || *end != '\0') 672105696Srwatson return (EINVAL); 673115395Srwatson if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 674105696Srwatson return (EINVAL); 675115395Srwatson MAC_BIBA_BIT_SET(value, element->mbe_compartments); 676105696Srwatson } 677105696Srwatson } 678105696Srwatson 679105696Srwatson return (0); 680105696Srwatson} 681105696Srwatson 682105696Srwatson/* 683105696Srwatson * Note: destructively consumes the string, make a local copy before 684105696Srwatson * calling if that's a problem. 685105696Srwatson */ 686105696Srwatsonstatic int 687105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string) 688105696Srwatson{ 689115395Srwatson char *rangehigh, *rangelow, *single; 690101099Srwatson int error; 691101099Srwatson 692115395Srwatson single = strsep(&string, "("); 693115395Srwatson if (*single == '\0') 694105696Srwatson single = NULL; 695115395Srwatson 696115395Srwatson if (string != NULL) { 697115395Srwatson rangelow = strsep(&string, "-"); 698115395Srwatson if (string == NULL) 699105696Srwatson return (EINVAL); 700115395Srwatson rangehigh = strsep(&string, ")"); 701115395Srwatson if (string == NULL) 702105696Srwatson return (EINVAL); 703115395Srwatson if (*string != '\0') 704105696Srwatson return (EINVAL); 705115395Srwatson } else { 706115395Srwatson rangelow = NULL; 707115395Srwatson rangehigh = NULL; 708105696Srwatson } 709115395Srwatson 710105696Srwatson KASSERT((rangelow != NULL && rangehigh != NULL) || 711105696Srwatson (rangelow == NULL && rangehigh == NULL), 712115395Srwatson ("mac_biba_parse: range mismatch")); 713101099Srwatson 714105696Srwatson bzero(mac_biba, sizeof(*mac_biba)); 715105696Srwatson if (single != NULL) { 716105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_single, single); 717105696Srwatson if (error) 718105696Srwatson return (error); 719105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 720105696Srwatson } 721105696Srwatson 722105696Srwatson if (rangelow != NULL) { 723105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangelow, 724105696Srwatson rangelow); 725105696Srwatson if (error) 726105696Srwatson return (error); 727105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 728105696Srwatson rangehigh); 729105696Srwatson if (error) 730105696Srwatson return (error); 731105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 732105696Srwatson } 733105696Srwatson 734101099Srwatson error = mac_biba_valid(mac_biba); 735101099Srwatson if (error) 736101099Srwatson return (error); 737101099Srwatson 738105696Srwatson return (0); 739105696Srwatson} 740101099Srwatson 741105696Srwatsonstatic int 742105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name, 743105696Srwatson char *element_data, int *claimed) 744105696Srwatson{ 745105696Srwatson struct mac_biba *mac_biba, mac_biba_temp; 746105696Srwatson int error; 747105696Srwatson 748105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 749105696Srwatson return (0); 750105696Srwatson 751105696Srwatson (*claimed)++; 752105696Srwatson 753105696Srwatson error = mac_biba_parse(&mac_biba_temp, element_data); 754105696Srwatson if (error) 755105696Srwatson return (error); 756105696Srwatson 757105696Srwatson mac_biba = SLOT(label); 758105696Srwatson *mac_biba = mac_biba_temp; 759105696Srwatson 760101099Srwatson return (0); 761101099Srwatson} 762101099Srwatson 763105696Srwatsonstatic void 764105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest) 765105696Srwatson{ 766105696Srwatson 767105696Srwatson *SLOT(dest) = *SLOT(src); 768105696Srwatson} 769105696Srwatson 770101099Srwatson/* 771101099Srwatson * Labeling event operations: file system objects, and things that look 772101099Srwatson * a lot like file system objects. 773101099Srwatson */ 774101099Srwatsonstatic void 775107698Srwatsonmac_biba_create_devfs_device(struct mount *mp, dev_t dev, 776107698Srwatson struct devfs_dirent *devfs_dirent, struct label *label) 777101099Srwatson{ 778101099Srwatson struct mac_biba *mac_biba; 779101099Srwatson int biba_type; 780101099Srwatson 781101099Srwatson mac_biba = SLOT(label); 782101099Srwatson if (strcmp(dev->si_name, "null") == 0 || 783101099Srwatson strcmp(dev->si_name, "zero") == 0 || 784101099Srwatson strcmp(dev->si_name, "random") == 0 || 785101099Srwatson strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 786101099Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 787105606Srwatson else if (ptys_equal && 788105606Srwatson (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 789105606Srwatson strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 790105606Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 791101099Srwatson else 792101099Srwatson biba_type = MAC_BIBA_TYPE_HIGH; 793105643Srwatson mac_biba_set_single(mac_biba, biba_type, 0, NULL); 794101099Srwatson} 795101099Srwatson 796101099Srwatsonstatic void 797107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname, 798107698Srwatson int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 799101099Srwatson{ 800101099Srwatson struct mac_biba *mac_biba; 801101099Srwatson 802101099Srwatson mac_biba = SLOT(label); 803105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 804101099Srwatson} 805101099Srwatson 806101099Srwatsonstatic void 807107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp, 808107698Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 809122563Srwatson struct label *delabel) 810104535Srwatson{ 811104535Srwatson struct mac_biba *source, *dest; 812104535Srwatson 813122524Srwatson source = SLOT(cred->cr_label); 814104535Srwatson dest = SLOT(delabel); 815104535Srwatson 816104535Srwatson mac_biba_copy_single(source, dest); 817104535Srwatson} 818104535Srwatson 819104535Srwatsonstatic void 820101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp, 821101099Srwatson struct label *mntlabel, struct label *fslabel) 822101099Srwatson{ 823101099Srwatson struct mac_biba *source, *dest; 824101099Srwatson 825122524Srwatson source = SLOT(cred->cr_label); 826101099Srwatson dest = SLOT(mntlabel); 827101099Srwatson mac_biba_copy_single(source, dest); 828101099Srwatson dest = SLOT(fslabel); 829101099Srwatson mac_biba_copy_single(source, dest); 830101099Srwatson} 831101099Srwatson 832101099Srwatsonstatic void 833101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 834101099Srwatson struct label *mntlabel, struct label *fslabel) 835101099Srwatson{ 836101099Srwatson struct mac_biba *mac_biba; 837101099Srwatson 838101099Srwatson /* Always mount root as high integrity. */ 839101099Srwatson mac_biba = SLOT(fslabel); 840105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 841101099Srwatson mac_biba = SLOT(mntlabel); 842105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 843101099Srwatson} 844101099Srwatson 845101099Srwatsonstatic void 846101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 847101099Srwatson struct label *vnodelabel, struct label *label) 848101099Srwatson{ 849101099Srwatson struct mac_biba *source, *dest; 850101099Srwatson 851101099Srwatson source = SLOT(label); 852101099Srwatson dest = SLOT(vnodelabel); 853101099Srwatson 854105656Srwatson mac_biba_copy(source, dest); 855101099Srwatson} 856101099Srwatson 857101099Srwatsonstatic void 858107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp, 859107698Srwatson struct devfs_dirent *devfs_dirent, struct label *direntlabel, 860107698Srwatson struct vnode *vp, struct label *vnodelabel) 861101099Srwatson{ 862101099Srwatson struct mac_biba *source, *dest; 863101099Srwatson 864101099Srwatson source = SLOT(vnodelabel); 865101099Srwatson dest = SLOT(direntlabel); 866101099Srwatson 867105656Srwatson mac_biba_copy(source, dest); 868101099Srwatson} 869101099Srwatson 870101099Srwatsonstatic void 871105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 872105988Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 873105988Srwatson struct label *vlabel) 874101099Srwatson{ 875101099Srwatson struct mac_biba *source, *dest; 876101099Srwatson 877105988Srwatson source = SLOT(delabel); 878105988Srwatson dest = SLOT(vlabel); 879101099Srwatson 880101099Srwatson mac_biba_copy_single(source, dest); 881101099Srwatson} 882101099Srwatson 883101099Srwatsonstatic int 884105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 885105988Srwatson struct vnode *vp, struct label *vlabel) 886101099Srwatson{ 887105988Srwatson struct mac_biba temp, *source, *dest; 888106354Smux int buflen, error; 889101099Srwatson 890105988Srwatson source = SLOT(fslabel); 891105988Srwatson dest = SLOT(vlabel); 892101099Srwatson 893105988Srwatson buflen = sizeof(temp); 894105988Srwatson bzero(&temp, buflen); 895105988Srwatson 896105988Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 897105988Srwatson MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 898105988Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 899105988Srwatson /* Fall back to the fslabel. */ 900105988Srwatson mac_biba_copy_single(source, dest); 901105988Srwatson return (0); 902105988Srwatson } else if (error) 903101099Srwatson return (error); 904101099Srwatson 905105988Srwatson if (buflen != sizeof(temp)) { 906105988Srwatson printf("mac_biba_associate_vnode_extattr: bad size %d\n", 907105988Srwatson buflen); 908105988Srwatson return (EPERM); 909105988Srwatson } 910105988Srwatson if (mac_biba_valid(&temp) != 0) { 911105988Srwatson printf("mac_biba_associate_vnode_extattr: invalid\n"); 912105988Srwatson return (EPERM); 913105988Srwatson } 914105988Srwatson if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 915105988Srwatson printf("mac_biba_associate_vnode_extattr: not single\n"); 916105988Srwatson return (EPERM); 917105988Srwatson } 918101099Srwatson 919105988Srwatson mac_biba_copy_single(&temp, dest); 920101099Srwatson return (0); 921101099Srwatson} 922101099Srwatson 923101099Srwatsonstatic void 924105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp, 925105988Srwatson struct label *fslabel, struct vnode *vp, struct label *vlabel) 926101099Srwatson{ 927101099Srwatson struct mac_biba *source, *dest; 928101099Srwatson 929101099Srwatson source = SLOT(fslabel); 930105988Srwatson dest = SLOT(vlabel); 931101099Srwatson 932101099Srwatson mac_biba_copy_single(source, dest); 933101099Srwatson} 934101099Srwatson 935105988Srwatsonstatic int 936105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 937105988Srwatson struct label *fslabel, struct vnode *dvp, struct label *dlabel, 938105988Srwatson struct vnode *vp, struct label *vlabel, struct componentname *cnp) 939105988Srwatson{ 940105988Srwatson struct mac_biba *source, *dest, temp; 941105988Srwatson size_t buflen; 942105988Srwatson int error; 943105988Srwatson 944105988Srwatson buflen = sizeof(temp); 945105988Srwatson bzero(&temp, buflen); 946105988Srwatson 947122524Srwatson source = SLOT(cred->cr_label); 948105988Srwatson dest = SLOT(vlabel); 949105988Srwatson mac_biba_copy_single(source, &temp); 950105988Srwatson 951105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 952105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 953105988Srwatson if (error == 0) 954105988Srwatson mac_biba_copy_single(source, dest); 955105988Srwatson return (error); 956105988Srwatson} 957105988Srwatson 958105988Srwatsonstatic int 959105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 960105988Srwatson struct label *vlabel, struct label *intlabel) 961105988Srwatson{ 962105988Srwatson struct mac_biba *source, temp; 963105988Srwatson size_t buflen; 964105988Srwatson int error; 965105988Srwatson 966105988Srwatson buflen = sizeof(temp); 967105988Srwatson bzero(&temp, buflen); 968105988Srwatson 969105988Srwatson source = SLOT(intlabel); 970105988Srwatson if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 971105988Srwatson return (0); 972105988Srwatson 973105988Srwatson mac_biba_copy_single(source, &temp); 974105988Srwatson 975105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 976105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 977105988Srwatson return (error); 978105988Srwatson} 979105988Srwatson 980101099Srwatson/* 981101099Srwatson * Labeling event operations: IPC object. 982101099Srwatson */ 983101099Srwatsonstatic void 984122875Srwatsonmac_biba_create_inpcb_from_socket(struct socket *so, struct label *solabel, 985122875Srwatson struct inpcb *inp, struct label *inplabel) 986122875Srwatson{ 987122875Srwatson struct mac_biba *source, *dest; 988122875Srwatson 989122875Srwatson source = SLOT(solabel); 990122875Srwatson dest = SLOT(inplabel); 991122875Srwatson 992122875Srwatson mac_biba_copy_single(source, dest); 993122875Srwatson} 994122875Srwatson 995122875Srwatsonstatic void 996101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 997101099Srwatson struct mbuf *m, struct label *mbuflabel) 998101099Srwatson{ 999101099Srwatson struct mac_biba *source, *dest; 1000101099Srwatson 1001101099Srwatson source = SLOT(socketlabel); 1002101099Srwatson dest = SLOT(mbuflabel); 1003101099Srwatson 1004101099Srwatson mac_biba_copy_single(source, dest); 1005101099Srwatson} 1006101099Srwatson 1007101099Srwatsonstatic void 1008101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket, 1009101099Srwatson struct label *socketlabel) 1010101099Srwatson{ 1011101099Srwatson struct mac_biba *source, *dest; 1012101099Srwatson 1013122524Srwatson source = SLOT(cred->cr_label); 1014101099Srwatson dest = SLOT(socketlabel); 1015101099Srwatson 1016101099Srwatson mac_biba_copy_single(source, dest); 1017101099Srwatson} 1018101099Srwatson 1019101099Srwatsonstatic void 1020101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1021101099Srwatson struct label *pipelabel) 1022101099Srwatson{ 1023101099Srwatson struct mac_biba *source, *dest; 1024101099Srwatson 1025122524Srwatson source = SLOT(cred->cr_label); 1026101099Srwatson dest = SLOT(pipelabel); 1027101099Srwatson 1028101099Srwatson mac_biba_copy_single(source, dest); 1029101099Srwatson} 1030101099Srwatson 1031101099Srwatsonstatic void 1032101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket, 1033101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1034101099Srwatson struct label *newsocketlabel) 1035101099Srwatson{ 1036101099Srwatson struct mac_biba *source, *dest; 1037101099Srwatson 1038101099Srwatson source = SLOT(oldsocketlabel); 1039101099Srwatson dest = SLOT(newsocketlabel); 1040101099Srwatson 1041101099Srwatson mac_biba_copy_single(source, dest); 1042101099Srwatson} 1043101099Srwatson 1044101099Srwatsonstatic void 1045101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1046101099Srwatson struct label *socketlabel, struct label *newlabel) 1047101099Srwatson{ 1048101099Srwatson struct mac_biba *source, *dest; 1049101099Srwatson 1050101099Srwatson source = SLOT(newlabel); 1051101099Srwatson dest = SLOT(socketlabel); 1052101099Srwatson 1053105656Srwatson mac_biba_copy(source, dest); 1054101099Srwatson} 1055101099Srwatson 1056101099Srwatsonstatic void 1057101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1058101099Srwatson struct label *pipelabel, struct label *newlabel) 1059101099Srwatson{ 1060101099Srwatson struct mac_biba *source, *dest; 1061101099Srwatson 1062101099Srwatson source = SLOT(newlabel); 1063101099Srwatson dest = SLOT(pipelabel); 1064101099Srwatson 1065105656Srwatson mac_biba_copy(source, dest); 1066101099Srwatson} 1067101099Srwatson 1068101099Srwatsonstatic void 1069101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1070101099Srwatson struct socket *socket, struct label *socketpeerlabel) 1071101099Srwatson{ 1072101099Srwatson struct mac_biba *source, *dest; 1073101099Srwatson 1074101099Srwatson source = SLOT(mbuflabel); 1075101099Srwatson dest = SLOT(socketpeerlabel); 1076101099Srwatson 1077101099Srwatson mac_biba_copy_single(source, dest); 1078101099Srwatson} 1079101099Srwatson 1080101099Srwatson/* 1081101099Srwatson * Labeling event operations: network objects. 1082101099Srwatson */ 1083101099Srwatsonstatic void 1084101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1085101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1086101099Srwatson struct label *newsocketpeerlabel) 1087101099Srwatson{ 1088101099Srwatson struct mac_biba *source, *dest; 1089101099Srwatson 1090101099Srwatson source = SLOT(oldsocketlabel); 1091101099Srwatson dest = SLOT(newsocketpeerlabel); 1092101099Srwatson 1093101099Srwatson mac_biba_copy_single(source, dest); 1094101099Srwatson} 1095101099Srwatson 1096101099Srwatsonstatic void 1097101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1098101099Srwatson struct label *bpflabel) 1099101099Srwatson{ 1100101099Srwatson struct mac_biba *source, *dest; 1101101099Srwatson 1102122524Srwatson source = SLOT(cred->cr_label); 1103101099Srwatson dest = SLOT(bpflabel); 1104101099Srwatson 1105101099Srwatson mac_biba_copy_single(source, dest); 1106101099Srwatson} 1107101099Srwatson 1108101099Srwatsonstatic void 1109101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1110101099Srwatson{ 1111121816Sbrooks char tifname[IFNAMSIZ], *p, *q; 1112101099Srwatson char tiflist[sizeof(trusted_interfaces)]; 1113101099Srwatson struct mac_biba *dest; 1114110350Srwatson int len, type; 1115101099Srwatson 1116101099Srwatson dest = SLOT(ifnetlabel); 1117101099Srwatson 1118101099Srwatson if (ifnet->if_type == IFT_LOOP) { 1119110350Srwatson type = MAC_BIBA_TYPE_EQUAL; 1120101099Srwatson goto set; 1121101099Srwatson } 1122101099Srwatson 1123101099Srwatson if (trust_all_interfaces) { 1124110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1125101099Srwatson goto set; 1126101099Srwatson } 1127101099Srwatson 1128110350Srwatson type = MAC_BIBA_TYPE_LOW; 1129101099Srwatson 1130101099Srwatson if (trusted_interfaces[0] == '\0' || 1131101099Srwatson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1132101099Srwatson goto set; 1133101099Srwatson 1134106089Srwatson bzero(tiflist, sizeof(tiflist)); 1135101099Srwatson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1136101099Srwatson if(*p != ' ' && *p != '\t') 1137101099Srwatson *q = *p; 1138101099Srwatson 1139101099Srwatson for (p = q = tiflist;; p++) { 1140101099Srwatson if (*p == ',' || *p == '\0') { 1141101099Srwatson len = p - q; 1142101099Srwatson if (len < IFNAMSIZ) { 1143101099Srwatson bzero(tifname, sizeof(tifname)); 1144101099Srwatson bcopy(q, tifname, len); 1145121816Sbrooks if (strcmp(tifname, ifnet->if_xname) == 0) { 1146110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1147101099Srwatson break; 1148101099Srwatson } 1149106089Srwatson } else { 1150106089Srwatson *p = '\0'; 1151106089Srwatson printf("mac_biba warning: interface name " 1152106089Srwatson "\"%s\" is too long (must be < %d)\n", 1153106089Srwatson q, IFNAMSIZ); 1154101099Srwatson } 1155101099Srwatson if (*p == '\0') 1156101099Srwatson break; 1157101099Srwatson q = p + 1; 1158101099Srwatson } 1159101099Srwatson } 1160101099Srwatsonset: 1161110350Srwatson mac_biba_set_single(dest, type, 0, NULL); 1162110350Srwatson mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1163101099Srwatson} 1164101099Srwatson 1165101099Srwatsonstatic void 1166101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1167101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1168101099Srwatson{ 1169101099Srwatson struct mac_biba *source, *dest; 1170101099Srwatson 1171101099Srwatson source = SLOT(fragmentlabel); 1172101099Srwatson dest = SLOT(ipqlabel); 1173101099Srwatson 1174101099Srwatson mac_biba_copy_single(source, dest); 1175101099Srwatson} 1176101099Srwatson 1177101099Srwatsonstatic void 1178101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1179101099Srwatson struct mbuf *datagram, struct label *datagramlabel) 1180101099Srwatson{ 1181101099Srwatson struct mac_biba *source, *dest; 1182101099Srwatson 1183101099Srwatson source = SLOT(ipqlabel); 1184101099Srwatson dest = SLOT(datagramlabel); 1185101099Srwatson 1186101099Srwatson /* Just use the head, since we require them all to match. */ 1187101099Srwatson mac_biba_copy_single(source, dest); 1188101099Srwatson} 1189101099Srwatson 1190101099Srwatsonstatic void 1191101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1192101099Srwatson struct mbuf *fragment, struct label *fragmentlabel) 1193101099Srwatson{ 1194101099Srwatson struct mac_biba *source, *dest; 1195101099Srwatson 1196101099Srwatson source = SLOT(datagramlabel); 1197101099Srwatson dest = SLOT(fragmentlabel); 1198101099Srwatson 1199101099Srwatson mac_biba_copy_single(source, dest); 1200101099Srwatson} 1201101099Srwatson 1202101099Srwatsonstatic void 1203101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1204101099Srwatson struct label *oldmbuflabel, struct mbuf *newmbuf, 1205101099Srwatson struct label *newmbuflabel) 1206101099Srwatson{ 1207101099Srwatson struct mac_biba *source, *dest; 1208101099Srwatson 1209101099Srwatson source = SLOT(oldmbuflabel); 1210101099Srwatson dest = SLOT(newmbuflabel); 1211101099Srwatson 1212105656Srwatson /* 1213105656Srwatson * Because the source mbuf may not yet have been "created", 1214105696Srwatson * just initialized, we do a conditional copy. Since we don't 1215105656Srwatson * allow mbufs to have ranges, do a KASSERT to make sure that 1216105656Srwatson * doesn't happen. 1217105656Srwatson */ 1218105656Srwatson KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1219105656Srwatson ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1220105656Srwatson mac_biba_copy(source, dest); 1221101099Srwatson} 1222101099Srwatson 1223101099Srwatsonstatic void 1224101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1225101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1226101099Srwatson{ 1227101099Srwatson struct mac_biba *dest; 1228101099Srwatson 1229101099Srwatson dest = SLOT(mbuflabel); 1230101099Srwatson 1231105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1232101099Srwatson} 1233101099Srwatson 1234101099Srwatsonstatic void 1235101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1236101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1237101099Srwatson{ 1238101099Srwatson struct mac_biba *source, *dest; 1239101099Srwatson 1240101099Srwatson source = SLOT(bpflabel); 1241101099Srwatson dest = SLOT(mbuflabel); 1242101099Srwatson 1243101099Srwatson mac_biba_copy_single(source, dest); 1244101099Srwatson} 1245101099Srwatson 1246101099Srwatsonstatic void 1247101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1248101099Srwatson struct mbuf *m, struct label *mbuflabel) 1249101099Srwatson{ 1250101099Srwatson struct mac_biba *source, *dest; 1251101099Srwatson 1252101099Srwatson source = SLOT(ifnetlabel); 1253101099Srwatson dest = SLOT(mbuflabel); 1254101099Srwatson 1255101099Srwatson mac_biba_copy_single(source, dest); 1256101099Srwatson} 1257101099Srwatson 1258101099Srwatsonstatic void 1259101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1260101099Srwatson struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1261101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1262101099Srwatson{ 1263101099Srwatson struct mac_biba *source, *dest; 1264101099Srwatson 1265101099Srwatson source = SLOT(oldmbuflabel); 1266101099Srwatson dest = SLOT(newmbuflabel); 1267101099Srwatson 1268101099Srwatson mac_biba_copy_single(source, dest); 1269101099Srwatson} 1270101099Srwatson 1271101099Srwatsonstatic void 1272101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1273101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1274101099Srwatson{ 1275101099Srwatson struct mac_biba *source, *dest; 1276101099Srwatson 1277101099Srwatson source = SLOT(oldmbuflabel); 1278101099Srwatson dest = SLOT(newmbuflabel); 1279101099Srwatson 1280101099Srwatson mac_biba_copy_single(source, dest); 1281101099Srwatson} 1282101099Srwatson 1283101099Srwatsonstatic int 1284101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1285101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1286101099Srwatson{ 1287101099Srwatson struct mac_biba *a, *b; 1288101099Srwatson 1289101099Srwatson a = SLOT(ipqlabel); 1290101099Srwatson b = SLOT(fragmentlabel); 1291101099Srwatson 1292101099Srwatson return (mac_biba_equal_single(a, b)); 1293101099Srwatson} 1294101099Srwatson 1295101099Srwatsonstatic void 1296101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1297101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1298101099Srwatson{ 1299101099Srwatson struct mac_biba *source, *dest; 1300101099Srwatson 1301101099Srwatson source = SLOT(newlabel); 1302101099Srwatson dest = SLOT(ifnetlabel); 1303101099Srwatson 1304105656Srwatson mac_biba_copy(source, dest); 1305101099Srwatson} 1306101099Srwatson 1307101099Srwatsonstatic void 1308101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1309101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1310101099Srwatson{ 1311101099Srwatson 1312101099Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1313101099Srwatson} 1314101099Srwatson 1315122875Srwatsonstatic void 1316122875Srwatsonmac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1317122875Srwatson struct inpcb *inp, struct label *inplabel) 1318122875Srwatson{ 1319122875Srwatson struct mac_biba *source, *dest; 1320122875Srwatson 1321122875Srwatson source = SLOT(solabel); 1322122875Srwatson dest = SLOT(inplabel); 1323122875Srwatson 1324122875Srwatson mac_biba_copy(source, dest); 1325122875Srwatson} 1326122875Srwatson 1327101099Srwatson/* 1328101099Srwatson * Labeling event operations: processes. 1329101099Srwatson */ 1330101099Srwatsonstatic void 1331101099Srwatsonmac_biba_create_proc0(struct ucred *cred) 1332101099Srwatson{ 1333101099Srwatson struct mac_biba *dest; 1334101099Srwatson 1335122524Srwatson dest = SLOT(cred->cr_label); 1336101099Srwatson 1337105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1338105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1339105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1340101099Srwatson} 1341101099Srwatson 1342101099Srwatsonstatic void 1343101099Srwatsonmac_biba_create_proc1(struct ucred *cred) 1344101099Srwatson{ 1345101099Srwatson struct mac_biba *dest; 1346101099Srwatson 1347122524Srwatson dest = SLOT(cred->cr_label); 1348101099Srwatson 1349105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1350105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1351105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1352101099Srwatson} 1353101099Srwatson 1354101099Srwatsonstatic void 1355101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1356101099Srwatson{ 1357101099Srwatson struct mac_biba *source, *dest; 1358101099Srwatson 1359101099Srwatson source = SLOT(newlabel); 1360122524Srwatson dest = SLOT(cred->cr_label); 1361101099Srwatson 1362105656Srwatson mac_biba_copy(source, dest); 1363101099Srwatson} 1364101099Srwatson 1365101099Srwatson/* 1366101099Srwatson * Access control checks. 1367101099Srwatson */ 1368101099Srwatsonstatic int 1369101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1370101099Srwatson struct ifnet *ifnet, struct label *ifnetlabel) 1371101099Srwatson{ 1372101099Srwatson struct mac_biba *a, *b; 1373101099Srwatson 1374101099Srwatson if (!mac_biba_enabled) 1375101099Srwatson return (0); 1376101099Srwatson 1377101099Srwatson a = SLOT(bpflabel); 1378101099Srwatson b = SLOT(ifnetlabel); 1379101099Srwatson 1380101099Srwatson if (mac_biba_equal_single(a, b)) 1381101099Srwatson return (0); 1382101099Srwatson return (EACCES); 1383101099Srwatson} 1384101099Srwatson 1385101099Srwatsonstatic int 1386101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1387101099Srwatson{ 1388101099Srwatson struct mac_biba *subj, *new; 1389105634Srwatson int error; 1390101099Srwatson 1391122524Srwatson subj = SLOT(cred->cr_label); 1392101099Srwatson new = SLOT(newlabel); 1393101099Srwatson 1394101099Srwatson /* 1395105634Srwatson * If there is a Biba label update for the credential, it may 1396105634Srwatson * be an update of the single, range, or both. 1397101099Srwatson */ 1398105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1399105634Srwatson if (error) 1400105634Srwatson return (error); 1401101099Srwatson 1402101099Srwatson /* 1403105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1404101099Srwatson */ 1405105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1406105634Srwatson /* 1407110351Srwatson * If the change request modifies both the Biba label 1408110351Srwatson * single and range, check that the new single will be 1409110351Srwatson * in the new range. 1410110351Srwatson */ 1411110351Srwatson if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1412110351Srwatson MAC_BIBA_FLAGS_BOTH && 1413110351Srwatson !mac_biba_single_in_range(new, new)) 1414110351Srwatson return (EINVAL); 1415110351Srwatson 1416110351Srwatson /* 1417105634Srwatson * To change the Biba single label on a credential, the 1418105634Srwatson * new single label must be in the current range. 1419105634Srwatson */ 1420105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1421105634Srwatson !mac_biba_single_in_range(new, subj)) 1422105634Srwatson return (EPERM); 1423101099Srwatson 1424105634Srwatson /* 1425105634Srwatson * To change the Biba range on a credential, the new 1426105634Srwatson * range label must be in the current range. 1427105634Srwatson */ 1428105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1429105634Srwatson !mac_biba_range_in_range(new, subj)) 1430105634Srwatson return (EPERM); 1431101099Srwatson 1432105634Srwatson /* 1433105634Srwatson * To have EQUAL in any component of the new credential 1434105634Srwatson * Biba label, the subject must already have EQUAL in 1435105634Srwatson * their label. 1436105634Srwatson */ 1437105634Srwatson if (mac_biba_contains_equal(new)) { 1438106090Srwatson error = mac_biba_subject_privileged(subj); 1439105634Srwatson if (error) 1440105634Srwatson return (error); 1441105634Srwatson } 1442105634Srwatson } 1443105634Srwatson 1444101099Srwatson return (0); 1445101099Srwatson} 1446101099Srwatson 1447101099Srwatsonstatic int 1448101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1449101099Srwatson{ 1450101099Srwatson struct mac_biba *subj, *obj; 1451101099Srwatson 1452101099Srwatson if (!mac_biba_enabled) 1453101099Srwatson return (0); 1454101099Srwatson 1455122524Srwatson subj = SLOT(u1->cr_label); 1456122524Srwatson obj = SLOT(u2->cr_label); 1457101099Srwatson 1458101099Srwatson /* XXX: range */ 1459101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1460101099Srwatson return (ESRCH); 1461101099Srwatson 1462101099Srwatson return (0); 1463101099Srwatson} 1464101099Srwatson 1465101099Srwatsonstatic int 1466101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1467101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1468101099Srwatson{ 1469101099Srwatson struct mac_biba *subj, *new; 1470105634Srwatson int error; 1471101099Srwatson 1472122524Srwatson subj = SLOT(cred->cr_label); 1473101099Srwatson new = SLOT(newlabel); 1474101099Srwatson 1475105634Srwatson /* 1476105634Srwatson * If there is a Biba label update for the interface, it may 1477105634Srwatson * be an update of the single, range, or both. 1478105634Srwatson */ 1479105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1480105634Srwatson if (error) 1481105634Srwatson return (error); 1482101099Srwatson 1483105634Srwatson /* 1484106160Srwatson * Relabling network interfaces requires Biba privilege. 1485106160Srwatson */ 1486106160Srwatson error = mac_biba_subject_privileged(subj); 1487106160Srwatson if (error) 1488106160Srwatson return (error); 1489106160Srwatson 1490105634Srwatson return (0); 1491101099Srwatson} 1492101099Srwatson 1493103759Srwatsonstatic int 1494101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1495101099Srwatson struct mbuf *m, struct label *mbuflabel) 1496101099Srwatson{ 1497101099Srwatson struct mac_biba *p, *i; 1498103761Srwatson 1499101099Srwatson if (!mac_biba_enabled) 1500101099Srwatson return (0); 1501101099Srwatson 1502101099Srwatson p = SLOT(mbuflabel); 1503101099Srwatson i = SLOT(ifnetlabel); 1504103759Srwatson 1505101099Srwatson return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1506101099Srwatson} 1507101099Srwatson 1508101099Srwatsonstatic int 1509122875Srwatsonmac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1510122875Srwatson struct mbuf *m, struct label *mlabel) 1511122875Srwatson{ 1512122875Srwatson struct mac_biba *p, *i; 1513122875Srwatson 1514122875Srwatson if (!mac_biba_enabled) 1515122875Srwatson return (0); 1516122875Srwatson 1517122875Srwatson p = SLOT(mlabel); 1518122875Srwatson i = SLOT(inplabel); 1519122875Srwatson 1520122875Srwatson return (mac_biba_equal_single(p, i) ? 0 : EACCES); 1521122875Srwatson} 1522122875Srwatson 1523122875Srwatsonstatic int 1524110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1525110354Srwatson struct label *label) 1526110354Srwatson{ 1527110354Srwatson struct mac_biba *subj, *obj; 1528110354Srwatson int error; 1529110354Srwatson 1530110354Srwatson if (!mac_biba_enabled) 1531110354Srwatson return (0); 1532110354Srwatson 1533122524Srwatson subj = SLOT(cred->cr_label); 1534110354Srwatson 1535110354Srwatson error = mac_biba_subject_privileged(subj); 1536110354Srwatson if (error) 1537110354Srwatson return (error); 1538110354Srwatson 1539110354Srwatson obj = SLOT(label); 1540110354Srwatson if (!mac_biba_high_single(obj)) 1541110354Srwatson return (EACCES); 1542110354Srwatson 1543110354Srwatson return (0); 1544110354Srwatson} 1545110354Srwatson 1546110354Srwatson 1547110354Srwatsonstatic int 1548110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred) 1549110354Srwatson{ 1550110354Srwatson struct mac_biba *subj; 1551110354Srwatson 1552110354Srwatson if (!mac_biba_enabled) 1553110354Srwatson return (0); 1554110354Srwatson 1555122524Srwatson subj = SLOT(cred->cr_label); 1556110354Srwatson 1557110354Srwatson return (mac_biba_subject_privileged(subj)); 1558110354Srwatson} 1559110354Srwatson 1560110354Srwatsonstatic int 1561101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1562101099Srwatson struct label *mntlabel) 1563101099Srwatson{ 1564101099Srwatson struct mac_biba *subj, *obj; 1565101099Srwatson 1566101099Srwatson if (!mac_biba_enabled) 1567101099Srwatson return (0); 1568101099Srwatson 1569122524Srwatson subj = SLOT(cred->cr_label); 1570101099Srwatson obj = SLOT(mntlabel); 1571101099Srwatson 1572101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1573101099Srwatson return (EACCES); 1574101099Srwatson 1575101099Srwatson return (0); 1576101099Srwatson} 1577101099Srwatson 1578101099Srwatsonstatic int 1579101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1580101099Srwatson struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1581101099Srwatson{ 1582103759Srwatson 1583101099Srwatson if(!mac_biba_enabled) 1584101099Srwatson return (0); 1585101099Srwatson 1586101099Srwatson /* XXX: This will be implemented soon... */ 1587101099Srwatson 1588101099Srwatson return (0); 1589101099Srwatson} 1590101099Srwatson 1591101099Srwatsonstatic int 1592102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1593102115Srwatson struct label *pipelabel) 1594101099Srwatson{ 1595101099Srwatson struct mac_biba *subj, *obj; 1596101099Srwatson 1597101099Srwatson if (!mac_biba_enabled) 1598101099Srwatson return (0); 1599101099Srwatson 1600122524Srwatson subj = SLOT(cred->cr_label); 1601101099Srwatson obj = SLOT((pipelabel)); 1602101099Srwatson 1603102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1604102115Srwatson return (EACCES); 1605101099Srwatson 1606101099Srwatson return (0); 1607101099Srwatson} 1608101099Srwatson 1609101099Srwatsonstatic int 1610102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1611102115Srwatson struct label *pipelabel) 1612102115Srwatson{ 1613102115Srwatson struct mac_biba *subj, *obj; 1614102115Srwatson 1615102115Srwatson if (!mac_biba_enabled) 1616102115Srwatson return (0); 1617102115Srwatson 1618122524Srwatson subj = SLOT(cred->cr_label); 1619102115Srwatson obj = SLOT((pipelabel)); 1620102115Srwatson 1621102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1622102115Srwatson return (EACCES); 1623102115Srwatson 1624102115Srwatson return (0); 1625102115Srwatson} 1626102115Srwatson 1627102115Srwatsonstatic int 1628101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1629101099Srwatson struct label *pipelabel, struct label *newlabel) 1630101099Srwatson{ 1631101099Srwatson struct mac_biba *subj, *obj, *new; 1632105634Srwatson int error; 1633101099Srwatson 1634101099Srwatson new = SLOT(newlabel); 1635122524Srwatson subj = SLOT(cred->cr_label); 1636101099Srwatson obj = SLOT(pipelabel); 1637101099Srwatson 1638101099Srwatson /* 1639105634Srwatson * If there is a Biba label update for a pipe, it must be a 1640105634Srwatson * single update. 1641101099Srwatson */ 1642105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1643105634Srwatson if (error) 1644105634Srwatson return (error); 1645101099Srwatson 1646101099Srwatson /* 1647105634Srwatson * To perform a relabel of a pipe (Biba label or not), Biba must 1648105634Srwatson * authorize the relabel. 1649101099Srwatson */ 1650105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1651101099Srwatson return (EPERM); 1652101099Srwatson 1653101099Srwatson /* 1654105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1655101099Srwatson */ 1656105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1657105634Srwatson /* 1658105634Srwatson * To change the Biba label on a pipe, the new pipe label 1659105634Srwatson * must be in the subject range. 1660105634Srwatson */ 1661105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1662105634Srwatson return (EPERM); 1663101099Srwatson 1664105634Srwatson /* 1665105634Srwatson * To change the Biba label on a pipe to be EQUAL, the 1666105634Srwatson * subject must have appropriate privilege. 1667105634Srwatson */ 1668105634Srwatson if (mac_biba_contains_equal(new)) { 1669106090Srwatson error = mac_biba_subject_privileged(subj); 1670105634Srwatson if (error) 1671105634Srwatson return (error); 1672105634Srwatson } 1673105634Srwatson } 1674105634Srwatson 1675101099Srwatson return (0); 1676101099Srwatson} 1677101099Srwatson 1678101099Srwatsonstatic int 1679102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1680102115Srwatson struct label *pipelabel) 1681102115Srwatson{ 1682102115Srwatson struct mac_biba *subj, *obj; 1683102115Srwatson 1684102115Srwatson if (!mac_biba_enabled) 1685102115Srwatson return (0); 1686102115Srwatson 1687122524Srwatson subj = SLOT(cred->cr_label); 1688102115Srwatson obj = SLOT((pipelabel)); 1689102115Srwatson 1690102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1691102115Srwatson return (EACCES); 1692102115Srwatson 1693102115Srwatson return (0); 1694102115Srwatson} 1695102115Srwatson 1696102115Srwatsonstatic int 1697102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1698102115Srwatson struct label *pipelabel) 1699102115Srwatson{ 1700102115Srwatson struct mac_biba *subj, *obj; 1701102115Srwatson 1702102115Srwatson if (!mac_biba_enabled) 1703102115Srwatson return (0); 1704102115Srwatson 1705122524Srwatson subj = SLOT(cred->cr_label); 1706102115Srwatson obj = SLOT((pipelabel)); 1707102115Srwatson 1708102115Srwatson if (!mac_biba_dominate_single(subj, obj)) 1709102115Srwatson return (EACCES); 1710102115Srwatson 1711102115Srwatson return (0); 1712102115Srwatson} 1713102115Srwatson 1714102115Srwatsonstatic int 1715101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1716101099Srwatson{ 1717101099Srwatson struct mac_biba *subj, *obj; 1718101099Srwatson 1719101099Srwatson if (!mac_biba_enabled) 1720101099Srwatson return (0); 1721101099Srwatson 1722122524Srwatson subj = SLOT(cred->cr_label); 1723122524Srwatson obj = SLOT(proc->p_ucred->cr_label); 1724101099Srwatson 1725101099Srwatson /* XXX: range checks */ 1726101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1727101099Srwatson return (ESRCH); 1728101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1729101099Srwatson return (EACCES); 1730101099Srwatson 1731101099Srwatson return (0); 1732101099Srwatson} 1733101099Srwatson 1734101099Srwatsonstatic int 1735101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1736101099Srwatson{ 1737101099Srwatson struct mac_biba *subj, *obj; 1738103759Srwatson 1739101099Srwatson if (!mac_biba_enabled) 1740101099Srwatson return (0); 1741101099Srwatson 1742122524Srwatson subj = SLOT(cred->cr_label); 1743122524Srwatson obj = SLOT(proc->p_ucred->cr_label); 1744103759Srwatson 1745101099Srwatson /* XXX: range checks */ 1746101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1747101099Srwatson return (ESRCH); 1748101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1749101099Srwatson return (EACCES); 1750101099Srwatson 1751101099Srwatson return (0); 1752101099Srwatson} 1753101099Srwatson 1754101099Srwatsonstatic int 1755101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1756101099Srwatson{ 1757101099Srwatson struct mac_biba *subj, *obj; 1758103759Srwatson 1759101099Srwatson if (!mac_biba_enabled) 1760101099Srwatson return (0); 1761101099Srwatson 1762122524Srwatson subj = SLOT(cred->cr_label); 1763122524Srwatson obj = SLOT(proc->p_ucred->cr_label); 1764103759Srwatson 1765101099Srwatson /* XXX: range checks */ 1766101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1767101099Srwatson return (ESRCH); 1768101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1769101099Srwatson return (EACCES); 1770101099Srwatson 1771101099Srwatson return (0); 1772101099Srwatson} 1773101099Srwatson 1774101099Srwatsonstatic int 1775101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1776101099Srwatson struct mbuf *m, struct label *mbuflabel) 1777101099Srwatson{ 1778101099Srwatson struct mac_biba *p, *s; 1779101099Srwatson 1780101099Srwatson if (!mac_biba_enabled) 1781101099Srwatson return (0); 1782101099Srwatson 1783101099Srwatson p = SLOT(mbuflabel); 1784101099Srwatson s = SLOT(socketlabel); 1785101099Srwatson 1786101099Srwatson return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1787101099Srwatson} 1788101099Srwatson 1789101099Srwatsonstatic int 1790106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1791101099Srwatson struct label *socketlabel, struct label *newlabel) 1792101099Srwatson{ 1793101099Srwatson struct mac_biba *subj, *obj, *new; 1794105634Srwatson int error; 1795101099Srwatson 1796101099Srwatson new = SLOT(newlabel); 1797122524Srwatson subj = SLOT(cred->cr_label); 1798101099Srwatson obj = SLOT(socketlabel); 1799101099Srwatson 1800101099Srwatson /* 1801105634Srwatson * If there is a Biba label update for the socket, it may be 1802105634Srwatson * an update of single. 1803101099Srwatson */ 1804105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1805105634Srwatson if (error) 1806105634Srwatson return (error); 1807101099Srwatson 1808101099Srwatson /* 1809105634Srwatson * To relabel a socket, the old socket single must be in the subject 1810101099Srwatson * range. 1811101099Srwatson */ 1812105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1813101099Srwatson return (EPERM); 1814101099Srwatson 1815101099Srwatson /* 1816105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1817101099Srwatson */ 1818105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1819105634Srwatson /* 1820105634Srwatson * To relabel a socket, the new socket single must be in 1821105634Srwatson * the subject range. 1822105634Srwatson */ 1823105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1824105634Srwatson return (EPERM); 1825101099Srwatson 1826105634Srwatson /* 1827105634Srwatson * To change the Biba label on the socket to contain EQUAL, 1828105634Srwatson * the subject must have appropriate privilege. 1829105634Srwatson */ 1830105634Srwatson if (mac_biba_contains_equal(new)) { 1831106090Srwatson error = mac_biba_subject_privileged(subj); 1832105634Srwatson if (error) 1833105634Srwatson return (error); 1834105634Srwatson } 1835105634Srwatson } 1836105634Srwatson 1837101099Srwatson return (0); 1838101099Srwatson} 1839101099Srwatson 1840101099Srwatsonstatic int 1841101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1842101099Srwatson struct label *socketlabel) 1843101099Srwatson{ 1844101099Srwatson struct mac_biba *subj, *obj; 1845101099Srwatson 1846105722Srwatson if (!mac_biba_enabled) 1847105722Srwatson return (0); 1848105722Srwatson 1849122524Srwatson subj = SLOT(cred->cr_label); 1850101099Srwatson obj = SLOT(socketlabel); 1851101099Srwatson 1852101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1853101099Srwatson return (ENOENT); 1854101099Srwatson 1855101099Srwatson return (0); 1856101099Srwatson} 1857101099Srwatson 1858101099Srwatsonstatic int 1859112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred) 1860112574Srwatson{ 1861112574Srwatson struct mac_biba *subj; 1862112574Srwatson int error; 1863112574Srwatson 1864112574Srwatson if (!mac_biba_enabled) 1865112574Srwatson return (0); 1866112574Srwatson 1867122524Srwatson subj = SLOT(cred->cr_label); 1868112574Srwatson 1869112574Srwatson error = mac_biba_subject_privileged(subj); 1870112574Srwatson if (error) 1871112574Srwatson return (error); 1872112574Srwatson 1873112574Srwatson return (0); 1874112574Srwatson} 1875112574Srwatson 1876112574Srwatsonstatic int 1877106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1878106418Srwatson struct label *label) 1879106418Srwatson{ 1880106418Srwatson struct mac_biba *subj, *obj; 1881106418Srwatson int error; 1882106418Srwatson 1883106418Srwatson if (!mac_biba_enabled) 1884106418Srwatson return (0); 1885106418Srwatson 1886122524Srwatson subj = SLOT(cred->cr_label); 1887106418Srwatson 1888106418Srwatson error = mac_biba_subject_privileged(subj); 1889106418Srwatson if (error) 1890106418Srwatson return (error); 1891106418Srwatson 1892106418Srwatson if (label == NULL) 1893106418Srwatson return (0); 1894106418Srwatson 1895106418Srwatson obj = SLOT(label); 1896106418Srwatson if (!mac_biba_high_single(obj)) 1897106418Srwatson return (EACCES); 1898106418Srwatson 1899106418Srwatson return (0); 1900106418Srwatson} 1901106418Srwatson 1902106418Srwatsonstatic int 1903106418Srwatsonmac_biba_check_system_settime(struct ucred *cred) 1904106418Srwatson{ 1905106418Srwatson struct mac_biba *subj; 1906106418Srwatson int error; 1907106418Srwatson 1908106418Srwatson if (!mac_biba_enabled) 1909106418Srwatson return (0); 1910106418Srwatson 1911122524Srwatson subj = SLOT(cred->cr_label); 1912106418Srwatson 1913106418Srwatson error = mac_biba_subject_privileged(subj); 1914106418Srwatson if (error) 1915106418Srwatson return (error); 1916106418Srwatson 1917106418Srwatson return (0); 1918106418Srwatson} 1919106418Srwatson 1920106418Srwatsonstatic int 1921106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1922106161Srwatson struct label *label) 1923106161Srwatson{ 1924106161Srwatson struct mac_biba *subj, *obj; 1925106416Srwatson int error; 1926106161Srwatson 1927106161Srwatson if (!mac_biba_enabled) 1928106161Srwatson return (0); 1929106161Srwatson 1930122524Srwatson subj = SLOT(cred->cr_label); 1931106161Srwatson obj = SLOT(label); 1932106161Srwatson 1933106416Srwatson error = mac_biba_subject_privileged(subj); 1934106416Srwatson if (error) 1935106416Srwatson return (error); 1936106161Srwatson 1937106161Srwatson if (!mac_biba_high_single(obj)) 1938106161Srwatson return (EACCES); 1939106161Srwatson 1940106161Srwatson return (0); 1941106161Srwatson} 1942106161Srwatson 1943106161Srwatsonstatic int 1944112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 1945112574Srwatson struct label *label) 1946112574Srwatson{ 1947112574Srwatson struct mac_biba *subj, *obj; 1948112574Srwatson int error; 1949112574Srwatson 1950112574Srwatson if (!mac_biba_enabled) 1951112574Srwatson return (0); 1952112574Srwatson 1953122524Srwatson subj = SLOT(cred->cr_label); 1954112574Srwatson obj = SLOT(label); 1955112574Srwatson 1956112574Srwatson error = mac_biba_subject_privileged(subj); 1957112574Srwatson if (error) 1958112574Srwatson return (error); 1959112574Srwatson 1960112574Srwatson return (0); 1961112574Srwatson} 1962112574Srwatson 1963112574Srwatsonstatic int 1964106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1965106161Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1966106161Srwatson{ 1967106161Srwatson struct mac_biba *subj; 1968106161Srwatson int error; 1969106161Srwatson 1970106161Srwatson if (!mac_biba_enabled) 1971106161Srwatson return (0); 1972106161Srwatson 1973122524Srwatson subj = SLOT(cred->cr_label); 1974106161Srwatson 1975106161Srwatson /* 1976106161Srwatson * In general, treat sysctl variables as biba/high, but also 1977106161Srwatson * require privilege to change them, since they are a 1978106161Srwatson * communications channel between grades. Exempt MIB 1979106161Srwatson * queries from this due to undocmented sysctl magic. 1980106161Srwatson * XXXMAC: This probably requires some more review. 1981106161Srwatson */ 1982106161Srwatson if (new != NULL) { 1983106161Srwatson if (namelen > 0 && name[0] == 0) 1984106161Srwatson return (0); 1985106161Srwatson 1986106161Srwatson if (!mac_biba_subject_dominate_high(subj)) 1987106161Srwatson return (EACCES); 1988106161Srwatson 1989106161Srwatson error = mac_biba_subject_privileged(subj); 1990106161Srwatson if (error) 1991106161Srwatson return (error); 1992106161Srwatson } 1993106161Srwatson 1994106161Srwatson return (0); 1995106161Srwatson} 1996106161Srwatson 1997106161Srwatsonstatic int 1998101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1999101099Srwatson struct label *dlabel) 2000101099Srwatson{ 2001101099Srwatson struct mac_biba *subj, *obj; 2002101099Srwatson 2003101099Srwatson if (!mac_biba_enabled) 2004101099Srwatson return (0); 2005101099Srwatson 2006122524Srwatson subj = SLOT(cred->cr_label); 2007101099Srwatson obj = SLOT(dlabel); 2008101099Srwatson 2009101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2010101099Srwatson return (EACCES); 2011101099Srwatson 2012101099Srwatson return (0); 2013101099Srwatson} 2014101099Srwatson 2015101099Srwatsonstatic int 2016101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2017101099Srwatson struct label *dlabel) 2018101099Srwatson{ 2019101099Srwatson struct mac_biba *subj, *obj; 2020101099Srwatson 2021101099Srwatson if (!mac_biba_enabled) 2022101099Srwatson return (0); 2023101099Srwatson 2024122524Srwatson subj = SLOT(cred->cr_label); 2025101099Srwatson obj = SLOT(dlabel); 2026101099Srwatson 2027101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2028101099Srwatson return (EACCES); 2029101099Srwatson 2030101099Srwatson return (0); 2031101099Srwatson} 2032101099Srwatson 2033101099Srwatsonstatic int 2034101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2035101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2036101099Srwatson{ 2037101099Srwatson struct mac_biba *subj, *obj; 2038101099Srwatson 2039101099Srwatson if (!mac_biba_enabled) 2040101099Srwatson return (0); 2041101099Srwatson 2042122524Srwatson subj = SLOT(cred->cr_label); 2043101099Srwatson obj = SLOT(dlabel); 2044101099Srwatson 2045101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2046101099Srwatson return (EACCES); 2047101099Srwatson 2048101099Srwatson return (0); 2049101099Srwatson} 2050101099Srwatson 2051101099Srwatsonstatic int 2052101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2053101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2054101099Srwatson struct componentname *cnp) 2055101099Srwatson{ 2056101099Srwatson struct mac_biba *subj, *obj; 2057101099Srwatson 2058101099Srwatson if (!mac_biba_enabled) 2059101099Srwatson return (0); 2060101099Srwatson 2061122524Srwatson subj = SLOT(cred->cr_label); 2062101099Srwatson obj = SLOT(dlabel); 2063101099Srwatson 2064101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2065101099Srwatson return (EACCES); 2066101099Srwatson 2067101099Srwatson obj = SLOT(label); 2068101099Srwatson 2069101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2070101099Srwatson return (EACCES); 2071101099Srwatson 2072101099Srwatson return (0); 2073101099Srwatson} 2074101099Srwatson 2075101099Srwatsonstatic int 2076101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2077101099Srwatson struct label *label, acl_type_t type) 2078101099Srwatson{ 2079101099Srwatson struct mac_biba *subj, *obj; 2080101099Srwatson 2081101099Srwatson if (!mac_biba_enabled) 2082101099Srwatson return (0); 2083101099Srwatson 2084122524Srwatson subj = SLOT(cred->cr_label); 2085101099Srwatson obj = SLOT(label); 2086101099Srwatson 2087101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2088101099Srwatson return (EACCES); 2089101099Srwatson 2090101099Srwatson return (0); 2091101099Srwatson} 2092101099Srwatson 2093101099Srwatsonstatic int 2094119202Srwatsonmac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2095119202Srwatson struct label *label, int attrnamespace, const char *name) 2096119202Srwatson{ 2097119202Srwatson struct mac_biba *subj, *obj; 2098119202Srwatson 2099119202Srwatson if (!mac_biba_enabled) 2100119202Srwatson return (0); 2101119202Srwatson 2102122524Srwatson subj = SLOT(cred->cr_label); 2103119202Srwatson obj = SLOT(label); 2104119202Srwatson 2105119202Srwatson if (!mac_biba_dominate_single(subj, obj)) 2106119202Srwatson return (EACCES); 2107119202Srwatson 2108119202Srwatson return (0); 2109119202Srwatson} 2110119202Srwatson 2111119202Srwatsonstatic int 2112101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2113106648Srwatson struct label *label, struct image_params *imgp, 2114106648Srwatson struct label *execlabel) 2115101099Srwatson{ 2116106648Srwatson struct mac_biba *subj, *obj, *exec; 2117106648Srwatson int error; 2118101099Srwatson 2119106648Srwatson if (execlabel != NULL) { 2120106648Srwatson /* 2121106648Srwatson * We currently don't permit labels to be changed at 2122106648Srwatson * exec-time as part of Biba, so disallow non-NULL 2123106648Srwatson * Biba label elements in the execlabel. 2124106648Srwatson */ 2125106648Srwatson exec = SLOT(execlabel); 2126106648Srwatson error = biba_atmostflags(exec, 0); 2127106648Srwatson if (error) 2128106648Srwatson return (error); 2129106648Srwatson } 2130106648Srwatson 2131101099Srwatson if (!mac_biba_enabled) 2132101099Srwatson return (0); 2133101099Srwatson 2134122524Srwatson subj = SLOT(cred->cr_label); 2135101099Srwatson obj = SLOT(label); 2136101099Srwatson 2137101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2138101099Srwatson return (EACCES); 2139101099Srwatson 2140101099Srwatson return (0); 2141101099Srwatson} 2142101099Srwatson 2143101099Srwatsonstatic int 2144101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2145101099Srwatson struct label *label, acl_type_t type) 2146101099Srwatson{ 2147101099Srwatson struct mac_biba *subj, *obj; 2148101099Srwatson 2149101099Srwatson if (!mac_biba_enabled) 2150101099Srwatson return (0); 2151101099Srwatson 2152122524Srwatson subj = SLOT(cred->cr_label); 2153101099Srwatson obj = SLOT(label); 2154101099Srwatson 2155101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2156101099Srwatson return (EACCES); 2157101099Srwatson 2158101099Srwatson return (0); 2159101099Srwatson} 2160101099Srwatson 2161101099Srwatsonstatic int 2162101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2163101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 2164101099Srwatson{ 2165101099Srwatson struct mac_biba *subj, *obj; 2166101099Srwatson 2167101099Srwatson if (!mac_biba_enabled) 2168101099Srwatson return (0); 2169101099Srwatson 2170122524Srwatson subj = SLOT(cred->cr_label); 2171101099Srwatson obj = SLOT(label); 2172101099Srwatson 2173101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2174101099Srwatson return (EACCES); 2175101099Srwatson 2176101099Srwatson return (0); 2177101099Srwatson} 2178101099Srwatson 2179101099Srwatsonstatic int 2180104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2181104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2182104530Srwatson struct componentname *cnp) 2183104530Srwatson{ 2184104530Srwatson struct mac_biba *subj, *obj; 2185104530Srwatson 2186104530Srwatson if (!mac_biba_enabled) 2187104530Srwatson return (0); 2188104530Srwatson 2189122524Srwatson subj = SLOT(cred->cr_label); 2190104530Srwatson obj = SLOT(dlabel); 2191104530Srwatson 2192104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2193104530Srwatson return (EACCES); 2194104530Srwatson 2195104530Srwatson obj = SLOT(label); 2196104530Srwatson 2197104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2198104530Srwatson return (EACCES); 2199104530Srwatson 2200104530Srwatson return (0); 2201104530Srwatson} 2202104530Srwatson 2203104530Srwatsonstatic int 2204119202Srwatsonmac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2205119202Srwatson struct label *label, int attrnamespace) 2206119202Srwatson{ 2207119202Srwatson struct mac_biba *subj, *obj; 2208119202Srwatson 2209119202Srwatson if (!mac_biba_enabled) 2210119202Srwatson return (0); 2211119202Srwatson 2212122524Srwatson subj = SLOT(cred->cr_label); 2213119202Srwatson obj = SLOT(label); 2214119202Srwatson 2215119202Srwatson if (!mac_biba_dominate_single(obj, subj)) 2216119202Srwatson return (EACCES); 2217119202Srwatson 2218119202Srwatson return (0); 2219119202Srwatson} 2220119202Srwatson 2221119202Srwatsonstatic int 2222103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2223101099Srwatson struct label *dlabel, struct componentname *cnp) 2224101099Srwatson{ 2225101099Srwatson struct mac_biba *subj, *obj; 2226103759Srwatson 2227101099Srwatson if (!mac_biba_enabled) 2228101099Srwatson return (0); 2229103759Srwatson 2230122524Srwatson subj = SLOT(cred->cr_label); 2231101099Srwatson obj = SLOT(dlabel); 2232103759Srwatson 2233101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2234101099Srwatson return (EACCES); 2235101099Srwatson 2236103759Srwatson return (0); 2237101099Srwatson} 2238101099Srwatson 2239101099Srwatsonstatic int 2240104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2241104546Srwatson struct label *label, int prot) 2242104546Srwatson{ 2243104546Srwatson struct mac_biba *subj, *obj; 2244104546Srwatson 2245104546Srwatson /* 2246104546Srwatson * Rely on the use of open()-time protections to handle 2247104546Srwatson * non-revocation cases. 2248104546Srwatson */ 2249105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2250104546Srwatson return (0); 2251104546Srwatson 2252122524Srwatson subj = SLOT(cred->cr_label); 2253104546Srwatson obj = SLOT(label); 2254104546Srwatson 2255104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2256104546Srwatson if (!mac_biba_dominate_single(obj, subj)) 2257104546Srwatson return (EACCES); 2258104546Srwatson } 2259104546Srwatson if (prot & VM_PROT_WRITE) { 2260104546Srwatson if (!mac_biba_dominate_single(subj, obj)) 2261104546Srwatson return (EACCES); 2262104546Srwatson } 2263104546Srwatson 2264104569Srwatson return (0); 2265104546Srwatson} 2266104546Srwatson 2267104546Srwatsonstatic int 2268101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2269106212Srwatson struct label *vnodelabel, int acc_mode) 2270101099Srwatson{ 2271101099Srwatson struct mac_biba *subj, *obj; 2272101099Srwatson 2273101099Srwatson if (!mac_biba_enabled) 2274101099Srwatson return (0); 2275101099Srwatson 2276122524Srwatson subj = SLOT(cred->cr_label); 2277101099Srwatson obj = SLOT(vnodelabel); 2278101099Srwatson 2279101099Srwatson /* XXX privilege override for admin? */ 2280101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2281101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2282101099Srwatson return (EACCES); 2283101099Srwatson } 2284101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2285101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2286101099Srwatson return (EACCES); 2287101099Srwatson } 2288101099Srwatson 2289101099Srwatson return (0); 2290101099Srwatson} 2291101099Srwatson 2292101099Srwatsonstatic int 2293102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2294102129Srwatson struct vnode *vp, struct label *label) 2295102112Srwatson{ 2296102112Srwatson struct mac_biba *subj, *obj; 2297102112Srwatson 2298105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2299102112Srwatson return (0); 2300102112Srwatson 2301122524Srwatson subj = SLOT(active_cred->cr_label); 2302102112Srwatson obj = SLOT(label); 2303102112Srwatson 2304102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2305102112Srwatson return (EACCES); 2306102112Srwatson 2307102112Srwatson return (0); 2308102112Srwatson} 2309102112Srwatson 2310102112Srwatsonstatic int 2311102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2312102129Srwatson struct vnode *vp, struct label *label) 2313102112Srwatson{ 2314102112Srwatson struct mac_biba *subj, *obj; 2315102112Srwatson 2316105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2317102112Srwatson return (0); 2318102112Srwatson 2319122524Srwatson subj = SLOT(active_cred->cr_label); 2320102112Srwatson obj = SLOT(label); 2321102112Srwatson 2322102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2323102112Srwatson return (EACCES); 2324102112Srwatson 2325102112Srwatson return (0); 2326102112Srwatson} 2327102112Srwatson 2328102112Srwatsonstatic int 2329101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2330101099Srwatson struct label *dlabel) 2331101099Srwatson{ 2332101099Srwatson struct mac_biba *subj, *obj; 2333101099Srwatson 2334101099Srwatson if (!mac_biba_enabled) 2335101099Srwatson return (0); 2336101099Srwatson 2337122524Srwatson subj = SLOT(cred->cr_label); 2338101099Srwatson obj = SLOT(dlabel); 2339101099Srwatson 2340101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2341101099Srwatson return (EACCES); 2342101099Srwatson 2343101099Srwatson return (0); 2344101099Srwatson} 2345101099Srwatson 2346101099Srwatsonstatic int 2347101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2348101099Srwatson struct label *label) 2349101099Srwatson{ 2350101099Srwatson struct mac_biba *subj, *obj; 2351101099Srwatson 2352101099Srwatson if (!mac_biba_enabled) 2353101099Srwatson return (0); 2354101099Srwatson 2355122524Srwatson subj = SLOT(cred->cr_label); 2356101099Srwatson obj = SLOT(label); 2357101099Srwatson 2358101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2359101099Srwatson return (EACCES); 2360101099Srwatson 2361101099Srwatson return (0); 2362101099Srwatson} 2363101099Srwatson 2364101099Srwatsonstatic int 2365101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2366101099Srwatson struct label *vnodelabel, struct label *newlabel) 2367101099Srwatson{ 2368101099Srwatson struct mac_biba *old, *new, *subj; 2369105634Srwatson int error; 2370101099Srwatson 2371101099Srwatson old = SLOT(vnodelabel); 2372101099Srwatson new = SLOT(newlabel); 2373122524Srwatson subj = SLOT(cred->cr_label); 2374101099Srwatson 2375101099Srwatson /* 2376105634Srwatson * If there is a Biba label update for the vnode, it must be a 2377105634Srwatson * single label. 2378101099Srwatson */ 2379105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2380105634Srwatson if (error) 2381105634Srwatson return (error); 2382101099Srwatson 2383101099Srwatson /* 2384105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2385105634Srwatson * authorize the relabel. 2386101099Srwatson */ 2387105634Srwatson if (!mac_biba_single_in_range(old, subj)) 2388101099Srwatson return (EPERM); 2389101099Srwatson 2390101099Srwatson /* 2391105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2392101099Srwatson */ 2393105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2394105634Srwatson /* 2395105634Srwatson * To change the Biba label on a vnode, the new vnode label 2396105634Srwatson * must be in the subject range. 2397105634Srwatson */ 2398105634Srwatson if (!mac_biba_single_in_range(new, subj)) 2399105634Srwatson return (EPERM); 2400101099Srwatson 2401105634Srwatson /* 2402105634Srwatson * To change the Biba label on the vnode to be EQUAL, 2403105634Srwatson * the subject must have appropriate privilege. 2404105634Srwatson */ 2405105634Srwatson if (mac_biba_contains_equal(new)) { 2406106090Srwatson error = mac_biba_subject_privileged(subj); 2407105634Srwatson if (error) 2408105634Srwatson return (error); 2409105634Srwatson } 2410105634Srwatson } 2411105634Srwatson 2412105634Srwatson return (0); 2413101099Srwatson} 2414101099Srwatson 2415101099Srwatsonstatic int 2416101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2417101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2418101099Srwatson struct componentname *cnp) 2419101099Srwatson{ 2420101099Srwatson struct mac_biba *subj, *obj; 2421101099Srwatson 2422101099Srwatson if (!mac_biba_enabled) 2423101099Srwatson return (0); 2424101099Srwatson 2425122524Srwatson subj = SLOT(cred->cr_label); 2426101099Srwatson obj = SLOT(dlabel); 2427101099Srwatson 2428101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2429101099Srwatson return (EACCES); 2430101099Srwatson 2431101099Srwatson obj = SLOT(label); 2432101099Srwatson 2433101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2434101099Srwatson return (EACCES); 2435101099Srwatson 2436101099Srwatson return (0); 2437101099Srwatson} 2438101099Srwatson 2439101099Srwatsonstatic int 2440101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2441101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2442101099Srwatson struct componentname *cnp) 2443101099Srwatson{ 2444101099Srwatson struct mac_biba *subj, *obj; 2445101099Srwatson 2446101099Srwatson if (!mac_biba_enabled) 2447101099Srwatson return (0); 2448101099Srwatson 2449122524Srwatson subj = SLOT(cred->cr_label); 2450101099Srwatson obj = SLOT(dlabel); 2451101099Srwatson 2452101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2453101099Srwatson return (EACCES); 2454101099Srwatson 2455101099Srwatson if (vp != NULL) { 2456101099Srwatson obj = SLOT(label); 2457101099Srwatson 2458101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2459101099Srwatson return (EACCES); 2460101099Srwatson } 2461101099Srwatson 2462101099Srwatson return (0); 2463101099Srwatson} 2464101099Srwatson 2465101099Srwatsonstatic int 2466101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2467101099Srwatson struct label *label) 2468101099Srwatson{ 2469101099Srwatson struct mac_biba *subj, *obj; 2470101099Srwatson 2471101099Srwatson if (!mac_biba_enabled) 2472101099Srwatson return (0); 2473101099Srwatson 2474122524Srwatson subj = SLOT(cred->cr_label); 2475101099Srwatson obj = SLOT(label); 2476101099Srwatson 2477101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2478101099Srwatson return (EACCES); 2479101099Srwatson 2480101099Srwatson return (0); 2481101099Srwatson} 2482101099Srwatson 2483101099Srwatsonstatic int 2484101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2485101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 2486101099Srwatson{ 2487101099Srwatson struct mac_biba *subj, *obj; 2488101099Srwatson 2489101099Srwatson if (!mac_biba_enabled) 2490101099Srwatson return (0); 2491101099Srwatson 2492122524Srwatson subj = SLOT(cred->cr_label); 2493101099Srwatson obj = SLOT(label); 2494101099Srwatson 2495101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2496101099Srwatson return (EACCES); 2497101099Srwatson 2498101099Srwatson return (0); 2499101099Srwatson} 2500101099Srwatson 2501101099Srwatsonstatic int 2502101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2503101099Srwatson struct label *vnodelabel, int attrnamespace, const char *name, 2504101099Srwatson struct uio *uio) 2505101099Srwatson{ 2506101099Srwatson struct mac_biba *subj, *obj; 2507101099Srwatson 2508101099Srwatson if (!mac_biba_enabled) 2509101099Srwatson return (0); 2510101099Srwatson 2511122524Srwatson subj = SLOT(cred->cr_label); 2512101099Srwatson obj = SLOT(vnodelabel); 2513101099Srwatson 2514101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2515101099Srwatson return (EACCES); 2516101099Srwatson 2517101099Srwatson /* XXX: protect the MAC EA in a special way? */ 2518101099Srwatson 2519101099Srwatson return (0); 2520101099Srwatson} 2521101099Srwatson 2522101099Srwatsonstatic int 2523101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2524101099Srwatson struct label *vnodelabel, u_long flags) 2525101099Srwatson{ 2526101099Srwatson struct mac_biba *subj, *obj; 2527101099Srwatson 2528101099Srwatson if (!mac_biba_enabled) 2529101099Srwatson return (0); 2530101099Srwatson 2531122524Srwatson subj = SLOT(cred->cr_label); 2532101099Srwatson obj = SLOT(vnodelabel); 2533101099Srwatson 2534101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2535101099Srwatson return (EACCES); 2536101099Srwatson 2537101099Srwatson return (0); 2538101099Srwatson} 2539101099Srwatson 2540101099Srwatsonstatic int 2541101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2542101099Srwatson struct label *vnodelabel, mode_t mode) 2543101099Srwatson{ 2544101099Srwatson struct mac_biba *subj, *obj; 2545101099Srwatson 2546101099Srwatson if (!mac_biba_enabled) 2547101099Srwatson return (0); 2548101099Srwatson 2549122524Srwatson subj = SLOT(cred->cr_label); 2550101099Srwatson obj = SLOT(vnodelabel); 2551101099Srwatson 2552101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2553101099Srwatson return (EACCES); 2554101099Srwatson 2555101099Srwatson return (0); 2556101099Srwatson} 2557101099Srwatson 2558101099Srwatsonstatic int 2559101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2560101099Srwatson struct label *vnodelabel, uid_t uid, gid_t gid) 2561101099Srwatson{ 2562101099Srwatson struct mac_biba *subj, *obj; 2563101099Srwatson 2564101099Srwatson if (!mac_biba_enabled) 2565101099Srwatson return (0); 2566101099Srwatson 2567122524Srwatson subj = SLOT(cred->cr_label); 2568101099Srwatson obj = SLOT(vnodelabel); 2569101099Srwatson 2570101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2571101099Srwatson return (EACCES); 2572101099Srwatson 2573101099Srwatson return (0); 2574101099Srwatson} 2575101099Srwatson 2576101099Srwatsonstatic int 2577101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2578101099Srwatson struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2579101099Srwatson{ 2580101099Srwatson struct mac_biba *subj, *obj; 2581101099Srwatson 2582101099Srwatson if (!mac_biba_enabled) 2583101099Srwatson return (0); 2584101099Srwatson 2585122524Srwatson subj = SLOT(cred->cr_label); 2586101099Srwatson obj = SLOT(vnodelabel); 2587101099Srwatson 2588101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2589101099Srwatson return (EACCES); 2590101099Srwatson 2591101099Srwatson return (0); 2592101099Srwatson} 2593101099Srwatson 2594101099Srwatsonstatic int 2595102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2596102129Srwatson struct vnode *vp, struct label *vnodelabel) 2597101099Srwatson{ 2598101099Srwatson struct mac_biba *subj, *obj; 2599101099Srwatson 2600101099Srwatson if (!mac_biba_enabled) 2601101099Srwatson return (0); 2602101099Srwatson 2603122524Srwatson subj = SLOT(active_cred->cr_label); 2604101099Srwatson obj = SLOT(vnodelabel); 2605101099Srwatson 2606101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2607101099Srwatson return (EACCES); 2608101099Srwatson 2609101099Srwatson return (0); 2610101099Srwatson} 2611101099Srwatson 2612102112Srwatsonstatic int 2613102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred, 2614102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 2615102112Srwatson{ 2616102112Srwatson struct mac_biba *subj, *obj; 2617102112Srwatson 2618105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2619102112Srwatson return (0); 2620102112Srwatson 2621122524Srwatson subj = SLOT(active_cred->cr_label); 2622102112Srwatson obj = SLOT(label); 2623102112Srwatson 2624102112Srwatson if (!mac_biba_dominate_single(subj, obj)) 2625102112Srwatson return (EACCES); 2626102112Srwatson 2627102112Srwatson return (0); 2628102112Srwatson} 2629102112Srwatson 2630106217Srwatsonstatic struct mac_policy_ops mac_biba_ops = 2631101099Srwatson{ 2632106217Srwatson .mpo_init = mac_biba_init, 2633106217Srwatson .mpo_init_bpfdesc_label = mac_biba_init_label, 2634106217Srwatson .mpo_init_cred_label = mac_biba_init_label, 2635106217Srwatson .mpo_init_devfsdirent_label = mac_biba_init_label, 2636106217Srwatson .mpo_init_ifnet_label = mac_biba_init_label, 2637122875Srwatson .mpo_init_inpcb_label = mac_biba_init_label_waitcheck, 2638112675Srwatson .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 2639106217Srwatson .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2640106217Srwatson .mpo_init_mount_label = mac_biba_init_label, 2641106217Srwatson .mpo_init_mount_fs_label = mac_biba_init_label, 2642106217Srwatson .mpo_init_pipe_label = mac_biba_init_label, 2643106217Srwatson .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2644106217Srwatson .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2645106217Srwatson .mpo_init_vnode_label = mac_biba_init_label, 2646106217Srwatson .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2647106217Srwatson .mpo_destroy_cred_label = mac_biba_destroy_label, 2648106217Srwatson .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2649106217Srwatson .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2650122875Srwatson .mpo_destroy_inpcb_label = mac_biba_destroy_label, 2651106217Srwatson .mpo_destroy_ipq_label = mac_biba_destroy_label, 2652106217Srwatson .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2653106217Srwatson .mpo_destroy_mount_label = mac_biba_destroy_label, 2654106217Srwatson .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2655106217Srwatson .mpo_destroy_pipe_label = mac_biba_destroy_label, 2656106217Srwatson .mpo_destroy_socket_label = mac_biba_destroy_label, 2657106217Srwatson .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2658106217Srwatson .mpo_destroy_vnode_label = mac_biba_destroy_label, 2659123173Srwatson .mpo_copy_cred_label = mac_biba_copy_label, 2660115707Srwatson .mpo_copy_mbuf_label = mac_biba_copy_label, 2661106217Srwatson .mpo_copy_pipe_label = mac_biba_copy_label, 2662122820Srwatson .mpo_copy_socket_label = mac_biba_copy_label, 2663106217Srwatson .mpo_copy_vnode_label = mac_biba_copy_label, 2664106217Srwatson .mpo_externalize_cred_label = mac_biba_externalize_label, 2665106217Srwatson .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2666106217Srwatson .mpo_externalize_pipe_label = mac_biba_externalize_label, 2667106217Srwatson .mpo_externalize_socket_label = mac_biba_externalize_label, 2668106217Srwatson .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2669106217Srwatson .mpo_externalize_vnode_label = mac_biba_externalize_label, 2670106217Srwatson .mpo_internalize_cred_label = mac_biba_internalize_label, 2671106217Srwatson .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2672106217Srwatson .mpo_internalize_pipe_label = mac_biba_internalize_label, 2673106217Srwatson .mpo_internalize_socket_label = mac_biba_internalize_label, 2674106217Srwatson .mpo_internalize_vnode_label = mac_biba_internalize_label, 2675106217Srwatson .mpo_create_devfs_device = mac_biba_create_devfs_device, 2676106217Srwatson .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2677106217Srwatson .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2678106217Srwatson .mpo_create_mount = mac_biba_create_mount, 2679106217Srwatson .mpo_create_root_mount = mac_biba_create_root_mount, 2680106217Srwatson .mpo_relabel_vnode = mac_biba_relabel_vnode, 2681106217Srwatson .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2682106217Srwatson .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2683106217Srwatson .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2684106217Srwatson .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2685106217Srwatson .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2686106217Srwatson .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2687106217Srwatson .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2688106217Srwatson .mpo_create_pipe = mac_biba_create_pipe, 2689106217Srwatson .mpo_create_socket = mac_biba_create_socket, 2690106217Srwatson .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2691106217Srwatson .mpo_relabel_pipe = mac_biba_relabel_pipe, 2692106217Srwatson .mpo_relabel_socket = mac_biba_relabel_socket, 2693106217Srwatson .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2694106217Srwatson .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2695106217Srwatson .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2696106217Srwatson .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2697106217Srwatson .mpo_create_fragment = mac_biba_create_fragment, 2698106217Srwatson .mpo_create_ifnet = mac_biba_create_ifnet, 2699122875Srwatson .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket, 2700106217Srwatson .mpo_create_ipq = mac_biba_create_ipq, 2701106217Srwatson .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2702106217Srwatson .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2703106217Srwatson .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2704106217Srwatson .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2705106217Srwatson .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2706106217Srwatson .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2707106217Srwatson .mpo_fragment_match = mac_biba_fragment_match, 2708106217Srwatson .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2709106217Srwatson .mpo_update_ipq = mac_biba_update_ipq, 2710122875Srwatson .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel, 2711106217Srwatson .mpo_create_proc0 = mac_biba_create_proc0, 2712106217Srwatson .mpo_create_proc1 = mac_biba_create_proc1, 2713106217Srwatson .mpo_relabel_cred = mac_biba_relabel_cred, 2714106217Srwatson .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2715106217Srwatson .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2716106217Srwatson .mpo_check_cred_visible = mac_biba_check_cred_visible, 2717106217Srwatson .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2718106217Srwatson .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2719122875Srwatson .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver, 2720110354Srwatson .mpo_check_kld_load = mac_biba_check_kld_load, 2721110354Srwatson .mpo_check_kld_unload = mac_biba_check_kld_unload, 2722106217Srwatson .mpo_check_mount_stat = mac_biba_check_mount_stat, 2723106217Srwatson .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2724106217Srwatson .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2725106217Srwatson .mpo_check_pipe_read = mac_biba_check_pipe_read, 2726106217Srwatson .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2727106217Srwatson .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2728106217Srwatson .mpo_check_pipe_write = mac_biba_check_pipe_write, 2729106217Srwatson .mpo_check_proc_debug = mac_biba_check_proc_debug, 2730106217Srwatson .mpo_check_proc_sched = mac_biba_check_proc_sched, 2731106217Srwatson .mpo_check_proc_signal = mac_biba_check_proc_signal, 2732106217Srwatson .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2733106217Srwatson .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2734106217Srwatson .mpo_check_socket_visible = mac_biba_check_socket_visible, 2735112574Srwatson .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 2736106418Srwatson .mpo_check_system_acct = mac_biba_check_system_acct, 2737106418Srwatson .mpo_check_system_settime = mac_biba_check_system_settime, 2738106217Srwatson .mpo_check_system_swapon = mac_biba_check_system_swapon, 2739112574Srwatson .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 2740106217Srwatson .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2741106217Srwatson .mpo_check_vnode_access = mac_biba_check_vnode_open, 2742106217Srwatson .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2743106217Srwatson .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2744106217Srwatson .mpo_check_vnode_create = mac_biba_check_vnode_create, 2745106217Srwatson .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2746106217Srwatson .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2747119202Srwatson .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr, 2748106217Srwatson .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2749106217Srwatson .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2750106217Srwatson .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2751106217Srwatson .mpo_check_vnode_link = mac_biba_check_vnode_link, 2752119202Srwatson .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr, 2753106217Srwatson .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2754106217Srwatson .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2755106217Srwatson .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2756106217Srwatson .mpo_check_vnode_open = mac_biba_check_vnode_open, 2757106217Srwatson .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2758106217Srwatson .mpo_check_vnode_read = mac_biba_check_vnode_read, 2759106217Srwatson .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2760106217Srwatson .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2761106217Srwatson .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2762106217Srwatson .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2763106217Srwatson .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2764106217Srwatson .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2765106217Srwatson .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2766106217Srwatson .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2767106217Srwatson .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2768106217Srwatson .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2769106217Srwatson .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2770106217Srwatson .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2771106217Srwatson .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2772106217Srwatson .mpo_check_vnode_write = mac_biba_check_vnode_write, 2773101099Srwatson}; 2774101099Srwatson 2775112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 2776113531Srwatson MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot); 2777