mac_biba.c revision 130585
1101099Srwatson/*- 2126097Srwatson * Copyright (c) 1999-2002 Robert N. M. Watson 3126097Srwatson * Copyright (c) 2001-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 130585 2004-06-16 09:47:26Z phk $ 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 775130585Sphkmac_biba_create_devfs_device(struct mount *mp, struct cdev *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 1020125293Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipepair *pp, 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 1057125293Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipepair *pp, 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 1203123607Srwatsonmac_biba_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1204123607Srwatson struct mbuf *m, struct label *mlabel) 1205123607Srwatson{ 1206123607Srwatson struct mac_biba *source, *dest; 1207123607Srwatson 1208123607Srwatson source = SLOT(inplabel); 1209123607Srwatson dest = SLOT(mlabel); 1210123607Srwatson 1211123607Srwatson mac_biba_copy_single(source, dest); 1212123607Srwatson} 1213123607Srwatson 1214123607Srwatsonstatic void 1215101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1216101099Srwatson struct label *oldmbuflabel, struct mbuf *newmbuf, 1217101099Srwatson struct label *newmbuflabel) 1218101099Srwatson{ 1219101099Srwatson struct mac_biba *source, *dest; 1220101099Srwatson 1221101099Srwatson source = SLOT(oldmbuflabel); 1222101099Srwatson dest = SLOT(newmbuflabel); 1223101099Srwatson 1224105656Srwatson /* 1225105656Srwatson * Because the source mbuf may not yet have been "created", 1226105696Srwatson * just initialized, we do a conditional copy. Since we don't 1227105656Srwatson * allow mbufs to have ranges, do a KASSERT to make sure that 1228105656Srwatson * doesn't happen. 1229105656Srwatson */ 1230105656Srwatson KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1231105656Srwatson ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1232105656Srwatson mac_biba_copy(source, dest); 1233101099Srwatson} 1234101099Srwatson 1235101099Srwatsonstatic void 1236101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1237101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1238101099Srwatson{ 1239101099Srwatson struct mac_biba *dest; 1240101099Srwatson 1241101099Srwatson dest = SLOT(mbuflabel); 1242101099Srwatson 1243105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1244101099Srwatson} 1245101099Srwatson 1246101099Srwatsonstatic void 1247101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1248101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1249101099Srwatson{ 1250101099Srwatson struct mac_biba *source, *dest; 1251101099Srwatson 1252101099Srwatson source = SLOT(bpflabel); 1253101099Srwatson dest = SLOT(mbuflabel); 1254101099Srwatson 1255101099Srwatson mac_biba_copy_single(source, dest); 1256101099Srwatson} 1257101099Srwatson 1258101099Srwatsonstatic void 1259101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1260101099Srwatson struct mbuf *m, struct label *mbuflabel) 1261101099Srwatson{ 1262101099Srwatson struct mac_biba *source, *dest; 1263101099Srwatson 1264101099Srwatson source = SLOT(ifnetlabel); 1265101099Srwatson dest = SLOT(mbuflabel); 1266101099Srwatson 1267101099Srwatson mac_biba_copy_single(source, dest); 1268101099Srwatson} 1269101099Srwatson 1270101099Srwatsonstatic void 1271101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1272101099Srwatson struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 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 void 1284101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1285101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1286101099Srwatson{ 1287101099Srwatson struct mac_biba *source, *dest; 1288101099Srwatson 1289101099Srwatson source = SLOT(oldmbuflabel); 1290101099Srwatson dest = SLOT(newmbuflabel); 1291101099Srwatson 1292101099Srwatson mac_biba_copy_single(source, dest); 1293101099Srwatson} 1294101099Srwatson 1295101099Srwatsonstatic int 1296101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1297101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1298101099Srwatson{ 1299101099Srwatson struct mac_biba *a, *b; 1300101099Srwatson 1301101099Srwatson a = SLOT(ipqlabel); 1302101099Srwatson b = SLOT(fragmentlabel); 1303101099Srwatson 1304101099Srwatson return (mac_biba_equal_single(a, b)); 1305101099Srwatson} 1306101099Srwatson 1307101099Srwatsonstatic void 1308101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1309101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1310101099Srwatson{ 1311101099Srwatson struct mac_biba *source, *dest; 1312101099Srwatson 1313101099Srwatson source = SLOT(newlabel); 1314101099Srwatson dest = SLOT(ifnetlabel); 1315101099Srwatson 1316105656Srwatson mac_biba_copy(source, dest); 1317101099Srwatson} 1318101099Srwatson 1319101099Srwatsonstatic void 1320101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1321101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1322101099Srwatson{ 1323101099Srwatson 1324101099Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1325101099Srwatson} 1326101099Srwatson 1327122875Srwatsonstatic void 1328122875Srwatsonmac_biba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1329122875Srwatson struct inpcb *inp, struct label *inplabel) 1330122875Srwatson{ 1331122875Srwatson struct mac_biba *source, *dest; 1332122875Srwatson 1333122875Srwatson source = SLOT(solabel); 1334122875Srwatson dest = SLOT(inplabel); 1335122875Srwatson 1336122875Srwatson mac_biba_copy(source, dest); 1337122875Srwatson} 1338122875Srwatson 1339101099Srwatson/* 1340101099Srwatson * Labeling event operations: processes. 1341101099Srwatson */ 1342101099Srwatsonstatic void 1343101099Srwatsonmac_biba_create_proc0(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_EQUAL, 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_create_proc1(struct ucred *cred) 1356101099Srwatson{ 1357101099Srwatson struct mac_biba *dest; 1358101099Srwatson 1359122524Srwatson dest = SLOT(cred->cr_label); 1360101099Srwatson 1361105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1362105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1363105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1364101099Srwatson} 1365101099Srwatson 1366101099Srwatsonstatic void 1367101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1368101099Srwatson{ 1369101099Srwatson struct mac_biba *source, *dest; 1370101099Srwatson 1371101099Srwatson source = SLOT(newlabel); 1372122524Srwatson dest = SLOT(cred->cr_label); 1373101099Srwatson 1374105656Srwatson mac_biba_copy(source, dest); 1375101099Srwatson} 1376101099Srwatson 1377101099Srwatson/* 1378101099Srwatson * Access control checks. 1379101099Srwatson */ 1380101099Srwatsonstatic int 1381101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1382101099Srwatson struct ifnet *ifnet, struct label *ifnetlabel) 1383101099Srwatson{ 1384101099Srwatson struct mac_biba *a, *b; 1385101099Srwatson 1386101099Srwatson if (!mac_biba_enabled) 1387101099Srwatson return (0); 1388101099Srwatson 1389101099Srwatson a = SLOT(bpflabel); 1390101099Srwatson b = SLOT(ifnetlabel); 1391101099Srwatson 1392101099Srwatson if (mac_biba_equal_single(a, b)) 1393101099Srwatson return (0); 1394101099Srwatson return (EACCES); 1395101099Srwatson} 1396101099Srwatson 1397101099Srwatsonstatic int 1398101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1399101099Srwatson{ 1400101099Srwatson struct mac_biba *subj, *new; 1401105634Srwatson int error; 1402101099Srwatson 1403122524Srwatson subj = SLOT(cred->cr_label); 1404101099Srwatson new = SLOT(newlabel); 1405101099Srwatson 1406101099Srwatson /* 1407105634Srwatson * If there is a Biba label update for the credential, it may 1408105634Srwatson * be an update of the single, range, or both. 1409101099Srwatson */ 1410105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1411105634Srwatson if (error) 1412105634Srwatson return (error); 1413101099Srwatson 1414101099Srwatson /* 1415105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1416101099Srwatson */ 1417105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1418105634Srwatson /* 1419110351Srwatson * If the change request modifies both the Biba label 1420110351Srwatson * single and range, check that the new single will be 1421110351Srwatson * in the new range. 1422110351Srwatson */ 1423110351Srwatson if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1424110351Srwatson MAC_BIBA_FLAGS_BOTH && 1425110351Srwatson !mac_biba_single_in_range(new, new)) 1426110351Srwatson return (EINVAL); 1427110351Srwatson 1428110351Srwatson /* 1429105634Srwatson * To change the Biba single label on a credential, the 1430105634Srwatson * new single label must be in the current range. 1431105634Srwatson */ 1432105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1433105634Srwatson !mac_biba_single_in_range(new, subj)) 1434105634Srwatson return (EPERM); 1435101099Srwatson 1436105634Srwatson /* 1437105634Srwatson * To change the Biba range on a credential, the new 1438105634Srwatson * range label must be in the current range. 1439105634Srwatson */ 1440105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1441105634Srwatson !mac_biba_range_in_range(new, subj)) 1442105634Srwatson return (EPERM); 1443101099Srwatson 1444105634Srwatson /* 1445105634Srwatson * To have EQUAL in any component of the new credential 1446105634Srwatson * Biba label, the subject must already have EQUAL in 1447105634Srwatson * their label. 1448105634Srwatson */ 1449105634Srwatson if (mac_biba_contains_equal(new)) { 1450106090Srwatson error = mac_biba_subject_privileged(subj); 1451105634Srwatson if (error) 1452105634Srwatson return (error); 1453105634Srwatson } 1454105634Srwatson } 1455105634Srwatson 1456101099Srwatson return (0); 1457101099Srwatson} 1458101099Srwatson 1459101099Srwatsonstatic int 1460101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1461101099Srwatson{ 1462101099Srwatson struct mac_biba *subj, *obj; 1463101099Srwatson 1464101099Srwatson if (!mac_biba_enabled) 1465101099Srwatson return (0); 1466101099Srwatson 1467122524Srwatson subj = SLOT(u1->cr_label); 1468122524Srwatson obj = SLOT(u2->cr_label); 1469101099Srwatson 1470101099Srwatson /* XXX: range */ 1471101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1472101099Srwatson return (ESRCH); 1473101099Srwatson 1474101099Srwatson return (0); 1475101099Srwatson} 1476101099Srwatson 1477101099Srwatsonstatic int 1478101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1479101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1480101099Srwatson{ 1481101099Srwatson struct mac_biba *subj, *new; 1482105634Srwatson int error; 1483101099Srwatson 1484122524Srwatson subj = SLOT(cred->cr_label); 1485101099Srwatson new = SLOT(newlabel); 1486101099Srwatson 1487105634Srwatson /* 1488105634Srwatson * If there is a Biba label update for the interface, it may 1489105634Srwatson * be an update of the single, range, or both. 1490105634Srwatson */ 1491105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1492105634Srwatson if (error) 1493105634Srwatson return (error); 1494101099Srwatson 1495105634Srwatson /* 1496106160Srwatson * Relabling network interfaces requires Biba privilege. 1497106160Srwatson */ 1498106160Srwatson error = mac_biba_subject_privileged(subj); 1499106160Srwatson if (error) 1500106160Srwatson return (error); 1501106160Srwatson 1502105634Srwatson return (0); 1503101099Srwatson} 1504101099Srwatson 1505103759Srwatsonstatic int 1506101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1507101099Srwatson struct mbuf *m, struct label *mbuflabel) 1508101099Srwatson{ 1509101099Srwatson struct mac_biba *p, *i; 1510103761Srwatson 1511101099Srwatson if (!mac_biba_enabled) 1512101099Srwatson return (0); 1513101099Srwatson 1514101099Srwatson p = SLOT(mbuflabel); 1515101099Srwatson i = SLOT(ifnetlabel); 1516103759Srwatson 1517101099Srwatson return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1518101099Srwatson} 1519101099Srwatson 1520101099Srwatsonstatic int 1521122875Srwatsonmac_biba_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1522122875Srwatson struct mbuf *m, struct label *mlabel) 1523122875Srwatson{ 1524122875Srwatson struct mac_biba *p, *i; 1525122875Srwatson 1526122875Srwatson if (!mac_biba_enabled) 1527122875Srwatson return (0); 1528122875Srwatson 1529122875Srwatson p = SLOT(mlabel); 1530122875Srwatson i = SLOT(inplabel); 1531122875Srwatson 1532122875Srwatson return (mac_biba_equal_single(p, i) ? 0 : EACCES); 1533122875Srwatson} 1534122875Srwatson 1535122875Srwatsonstatic int 1536110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1537110354Srwatson struct label *label) 1538110354Srwatson{ 1539110354Srwatson struct mac_biba *subj, *obj; 1540110354Srwatson int error; 1541110354Srwatson 1542110354Srwatson if (!mac_biba_enabled) 1543110354Srwatson return (0); 1544110354Srwatson 1545122524Srwatson subj = SLOT(cred->cr_label); 1546110354Srwatson 1547110354Srwatson error = mac_biba_subject_privileged(subj); 1548110354Srwatson if (error) 1549110354Srwatson return (error); 1550110354Srwatson 1551110354Srwatson obj = SLOT(label); 1552110354Srwatson if (!mac_biba_high_single(obj)) 1553110354Srwatson return (EACCES); 1554110354Srwatson 1555110354Srwatson return (0); 1556110354Srwatson} 1557110354Srwatson 1558110354Srwatson 1559110354Srwatsonstatic int 1560110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred) 1561110354Srwatson{ 1562110354Srwatson struct mac_biba *subj; 1563110354Srwatson 1564110354Srwatson if (!mac_biba_enabled) 1565110354Srwatson return (0); 1566110354Srwatson 1567122524Srwatson subj = SLOT(cred->cr_label); 1568110354Srwatson 1569110354Srwatson return (mac_biba_subject_privileged(subj)); 1570110354Srwatson} 1571110354Srwatson 1572110354Srwatsonstatic int 1573101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1574101099Srwatson struct label *mntlabel) 1575101099Srwatson{ 1576101099Srwatson struct mac_biba *subj, *obj; 1577101099Srwatson 1578101099Srwatson if (!mac_biba_enabled) 1579101099Srwatson return (0); 1580101099Srwatson 1581122524Srwatson subj = SLOT(cred->cr_label); 1582101099Srwatson obj = SLOT(mntlabel); 1583101099Srwatson 1584101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1585101099Srwatson return (EACCES); 1586101099Srwatson 1587101099Srwatson return (0); 1588101099Srwatson} 1589101099Srwatson 1590101099Srwatsonstatic int 1591125293Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1592101099Srwatson struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1593101099Srwatson{ 1594103759Srwatson 1595101099Srwatson if(!mac_biba_enabled) 1596101099Srwatson return (0); 1597101099Srwatson 1598101099Srwatson /* XXX: This will be implemented soon... */ 1599101099Srwatson 1600101099Srwatson return (0); 1601101099Srwatson} 1602101099Srwatson 1603101099Srwatsonstatic int 1604125293Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipepair *pp, 1605102115Srwatson struct label *pipelabel) 1606101099Srwatson{ 1607101099Srwatson struct mac_biba *subj, *obj; 1608101099Srwatson 1609101099Srwatson if (!mac_biba_enabled) 1610101099Srwatson return (0); 1611101099Srwatson 1612122524Srwatson subj = SLOT(cred->cr_label); 1613101099Srwatson obj = SLOT((pipelabel)); 1614101099Srwatson 1615102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1616102115Srwatson return (EACCES); 1617101099Srwatson 1618101099Srwatson return (0); 1619101099Srwatson} 1620101099Srwatson 1621101099Srwatsonstatic int 1622125293Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1623102115Srwatson struct label *pipelabel) 1624102115Srwatson{ 1625102115Srwatson struct mac_biba *subj, *obj; 1626102115Srwatson 1627102115Srwatson if (!mac_biba_enabled) 1628102115Srwatson return (0); 1629102115Srwatson 1630122524Srwatson subj = SLOT(cred->cr_label); 1631102115Srwatson obj = SLOT((pipelabel)); 1632102115Srwatson 1633102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1634102115Srwatson return (EACCES); 1635102115Srwatson 1636102115Srwatson return (0); 1637102115Srwatson} 1638102115Srwatson 1639102115Srwatsonstatic int 1640125293Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1641101099Srwatson struct label *pipelabel, struct label *newlabel) 1642101099Srwatson{ 1643101099Srwatson struct mac_biba *subj, *obj, *new; 1644105634Srwatson int error; 1645101099Srwatson 1646101099Srwatson new = SLOT(newlabel); 1647122524Srwatson subj = SLOT(cred->cr_label); 1648101099Srwatson obj = SLOT(pipelabel); 1649101099Srwatson 1650101099Srwatson /* 1651105634Srwatson * If there is a Biba label update for a pipe, it must be a 1652105634Srwatson * single update. 1653101099Srwatson */ 1654105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1655105634Srwatson if (error) 1656105634Srwatson return (error); 1657101099Srwatson 1658101099Srwatson /* 1659105634Srwatson * To perform a relabel of a pipe (Biba label or not), Biba must 1660105634Srwatson * authorize the relabel. 1661101099Srwatson */ 1662105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1663101099Srwatson return (EPERM); 1664101099Srwatson 1665101099Srwatson /* 1666105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1667101099Srwatson */ 1668105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1669105634Srwatson /* 1670105634Srwatson * To change the Biba label on a pipe, the new pipe label 1671105634Srwatson * must be in the subject range. 1672105634Srwatson */ 1673105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1674105634Srwatson return (EPERM); 1675101099Srwatson 1676105634Srwatson /* 1677105634Srwatson * To change the Biba label on a pipe to be EQUAL, the 1678105634Srwatson * subject must have appropriate privilege. 1679105634Srwatson */ 1680105634Srwatson if (mac_biba_contains_equal(new)) { 1681106090Srwatson error = mac_biba_subject_privileged(subj); 1682105634Srwatson if (error) 1683105634Srwatson return (error); 1684105634Srwatson } 1685105634Srwatson } 1686105634Srwatson 1687101099Srwatson return (0); 1688101099Srwatson} 1689101099Srwatson 1690101099Srwatsonstatic int 1691125293Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipepair *pp, 1692102115Srwatson struct label *pipelabel) 1693102115Srwatson{ 1694102115Srwatson struct mac_biba *subj, *obj; 1695102115Srwatson 1696102115Srwatson if (!mac_biba_enabled) 1697102115Srwatson return (0); 1698102115Srwatson 1699122524Srwatson subj = SLOT(cred->cr_label); 1700102115Srwatson obj = SLOT((pipelabel)); 1701102115Srwatson 1702102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1703102115Srwatson return (EACCES); 1704102115Srwatson 1705102115Srwatson return (0); 1706102115Srwatson} 1707102115Srwatson 1708102115Srwatsonstatic int 1709125293Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipepair *pp, 1710102115Srwatson struct label *pipelabel) 1711102115Srwatson{ 1712102115Srwatson struct mac_biba *subj, *obj; 1713102115Srwatson 1714102115Srwatson if (!mac_biba_enabled) 1715102115Srwatson return (0); 1716102115Srwatson 1717122524Srwatson subj = SLOT(cred->cr_label); 1718102115Srwatson obj = SLOT((pipelabel)); 1719102115Srwatson 1720102115Srwatson if (!mac_biba_dominate_single(subj, obj)) 1721102115Srwatson return (EACCES); 1722102115Srwatson 1723102115Srwatson return (0); 1724102115Srwatson} 1725102115Srwatson 1726102115Srwatsonstatic int 1727101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1728101099Srwatson{ 1729101099Srwatson struct mac_biba *subj, *obj; 1730101099Srwatson 1731101099Srwatson if (!mac_biba_enabled) 1732101099Srwatson return (0); 1733101099Srwatson 1734122524Srwatson subj = SLOT(cred->cr_label); 1735122524Srwatson obj = SLOT(proc->p_ucred->cr_label); 1736101099Srwatson 1737101099Srwatson /* XXX: range checks */ 1738101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1739101099Srwatson return (ESRCH); 1740101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1741101099Srwatson return (EACCES); 1742101099Srwatson 1743101099Srwatson return (0); 1744101099Srwatson} 1745101099Srwatson 1746101099Srwatsonstatic int 1747101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1748101099Srwatson{ 1749101099Srwatson struct mac_biba *subj, *obj; 1750103759Srwatson 1751101099Srwatson if (!mac_biba_enabled) 1752101099Srwatson return (0); 1753101099Srwatson 1754122524Srwatson subj = SLOT(cred->cr_label); 1755122524Srwatson obj = SLOT(proc->p_ucred->cr_label); 1756103759Srwatson 1757101099Srwatson /* XXX: range checks */ 1758101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1759101099Srwatson return (ESRCH); 1760101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1761101099Srwatson return (EACCES); 1762101099Srwatson 1763101099Srwatson return (0); 1764101099Srwatson} 1765101099Srwatson 1766101099Srwatsonstatic int 1767101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1768101099Srwatson{ 1769101099Srwatson struct mac_biba *subj, *obj; 1770103759Srwatson 1771101099Srwatson if (!mac_biba_enabled) 1772101099Srwatson return (0); 1773101099Srwatson 1774122524Srwatson subj = SLOT(cred->cr_label); 1775122524Srwatson obj = SLOT(proc->p_ucred->cr_label); 1776103759Srwatson 1777101099Srwatson /* XXX: range checks */ 1778101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1779101099Srwatson return (ESRCH); 1780101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1781101099Srwatson return (EACCES); 1782101099Srwatson 1783101099Srwatson return (0); 1784101099Srwatson} 1785101099Srwatson 1786101099Srwatsonstatic int 1787101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1788101099Srwatson struct mbuf *m, struct label *mbuflabel) 1789101099Srwatson{ 1790101099Srwatson struct mac_biba *p, *s; 1791101099Srwatson 1792101099Srwatson if (!mac_biba_enabled) 1793101099Srwatson return (0); 1794101099Srwatson 1795101099Srwatson p = SLOT(mbuflabel); 1796101099Srwatson s = SLOT(socketlabel); 1797101099Srwatson 1798101099Srwatson return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1799101099Srwatson} 1800101099Srwatson 1801101099Srwatsonstatic int 1802106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1803101099Srwatson struct label *socketlabel, struct label *newlabel) 1804101099Srwatson{ 1805101099Srwatson struct mac_biba *subj, *obj, *new; 1806105634Srwatson int error; 1807101099Srwatson 1808101099Srwatson new = SLOT(newlabel); 1809122524Srwatson subj = SLOT(cred->cr_label); 1810101099Srwatson obj = SLOT(socketlabel); 1811101099Srwatson 1812101099Srwatson /* 1813105634Srwatson * If there is a Biba label update for the socket, it may be 1814105634Srwatson * an update of single. 1815101099Srwatson */ 1816105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1817105634Srwatson if (error) 1818105634Srwatson return (error); 1819101099Srwatson 1820101099Srwatson /* 1821105634Srwatson * To relabel a socket, the old socket single must be in the subject 1822101099Srwatson * range. 1823101099Srwatson */ 1824105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1825101099Srwatson return (EPERM); 1826101099Srwatson 1827101099Srwatson /* 1828105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1829101099Srwatson */ 1830105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1831105634Srwatson /* 1832105634Srwatson * To relabel a socket, the new socket single must be in 1833105634Srwatson * the subject range. 1834105634Srwatson */ 1835105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1836105634Srwatson return (EPERM); 1837101099Srwatson 1838105634Srwatson /* 1839105634Srwatson * To change the Biba label on the socket to contain EQUAL, 1840105634Srwatson * the subject must have appropriate privilege. 1841105634Srwatson */ 1842105634Srwatson if (mac_biba_contains_equal(new)) { 1843106090Srwatson error = mac_biba_subject_privileged(subj); 1844105634Srwatson if (error) 1845105634Srwatson return (error); 1846105634Srwatson } 1847105634Srwatson } 1848105634Srwatson 1849101099Srwatson return (0); 1850101099Srwatson} 1851101099Srwatson 1852101099Srwatsonstatic int 1853101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1854101099Srwatson struct label *socketlabel) 1855101099Srwatson{ 1856101099Srwatson struct mac_biba *subj, *obj; 1857101099Srwatson 1858105722Srwatson if (!mac_biba_enabled) 1859105722Srwatson return (0); 1860105722Srwatson 1861122524Srwatson subj = SLOT(cred->cr_label); 1862101099Srwatson obj = SLOT(socketlabel); 1863101099Srwatson 1864101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1865101099Srwatson return (ENOENT); 1866101099Srwatson 1867101099Srwatson return (0); 1868101099Srwatson} 1869101099Srwatson 1870101099Srwatsonstatic int 1871112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred) 1872112574Srwatson{ 1873112574Srwatson struct mac_biba *subj; 1874112574Srwatson int error; 1875112574Srwatson 1876112574Srwatson if (!mac_biba_enabled) 1877112574Srwatson return (0); 1878112574Srwatson 1879122524Srwatson subj = SLOT(cred->cr_label); 1880112574Srwatson 1881112574Srwatson error = mac_biba_subject_privileged(subj); 1882112574Srwatson if (error) 1883112574Srwatson return (error); 1884112574Srwatson 1885112574Srwatson return (0); 1886112574Srwatson} 1887112574Srwatson 1888112574Srwatsonstatic int 1889106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1890106418Srwatson struct label *label) 1891106418Srwatson{ 1892106418Srwatson struct mac_biba *subj, *obj; 1893106418Srwatson int error; 1894106418Srwatson 1895106418Srwatson if (!mac_biba_enabled) 1896106418Srwatson return (0); 1897106418Srwatson 1898122524Srwatson subj = SLOT(cred->cr_label); 1899106418Srwatson 1900106418Srwatson error = mac_biba_subject_privileged(subj); 1901106418Srwatson if (error) 1902106418Srwatson return (error); 1903106418Srwatson 1904106418Srwatson if (label == NULL) 1905106418Srwatson return (0); 1906106418Srwatson 1907106418Srwatson obj = SLOT(label); 1908106418Srwatson if (!mac_biba_high_single(obj)) 1909106418Srwatson return (EACCES); 1910106418Srwatson 1911106418Srwatson return (0); 1912106418Srwatson} 1913106418Srwatson 1914106418Srwatsonstatic int 1915106418Srwatsonmac_biba_check_system_settime(struct ucred *cred) 1916106418Srwatson{ 1917106418Srwatson struct mac_biba *subj; 1918106418Srwatson int error; 1919106418Srwatson 1920106418Srwatson if (!mac_biba_enabled) 1921106418Srwatson return (0); 1922106418Srwatson 1923122524Srwatson subj = SLOT(cred->cr_label); 1924106418Srwatson 1925106418Srwatson error = mac_biba_subject_privileged(subj); 1926106418Srwatson if (error) 1927106418Srwatson return (error); 1928106418Srwatson 1929106418Srwatson return (0); 1930106418Srwatson} 1931106418Srwatson 1932106418Srwatsonstatic int 1933106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1934106161Srwatson struct label *label) 1935106161Srwatson{ 1936106161Srwatson struct mac_biba *subj, *obj; 1937106416Srwatson int error; 1938106161Srwatson 1939106161Srwatson if (!mac_biba_enabled) 1940106161Srwatson return (0); 1941106161Srwatson 1942122524Srwatson subj = SLOT(cred->cr_label); 1943106161Srwatson obj = SLOT(label); 1944106161Srwatson 1945106416Srwatson error = mac_biba_subject_privileged(subj); 1946106416Srwatson if (error) 1947106416Srwatson return (error); 1948106161Srwatson 1949106161Srwatson if (!mac_biba_high_single(obj)) 1950106161Srwatson return (EACCES); 1951106161Srwatson 1952106161Srwatson return (0); 1953106161Srwatson} 1954106161Srwatson 1955106161Srwatsonstatic int 1956112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 1957112574Srwatson struct label *label) 1958112574Srwatson{ 1959112574Srwatson struct mac_biba *subj, *obj; 1960112574Srwatson int error; 1961112574Srwatson 1962112574Srwatson if (!mac_biba_enabled) 1963112574Srwatson return (0); 1964112574Srwatson 1965122524Srwatson subj = SLOT(cred->cr_label); 1966112574Srwatson obj = SLOT(label); 1967112574Srwatson 1968112574Srwatson error = mac_biba_subject_privileged(subj); 1969112574Srwatson if (error) 1970112574Srwatson return (error); 1971112574Srwatson 1972112574Srwatson return (0); 1973112574Srwatson} 1974112574Srwatson 1975112574Srwatsonstatic int 1976126121Spjdmac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 1977126121Spjd void *arg1, int arg2, struct sysctl_req *req) 1978106161Srwatson{ 1979106161Srwatson struct mac_biba *subj; 1980106161Srwatson int error; 1981106161Srwatson 1982106161Srwatson if (!mac_biba_enabled) 1983106161Srwatson return (0); 1984106161Srwatson 1985122524Srwatson subj = SLOT(cred->cr_label); 1986106161Srwatson 1987106161Srwatson /* 1988126121Spjd * Treat sysctl variables without CTLFLAG_ANYBODY flag as 1989126121Spjd * biba/high, but also require privilege to change them. 1990106161Srwatson */ 1991126121Spjd if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 1992106161Srwatson if (!mac_biba_subject_dominate_high(subj)) 1993106161Srwatson return (EACCES); 1994106161Srwatson 1995106161Srwatson error = mac_biba_subject_privileged(subj); 1996106161Srwatson if (error) 1997106161Srwatson return (error); 1998106161Srwatson } 1999106161Srwatson 2000106161Srwatson return (0); 2001106161Srwatson} 2002106161Srwatson 2003106161Srwatsonstatic int 2004101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2005101099Srwatson struct label *dlabel) 2006101099Srwatson{ 2007101099Srwatson struct mac_biba *subj, *obj; 2008101099Srwatson 2009101099Srwatson if (!mac_biba_enabled) 2010101099Srwatson return (0); 2011101099Srwatson 2012122524Srwatson subj = SLOT(cred->cr_label); 2013101099Srwatson obj = SLOT(dlabel); 2014101099Srwatson 2015101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2016101099Srwatson return (EACCES); 2017101099Srwatson 2018101099Srwatson return (0); 2019101099Srwatson} 2020101099Srwatson 2021101099Srwatsonstatic int 2022101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2023101099Srwatson struct label *dlabel) 2024101099Srwatson{ 2025101099Srwatson struct mac_biba *subj, *obj; 2026101099Srwatson 2027101099Srwatson if (!mac_biba_enabled) 2028101099Srwatson return (0); 2029101099Srwatson 2030122524Srwatson subj = SLOT(cred->cr_label); 2031101099Srwatson obj = SLOT(dlabel); 2032101099Srwatson 2033101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2034101099Srwatson return (EACCES); 2035101099Srwatson 2036101099Srwatson return (0); 2037101099Srwatson} 2038101099Srwatson 2039101099Srwatsonstatic int 2040101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2041101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2042101099Srwatson{ 2043101099Srwatson struct mac_biba *subj, *obj; 2044101099Srwatson 2045101099Srwatson if (!mac_biba_enabled) 2046101099Srwatson return (0); 2047101099Srwatson 2048122524Srwatson subj = SLOT(cred->cr_label); 2049101099Srwatson obj = SLOT(dlabel); 2050101099Srwatson 2051101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2052101099Srwatson return (EACCES); 2053101099Srwatson 2054101099Srwatson return (0); 2055101099Srwatson} 2056101099Srwatson 2057101099Srwatsonstatic int 2058101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2059101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2060101099Srwatson struct componentname *cnp) 2061101099Srwatson{ 2062101099Srwatson struct mac_biba *subj, *obj; 2063101099Srwatson 2064101099Srwatson if (!mac_biba_enabled) 2065101099Srwatson return (0); 2066101099Srwatson 2067122524Srwatson subj = SLOT(cred->cr_label); 2068101099Srwatson obj = SLOT(dlabel); 2069101099Srwatson 2070101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2071101099Srwatson return (EACCES); 2072101099Srwatson 2073101099Srwatson obj = SLOT(label); 2074101099Srwatson 2075101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2076101099Srwatson return (EACCES); 2077101099Srwatson 2078101099Srwatson return (0); 2079101099Srwatson} 2080101099Srwatson 2081101099Srwatsonstatic int 2082101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2083101099Srwatson struct label *label, acl_type_t type) 2084101099Srwatson{ 2085101099Srwatson struct mac_biba *subj, *obj; 2086101099Srwatson 2087101099Srwatson if (!mac_biba_enabled) 2088101099Srwatson return (0); 2089101099Srwatson 2090122524Srwatson subj = SLOT(cred->cr_label); 2091101099Srwatson obj = SLOT(label); 2092101099Srwatson 2093101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2094101099Srwatson return (EACCES); 2095101099Srwatson 2096101099Srwatson return (0); 2097101099Srwatson} 2098101099Srwatson 2099101099Srwatsonstatic int 2100119202Srwatsonmac_biba_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 2101119202Srwatson struct label *label, int attrnamespace, const char *name) 2102119202Srwatson{ 2103119202Srwatson struct mac_biba *subj, *obj; 2104119202Srwatson 2105119202Srwatson if (!mac_biba_enabled) 2106119202Srwatson return (0); 2107119202Srwatson 2108122524Srwatson subj = SLOT(cred->cr_label); 2109119202Srwatson obj = SLOT(label); 2110119202Srwatson 2111119202Srwatson if (!mac_biba_dominate_single(subj, obj)) 2112119202Srwatson return (EACCES); 2113119202Srwatson 2114119202Srwatson return (0); 2115119202Srwatson} 2116119202Srwatson 2117119202Srwatsonstatic int 2118101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2119106648Srwatson struct label *label, struct image_params *imgp, 2120106648Srwatson struct label *execlabel) 2121101099Srwatson{ 2122106648Srwatson struct mac_biba *subj, *obj, *exec; 2123106648Srwatson int error; 2124101099Srwatson 2125106648Srwatson if (execlabel != NULL) { 2126106648Srwatson /* 2127106648Srwatson * We currently don't permit labels to be changed at 2128106648Srwatson * exec-time as part of Biba, so disallow non-NULL 2129106648Srwatson * Biba label elements in the execlabel. 2130106648Srwatson */ 2131106648Srwatson exec = SLOT(execlabel); 2132106648Srwatson error = biba_atmostflags(exec, 0); 2133106648Srwatson if (error) 2134106648Srwatson return (error); 2135106648Srwatson } 2136106648Srwatson 2137101099Srwatson if (!mac_biba_enabled) 2138101099Srwatson return (0); 2139101099Srwatson 2140122524Srwatson subj = SLOT(cred->cr_label); 2141101099Srwatson obj = SLOT(label); 2142101099Srwatson 2143101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2144101099Srwatson return (EACCES); 2145101099Srwatson 2146101099Srwatson return (0); 2147101099Srwatson} 2148101099Srwatson 2149101099Srwatsonstatic int 2150101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2151101099Srwatson struct label *label, acl_type_t type) 2152101099Srwatson{ 2153101099Srwatson struct mac_biba *subj, *obj; 2154101099Srwatson 2155101099Srwatson if (!mac_biba_enabled) 2156101099Srwatson return (0); 2157101099Srwatson 2158122524Srwatson subj = SLOT(cred->cr_label); 2159101099Srwatson obj = SLOT(label); 2160101099Srwatson 2161101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2162101099Srwatson return (EACCES); 2163101099Srwatson 2164101099Srwatson return (0); 2165101099Srwatson} 2166101099Srwatson 2167101099Srwatsonstatic int 2168101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2169101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 2170101099Srwatson{ 2171101099Srwatson struct mac_biba *subj, *obj; 2172101099Srwatson 2173101099Srwatson if (!mac_biba_enabled) 2174101099Srwatson return (0); 2175101099Srwatson 2176122524Srwatson subj = SLOT(cred->cr_label); 2177101099Srwatson obj = SLOT(label); 2178101099Srwatson 2179101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2180101099Srwatson return (EACCES); 2181101099Srwatson 2182101099Srwatson return (0); 2183101099Srwatson} 2184101099Srwatson 2185101099Srwatsonstatic int 2186104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2187104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2188104530Srwatson struct componentname *cnp) 2189104530Srwatson{ 2190104530Srwatson struct mac_biba *subj, *obj; 2191104530Srwatson 2192104530Srwatson if (!mac_biba_enabled) 2193104530Srwatson return (0); 2194104530Srwatson 2195122524Srwatson subj = SLOT(cred->cr_label); 2196104530Srwatson obj = SLOT(dlabel); 2197104530Srwatson 2198104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2199104530Srwatson return (EACCES); 2200104530Srwatson 2201104530Srwatson obj = SLOT(label); 2202104530Srwatson 2203104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2204104530Srwatson return (EACCES); 2205104530Srwatson 2206104530Srwatson return (0); 2207104530Srwatson} 2208104530Srwatson 2209104530Srwatsonstatic int 2210119202Srwatsonmac_biba_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 2211119202Srwatson struct label *label, int attrnamespace) 2212119202Srwatson{ 2213119202Srwatson struct mac_biba *subj, *obj; 2214119202Srwatson 2215119202Srwatson if (!mac_biba_enabled) 2216119202Srwatson return (0); 2217119202Srwatson 2218122524Srwatson subj = SLOT(cred->cr_label); 2219119202Srwatson obj = SLOT(label); 2220119202Srwatson 2221119202Srwatson if (!mac_biba_dominate_single(obj, subj)) 2222119202Srwatson return (EACCES); 2223119202Srwatson 2224119202Srwatson return (0); 2225119202Srwatson} 2226119202Srwatson 2227119202Srwatsonstatic int 2228103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2229101099Srwatson struct label *dlabel, struct componentname *cnp) 2230101099Srwatson{ 2231101099Srwatson struct mac_biba *subj, *obj; 2232103759Srwatson 2233101099Srwatson if (!mac_biba_enabled) 2234101099Srwatson return (0); 2235103759Srwatson 2236122524Srwatson subj = SLOT(cred->cr_label); 2237101099Srwatson obj = SLOT(dlabel); 2238103759Srwatson 2239101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2240101099Srwatson return (EACCES); 2241101099Srwatson 2242103759Srwatson return (0); 2243101099Srwatson} 2244101099Srwatson 2245101099Srwatsonstatic int 2246104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2247104546Srwatson struct label *label, int prot) 2248104546Srwatson{ 2249104546Srwatson struct mac_biba *subj, *obj; 2250104546Srwatson 2251104546Srwatson /* 2252104546Srwatson * Rely on the use of open()-time protections to handle 2253104546Srwatson * non-revocation cases. 2254104546Srwatson */ 2255105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2256104546Srwatson return (0); 2257104546Srwatson 2258122524Srwatson subj = SLOT(cred->cr_label); 2259104546Srwatson obj = SLOT(label); 2260104546Srwatson 2261104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2262104546Srwatson if (!mac_biba_dominate_single(obj, subj)) 2263104546Srwatson return (EACCES); 2264104546Srwatson } 2265104546Srwatson if (prot & VM_PROT_WRITE) { 2266104546Srwatson if (!mac_biba_dominate_single(subj, obj)) 2267104546Srwatson return (EACCES); 2268104546Srwatson } 2269104546Srwatson 2270104569Srwatson return (0); 2271104546Srwatson} 2272104546Srwatson 2273104546Srwatsonstatic int 2274101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2275106212Srwatson struct label *vnodelabel, int acc_mode) 2276101099Srwatson{ 2277101099Srwatson struct mac_biba *subj, *obj; 2278101099Srwatson 2279101099Srwatson if (!mac_biba_enabled) 2280101099Srwatson return (0); 2281101099Srwatson 2282122524Srwatson subj = SLOT(cred->cr_label); 2283101099Srwatson obj = SLOT(vnodelabel); 2284101099Srwatson 2285101099Srwatson /* XXX privilege override for admin? */ 2286101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2287101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2288101099Srwatson return (EACCES); 2289101099Srwatson } 2290101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2291101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2292101099Srwatson return (EACCES); 2293101099Srwatson } 2294101099Srwatson 2295101099Srwatson return (0); 2296101099Srwatson} 2297101099Srwatson 2298101099Srwatsonstatic int 2299102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2300102129Srwatson struct vnode *vp, struct label *label) 2301102112Srwatson{ 2302102112Srwatson struct mac_biba *subj, *obj; 2303102112Srwatson 2304105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2305102112Srwatson return (0); 2306102112Srwatson 2307122524Srwatson subj = SLOT(active_cred->cr_label); 2308102112Srwatson obj = SLOT(label); 2309102112Srwatson 2310102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2311102112Srwatson return (EACCES); 2312102112Srwatson 2313102112Srwatson return (0); 2314102112Srwatson} 2315102112Srwatson 2316102112Srwatsonstatic int 2317102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2318102129Srwatson struct vnode *vp, struct label *label) 2319102112Srwatson{ 2320102112Srwatson struct mac_biba *subj, *obj; 2321102112Srwatson 2322105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2323102112Srwatson return (0); 2324102112Srwatson 2325122524Srwatson subj = SLOT(active_cred->cr_label); 2326102112Srwatson obj = SLOT(label); 2327102112Srwatson 2328102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2329102112Srwatson return (EACCES); 2330102112Srwatson 2331102112Srwatson return (0); 2332102112Srwatson} 2333102112Srwatson 2334102112Srwatsonstatic int 2335101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2336101099Srwatson struct label *dlabel) 2337101099Srwatson{ 2338101099Srwatson struct mac_biba *subj, *obj; 2339101099Srwatson 2340101099Srwatson if (!mac_biba_enabled) 2341101099Srwatson return (0); 2342101099Srwatson 2343122524Srwatson subj = SLOT(cred->cr_label); 2344101099Srwatson obj = SLOT(dlabel); 2345101099Srwatson 2346101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2347101099Srwatson return (EACCES); 2348101099Srwatson 2349101099Srwatson return (0); 2350101099Srwatson} 2351101099Srwatson 2352101099Srwatsonstatic int 2353101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2354101099Srwatson struct label *label) 2355101099Srwatson{ 2356101099Srwatson struct mac_biba *subj, *obj; 2357101099Srwatson 2358101099Srwatson if (!mac_biba_enabled) 2359101099Srwatson return (0); 2360101099Srwatson 2361122524Srwatson subj = SLOT(cred->cr_label); 2362101099Srwatson obj = SLOT(label); 2363101099Srwatson 2364101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2365101099Srwatson return (EACCES); 2366101099Srwatson 2367101099Srwatson return (0); 2368101099Srwatson} 2369101099Srwatson 2370101099Srwatsonstatic int 2371101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2372101099Srwatson struct label *vnodelabel, struct label *newlabel) 2373101099Srwatson{ 2374101099Srwatson struct mac_biba *old, *new, *subj; 2375105634Srwatson int error; 2376101099Srwatson 2377101099Srwatson old = SLOT(vnodelabel); 2378101099Srwatson new = SLOT(newlabel); 2379122524Srwatson subj = SLOT(cred->cr_label); 2380101099Srwatson 2381101099Srwatson /* 2382105634Srwatson * If there is a Biba label update for the vnode, it must be a 2383105634Srwatson * single label. 2384101099Srwatson */ 2385105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2386105634Srwatson if (error) 2387105634Srwatson return (error); 2388101099Srwatson 2389101099Srwatson /* 2390105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2391105634Srwatson * authorize the relabel. 2392101099Srwatson */ 2393105634Srwatson if (!mac_biba_single_in_range(old, subj)) 2394101099Srwatson return (EPERM); 2395101099Srwatson 2396101099Srwatson /* 2397105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2398101099Srwatson */ 2399105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2400105634Srwatson /* 2401105634Srwatson * To change the Biba label on a vnode, the new vnode label 2402105634Srwatson * must be in the subject range. 2403105634Srwatson */ 2404105634Srwatson if (!mac_biba_single_in_range(new, subj)) 2405105634Srwatson return (EPERM); 2406101099Srwatson 2407105634Srwatson /* 2408105634Srwatson * To change the Biba label on the vnode to be EQUAL, 2409105634Srwatson * the subject must have appropriate privilege. 2410105634Srwatson */ 2411105634Srwatson if (mac_biba_contains_equal(new)) { 2412106090Srwatson error = mac_biba_subject_privileged(subj); 2413105634Srwatson if (error) 2414105634Srwatson return (error); 2415105634Srwatson } 2416105634Srwatson } 2417105634Srwatson 2418105634Srwatson return (0); 2419101099Srwatson} 2420101099Srwatson 2421101099Srwatsonstatic int 2422101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2423101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2424101099Srwatson struct componentname *cnp) 2425101099Srwatson{ 2426101099Srwatson struct mac_biba *subj, *obj; 2427101099Srwatson 2428101099Srwatson if (!mac_biba_enabled) 2429101099Srwatson return (0); 2430101099Srwatson 2431122524Srwatson subj = SLOT(cred->cr_label); 2432101099Srwatson obj = SLOT(dlabel); 2433101099Srwatson 2434101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2435101099Srwatson return (EACCES); 2436101099Srwatson 2437101099Srwatson obj = SLOT(label); 2438101099Srwatson 2439101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2440101099Srwatson return (EACCES); 2441101099Srwatson 2442101099Srwatson return (0); 2443101099Srwatson} 2444101099Srwatson 2445101099Srwatsonstatic int 2446101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2447101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2448101099Srwatson struct componentname *cnp) 2449101099Srwatson{ 2450101099Srwatson struct mac_biba *subj, *obj; 2451101099Srwatson 2452101099Srwatson if (!mac_biba_enabled) 2453101099Srwatson return (0); 2454101099Srwatson 2455122524Srwatson subj = SLOT(cred->cr_label); 2456101099Srwatson obj = SLOT(dlabel); 2457101099Srwatson 2458101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2459101099Srwatson return (EACCES); 2460101099Srwatson 2461101099Srwatson if (vp != NULL) { 2462101099Srwatson obj = SLOT(label); 2463101099Srwatson 2464101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2465101099Srwatson return (EACCES); 2466101099Srwatson } 2467101099Srwatson 2468101099Srwatson return (0); 2469101099Srwatson} 2470101099Srwatson 2471101099Srwatsonstatic int 2472101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2473101099Srwatson struct label *label) 2474101099Srwatson{ 2475101099Srwatson struct mac_biba *subj, *obj; 2476101099Srwatson 2477101099Srwatson if (!mac_biba_enabled) 2478101099Srwatson return (0); 2479101099Srwatson 2480122524Srwatson subj = SLOT(cred->cr_label); 2481101099Srwatson obj = SLOT(label); 2482101099Srwatson 2483101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2484101099Srwatson return (EACCES); 2485101099Srwatson 2486101099Srwatson return (0); 2487101099Srwatson} 2488101099Srwatson 2489101099Srwatsonstatic int 2490101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2491101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 2492101099Srwatson{ 2493101099Srwatson struct mac_biba *subj, *obj; 2494101099Srwatson 2495101099Srwatson if (!mac_biba_enabled) 2496101099Srwatson return (0); 2497101099Srwatson 2498122524Srwatson subj = SLOT(cred->cr_label); 2499101099Srwatson obj = SLOT(label); 2500101099Srwatson 2501101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2502101099Srwatson return (EACCES); 2503101099Srwatson 2504101099Srwatson return (0); 2505101099Srwatson} 2506101099Srwatson 2507101099Srwatsonstatic int 2508101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2509101099Srwatson struct label *vnodelabel, int attrnamespace, const char *name, 2510101099Srwatson struct uio *uio) 2511101099Srwatson{ 2512101099Srwatson struct mac_biba *subj, *obj; 2513101099Srwatson 2514101099Srwatson if (!mac_biba_enabled) 2515101099Srwatson return (0); 2516101099Srwatson 2517122524Srwatson subj = SLOT(cred->cr_label); 2518101099Srwatson obj = SLOT(vnodelabel); 2519101099Srwatson 2520101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2521101099Srwatson return (EACCES); 2522101099Srwatson 2523101099Srwatson /* XXX: protect the MAC EA in a special way? */ 2524101099Srwatson 2525101099Srwatson return (0); 2526101099Srwatson} 2527101099Srwatson 2528101099Srwatsonstatic int 2529101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2530101099Srwatson struct label *vnodelabel, u_long flags) 2531101099Srwatson{ 2532101099Srwatson struct mac_biba *subj, *obj; 2533101099Srwatson 2534101099Srwatson if (!mac_biba_enabled) 2535101099Srwatson return (0); 2536101099Srwatson 2537122524Srwatson subj = SLOT(cred->cr_label); 2538101099Srwatson obj = SLOT(vnodelabel); 2539101099Srwatson 2540101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2541101099Srwatson return (EACCES); 2542101099Srwatson 2543101099Srwatson return (0); 2544101099Srwatson} 2545101099Srwatson 2546101099Srwatsonstatic int 2547101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2548101099Srwatson struct label *vnodelabel, mode_t mode) 2549101099Srwatson{ 2550101099Srwatson struct mac_biba *subj, *obj; 2551101099Srwatson 2552101099Srwatson if (!mac_biba_enabled) 2553101099Srwatson return (0); 2554101099Srwatson 2555122524Srwatson subj = SLOT(cred->cr_label); 2556101099Srwatson obj = SLOT(vnodelabel); 2557101099Srwatson 2558101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2559101099Srwatson return (EACCES); 2560101099Srwatson 2561101099Srwatson return (0); 2562101099Srwatson} 2563101099Srwatson 2564101099Srwatsonstatic int 2565101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2566101099Srwatson struct label *vnodelabel, uid_t uid, gid_t gid) 2567101099Srwatson{ 2568101099Srwatson struct mac_biba *subj, *obj; 2569101099Srwatson 2570101099Srwatson if (!mac_biba_enabled) 2571101099Srwatson return (0); 2572101099Srwatson 2573122524Srwatson subj = SLOT(cred->cr_label); 2574101099Srwatson obj = SLOT(vnodelabel); 2575101099Srwatson 2576101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2577101099Srwatson return (EACCES); 2578101099Srwatson 2579101099Srwatson return (0); 2580101099Srwatson} 2581101099Srwatson 2582101099Srwatsonstatic int 2583101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2584101099Srwatson struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2585101099Srwatson{ 2586101099Srwatson struct mac_biba *subj, *obj; 2587101099Srwatson 2588101099Srwatson if (!mac_biba_enabled) 2589101099Srwatson return (0); 2590101099Srwatson 2591122524Srwatson subj = SLOT(cred->cr_label); 2592101099Srwatson obj = SLOT(vnodelabel); 2593101099Srwatson 2594101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2595101099Srwatson return (EACCES); 2596101099Srwatson 2597101099Srwatson return (0); 2598101099Srwatson} 2599101099Srwatson 2600101099Srwatsonstatic int 2601102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2602102129Srwatson struct vnode *vp, struct label *vnodelabel) 2603101099Srwatson{ 2604101099Srwatson struct mac_biba *subj, *obj; 2605101099Srwatson 2606101099Srwatson if (!mac_biba_enabled) 2607101099Srwatson return (0); 2608101099Srwatson 2609122524Srwatson subj = SLOT(active_cred->cr_label); 2610101099Srwatson obj = SLOT(vnodelabel); 2611101099Srwatson 2612101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2613101099Srwatson return (EACCES); 2614101099Srwatson 2615101099Srwatson return (0); 2616101099Srwatson} 2617101099Srwatson 2618102112Srwatsonstatic int 2619102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred, 2620102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 2621102112Srwatson{ 2622102112Srwatson struct mac_biba *subj, *obj; 2623102112Srwatson 2624105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2625102112Srwatson return (0); 2626102112Srwatson 2627122524Srwatson subj = SLOT(active_cred->cr_label); 2628102112Srwatson obj = SLOT(label); 2629102112Srwatson 2630102112Srwatson if (!mac_biba_dominate_single(subj, obj)) 2631102112Srwatson return (EACCES); 2632102112Srwatson 2633102112Srwatson return (0); 2634102112Srwatson} 2635102112Srwatson 2636106217Srwatsonstatic struct mac_policy_ops mac_biba_ops = 2637101099Srwatson{ 2638106217Srwatson .mpo_init = mac_biba_init, 2639106217Srwatson .mpo_init_bpfdesc_label = mac_biba_init_label, 2640106217Srwatson .mpo_init_cred_label = mac_biba_init_label, 2641106217Srwatson .mpo_init_devfsdirent_label = mac_biba_init_label, 2642106217Srwatson .mpo_init_ifnet_label = mac_biba_init_label, 2643122875Srwatson .mpo_init_inpcb_label = mac_biba_init_label_waitcheck, 2644112675Srwatson .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 2645106217Srwatson .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2646106217Srwatson .mpo_init_mount_label = mac_biba_init_label, 2647106217Srwatson .mpo_init_mount_fs_label = mac_biba_init_label, 2648106217Srwatson .mpo_init_pipe_label = mac_biba_init_label, 2649106217Srwatson .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2650106217Srwatson .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2651106217Srwatson .mpo_init_vnode_label = mac_biba_init_label, 2652106217Srwatson .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2653106217Srwatson .mpo_destroy_cred_label = mac_biba_destroy_label, 2654106217Srwatson .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2655106217Srwatson .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2656122875Srwatson .mpo_destroy_inpcb_label = mac_biba_destroy_label, 2657106217Srwatson .mpo_destroy_ipq_label = mac_biba_destroy_label, 2658106217Srwatson .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2659106217Srwatson .mpo_destroy_mount_label = mac_biba_destroy_label, 2660106217Srwatson .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2661106217Srwatson .mpo_destroy_pipe_label = mac_biba_destroy_label, 2662106217Srwatson .mpo_destroy_socket_label = mac_biba_destroy_label, 2663106217Srwatson .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2664106217Srwatson .mpo_destroy_vnode_label = mac_biba_destroy_label, 2665123173Srwatson .mpo_copy_cred_label = mac_biba_copy_label, 2666115707Srwatson .mpo_copy_mbuf_label = mac_biba_copy_label, 2667106217Srwatson .mpo_copy_pipe_label = mac_biba_copy_label, 2668122820Srwatson .mpo_copy_socket_label = mac_biba_copy_label, 2669106217Srwatson .mpo_copy_vnode_label = mac_biba_copy_label, 2670106217Srwatson .mpo_externalize_cred_label = mac_biba_externalize_label, 2671106217Srwatson .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2672106217Srwatson .mpo_externalize_pipe_label = mac_biba_externalize_label, 2673106217Srwatson .mpo_externalize_socket_label = mac_biba_externalize_label, 2674106217Srwatson .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2675106217Srwatson .mpo_externalize_vnode_label = mac_biba_externalize_label, 2676106217Srwatson .mpo_internalize_cred_label = mac_biba_internalize_label, 2677106217Srwatson .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2678106217Srwatson .mpo_internalize_pipe_label = mac_biba_internalize_label, 2679106217Srwatson .mpo_internalize_socket_label = mac_biba_internalize_label, 2680106217Srwatson .mpo_internalize_vnode_label = mac_biba_internalize_label, 2681106217Srwatson .mpo_create_devfs_device = mac_biba_create_devfs_device, 2682106217Srwatson .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2683106217Srwatson .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2684106217Srwatson .mpo_create_mount = mac_biba_create_mount, 2685106217Srwatson .mpo_create_root_mount = mac_biba_create_root_mount, 2686106217Srwatson .mpo_relabel_vnode = mac_biba_relabel_vnode, 2687106217Srwatson .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2688106217Srwatson .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2689106217Srwatson .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2690106217Srwatson .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2691106217Srwatson .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2692106217Srwatson .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2693106217Srwatson .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2694106217Srwatson .mpo_create_pipe = mac_biba_create_pipe, 2695106217Srwatson .mpo_create_socket = mac_biba_create_socket, 2696106217Srwatson .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2697106217Srwatson .mpo_relabel_pipe = mac_biba_relabel_pipe, 2698106217Srwatson .mpo_relabel_socket = mac_biba_relabel_socket, 2699106217Srwatson .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2700106217Srwatson .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2701106217Srwatson .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2702106217Srwatson .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2703106217Srwatson .mpo_create_fragment = mac_biba_create_fragment, 2704106217Srwatson .mpo_create_ifnet = mac_biba_create_ifnet, 2705122875Srwatson .mpo_create_inpcb_from_socket = mac_biba_create_inpcb_from_socket, 2706106217Srwatson .mpo_create_ipq = mac_biba_create_ipq, 2707123607Srwatson .mpo_create_mbuf_from_inpcb = mac_biba_create_mbuf_from_inpcb, 2708106217Srwatson .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2709106217Srwatson .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2710106217Srwatson .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2711106217Srwatson .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2712106217Srwatson .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2713106217Srwatson .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2714106217Srwatson .mpo_fragment_match = mac_biba_fragment_match, 2715106217Srwatson .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2716106217Srwatson .mpo_update_ipq = mac_biba_update_ipq, 2717122875Srwatson .mpo_inpcb_sosetlabel = mac_biba_inpcb_sosetlabel, 2718106217Srwatson .mpo_create_proc0 = mac_biba_create_proc0, 2719106217Srwatson .mpo_create_proc1 = mac_biba_create_proc1, 2720106217Srwatson .mpo_relabel_cred = mac_biba_relabel_cred, 2721106217Srwatson .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2722106217Srwatson .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2723106217Srwatson .mpo_check_cred_visible = mac_biba_check_cred_visible, 2724106217Srwatson .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2725106217Srwatson .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2726122875Srwatson .mpo_check_inpcb_deliver = mac_biba_check_inpcb_deliver, 2727110354Srwatson .mpo_check_kld_load = mac_biba_check_kld_load, 2728110354Srwatson .mpo_check_kld_unload = mac_biba_check_kld_unload, 2729106217Srwatson .mpo_check_mount_stat = mac_biba_check_mount_stat, 2730106217Srwatson .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2731106217Srwatson .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2732106217Srwatson .mpo_check_pipe_read = mac_biba_check_pipe_read, 2733106217Srwatson .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2734106217Srwatson .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2735106217Srwatson .mpo_check_pipe_write = mac_biba_check_pipe_write, 2736106217Srwatson .mpo_check_proc_debug = mac_biba_check_proc_debug, 2737106217Srwatson .mpo_check_proc_sched = mac_biba_check_proc_sched, 2738106217Srwatson .mpo_check_proc_signal = mac_biba_check_proc_signal, 2739106217Srwatson .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2740106217Srwatson .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2741106217Srwatson .mpo_check_socket_visible = mac_biba_check_socket_visible, 2742112574Srwatson .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 2743106418Srwatson .mpo_check_system_acct = mac_biba_check_system_acct, 2744106418Srwatson .mpo_check_system_settime = mac_biba_check_system_settime, 2745106217Srwatson .mpo_check_system_swapon = mac_biba_check_system_swapon, 2746112574Srwatson .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 2747106217Srwatson .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2748106217Srwatson .mpo_check_vnode_access = mac_biba_check_vnode_open, 2749106217Srwatson .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2750106217Srwatson .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2751106217Srwatson .mpo_check_vnode_create = mac_biba_check_vnode_create, 2752106217Srwatson .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2753106217Srwatson .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2754119202Srwatson .mpo_check_vnode_deleteextattr = mac_biba_check_vnode_deleteextattr, 2755106217Srwatson .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2756106217Srwatson .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2757106217Srwatson .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2758106217Srwatson .mpo_check_vnode_link = mac_biba_check_vnode_link, 2759119202Srwatson .mpo_check_vnode_listextattr = mac_biba_check_vnode_listextattr, 2760106217Srwatson .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2761106217Srwatson .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2762106217Srwatson .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2763106217Srwatson .mpo_check_vnode_open = mac_biba_check_vnode_open, 2764106217Srwatson .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2765106217Srwatson .mpo_check_vnode_read = mac_biba_check_vnode_read, 2766106217Srwatson .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2767106217Srwatson .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2768106217Srwatson .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2769106217Srwatson .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2770106217Srwatson .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2771106217Srwatson .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2772106217Srwatson .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2773106217Srwatson .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2774106217Srwatson .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2775106217Srwatson .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2776106217Srwatson .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2777106217Srwatson .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2778106217Srwatson .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2779106217Srwatson .mpo_check_vnode_write = mac_biba_check_vnode_write, 2780101099Srwatson}; 2781101099Srwatson 2782112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 2783113531Srwatson MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot); 2784