mac_biba.c revision 111119
1101099Srwatson/*- 2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3101099Srwatson * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 4101099Srwatson * All rights reserved. 5101099Srwatson * 6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 7101099Srwatson * 8106393Srwatson * This software was developed for the FreeBSD Project in part by Network 9106393Srwatson * Associates Laboratories, the Security Research Division of Network 10106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 11106393Srwatson * as part of the DARPA CHATS research program. 12101099Srwatson * 13101099Srwatson * Redistribution and use in source and binary forms, with or without 14101099Srwatson * modification, are permitted provided that the following conditions 15101099Srwatson * are met: 16101099Srwatson * 1. Redistributions of source code must retain the above copyright 17101099Srwatson * notice, this list of conditions and the following disclaimer. 18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright 19101099Srwatson * notice, this list of conditions and the following disclaimer in the 20101099Srwatson * documentation and/or other materials provided with the distribution. 21101099Srwatson * 22101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32101099Srwatson * SUCH DAMAGE. 33101099Srwatson * 34101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 111119 2003-02-19 05:47:46Z imp $ 35101099Srwatson */ 36101099Srwatson 37101099Srwatson/* 38101099Srwatson * Developed by the TrustedBSD Project. 39101099Srwatson * Biba fixed label mandatory integrity policy. 40101099Srwatson */ 41101099Srwatson 42101099Srwatson#include <sys/types.h> 43101099Srwatson#include <sys/param.h> 44101099Srwatson#include <sys/acl.h> 45101099Srwatson#include <sys/conf.h> 46105988Srwatson#include <sys/extattr.h> 47101099Srwatson#include <sys/kernel.h> 48101099Srwatson#include <sys/mac.h> 49103183Sbde#include <sys/malloc.h> 50101099Srwatson#include <sys/mount.h> 51101099Srwatson#include <sys/proc.h> 52101099Srwatson#include <sys/systm.h> 53101099Srwatson#include <sys/sysproto.h> 54101099Srwatson#include <sys/sysent.h> 55105696Srwatson#include <sys/systm.h> 56101099Srwatson#include <sys/vnode.h> 57101099Srwatson#include <sys/file.h> 58101099Srwatson#include <sys/socket.h> 59101099Srwatson#include <sys/socketvar.h> 60101099Srwatson#include <sys/pipe.h> 61101099Srwatson#include <sys/sysctl.h> 62101099Srwatson 63101099Srwatson#include <fs/devfs/devfs.h> 64101099Srwatson 65101099Srwatson#include <net/bpfdesc.h> 66101099Srwatson#include <net/if.h> 67101099Srwatson#include <net/if_types.h> 68101099Srwatson#include <net/if_var.h> 69101099Srwatson 70101099Srwatson#include <netinet/in.h> 71101099Srwatson#include <netinet/ip_var.h> 72101099Srwatson 73101099Srwatson#include <vm/vm.h> 74101099Srwatson 75101099Srwatson#include <sys/mac_policy.h> 76101099Srwatson 77101099Srwatson#include <security/mac_biba/mac_biba.h> 78101099Srwatson 79101099SrwatsonSYSCTL_DECL(_security_mac); 80101099Srwatson 81101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 82101099Srwatson "TrustedBSD mac_biba policy controls"); 83101099Srwatson 84105988Srwatsonstatic int mac_biba_label_size = sizeof(struct mac_biba); 85105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 86105988Srwatson &mac_biba_label_size, 0, "Size of struct mac_biba"); 87105988Srwatson 88107731Srwatsonstatic int mac_biba_enabled = 1; 89101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 90101099Srwatson &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 91102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 92101099Srwatson 93101099Srwatsonstatic int destroyed_not_inited; 94101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 95101099Srwatson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 96101099Srwatson 97101099Srwatsonstatic int trust_all_interfaces = 0; 98101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 99101099Srwatson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 100101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 101101099Srwatson 102101099Srwatsonstatic char trusted_interfaces[128]; 103101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 104101099Srwatson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 105101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 106101099Srwatson sizeof(trusted_interfaces)); 107101099Srwatson 108105643Srwatsonstatic int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 109105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 110105643Srwatson &max_compartments, 0, "Maximum supported compartments"); 111105643Srwatson 112105606Srwatsonstatic int ptys_equal = 0; 113105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 114105606Srwatson &ptys_equal, 0, "Label pty devices as biba/equal on create"); 115105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 116105606Srwatson 117105637Srwatsonstatic int revocation_enabled = 0; 118101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 119105637Srwatson &revocation_enabled, 0, "Revoke access to objects on relabel"); 120105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 121101099Srwatson 122101099Srwatsonstatic int mac_biba_slot; 123101099Srwatson#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 124101099Srwatson 125101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels"); 126101099Srwatson 127105643Srwatsonstatic __inline int 128105643Srwatsonbiba_bit_set_empty(u_char *set) { 129105643Srwatson int i; 130105643Srwatson 131105643Srwatson for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 132105643Srwatson if (set[i] != 0) 133105643Srwatson return (0); 134105643Srwatson return (1); 135105643Srwatson} 136105643Srwatson 137101099Srwatsonstatic struct mac_biba * 138104514Srwatsonbiba_alloc(int flag) 139101099Srwatson{ 140101099Srwatson struct mac_biba *mac_biba; 141101099Srwatson 142104514Srwatson mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag); 143101099Srwatson 144101099Srwatson return (mac_biba); 145101099Srwatson} 146101099Srwatson 147101099Srwatsonstatic void 148101099Srwatsonbiba_free(struct mac_biba *mac_biba) 149101099Srwatson{ 150101099Srwatson 151101099Srwatson if (mac_biba != NULL) 152101099Srwatson free(mac_biba, M_MACBIBA); 153101099Srwatson else 154101099Srwatson atomic_add_int(&destroyed_not_inited, 1); 155101099Srwatson} 156101099Srwatson 157101099Srwatsonstatic int 158105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags) 159105634Srwatson{ 160105634Srwatson 161105634Srwatson if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 162105634Srwatson return (EINVAL); 163105634Srwatson return (0); 164105634Srwatson} 165105634Srwatson 166105634Srwatsonstatic int 167101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a, 168101099Srwatson struct mac_biba_element *b) 169101099Srwatson{ 170105643Srwatson int bit; 171101099Srwatson 172105736Srwatson switch (a->mbe_type) { 173101099Srwatson case MAC_BIBA_TYPE_EQUAL: 174101099Srwatson case MAC_BIBA_TYPE_HIGH: 175101099Srwatson return (1); 176101099Srwatson 177101099Srwatson case MAC_BIBA_TYPE_LOW: 178101099Srwatson switch (b->mbe_type) { 179101099Srwatson case MAC_BIBA_TYPE_GRADE: 180101099Srwatson case MAC_BIBA_TYPE_HIGH: 181101099Srwatson return (0); 182101099Srwatson 183101099Srwatson case MAC_BIBA_TYPE_EQUAL: 184101099Srwatson case MAC_BIBA_TYPE_LOW: 185101099Srwatson return (1); 186101099Srwatson 187101099Srwatson default: 188101099Srwatson panic("mac_biba_dominate_element: b->mbe_type invalid"); 189101099Srwatson } 190101099Srwatson 191101099Srwatson case MAC_BIBA_TYPE_GRADE: 192101099Srwatson switch (b->mbe_type) { 193101099Srwatson case MAC_BIBA_TYPE_EQUAL: 194101099Srwatson case MAC_BIBA_TYPE_LOW: 195101099Srwatson return (1); 196101099Srwatson 197101099Srwatson case MAC_BIBA_TYPE_HIGH: 198101099Srwatson return (0); 199101099Srwatson 200101099Srwatson case MAC_BIBA_TYPE_GRADE: 201105643Srwatson for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 202105643Srwatson if (!MAC_BIBA_BIT_TEST(bit, 203105643Srwatson a->mbe_compartments) && 204105643Srwatson MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 205105643Srwatson return (0); 206101099Srwatson return (a->mbe_grade >= b->mbe_grade); 207101099Srwatson 208101099Srwatson default: 209101099Srwatson panic("mac_biba_dominate_element: b->mbe_type invalid"); 210101099Srwatson } 211101099Srwatson 212101099Srwatson default: 213101099Srwatson panic("mac_biba_dominate_element: a->mbe_type invalid"); 214101099Srwatson } 215101099Srwatson 216101099Srwatson return (0); 217101099Srwatson} 218101099Srwatson 219101099Srwatsonstatic int 220105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba) 221105988Srwatson{ 222105988Srwatson struct mac_biba_element *element; 223105988Srwatson 224106174Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 225105988Srwatson ("mac_biba_single_in_range: mac_biba not single")); 226105988Srwatson element = &mac_biba->mb_single; 227105988Srwatson 228105988Srwatson return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 229105988Srwatson element->mbe_type == MAC_BIBA_TYPE_HIGH); 230105988Srwatson} 231105988Srwatson 232105988Srwatsonstatic int 233101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 234101099Srwatson{ 235101099Srwatson 236101099Srwatson return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 237101099Srwatson &rangea->mb_rangehigh) && 238101099Srwatson mac_biba_dominate_element(&rangea->mb_rangelow, 239101099Srwatson &rangeb->mb_rangelow)); 240101099Srwatson} 241101099Srwatson 242101099Srwatsonstatic int 243101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range) 244101099Srwatson{ 245101099Srwatson 246103750Srwatson KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 247101099Srwatson ("mac_biba_single_in_range: a not single")); 248103750Srwatson KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 249101099Srwatson ("mac_biba_single_in_range: b not range")); 250101099Srwatson 251101099Srwatson return (mac_biba_dominate_element(&range->mb_rangehigh, 252101099Srwatson &single->mb_single) && 253101099Srwatson mac_biba_dominate_element(&single->mb_single, 254101099Srwatson &range->mb_rangelow)); 255101099Srwatson 256101099Srwatson return (1); 257101099Srwatson} 258101099Srwatson 259101099Srwatsonstatic int 260101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b) 261101099Srwatson{ 262101099Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 263101099Srwatson ("mac_biba_dominate_single: a not single")); 264101099Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 265101099Srwatson ("mac_biba_dominate_single: b not single")); 266101099Srwatson 267101099Srwatson return (mac_biba_dominate_element(&a->mb_single, &b->mb_single)); 268101099Srwatson} 269101099Srwatson 270101099Srwatsonstatic int 271101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 272101099Srwatson{ 273101099Srwatson 274101099Srwatson if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 275101099Srwatson b->mbe_type == MAC_BIBA_TYPE_EQUAL) 276101099Srwatson return (1); 277101099Srwatson 278101099Srwatson return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 279101099Srwatson} 280101099Srwatson 281101099Srwatsonstatic int 282101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b) 283101099Srwatson{ 284101099Srwatson 285101099Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 286101099Srwatson ("mac_biba_equal_single: a not single")); 287101099Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 288101099Srwatson ("mac_biba_equal_single: b not single")); 289101099Srwatson 290101099Srwatson return (mac_biba_equal_element(&a->mb_single, &b->mb_single)); 291101099Srwatson} 292101099Srwatson 293101099Srwatsonstatic int 294105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba) 295105634Srwatson{ 296105634Srwatson 297105634Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) 298105634Srwatson if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 299105634Srwatson return (1); 300105634Srwatson 301105634Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 302105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 303105634Srwatson return (1); 304105634Srwatson if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 305105637Srwatson return (1); 306105634Srwatson } 307105634Srwatson 308105634Srwatson return (0); 309105634Srwatson} 310105634Srwatson 311105634Srwatsonstatic int 312106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba) 313105634Srwatson{ 314105634Srwatson 315105634Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 316105634Srwatson MAC_BIBA_FLAGS_BOTH, 317106090Srwatson ("mac_biba_subject_privileged: subject doesn't have both labels")); 318105634Srwatson 319105634Srwatson /* If the single is EQUAL, it's ok. */ 320105634Srwatson if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 321105634Srwatson return (0); 322105634Srwatson 323105634Srwatson /* If either range endpoint is EQUAL, it's ok. */ 324105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 325105634Srwatson mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 326105634Srwatson return (0); 327105634Srwatson 328105634Srwatson /* If the range is low-high, it's ok. */ 329105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 330105634Srwatson mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 331105634Srwatson return (0); 332105634Srwatson 333105634Srwatson /* It's not ok. */ 334105634Srwatson return (EPERM); 335105634Srwatson} 336105634Srwatson 337106091Srwatsonstatic int 338105988Srwatsonmac_biba_high_single(struct mac_biba *mac_biba) 339105988Srwatson{ 340105988Srwatson 341105988Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 342105988Srwatson ("mac_biba_equal_single: mac_biba not single")); 343105988Srwatson 344105988Srwatson return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH); 345105988Srwatson} 346105988Srwatson 347105634Srwatsonstatic int 348101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba) 349101099Srwatson{ 350101099Srwatson 351101099Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 352101099Srwatson switch (mac_biba->mb_single.mbe_type) { 353101099Srwatson case MAC_BIBA_TYPE_GRADE: 354101099Srwatson break; 355101099Srwatson 356101099Srwatson case MAC_BIBA_TYPE_EQUAL: 357101099Srwatson case MAC_BIBA_TYPE_HIGH: 358101099Srwatson case MAC_BIBA_TYPE_LOW: 359105643Srwatson if (mac_biba->mb_single.mbe_grade != 0 || 360105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 361105643Srwatson mac_biba->mb_single.mbe_compartments)) 362101099Srwatson return (EINVAL); 363101099Srwatson break; 364101099Srwatson 365101099Srwatson default: 366101099Srwatson return (EINVAL); 367101099Srwatson } 368101099Srwatson } else { 369101099Srwatson if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 370101099Srwatson return (EINVAL); 371101099Srwatson } 372101099Srwatson 373101099Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 374101099Srwatson switch (mac_biba->mb_rangelow.mbe_type) { 375101099Srwatson case MAC_BIBA_TYPE_GRADE: 376101099Srwatson break; 377101099Srwatson 378101099Srwatson case MAC_BIBA_TYPE_EQUAL: 379101099Srwatson case MAC_BIBA_TYPE_HIGH: 380101099Srwatson case MAC_BIBA_TYPE_LOW: 381105643Srwatson if (mac_biba->mb_rangelow.mbe_grade != 0 || 382105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 383105643Srwatson mac_biba->mb_rangelow.mbe_compartments)) 384101099Srwatson return (EINVAL); 385101099Srwatson break; 386101099Srwatson 387101099Srwatson default: 388101099Srwatson return (EINVAL); 389101099Srwatson } 390101099Srwatson 391101099Srwatson switch (mac_biba->mb_rangehigh.mbe_type) { 392101099Srwatson case MAC_BIBA_TYPE_GRADE: 393101099Srwatson break; 394101099Srwatson 395101099Srwatson case MAC_BIBA_TYPE_EQUAL: 396101099Srwatson case MAC_BIBA_TYPE_HIGH: 397101099Srwatson case MAC_BIBA_TYPE_LOW: 398105643Srwatson if (mac_biba->mb_rangehigh.mbe_grade != 0 || 399105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 400105643Srwatson mac_biba->mb_rangehigh.mbe_compartments)) 401101099Srwatson return (EINVAL); 402101099Srwatson break; 403101099Srwatson 404101099Srwatson default: 405101099Srwatson return (EINVAL); 406101099Srwatson } 407101099Srwatson if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 408101099Srwatson &mac_biba->mb_rangelow)) 409101099Srwatson return (EINVAL); 410101099Srwatson } else { 411101099Srwatson if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 412101099Srwatson mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 413101099Srwatson return (EINVAL); 414101099Srwatson } 415101099Srwatson 416101099Srwatson return (0); 417101099Srwatson} 418101099Srwatson 419101099Srwatsonstatic void 420101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 421105643Srwatson u_short gradelow, u_char *compartmentslow, u_short typehigh, 422105643Srwatson u_short gradehigh, u_char *compartmentshigh) 423101099Srwatson{ 424101099Srwatson 425101099Srwatson mac_biba->mb_rangelow.mbe_type = typelow; 426101099Srwatson mac_biba->mb_rangelow.mbe_grade = gradelow; 427105643Srwatson if (compartmentslow != NULL) 428105643Srwatson memcpy(mac_biba->mb_rangelow.mbe_compartments, 429105643Srwatson compartmentslow, 430105643Srwatson sizeof(mac_biba->mb_rangelow.mbe_compartments)); 431101099Srwatson mac_biba->mb_rangehigh.mbe_type = typehigh; 432101099Srwatson mac_biba->mb_rangehigh.mbe_grade = gradehigh; 433105643Srwatson if (compartmentshigh != NULL) 434105643Srwatson memcpy(mac_biba->mb_rangehigh.mbe_compartments, 435105643Srwatson compartmentshigh, 436105643Srwatson sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 437101099Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 438101099Srwatson} 439101099Srwatson 440101099Srwatsonstatic void 441105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 442105643Srwatson u_char *compartments) 443101099Srwatson{ 444101099Srwatson 445101099Srwatson mac_biba->mb_single.mbe_type = type; 446101099Srwatson mac_biba->mb_single.mbe_grade = grade; 447105643Srwatson if (compartments != NULL) 448105643Srwatson memcpy(mac_biba->mb_single.mbe_compartments, compartments, 449105643Srwatson sizeof(mac_biba->mb_single.mbe_compartments)); 450101099Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 451101099Srwatson} 452101099Srwatson 453101099Srwatsonstatic void 454101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 455101099Srwatson{ 456105643Srwatson 457101099Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 458101099Srwatson ("mac_biba_copy_range: labelfrom not range")); 459101099Srwatson 460101099Srwatson labelto->mb_rangelow = labelfrom->mb_rangelow; 461101099Srwatson labelto->mb_rangehigh = labelfrom->mb_rangehigh; 462101099Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 463101099Srwatson} 464101099Srwatson 465101099Srwatsonstatic void 466101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 467101099Srwatson{ 468101099Srwatson 469101099Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 470101099Srwatson ("mac_biba_copy_single: labelfrom not single")); 471101099Srwatson 472101099Srwatson labelto->mb_single = labelfrom->mb_single; 473101099Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 474101099Srwatson} 475101099Srwatson 476105656Srwatsonstatic void 477105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 478105656Srwatson{ 479105656Srwatson 480105656Srwatson if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 481105656Srwatson mac_biba_copy_single(source, dest); 482105656Srwatson if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 483105656Srwatson mac_biba_copy_range(source, dest); 484105656Srwatson} 485105656Srwatson 486101099Srwatson/* 487101099Srwatson * Policy module operations. 488101099Srwatson */ 489101099Srwatsonstatic void 490101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf) 491101099Srwatson{ 492101099Srwatson 493101099Srwatson} 494101099Srwatson 495101099Srwatsonstatic void 496101099Srwatsonmac_biba_init(struct mac_policy_conf *conf) 497101099Srwatson{ 498101099Srwatson 499101099Srwatson} 500101099Srwatson 501101099Srwatson/* 502101099Srwatson * Label operations. 503101099Srwatson */ 504101099Srwatsonstatic void 505104514Srwatsonmac_biba_init_label(struct label *label) 506101099Srwatson{ 507101099Srwatson 508111119Simp SLOT(label) = biba_alloc(M_WAITOK); 509101099Srwatson} 510101099Srwatson 511101099Srwatsonstatic int 512104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag) 513101099Srwatson{ 514101099Srwatson 515104514Srwatson SLOT(label) = biba_alloc(flag); 516101099Srwatson if (SLOT(label) == NULL) 517101099Srwatson return (ENOMEM); 518101099Srwatson 519101099Srwatson return (0); 520101099Srwatson} 521101099Srwatson 522101099Srwatsonstatic void 523104514Srwatsonmac_biba_destroy_label(struct label *label) 524101099Srwatson{ 525101099Srwatson 526101099Srwatson biba_free(SLOT(label)); 527101099Srwatson SLOT(label) = NULL; 528101099Srwatson} 529101099Srwatson 530105696Srwatson/* 531105696Srwatson * mac_biba_element_to_string() is basically an snprintf wrapper with 532105696Srwatson * the same properties as snprintf(). It returns the length it would 533105696Srwatson * have added to the string in the event the string is too short. 534105696Srwatson */ 535105696Srwatsonstatic size_t 536105696Srwatsonmac_biba_element_to_string(char *string, size_t size, 537105696Srwatson struct mac_biba_element *element) 538105696Srwatson{ 539105696Srwatson int pos, bit = 1; 540105696Srwatson 541105696Srwatson switch (element->mbe_type) { 542105696Srwatson case MAC_BIBA_TYPE_HIGH: 543105696Srwatson return (snprintf(string, size, "high")); 544105696Srwatson 545105696Srwatson case MAC_BIBA_TYPE_LOW: 546105696Srwatson return (snprintf(string, size, "low")); 547105696Srwatson 548105696Srwatson case MAC_BIBA_TYPE_EQUAL: 549105696Srwatson return (snprintf(string, size, "equal")); 550105696Srwatson 551105696Srwatson case MAC_BIBA_TYPE_GRADE: 552105696Srwatson pos = snprintf(string, size, "%d:", element->mbe_grade); 553105696Srwatson for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) { 554105696Srwatson if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments)) 555105696Srwatson pos += snprintf(string + pos, size - pos, 556105696Srwatson "%d+", bit); 557105696Srwatson } 558105696Srwatson if (string[pos - 1] == '+' || string[pos - 1] == ':') 559106214Srwatson string[--pos] = '\0'; 560105696Srwatson return (pos); 561105696Srwatson 562105696Srwatson default: 563105696Srwatson panic("mac_biba_element_to_string: invalid type (%d)", 564105696Srwatson element->mbe_type); 565105696Srwatson } 566105696Srwatson} 567105696Srwatson 568101099Srwatsonstatic int 569105696Srwatsonmac_biba_to_string(char *string, size_t size, size_t *caller_len, 570105696Srwatson struct mac_biba *mac_biba) 571101099Srwatson{ 572105696Srwatson size_t left, len; 573105696Srwatson char *curptr; 574105696Srwatson 575105696Srwatson bzero(string, size); 576105696Srwatson curptr = string; 577105696Srwatson left = size; 578105696Srwatson 579105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 580105696Srwatson len = mac_biba_element_to_string(curptr, left, 581105696Srwatson &mac_biba->mb_single); 582105696Srwatson if (len >= left) 583105696Srwatson return (EINVAL); 584105696Srwatson left -= len; 585105696Srwatson curptr += len; 586105696Srwatson } 587105696Srwatson 588105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 589105696Srwatson len = snprintf(curptr, left, "("); 590105696Srwatson if (len >= left) 591105696Srwatson return (EINVAL); 592105696Srwatson left -= len; 593105696Srwatson curptr += len; 594105696Srwatson 595105696Srwatson len = mac_biba_element_to_string(curptr, left, 596105696Srwatson &mac_biba->mb_rangelow); 597105696Srwatson if (len >= left) 598105696Srwatson return (EINVAL); 599105696Srwatson left -= len; 600105696Srwatson curptr += len; 601105696Srwatson 602105696Srwatson len = snprintf(curptr, left, "-"); 603105696Srwatson if (len >= left) 604105696Srwatson return (EINVAL); 605105696Srwatson left -= len; 606105696Srwatson curptr += len; 607105696Srwatson 608105696Srwatson len = mac_biba_element_to_string(curptr, left, 609105696Srwatson &mac_biba->mb_rangehigh); 610105696Srwatson if (len >= left) 611105696Srwatson return (EINVAL); 612105696Srwatson left -= len; 613105696Srwatson curptr += len; 614105696Srwatson 615105696Srwatson len = snprintf(curptr, left, ")"); 616105696Srwatson if (len >= left) 617105696Srwatson return (EINVAL); 618105696Srwatson left -= len; 619105696Srwatson curptr += len; 620105696Srwatson } 621105696Srwatson 622105696Srwatson *caller_len = strlen(string); 623105696Srwatson return (0); 624105696Srwatson} 625105696Srwatson 626105696Srwatsonstatic int 627105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name, 628105696Srwatson char *element_data, size_t size, size_t *len, int *claimed) 629105696Srwatson{ 630101099Srwatson struct mac_biba *mac_biba; 631105696Srwatson int error; 632101099Srwatson 633105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 634105696Srwatson return (0); 635105696Srwatson 636105696Srwatson (*claimed)++; 637105696Srwatson 638101099Srwatson mac_biba = SLOT(label); 639105696Srwatson error = mac_biba_to_string(element_data, size, len, mac_biba); 640105696Srwatson if (error) 641105696Srwatson return (error); 642101099Srwatson 643105696Srwatson *len = strlen(element_data); 644105696Srwatson return (0); 645105696Srwatson} 646105696Srwatson 647105696Srwatsonstatic int 648105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string) 649101099Srwatson{ 650105696Srwatson 651105696Srwatson if (strcmp(string, "high") == 0 || 652105696Srwatson strcmp(string, "hi") == 0) { 653105696Srwatson element->mbe_type = MAC_BIBA_TYPE_HIGH; 654105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 655105696Srwatson } else if (strcmp(string, "low") == 0 || 656105696Srwatson strcmp(string, "lo") == 0) { 657105696Srwatson element->mbe_type = MAC_BIBA_TYPE_LOW; 658105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 659105696Srwatson } else if (strcmp(string, "equal") == 0 || 660105696Srwatson strcmp(string, "eq") == 0) { 661105696Srwatson element->mbe_type = MAC_BIBA_TYPE_EQUAL; 662105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 663105696Srwatson } else { 664105696Srwatson char *p0, *p1; 665105696Srwatson int d; 666105696Srwatson 667105696Srwatson p0 = string; 668105696Srwatson d = strtol(p0, &p1, 10); 669105696Srwatson 670105696Srwatson if (d < 0 || d > 65535) 671105696Srwatson return (EINVAL); 672105696Srwatson element->mbe_type = MAC_BIBA_TYPE_GRADE; 673105696Srwatson element->mbe_grade = d; 674105696Srwatson 675105696Srwatson if (*p1 != ':') { 676105696Srwatson if (p1 == p0 || *p1 != '\0') 677105696Srwatson return (EINVAL); 678105696Srwatson else 679105696Srwatson return (0); 680105696Srwatson } 681105696Srwatson else 682105696Srwatson if (*(p1 + 1) == '\0') 683105696Srwatson return (0); 684105696Srwatson 685105696Srwatson while ((p0 = ++p1)) { 686105696Srwatson d = strtol(p0, &p1, 10); 687105696Srwatson if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS) 688105696Srwatson return (EINVAL); 689105696Srwatson 690105696Srwatson MAC_BIBA_BIT_SET(d, element->mbe_compartments); 691105696Srwatson 692105696Srwatson if (*p1 == '\0') 693105696Srwatson break; 694105696Srwatson if (p1 == p0 || *p1 != '+') 695105696Srwatson return (EINVAL); 696105696Srwatson } 697105696Srwatson } 698105696Srwatson 699105696Srwatson return (0); 700105696Srwatson} 701105696Srwatson 702105696Srwatson/* 703105696Srwatson * Note: destructively consumes the string, make a local copy before 704105696Srwatson * calling if that's a problem. 705105696Srwatson */ 706105696Srwatsonstatic int 707105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string) 708105696Srwatson{ 709105696Srwatson char *range, *rangeend, *rangehigh, *rangelow, *single; 710101099Srwatson int error; 711101099Srwatson 712105696Srwatson /* Do we have a range? */ 713105696Srwatson single = string; 714105696Srwatson range = index(string, '('); 715105696Srwatson if (range == single) 716105696Srwatson single = NULL; 717105696Srwatson rangelow = rangehigh = NULL; 718105696Srwatson if (range != NULL) { 719105696Srwatson /* Nul terminate the end of the single string. */ 720105696Srwatson *range = '\0'; 721105696Srwatson range++; 722105696Srwatson rangelow = range; 723105696Srwatson rangehigh = index(rangelow, '-'); 724105696Srwatson if (rangehigh == NULL) 725105696Srwatson return (EINVAL); 726105696Srwatson rangehigh++; 727105696Srwatson if (*rangelow == '\0' || *rangehigh == '\0') 728105696Srwatson return (EINVAL); 729105696Srwatson rangeend = index(rangehigh, ')'); 730105696Srwatson if (rangeend == NULL) 731105696Srwatson return (EINVAL); 732105696Srwatson if (*(rangeend + 1) != '\0') 733105696Srwatson return (EINVAL); 734105696Srwatson /* Nul terminate the ends of the ranges. */ 735105696Srwatson *(rangehigh - 1) = '\0'; 736105696Srwatson *rangeend = '\0'; 737105696Srwatson } 738105696Srwatson KASSERT((rangelow != NULL && rangehigh != NULL) || 739105696Srwatson (rangelow == NULL && rangehigh == NULL), 740105696Srwatson ("mac_biba_internalize_label: range mismatch")); 741101099Srwatson 742105696Srwatson bzero(mac_biba, sizeof(*mac_biba)); 743105696Srwatson if (single != NULL) { 744105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_single, single); 745105696Srwatson if (error) 746105696Srwatson return (error); 747105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 748105696Srwatson } 749105696Srwatson 750105696Srwatson if (rangelow != NULL) { 751105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangelow, 752105696Srwatson rangelow); 753105696Srwatson if (error) 754105696Srwatson return (error); 755105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 756105696Srwatson rangehigh); 757105696Srwatson if (error) 758105696Srwatson return (error); 759105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 760105696Srwatson } 761105696Srwatson 762101099Srwatson error = mac_biba_valid(mac_biba); 763101099Srwatson if (error) 764101099Srwatson return (error); 765101099Srwatson 766105696Srwatson return (0); 767105696Srwatson} 768101099Srwatson 769105696Srwatsonstatic int 770105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name, 771105696Srwatson char *element_data, int *claimed) 772105696Srwatson{ 773105696Srwatson struct mac_biba *mac_biba, mac_biba_temp; 774105696Srwatson int error; 775105696Srwatson 776105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 777105696Srwatson return (0); 778105696Srwatson 779105696Srwatson (*claimed)++; 780105696Srwatson 781105696Srwatson error = mac_biba_parse(&mac_biba_temp, element_data); 782105696Srwatson if (error) 783105696Srwatson return (error); 784105696Srwatson 785105696Srwatson mac_biba = SLOT(label); 786105696Srwatson *mac_biba = mac_biba_temp; 787105696Srwatson 788101099Srwatson return (0); 789101099Srwatson} 790101099Srwatson 791105696Srwatsonstatic void 792105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest) 793105696Srwatson{ 794105696Srwatson 795105696Srwatson *SLOT(dest) = *SLOT(src); 796105696Srwatson} 797105696Srwatson 798101099Srwatson/* 799101099Srwatson * Labeling event operations: file system objects, and things that look 800101099Srwatson * a lot like file system objects. 801101099Srwatson */ 802101099Srwatsonstatic void 803107698Srwatsonmac_biba_create_devfs_device(struct mount *mp, dev_t dev, 804107698Srwatson struct devfs_dirent *devfs_dirent, struct label *label) 805101099Srwatson{ 806101099Srwatson struct mac_biba *mac_biba; 807101099Srwatson int biba_type; 808101099Srwatson 809101099Srwatson mac_biba = SLOT(label); 810101099Srwatson if (strcmp(dev->si_name, "null") == 0 || 811101099Srwatson strcmp(dev->si_name, "zero") == 0 || 812101099Srwatson strcmp(dev->si_name, "random") == 0 || 813101099Srwatson strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 814101099Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 815105606Srwatson else if (ptys_equal && 816105606Srwatson (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 817105606Srwatson strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 818105606Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 819101099Srwatson else 820101099Srwatson biba_type = MAC_BIBA_TYPE_HIGH; 821105643Srwatson mac_biba_set_single(mac_biba, biba_type, 0, NULL); 822101099Srwatson} 823101099Srwatson 824101099Srwatsonstatic void 825107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname, 826107698Srwatson int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 827101099Srwatson{ 828101099Srwatson struct mac_biba *mac_biba; 829101099Srwatson 830101099Srwatson mac_biba = SLOT(label); 831105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 832101099Srwatson} 833101099Srwatson 834101099Srwatsonstatic void 835107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp, 836107698Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 837107698Srwatson struct label *delabel) 838104535Srwatson{ 839104535Srwatson struct mac_biba *source, *dest; 840104535Srwatson 841104535Srwatson source = SLOT(&cred->cr_label); 842104535Srwatson dest = SLOT(delabel); 843104535Srwatson 844104535Srwatson mac_biba_copy_single(source, dest); 845104535Srwatson} 846104535Srwatson 847104535Srwatsonstatic void 848101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp, 849101099Srwatson struct label *mntlabel, struct label *fslabel) 850101099Srwatson{ 851101099Srwatson struct mac_biba *source, *dest; 852101099Srwatson 853101099Srwatson source = SLOT(&cred->cr_label); 854101099Srwatson dest = SLOT(mntlabel); 855101099Srwatson mac_biba_copy_single(source, dest); 856101099Srwatson dest = SLOT(fslabel); 857101099Srwatson mac_biba_copy_single(source, dest); 858101099Srwatson} 859101099Srwatson 860101099Srwatsonstatic void 861101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 862101099Srwatson struct label *mntlabel, struct label *fslabel) 863101099Srwatson{ 864101099Srwatson struct mac_biba *mac_biba; 865101099Srwatson 866101099Srwatson /* Always mount root as high integrity. */ 867101099Srwatson mac_biba = SLOT(fslabel); 868105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 869101099Srwatson mac_biba = SLOT(mntlabel); 870105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 871101099Srwatson} 872101099Srwatson 873101099Srwatsonstatic void 874101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 875101099Srwatson struct label *vnodelabel, struct label *label) 876101099Srwatson{ 877101099Srwatson struct mac_biba *source, *dest; 878101099Srwatson 879101099Srwatson source = SLOT(label); 880101099Srwatson dest = SLOT(vnodelabel); 881101099Srwatson 882105656Srwatson mac_biba_copy(source, dest); 883101099Srwatson} 884101099Srwatson 885101099Srwatsonstatic void 886107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp, 887107698Srwatson struct devfs_dirent *devfs_dirent, struct label *direntlabel, 888107698Srwatson struct vnode *vp, struct label *vnodelabel) 889101099Srwatson{ 890101099Srwatson struct mac_biba *source, *dest; 891101099Srwatson 892101099Srwatson source = SLOT(vnodelabel); 893101099Srwatson dest = SLOT(direntlabel); 894101099Srwatson 895105656Srwatson mac_biba_copy(source, dest); 896101099Srwatson} 897101099Srwatson 898101099Srwatsonstatic void 899105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 900105988Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 901105988Srwatson struct label *vlabel) 902101099Srwatson{ 903101099Srwatson struct mac_biba *source, *dest; 904101099Srwatson 905105988Srwatson source = SLOT(delabel); 906105988Srwatson dest = SLOT(vlabel); 907101099Srwatson 908101099Srwatson mac_biba_copy_single(source, dest); 909101099Srwatson} 910101099Srwatson 911101099Srwatsonstatic int 912105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 913105988Srwatson struct vnode *vp, struct label *vlabel) 914101099Srwatson{ 915105988Srwatson struct mac_biba temp, *source, *dest; 916106354Smux int buflen, error; 917101099Srwatson 918105988Srwatson source = SLOT(fslabel); 919105988Srwatson dest = SLOT(vlabel); 920101099Srwatson 921105988Srwatson buflen = sizeof(temp); 922105988Srwatson bzero(&temp, buflen); 923105988Srwatson 924105988Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 925105988Srwatson MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 926105988Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 927105988Srwatson /* Fall back to the fslabel. */ 928105988Srwatson mac_biba_copy_single(source, dest); 929105988Srwatson return (0); 930105988Srwatson } else if (error) 931101099Srwatson return (error); 932101099Srwatson 933105988Srwatson if (buflen != sizeof(temp)) { 934105988Srwatson printf("mac_biba_associate_vnode_extattr: bad size %d\n", 935105988Srwatson buflen); 936105988Srwatson return (EPERM); 937105988Srwatson } 938105988Srwatson if (mac_biba_valid(&temp) != 0) { 939105988Srwatson printf("mac_biba_associate_vnode_extattr: invalid\n"); 940105988Srwatson return (EPERM); 941105988Srwatson } 942105988Srwatson if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 943105988Srwatson printf("mac_biba_associate_vnode_extattr: not single\n"); 944105988Srwatson return (EPERM); 945105988Srwatson } 946101099Srwatson 947105988Srwatson mac_biba_copy_single(&temp, dest); 948101099Srwatson return (0); 949101099Srwatson} 950101099Srwatson 951101099Srwatsonstatic void 952105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp, 953105988Srwatson struct label *fslabel, struct vnode *vp, struct label *vlabel) 954101099Srwatson{ 955101099Srwatson struct mac_biba *source, *dest; 956101099Srwatson 957101099Srwatson source = SLOT(fslabel); 958105988Srwatson dest = SLOT(vlabel); 959101099Srwatson 960101099Srwatson mac_biba_copy_single(source, dest); 961101099Srwatson} 962101099Srwatson 963105988Srwatsonstatic int 964105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 965105988Srwatson struct label *fslabel, struct vnode *dvp, struct label *dlabel, 966105988Srwatson struct vnode *vp, struct label *vlabel, struct componentname *cnp) 967105988Srwatson{ 968105988Srwatson struct mac_biba *source, *dest, temp; 969105988Srwatson size_t buflen; 970105988Srwatson int error; 971105988Srwatson 972105988Srwatson buflen = sizeof(temp); 973105988Srwatson bzero(&temp, buflen); 974105988Srwatson 975105988Srwatson source = SLOT(&cred->cr_label); 976105988Srwatson dest = SLOT(vlabel); 977105988Srwatson mac_biba_copy_single(source, &temp); 978105988Srwatson 979105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 980105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 981105988Srwatson if (error == 0) 982105988Srwatson mac_biba_copy_single(source, dest); 983105988Srwatson return (error); 984105988Srwatson} 985105988Srwatson 986105988Srwatsonstatic int 987105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 988105988Srwatson struct label *vlabel, struct label *intlabel) 989105988Srwatson{ 990105988Srwatson struct mac_biba *source, temp; 991105988Srwatson size_t buflen; 992105988Srwatson int error; 993105988Srwatson 994105988Srwatson buflen = sizeof(temp); 995105988Srwatson bzero(&temp, buflen); 996105988Srwatson 997105988Srwatson source = SLOT(intlabel); 998105988Srwatson if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 999105988Srwatson return (0); 1000105988Srwatson 1001105988Srwatson mac_biba_copy_single(source, &temp); 1002105988Srwatson 1003105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 1004105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 1005105988Srwatson return (error); 1006105988Srwatson} 1007105988Srwatson 1008101099Srwatson/* 1009101099Srwatson * Labeling event operations: IPC object. 1010101099Srwatson */ 1011101099Srwatsonstatic void 1012101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1013101099Srwatson struct mbuf *m, struct label *mbuflabel) 1014101099Srwatson{ 1015101099Srwatson struct mac_biba *source, *dest; 1016101099Srwatson 1017101099Srwatson source = SLOT(socketlabel); 1018101099Srwatson dest = SLOT(mbuflabel); 1019101099Srwatson 1020101099Srwatson mac_biba_copy_single(source, dest); 1021101099Srwatson} 1022101099Srwatson 1023101099Srwatsonstatic void 1024101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket, 1025101099Srwatson struct label *socketlabel) 1026101099Srwatson{ 1027101099Srwatson struct mac_biba *source, *dest; 1028101099Srwatson 1029101099Srwatson source = SLOT(&cred->cr_label); 1030101099Srwatson dest = SLOT(socketlabel); 1031101099Srwatson 1032101099Srwatson mac_biba_copy_single(source, dest); 1033101099Srwatson} 1034101099Srwatson 1035101099Srwatsonstatic void 1036101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1037101099Srwatson struct label *pipelabel) 1038101099Srwatson{ 1039101099Srwatson struct mac_biba *source, *dest; 1040101099Srwatson 1041101099Srwatson source = SLOT(&cred->cr_label); 1042101099Srwatson dest = SLOT(pipelabel); 1043101099Srwatson 1044101099Srwatson mac_biba_copy_single(source, dest); 1045101099Srwatson} 1046101099Srwatson 1047101099Srwatsonstatic void 1048101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket, 1049101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1050101099Srwatson struct label *newsocketlabel) 1051101099Srwatson{ 1052101099Srwatson struct mac_biba *source, *dest; 1053101099Srwatson 1054101099Srwatson source = SLOT(oldsocketlabel); 1055101099Srwatson dest = SLOT(newsocketlabel); 1056101099Srwatson 1057101099Srwatson mac_biba_copy_single(source, dest); 1058101099Srwatson} 1059101099Srwatson 1060101099Srwatsonstatic void 1061101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1062101099Srwatson struct label *socketlabel, struct label *newlabel) 1063101099Srwatson{ 1064101099Srwatson struct mac_biba *source, *dest; 1065101099Srwatson 1066101099Srwatson source = SLOT(newlabel); 1067101099Srwatson dest = SLOT(socketlabel); 1068101099Srwatson 1069105656Srwatson mac_biba_copy(source, dest); 1070101099Srwatson} 1071101099Srwatson 1072101099Srwatsonstatic void 1073101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1074101099Srwatson struct label *pipelabel, struct label *newlabel) 1075101099Srwatson{ 1076101099Srwatson struct mac_biba *source, *dest; 1077101099Srwatson 1078101099Srwatson source = SLOT(newlabel); 1079101099Srwatson dest = SLOT(pipelabel); 1080101099Srwatson 1081105656Srwatson mac_biba_copy(source, dest); 1082101099Srwatson} 1083101099Srwatson 1084101099Srwatsonstatic void 1085101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1086101099Srwatson struct socket *socket, struct label *socketpeerlabel) 1087101099Srwatson{ 1088101099Srwatson struct mac_biba *source, *dest; 1089101099Srwatson 1090101099Srwatson source = SLOT(mbuflabel); 1091101099Srwatson dest = SLOT(socketpeerlabel); 1092101099Srwatson 1093101099Srwatson mac_biba_copy_single(source, dest); 1094101099Srwatson} 1095101099Srwatson 1096101099Srwatson/* 1097101099Srwatson * Labeling event operations: network objects. 1098101099Srwatson */ 1099101099Srwatsonstatic void 1100101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1101101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1102101099Srwatson struct label *newsocketpeerlabel) 1103101099Srwatson{ 1104101099Srwatson struct mac_biba *source, *dest; 1105101099Srwatson 1106101099Srwatson source = SLOT(oldsocketlabel); 1107101099Srwatson dest = SLOT(newsocketpeerlabel); 1108101099Srwatson 1109101099Srwatson mac_biba_copy_single(source, dest); 1110101099Srwatson} 1111101099Srwatson 1112101099Srwatsonstatic void 1113101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1114101099Srwatson struct label *bpflabel) 1115101099Srwatson{ 1116101099Srwatson struct mac_biba *source, *dest; 1117101099Srwatson 1118101099Srwatson source = SLOT(&cred->cr_label); 1119101099Srwatson dest = SLOT(bpflabel); 1120101099Srwatson 1121101099Srwatson mac_biba_copy_single(source, dest); 1122101099Srwatson} 1123101099Srwatson 1124101099Srwatsonstatic void 1125101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1126101099Srwatson{ 1127101099Srwatson char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1128101099Srwatson char tiflist[sizeof(trusted_interfaces)]; 1129101099Srwatson struct mac_biba *dest; 1130110350Srwatson int len, type; 1131101099Srwatson 1132101099Srwatson dest = SLOT(ifnetlabel); 1133101099Srwatson 1134101099Srwatson if (ifnet->if_type == IFT_LOOP) { 1135110350Srwatson type = MAC_BIBA_TYPE_EQUAL; 1136101099Srwatson goto set; 1137101099Srwatson } 1138101099Srwatson 1139101099Srwatson if (trust_all_interfaces) { 1140110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1141101099Srwatson goto set; 1142101099Srwatson } 1143101099Srwatson 1144110350Srwatson type = MAC_BIBA_TYPE_LOW; 1145101099Srwatson 1146101099Srwatson if (trusted_interfaces[0] == '\0' || 1147101099Srwatson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1148101099Srwatson goto set; 1149101099Srwatson 1150106089Srwatson bzero(tiflist, sizeof(tiflist)); 1151101099Srwatson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1152101099Srwatson if(*p != ' ' && *p != '\t') 1153101099Srwatson *q = *p; 1154101099Srwatson 1155101099Srwatson snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1156101099Srwatson 1157101099Srwatson for (p = q = tiflist;; p++) { 1158101099Srwatson if (*p == ',' || *p == '\0') { 1159101099Srwatson len = p - q; 1160101099Srwatson if (len < IFNAMSIZ) { 1161101099Srwatson bzero(tifname, sizeof(tifname)); 1162101099Srwatson bcopy(q, tifname, len); 1163101099Srwatson if (strcmp(tifname, ifname) == 0) { 1164110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1165101099Srwatson break; 1166101099Srwatson } 1167106089Srwatson } else { 1168106089Srwatson *p = '\0'; 1169106089Srwatson printf("mac_biba warning: interface name " 1170106089Srwatson "\"%s\" is too long (must be < %d)\n", 1171106089Srwatson q, IFNAMSIZ); 1172101099Srwatson } 1173101099Srwatson if (*p == '\0') 1174101099Srwatson break; 1175101099Srwatson q = p + 1; 1176101099Srwatson } 1177101099Srwatson } 1178101099Srwatsonset: 1179110350Srwatson mac_biba_set_single(dest, type, 0, NULL); 1180110350Srwatson mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1181101099Srwatson} 1182101099Srwatson 1183101099Srwatsonstatic void 1184101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1185101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1186101099Srwatson{ 1187101099Srwatson struct mac_biba *source, *dest; 1188101099Srwatson 1189101099Srwatson source = SLOT(fragmentlabel); 1190101099Srwatson dest = SLOT(ipqlabel); 1191101099Srwatson 1192101099Srwatson mac_biba_copy_single(source, dest); 1193101099Srwatson} 1194101099Srwatson 1195101099Srwatsonstatic void 1196101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1197101099Srwatson struct mbuf *datagram, struct label *datagramlabel) 1198101099Srwatson{ 1199101099Srwatson struct mac_biba *source, *dest; 1200101099Srwatson 1201101099Srwatson source = SLOT(ipqlabel); 1202101099Srwatson dest = SLOT(datagramlabel); 1203101099Srwatson 1204101099Srwatson /* Just use the head, since we require them all to match. */ 1205101099Srwatson mac_biba_copy_single(source, dest); 1206101099Srwatson} 1207101099Srwatson 1208101099Srwatsonstatic void 1209101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1210101099Srwatson struct mbuf *fragment, struct label *fragmentlabel) 1211101099Srwatson{ 1212101099Srwatson struct mac_biba *source, *dest; 1213101099Srwatson 1214101099Srwatson source = SLOT(datagramlabel); 1215101099Srwatson dest = SLOT(fragmentlabel); 1216101099Srwatson 1217101099Srwatson mac_biba_copy_single(source, dest); 1218101099Srwatson} 1219101099Srwatson 1220101099Srwatsonstatic void 1221101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1222101099Srwatson struct label *oldmbuflabel, struct mbuf *newmbuf, 1223101099Srwatson struct label *newmbuflabel) 1224101099Srwatson{ 1225101099Srwatson struct mac_biba *source, *dest; 1226101099Srwatson 1227101099Srwatson source = SLOT(oldmbuflabel); 1228101099Srwatson dest = SLOT(newmbuflabel); 1229101099Srwatson 1230105656Srwatson /* 1231105656Srwatson * Because the source mbuf may not yet have been "created", 1232105696Srwatson * just initialized, we do a conditional copy. Since we don't 1233105656Srwatson * allow mbufs to have ranges, do a KASSERT to make sure that 1234105656Srwatson * doesn't happen. 1235105656Srwatson */ 1236105656Srwatson KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1237105656Srwatson ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1238105656Srwatson mac_biba_copy(source, dest); 1239101099Srwatson} 1240101099Srwatson 1241101099Srwatsonstatic void 1242101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1243101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1244101099Srwatson{ 1245101099Srwatson struct mac_biba *dest; 1246101099Srwatson 1247101099Srwatson dest = SLOT(mbuflabel); 1248101099Srwatson 1249105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1250101099Srwatson} 1251101099Srwatson 1252101099Srwatsonstatic void 1253101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1254101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1255101099Srwatson{ 1256101099Srwatson struct mac_biba *source, *dest; 1257101099Srwatson 1258101099Srwatson source = SLOT(bpflabel); 1259101099Srwatson dest = SLOT(mbuflabel); 1260101099Srwatson 1261101099Srwatson mac_biba_copy_single(source, dest); 1262101099Srwatson} 1263101099Srwatson 1264101099Srwatsonstatic void 1265101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1266101099Srwatson struct mbuf *m, struct label *mbuflabel) 1267101099Srwatson{ 1268101099Srwatson struct mac_biba *source, *dest; 1269101099Srwatson 1270101099Srwatson source = SLOT(ifnetlabel); 1271101099Srwatson dest = SLOT(mbuflabel); 1272101099Srwatson 1273101099Srwatson mac_biba_copy_single(source, dest); 1274101099Srwatson} 1275101099Srwatson 1276101099Srwatsonstatic void 1277101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1278101099Srwatson struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1279101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1280101099Srwatson{ 1281101099Srwatson struct mac_biba *source, *dest; 1282101099Srwatson 1283101099Srwatson source = SLOT(oldmbuflabel); 1284101099Srwatson dest = SLOT(newmbuflabel); 1285101099Srwatson 1286101099Srwatson mac_biba_copy_single(source, dest); 1287101099Srwatson} 1288101099Srwatson 1289101099Srwatsonstatic void 1290101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1291101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1292101099Srwatson{ 1293101099Srwatson struct mac_biba *source, *dest; 1294101099Srwatson 1295101099Srwatson source = SLOT(oldmbuflabel); 1296101099Srwatson dest = SLOT(newmbuflabel); 1297101099Srwatson 1298101099Srwatson mac_biba_copy_single(source, dest); 1299101099Srwatson} 1300101099Srwatson 1301101099Srwatsonstatic int 1302101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1303101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1304101099Srwatson{ 1305101099Srwatson struct mac_biba *a, *b; 1306101099Srwatson 1307101099Srwatson a = SLOT(ipqlabel); 1308101099Srwatson b = SLOT(fragmentlabel); 1309101099Srwatson 1310101099Srwatson return (mac_biba_equal_single(a, b)); 1311101099Srwatson} 1312101099Srwatson 1313101099Srwatsonstatic void 1314101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1315101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1316101099Srwatson{ 1317101099Srwatson struct mac_biba *source, *dest; 1318101099Srwatson 1319101099Srwatson source = SLOT(newlabel); 1320101099Srwatson dest = SLOT(ifnetlabel); 1321101099Srwatson 1322105656Srwatson mac_biba_copy(source, dest); 1323101099Srwatson} 1324101099Srwatson 1325101099Srwatsonstatic void 1326101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1327101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1328101099Srwatson{ 1329101099Srwatson 1330101099Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1331101099Srwatson} 1332101099Srwatson 1333101099Srwatson/* 1334101099Srwatson * Labeling event operations: processes. 1335101099Srwatson */ 1336101099Srwatsonstatic void 1337101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1338101099Srwatson{ 1339101099Srwatson struct mac_biba *source, *dest; 1340101099Srwatson 1341101099Srwatson source = SLOT(&cred_parent->cr_label); 1342101099Srwatson dest = SLOT(&cred_child->cr_label); 1343101099Srwatson 1344101099Srwatson mac_biba_copy_single(source, dest); 1345101099Srwatson mac_biba_copy_range(source, dest); 1346101099Srwatson} 1347101099Srwatson 1348101099Srwatsonstatic void 1349101099Srwatsonmac_biba_create_proc0(struct ucred *cred) 1350101099Srwatson{ 1351101099Srwatson struct mac_biba *dest; 1352101099Srwatson 1353101099Srwatson dest = SLOT(&cred->cr_label); 1354101099Srwatson 1355105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1356105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1357105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1358101099Srwatson} 1359101099Srwatson 1360101099Srwatsonstatic void 1361101099Srwatsonmac_biba_create_proc1(struct ucred *cred) 1362101099Srwatson{ 1363101099Srwatson struct mac_biba *dest; 1364101099Srwatson 1365101099Srwatson dest = SLOT(&cred->cr_label); 1366101099Srwatson 1367105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1368105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1369105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1370101099Srwatson} 1371101099Srwatson 1372101099Srwatsonstatic void 1373101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1374101099Srwatson{ 1375101099Srwatson struct mac_biba *source, *dest; 1376101099Srwatson 1377101099Srwatson source = SLOT(newlabel); 1378101099Srwatson dest = SLOT(&cred->cr_label); 1379101099Srwatson 1380105656Srwatson mac_biba_copy(source, dest); 1381101099Srwatson} 1382101099Srwatson 1383101099Srwatson/* 1384101099Srwatson * Access control checks. 1385101099Srwatson */ 1386101099Srwatsonstatic int 1387101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1388101099Srwatson struct ifnet *ifnet, struct label *ifnetlabel) 1389101099Srwatson{ 1390101099Srwatson struct mac_biba *a, *b; 1391101099Srwatson 1392101099Srwatson if (!mac_biba_enabled) 1393101099Srwatson return (0); 1394101099Srwatson 1395101099Srwatson a = SLOT(bpflabel); 1396101099Srwatson b = SLOT(ifnetlabel); 1397101099Srwatson 1398101099Srwatson if (mac_biba_equal_single(a, b)) 1399101099Srwatson return (0); 1400101099Srwatson return (EACCES); 1401101099Srwatson} 1402101099Srwatson 1403101099Srwatsonstatic int 1404101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1405101099Srwatson{ 1406101099Srwatson struct mac_biba *subj, *new; 1407105634Srwatson int error; 1408101099Srwatson 1409101099Srwatson subj = SLOT(&cred->cr_label); 1410101099Srwatson new = SLOT(newlabel); 1411101099Srwatson 1412101099Srwatson /* 1413105634Srwatson * If there is a Biba label update for the credential, it may 1414105634Srwatson * be an update of the single, range, or both. 1415101099Srwatson */ 1416105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1417105634Srwatson if (error) 1418105634Srwatson return (error); 1419101099Srwatson 1420101099Srwatson /* 1421105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1422101099Srwatson */ 1423105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1424105634Srwatson /* 1425110351Srwatson * If the change request modifies both the Biba label 1426110351Srwatson * single and range, check that the new single will be 1427110351Srwatson * in the new range. 1428110351Srwatson */ 1429110351Srwatson if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1430110351Srwatson MAC_BIBA_FLAGS_BOTH && 1431110351Srwatson !mac_biba_single_in_range(new, new)) 1432110351Srwatson return (EINVAL); 1433110351Srwatson 1434110351Srwatson /* 1435105634Srwatson * To change the Biba single label on a credential, the 1436105634Srwatson * new single label must be in the current range. 1437105634Srwatson */ 1438105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1439105634Srwatson !mac_biba_single_in_range(new, subj)) 1440105634Srwatson return (EPERM); 1441101099Srwatson 1442105634Srwatson /* 1443105634Srwatson * To change the Biba range on a credential, the new 1444105634Srwatson * range label must be in the current range. 1445105634Srwatson */ 1446105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1447105634Srwatson !mac_biba_range_in_range(new, subj)) 1448105634Srwatson return (EPERM); 1449101099Srwatson 1450105634Srwatson /* 1451105634Srwatson * To have EQUAL in any component of the new credential 1452105634Srwatson * Biba label, the subject must already have EQUAL in 1453105634Srwatson * their label. 1454105634Srwatson */ 1455105634Srwatson if (mac_biba_contains_equal(new)) { 1456106090Srwatson error = mac_biba_subject_privileged(subj); 1457105634Srwatson if (error) 1458105634Srwatson return (error); 1459105634Srwatson } 1460105634Srwatson } 1461105634Srwatson 1462101099Srwatson return (0); 1463101099Srwatson} 1464101099Srwatson 1465101099Srwatsonstatic int 1466101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1467101099Srwatson{ 1468101099Srwatson struct mac_biba *subj, *obj; 1469101099Srwatson 1470101099Srwatson if (!mac_biba_enabled) 1471101099Srwatson return (0); 1472101099Srwatson 1473101099Srwatson subj = SLOT(&u1->cr_label); 1474101099Srwatson obj = SLOT(&u2->cr_label); 1475101099Srwatson 1476101099Srwatson /* XXX: range */ 1477101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1478101099Srwatson return (ESRCH); 1479101099Srwatson 1480101099Srwatson return (0); 1481101099Srwatson} 1482101099Srwatson 1483101099Srwatsonstatic int 1484101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1485101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1486101099Srwatson{ 1487101099Srwatson struct mac_biba *subj, *new; 1488105634Srwatson int error; 1489101099Srwatson 1490101099Srwatson subj = SLOT(&cred->cr_label); 1491101099Srwatson new = SLOT(newlabel); 1492101099Srwatson 1493105634Srwatson /* 1494105634Srwatson * If there is a Biba label update for the interface, it may 1495105634Srwatson * be an update of the single, range, or both. 1496105634Srwatson */ 1497105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1498105634Srwatson if (error) 1499105634Srwatson return (error); 1500101099Srwatson 1501105634Srwatson /* 1502106160Srwatson * Relabling network interfaces requires Biba privilege. 1503106160Srwatson */ 1504106160Srwatson error = mac_biba_subject_privileged(subj); 1505106160Srwatson if (error) 1506106160Srwatson return (error); 1507106160Srwatson 1508106160Srwatson /* 1509105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1510105634Srwatson */ 1511105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1512105634Srwatson /* 1513105634Srwatson * Rely on the traditional superuser status for the Biba 1514105634Srwatson * interface relabel requirements. XXXMAC: This will go 1515105634Srwatson * away. 1516105634Srwatson */ 1517105634Srwatson error = suser_cred(cred, 0); 1518105634Srwatson if (error) 1519105634Srwatson return (EPERM); 1520105634Srwatson 1521105634Srwatson /* 1522105634Srwatson * XXXMAC: Additional consistency tests regarding the single 1523105634Srwatson * and the range of the new label might be performed here. 1524105634Srwatson */ 1525105634Srwatson } 1526105634Srwatson 1527105634Srwatson return (0); 1528101099Srwatson} 1529101099Srwatson 1530103759Srwatsonstatic int 1531101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1532101099Srwatson struct mbuf *m, struct label *mbuflabel) 1533101099Srwatson{ 1534101099Srwatson struct mac_biba *p, *i; 1535103761Srwatson 1536101099Srwatson if (!mac_biba_enabled) 1537101099Srwatson return (0); 1538101099Srwatson 1539101099Srwatson p = SLOT(mbuflabel); 1540101099Srwatson i = SLOT(ifnetlabel); 1541103759Srwatson 1542101099Srwatson return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1543101099Srwatson} 1544101099Srwatson 1545101099Srwatsonstatic int 1546110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1547110354Srwatson struct label *label) 1548110354Srwatson{ 1549110354Srwatson struct mac_biba *subj, *obj; 1550110354Srwatson int error; 1551110354Srwatson 1552110354Srwatson if (!mac_biba_enabled) 1553110354Srwatson return (0); 1554110354Srwatson 1555110354Srwatson subj = SLOT(&cred->cr_label); 1556110354Srwatson 1557110354Srwatson error = mac_biba_subject_privileged(subj); 1558110354Srwatson if (error) 1559110354Srwatson return (error); 1560110354Srwatson 1561110354Srwatson obj = SLOT(label); 1562110354Srwatson if (!mac_biba_high_single(obj)) 1563110354Srwatson return (EACCES); 1564110354Srwatson 1565110354Srwatson return (0); 1566110354Srwatson} 1567110354Srwatson 1568110354Srwatson 1569110354Srwatsonstatic int 1570110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred) 1571110354Srwatson{ 1572110354Srwatson struct mac_biba *subj; 1573110354Srwatson 1574110354Srwatson if (!mac_biba_enabled) 1575110354Srwatson return (0); 1576110354Srwatson 1577110354Srwatson subj = SLOT(&cred->cr_label); 1578110354Srwatson 1579110354Srwatson return (mac_biba_subject_privileged(subj)); 1580110354Srwatson} 1581110354Srwatson 1582110354Srwatsonstatic int 1583101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1584101099Srwatson struct label *mntlabel) 1585101099Srwatson{ 1586101099Srwatson struct mac_biba *subj, *obj; 1587101099Srwatson 1588101099Srwatson if (!mac_biba_enabled) 1589101099Srwatson return (0); 1590101099Srwatson 1591101099Srwatson subj = SLOT(&cred->cr_label); 1592101099Srwatson obj = SLOT(mntlabel); 1593101099Srwatson 1594101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1595101099Srwatson return (EACCES); 1596101099Srwatson 1597101099Srwatson return (0); 1598101099Srwatson} 1599101099Srwatson 1600101099Srwatsonstatic int 1601101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1602101099Srwatson struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1603101099Srwatson{ 1604103759Srwatson 1605101099Srwatson if(!mac_biba_enabled) 1606101099Srwatson return (0); 1607101099Srwatson 1608101099Srwatson /* XXX: This will be implemented soon... */ 1609101099Srwatson 1610101099Srwatson return (0); 1611101099Srwatson} 1612101099Srwatson 1613101099Srwatsonstatic int 1614102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1615102115Srwatson struct label *pipelabel) 1616101099Srwatson{ 1617101099Srwatson struct mac_biba *subj, *obj; 1618101099Srwatson 1619101099Srwatson if (!mac_biba_enabled) 1620101099Srwatson return (0); 1621101099Srwatson 1622101099Srwatson subj = SLOT(&cred->cr_label); 1623101099Srwatson obj = SLOT((pipelabel)); 1624101099Srwatson 1625102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1626102115Srwatson return (EACCES); 1627101099Srwatson 1628101099Srwatson return (0); 1629101099Srwatson} 1630101099Srwatson 1631101099Srwatsonstatic int 1632102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1633102115Srwatson struct label *pipelabel) 1634102115Srwatson{ 1635102115Srwatson struct mac_biba *subj, *obj; 1636102115Srwatson 1637102115Srwatson if (!mac_biba_enabled) 1638102115Srwatson return (0); 1639102115Srwatson 1640102115Srwatson subj = SLOT(&cred->cr_label); 1641102115Srwatson obj = SLOT((pipelabel)); 1642102115Srwatson 1643102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1644102115Srwatson return (EACCES); 1645102115Srwatson 1646102115Srwatson return (0); 1647102115Srwatson} 1648102115Srwatson 1649102115Srwatsonstatic int 1650101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1651101099Srwatson struct label *pipelabel, struct label *newlabel) 1652101099Srwatson{ 1653101099Srwatson struct mac_biba *subj, *obj, *new; 1654105634Srwatson int error; 1655101099Srwatson 1656101099Srwatson new = SLOT(newlabel); 1657101099Srwatson subj = SLOT(&cred->cr_label); 1658101099Srwatson obj = SLOT(pipelabel); 1659101099Srwatson 1660101099Srwatson /* 1661105634Srwatson * If there is a Biba label update for a pipe, it must be a 1662105634Srwatson * single update. 1663101099Srwatson */ 1664105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1665105634Srwatson if (error) 1666105634Srwatson return (error); 1667101099Srwatson 1668101099Srwatson /* 1669105634Srwatson * To perform a relabel of a pipe (Biba label or not), Biba must 1670105634Srwatson * authorize the relabel. 1671101099Srwatson */ 1672105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1673101099Srwatson return (EPERM); 1674101099Srwatson 1675101099Srwatson /* 1676105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1677101099Srwatson */ 1678105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1679105634Srwatson /* 1680105634Srwatson * To change the Biba label on a pipe, the new pipe label 1681105634Srwatson * must be in the subject range. 1682105634Srwatson */ 1683105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1684105634Srwatson return (EPERM); 1685101099Srwatson 1686105634Srwatson /* 1687105634Srwatson * To change the Biba label on a pipe to be EQUAL, the 1688105634Srwatson * subject must have appropriate privilege. 1689105634Srwatson */ 1690105634Srwatson if (mac_biba_contains_equal(new)) { 1691106090Srwatson error = mac_biba_subject_privileged(subj); 1692105634Srwatson if (error) 1693105634Srwatson return (error); 1694105634Srwatson } 1695105634Srwatson } 1696105634Srwatson 1697101099Srwatson return (0); 1698101099Srwatson} 1699101099Srwatson 1700101099Srwatsonstatic int 1701102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1702102115Srwatson struct label *pipelabel) 1703102115Srwatson{ 1704102115Srwatson struct mac_biba *subj, *obj; 1705102115Srwatson 1706102115Srwatson if (!mac_biba_enabled) 1707102115Srwatson return (0); 1708102115Srwatson 1709102115Srwatson subj = SLOT(&cred->cr_label); 1710102115Srwatson obj = SLOT((pipelabel)); 1711102115Srwatson 1712102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1713102115Srwatson return (EACCES); 1714102115Srwatson 1715102115Srwatson return (0); 1716102115Srwatson} 1717102115Srwatson 1718102115Srwatsonstatic int 1719102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1720102115Srwatson struct label *pipelabel) 1721102115Srwatson{ 1722102115Srwatson struct mac_biba *subj, *obj; 1723102115Srwatson 1724102115Srwatson if (!mac_biba_enabled) 1725102115Srwatson return (0); 1726102115Srwatson 1727102115Srwatson subj = SLOT(&cred->cr_label); 1728102115Srwatson obj = SLOT((pipelabel)); 1729102115Srwatson 1730102115Srwatson if (!mac_biba_dominate_single(subj, obj)) 1731102115Srwatson return (EACCES); 1732102115Srwatson 1733102115Srwatson return (0); 1734102115Srwatson} 1735102115Srwatson 1736102115Srwatsonstatic int 1737101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1738101099Srwatson{ 1739101099Srwatson struct mac_biba *subj, *obj; 1740101099Srwatson 1741101099Srwatson if (!mac_biba_enabled) 1742101099Srwatson return (0); 1743101099Srwatson 1744101099Srwatson subj = SLOT(&cred->cr_label); 1745101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1746101099Srwatson 1747101099Srwatson /* XXX: range checks */ 1748101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1749101099Srwatson return (ESRCH); 1750101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1751101099Srwatson return (EACCES); 1752101099Srwatson 1753101099Srwatson return (0); 1754101099Srwatson} 1755101099Srwatson 1756101099Srwatsonstatic int 1757101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1758101099Srwatson{ 1759101099Srwatson struct mac_biba *subj, *obj; 1760103759Srwatson 1761101099Srwatson if (!mac_biba_enabled) 1762101099Srwatson return (0); 1763101099Srwatson 1764101099Srwatson subj = SLOT(&cred->cr_label); 1765101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1766103759Srwatson 1767101099Srwatson /* XXX: range checks */ 1768101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1769101099Srwatson return (ESRCH); 1770101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1771101099Srwatson return (EACCES); 1772101099Srwatson 1773101099Srwatson return (0); 1774101099Srwatson} 1775101099Srwatson 1776101099Srwatsonstatic int 1777101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1778101099Srwatson{ 1779101099Srwatson struct mac_biba *subj, *obj; 1780103759Srwatson 1781101099Srwatson if (!mac_biba_enabled) 1782101099Srwatson return (0); 1783101099Srwatson 1784101099Srwatson subj = SLOT(&cred->cr_label); 1785101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1786103759Srwatson 1787101099Srwatson /* XXX: range checks */ 1788101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1789101099Srwatson return (ESRCH); 1790101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1791101099Srwatson return (EACCES); 1792101099Srwatson 1793101099Srwatson return (0); 1794101099Srwatson} 1795101099Srwatson 1796101099Srwatsonstatic int 1797101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1798101099Srwatson struct mbuf *m, struct label *mbuflabel) 1799101099Srwatson{ 1800101099Srwatson struct mac_biba *p, *s; 1801101099Srwatson 1802101099Srwatson if (!mac_biba_enabled) 1803101099Srwatson return (0); 1804101099Srwatson 1805101099Srwatson p = SLOT(mbuflabel); 1806101099Srwatson s = SLOT(socketlabel); 1807101099Srwatson 1808101099Srwatson return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1809101099Srwatson} 1810101099Srwatson 1811101099Srwatsonstatic int 1812106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1813101099Srwatson struct label *socketlabel, struct label *newlabel) 1814101099Srwatson{ 1815101099Srwatson struct mac_biba *subj, *obj, *new; 1816105634Srwatson int error; 1817101099Srwatson 1818101099Srwatson new = SLOT(newlabel); 1819101099Srwatson subj = SLOT(&cred->cr_label); 1820101099Srwatson obj = SLOT(socketlabel); 1821101099Srwatson 1822101099Srwatson /* 1823105634Srwatson * If there is a Biba label update for the socket, it may be 1824105634Srwatson * an update of single. 1825101099Srwatson */ 1826105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1827105634Srwatson if (error) 1828105634Srwatson return (error); 1829101099Srwatson 1830101099Srwatson /* 1831105634Srwatson * To relabel a socket, the old socket single must be in the subject 1832101099Srwatson * range. 1833101099Srwatson */ 1834105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1835101099Srwatson return (EPERM); 1836101099Srwatson 1837101099Srwatson /* 1838105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1839101099Srwatson */ 1840105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1841105634Srwatson /* 1842105634Srwatson * To relabel a socket, the new socket single must be in 1843105634Srwatson * the subject range. 1844105634Srwatson */ 1845105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1846105634Srwatson return (EPERM); 1847101099Srwatson 1848105634Srwatson /* 1849105634Srwatson * To change the Biba label on the socket to contain EQUAL, 1850105634Srwatson * the subject must have appropriate privilege. 1851105634Srwatson */ 1852105634Srwatson if (mac_biba_contains_equal(new)) { 1853106090Srwatson error = mac_biba_subject_privileged(subj); 1854105634Srwatson if (error) 1855105634Srwatson return (error); 1856105634Srwatson } 1857105634Srwatson } 1858105634Srwatson 1859101099Srwatson return (0); 1860101099Srwatson} 1861101099Srwatson 1862101099Srwatsonstatic int 1863101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1864101099Srwatson struct label *socketlabel) 1865101099Srwatson{ 1866101099Srwatson struct mac_biba *subj, *obj; 1867101099Srwatson 1868105722Srwatson if (!mac_biba_enabled) 1869105722Srwatson return (0); 1870105722Srwatson 1871101099Srwatson subj = SLOT(&cred->cr_label); 1872101099Srwatson obj = SLOT(socketlabel); 1873101099Srwatson 1874101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1875101099Srwatson return (ENOENT); 1876101099Srwatson 1877101099Srwatson return (0); 1878101099Srwatson} 1879101099Srwatson 1880101099Srwatsonstatic int 1881106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1882106418Srwatson struct label *label) 1883106418Srwatson{ 1884106418Srwatson struct mac_biba *subj, *obj; 1885106418Srwatson int error; 1886106418Srwatson 1887106418Srwatson if (!mac_biba_enabled) 1888106418Srwatson return (0); 1889106418Srwatson 1890106418Srwatson subj = SLOT(&cred->cr_label); 1891106418Srwatson 1892106418Srwatson error = mac_biba_subject_privileged(subj); 1893106418Srwatson if (error) 1894106418Srwatson return (error); 1895106418Srwatson 1896106418Srwatson if (label == NULL) 1897106418Srwatson return (0); 1898106418Srwatson 1899106418Srwatson obj = SLOT(label); 1900106418Srwatson if (!mac_biba_high_single(obj)) 1901106418Srwatson return (EACCES); 1902106418Srwatson 1903106418Srwatson return (0); 1904106418Srwatson} 1905106418Srwatson 1906106418Srwatsonstatic int 1907106418Srwatsonmac_biba_check_system_settime(struct ucred *cred) 1908106418Srwatson{ 1909106418Srwatson struct mac_biba *subj; 1910106418Srwatson int error; 1911106418Srwatson 1912106418Srwatson if (!mac_biba_enabled) 1913106418Srwatson return (0); 1914106418Srwatson 1915106418Srwatson subj = SLOT(&cred->cr_label); 1916106418Srwatson 1917106418Srwatson error = mac_biba_subject_privileged(subj); 1918106418Srwatson if (error) 1919106418Srwatson return (error); 1920106418Srwatson 1921106418Srwatson return (0); 1922106418Srwatson} 1923106418Srwatson 1924106418Srwatsonstatic int 1925106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1926106161Srwatson struct label *label) 1927106161Srwatson{ 1928106161Srwatson struct mac_biba *subj, *obj; 1929106416Srwatson int error; 1930106161Srwatson 1931106161Srwatson if (!mac_biba_enabled) 1932106161Srwatson return (0); 1933106161Srwatson 1934106161Srwatson subj = SLOT(&cred->cr_label); 1935106161Srwatson obj = SLOT(label); 1936106161Srwatson 1937106416Srwatson error = mac_biba_subject_privileged(subj); 1938106416Srwatson if (error) 1939106416Srwatson return (error); 1940106161Srwatson 1941106161Srwatson if (!mac_biba_high_single(obj)) 1942106161Srwatson return (EACCES); 1943106161Srwatson 1944106161Srwatson return (0); 1945106161Srwatson} 1946106161Srwatson 1947106161Srwatsonstatic int 1948106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1949106161Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1950106161Srwatson{ 1951106161Srwatson struct mac_biba *subj; 1952106161Srwatson int error; 1953106161Srwatson 1954106161Srwatson if (!mac_biba_enabled) 1955106161Srwatson return (0); 1956106161Srwatson 1957106161Srwatson subj = SLOT(&cred->cr_label); 1958106161Srwatson 1959106161Srwatson /* 1960106161Srwatson * In general, treat sysctl variables as biba/high, but also 1961106161Srwatson * require privilege to change them, since they are a 1962106161Srwatson * communications channel between grades. Exempt MIB 1963106161Srwatson * queries from this due to undocmented sysctl magic. 1964106161Srwatson * XXXMAC: This probably requires some more review. 1965106161Srwatson */ 1966106161Srwatson if (new != NULL) { 1967106161Srwatson if (namelen > 0 && name[0] == 0) 1968106161Srwatson return (0); 1969106161Srwatson 1970106161Srwatson if (!mac_biba_subject_dominate_high(subj)) 1971106161Srwatson return (EACCES); 1972106161Srwatson 1973106161Srwatson error = mac_biba_subject_privileged(subj); 1974106161Srwatson if (error) 1975106161Srwatson return (error); 1976106161Srwatson } 1977106161Srwatson 1978106161Srwatson return (0); 1979106161Srwatson} 1980106161Srwatson 1981106161Srwatsonstatic int 1982101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1983101099Srwatson struct label *dlabel) 1984101099Srwatson{ 1985101099Srwatson struct mac_biba *subj, *obj; 1986101099Srwatson 1987101099Srwatson if (!mac_biba_enabled) 1988101099Srwatson return (0); 1989101099Srwatson 1990101099Srwatson subj = SLOT(&cred->cr_label); 1991101099Srwatson obj = SLOT(dlabel); 1992101099Srwatson 1993101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1994101099Srwatson return (EACCES); 1995101099Srwatson 1996101099Srwatson return (0); 1997101099Srwatson} 1998101099Srwatson 1999101099Srwatsonstatic int 2000101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2001101099Srwatson struct label *dlabel) 2002101099Srwatson{ 2003101099Srwatson struct mac_biba *subj, *obj; 2004101099Srwatson 2005101099Srwatson if (!mac_biba_enabled) 2006101099Srwatson return (0); 2007101099Srwatson 2008101099Srwatson subj = SLOT(&cred->cr_label); 2009101099Srwatson obj = SLOT(dlabel); 2010101099Srwatson 2011101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2012101099Srwatson return (EACCES); 2013101099Srwatson 2014101099Srwatson return (0); 2015101099Srwatson} 2016101099Srwatson 2017101099Srwatsonstatic int 2018101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2019101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2020101099Srwatson{ 2021101099Srwatson struct mac_biba *subj, *obj; 2022101099Srwatson 2023101099Srwatson if (!mac_biba_enabled) 2024101099Srwatson return (0); 2025101099Srwatson 2026101099Srwatson subj = SLOT(&cred->cr_label); 2027101099Srwatson obj = SLOT(dlabel); 2028101099Srwatson 2029101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2030101099Srwatson return (EACCES); 2031101099Srwatson 2032101099Srwatson return (0); 2033101099Srwatson} 2034101099Srwatson 2035101099Srwatsonstatic int 2036101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2037101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2038101099Srwatson struct componentname *cnp) 2039101099Srwatson{ 2040101099Srwatson struct mac_biba *subj, *obj; 2041101099Srwatson 2042101099Srwatson if (!mac_biba_enabled) 2043101099Srwatson return (0); 2044101099Srwatson 2045101099Srwatson subj = SLOT(&cred->cr_label); 2046101099Srwatson obj = SLOT(dlabel); 2047101099Srwatson 2048101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2049101099Srwatson return (EACCES); 2050101099Srwatson 2051101099Srwatson obj = SLOT(label); 2052101099Srwatson 2053101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2054101099Srwatson return (EACCES); 2055101099Srwatson 2056101099Srwatson return (0); 2057101099Srwatson} 2058101099Srwatson 2059101099Srwatsonstatic int 2060101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2061101099Srwatson struct label *label, acl_type_t type) 2062101099Srwatson{ 2063101099Srwatson struct mac_biba *subj, *obj; 2064101099Srwatson 2065101099Srwatson if (!mac_biba_enabled) 2066101099Srwatson return (0); 2067101099Srwatson 2068101099Srwatson subj = SLOT(&cred->cr_label); 2069101099Srwatson obj = SLOT(label); 2070101099Srwatson 2071101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2072101099Srwatson return (EACCES); 2073101099Srwatson 2074101099Srwatson return (0); 2075101099Srwatson} 2076101099Srwatson 2077101099Srwatsonstatic int 2078101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2079106648Srwatson struct label *label, struct image_params *imgp, 2080106648Srwatson struct label *execlabel) 2081101099Srwatson{ 2082106648Srwatson struct mac_biba *subj, *obj, *exec; 2083106648Srwatson int error; 2084101099Srwatson 2085106648Srwatson if (execlabel != NULL) { 2086106648Srwatson /* 2087106648Srwatson * We currently don't permit labels to be changed at 2088106648Srwatson * exec-time as part of Biba, so disallow non-NULL 2089106648Srwatson * Biba label elements in the execlabel. 2090106648Srwatson */ 2091106648Srwatson exec = SLOT(execlabel); 2092106648Srwatson error = biba_atmostflags(exec, 0); 2093106648Srwatson if (error) 2094106648Srwatson return (error); 2095106648Srwatson } 2096106648Srwatson 2097101099Srwatson if (!mac_biba_enabled) 2098101099Srwatson return (0); 2099101099Srwatson 2100101099Srwatson subj = SLOT(&cred->cr_label); 2101101099Srwatson obj = SLOT(label); 2102101099Srwatson 2103101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2104101099Srwatson return (EACCES); 2105101099Srwatson 2106101099Srwatson return (0); 2107101099Srwatson} 2108101099Srwatson 2109101099Srwatsonstatic int 2110101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2111101099Srwatson struct label *label, acl_type_t type) 2112101099Srwatson{ 2113101099Srwatson struct mac_biba *subj, *obj; 2114101099Srwatson 2115101099Srwatson if (!mac_biba_enabled) 2116101099Srwatson return (0); 2117101099Srwatson 2118101099Srwatson subj = SLOT(&cred->cr_label); 2119101099Srwatson obj = SLOT(label); 2120101099Srwatson 2121101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2122101099Srwatson return (EACCES); 2123101099Srwatson 2124101099Srwatson return (0); 2125101099Srwatson} 2126101099Srwatson 2127101099Srwatsonstatic int 2128101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2129101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 2130101099Srwatson{ 2131101099Srwatson struct mac_biba *subj, *obj; 2132101099Srwatson 2133101099Srwatson if (!mac_biba_enabled) 2134101099Srwatson return (0); 2135101099Srwatson 2136101099Srwatson subj = SLOT(&cred->cr_label); 2137101099Srwatson obj = SLOT(label); 2138101099Srwatson 2139101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2140101099Srwatson return (EACCES); 2141101099Srwatson 2142101099Srwatson return (0); 2143101099Srwatson} 2144101099Srwatson 2145101099Srwatsonstatic int 2146104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2147104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2148104530Srwatson struct componentname *cnp) 2149104530Srwatson{ 2150104530Srwatson struct mac_biba *subj, *obj; 2151104530Srwatson 2152104530Srwatson if (!mac_biba_enabled) 2153104530Srwatson return (0); 2154104530Srwatson 2155104530Srwatson subj = SLOT(&cred->cr_label); 2156104530Srwatson obj = SLOT(dlabel); 2157104530Srwatson 2158104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2159104530Srwatson return (EACCES); 2160104530Srwatson 2161104530Srwatson obj = SLOT(label); 2162104530Srwatson 2163104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2164104530Srwatson return (EACCES); 2165104530Srwatson 2166104530Srwatson return (0); 2167104530Srwatson} 2168104530Srwatson 2169104530Srwatsonstatic int 2170103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2171101099Srwatson struct label *dlabel, struct componentname *cnp) 2172101099Srwatson{ 2173101099Srwatson struct mac_biba *subj, *obj; 2174103759Srwatson 2175101099Srwatson if (!mac_biba_enabled) 2176101099Srwatson return (0); 2177103759Srwatson 2178101099Srwatson subj = SLOT(&cred->cr_label); 2179101099Srwatson obj = SLOT(dlabel); 2180103759Srwatson 2181101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2182101099Srwatson return (EACCES); 2183101099Srwatson 2184103759Srwatson return (0); 2185101099Srwatson} 2186101099Srwatson 2187101099Srwatsonstatic int 2188104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2189104546Srwatson struct label *label, int prot) 2190104546Srwatson{ 2191104546Srwatson struct mac_biba *subj, *obj; 2192104546Srwatson 2193104546Srwatson /* 2194104546Srwatson * Rely on the use of open()-time protections to handle 2195104546Srwatson * non-revocation cases. 2196104546Srwatson */ 2197105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2198104546Srwatson return (0); 2199104546Srwatson 2200104546Srwatson subj = SLOT(&cred->cr_label); 2201104546Srwatson obj = SLOT(label); 2202104546Srwatson 2203104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2204104546Srwatson if (!mac_biba_dominate_single(obj, subj)) 2205104546Srwatson return (EACCES); 2206104546Srwatson } 2207104546Srwatson if (prot & VM_PROT_WRITE) { 2208104546Srwatson if (!mac_biba_dominate_single(subj, obj)) 2209104546Srwatson return (EACCES); 2210104546Srwatson } 2211104546Srwatson 2212104569Srwatson return (0); 2213104546Srwatson} 2214104546Srwatson 2215104546Srwatsonstatic int 2216101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2217106212Srwatson struct label *vnodelabel, int acc_mode) 2218101099Srwatson{ 2219101099Srwatson struct mac_biba *subj, *obj; 2220101099Srwatson 2221101099Srwatson if (!mac_biba_enabled) 2222101099Srwatson return (0); 2223101099Srwatson 2224101099Srwatson subj = SLOT(&cred->cr_label); 2225101099Srwatson obj = SLOT(vnodelabel); 2226101099Srwatson 2227101099Srwatson /* XXX privilege override for admin? */ 2228101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2229101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2230101099Srwatson return (EACCES); 2231101099Srwatson } 2232101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2233101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2234101099Srwatson return (EACCES); 2235101099Srwatson } 2236101099Srwatson 2237101099Srwatson return (0); 2238101099Srwatson} 2239101099Srwatson 2240101099Srwatsonstatic int 2241102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2242102129Srwatson struct vnode *vp, struct label *label) 2243102112Srwatson{ 2244102112Srwatson struct mac_biba *subj, *obj; 2245102112Srwatson 2246105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2247102112Srwatson return (0); 2248102112Srwatson 2249102129Srwatson subj = SLOT(&active_cred->cr_label); 2250102112Srwatson obj = SLOT(label); 2251102112Srwatson 2252102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2253102112Srwatson return (EACCES); 2254102112Srwatson 2255102112Srwatson return (0); 2256102112Srwatson} 2257102112Srwatson 2258102112Srwatsonstatic int 2259102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2260102129Srwatson struct vnode *vp, struct label *label) 2261102112Srwatson{ 2262102112Srwatson struct mac_biba *subj, *obj; 2263102112Srwatson 2264105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2265102112Srwatson return (0); 2266102112Srwatson 2267102129Srwatson subj = SLOT(&active_cred->cr_label); 2268102112Srwatson obj = SLOT(label); 2269102112Srwatson 2270102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2271102112Srwatson return (EACCES); 2272102112Srwatson 2273102112Srwatson return (0); 2274102112Srwatson} 2275102112Srwatson 2276102112Srwatsonstatic int 2277101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2278101099Srwatson struct label *dlabel) 2279101099Srwatson{ 2280101099Srwatson struct mac_biba *subj, *obj; 2281101099Srwatson 2282101099Srwatson if (!mac_biba_enabled) 2283101099Srwatson return (0); 2284101099Srwatson 2285101099Srwatson subj = SLOT(&cred->cr_label); 2286101099Srwatson obj = SLOT(dlabel); 2287101099Srwatson 2288101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2289101099Srwatson return (EACCES); 2290101099Srwatson 2291101099Srwatson return (0); 2292101099Srwatson} 2293101099Srwatson 2294101099Srwatsonstatic int 2295101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2296101099Srwatson struct label *label) 2297101099Srwatson{ 2298101099Srwatson struct mac_biba *subj, *obj; 2299101099Srwatson 2300101099Srwatson if (!mac_biba_enabled) 2301101099Srwatson return (0); 2302101099Srwatson 2303101099Srwatson subj = SLOT(&cred->cr_label); 2304101099Srwatson obj = SLOT(label); 2305101099Srwatson 2306101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2307101099Srwatson return (EACCES); 2308101099Srwatson 2309101099Srwatson return (0); 2310101099Srwatson} 2311101099Srwatson 2312101099Srwatsonstatic int 2313101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2314101099Srwatson struct label *vnodelabel, struct label *newlabel) 2315101099Srwatson{ 2316101099Srwatson struct mac_biba *old, *new, *subj; 2317105634Srwatson int error; 2318101099Srwatson 2319101099Srwatson old = SLOT(vnodelabel); 2320101099Srwatson new = SLOT(newlabel); 2321101099Srwatson subj = SLOT(&cred->cr_label); 2322101099Srwatson 2323101099Srwatson /* 2324105634Srwatson * If there is a Biba label update for the vnode, it must be a 2325105634Srwatson * single label. 2326101099Srwatson */ 2327105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2328105634Srwatson if (error) 2329105634Srwatson return (error); 2330101099Srwatson 2331101099Srwatson /* 2332105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2333105634Srwatson * authorize the relabel. 2334101099Srwatson */ 2335105634Srwatson if (!mac_biba_single_in_range(old, subj)) 2336101099Srwatson return (EPERM); 2337101099Srwatson 2338101099Srwatson /* 2339105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2340101099Srwatson */ 2341105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2342105634Srwatson /* 2343105634Srwatson * To change the Biba label on a vnode, the new vnode label 2344105634Srwatson * must be in the subject range. 2345105634Srwatson */ 2346105634Srwatson if (!mac_biba_single_in_range(new, subj)) 2347105634Srwatson return (EPERM); 2348101099Srwatson 2349105634Srwatson /* 2350105634Srwatson * To change the Biba label on the vnode to be EQUAL, 2351105634Srwatson * the subject must have appropriate privilege. 2352105634Srwatson */ 2353105634Srwatson if (mac_biba_contains_equal(new)) { 2354106090Srwatson error = mac_biba_subject_privileged(subj); 2355105634Srwatson if (error) 2356105634Srwatson return (error); 2357105634Srwatson } 2358105634Srwatson } 2359105634Srwatson 2360105634Srwatson return (0); 2361101099Srwatson} 2362101099Srwatson 2363101099Srwatsonstatic int 2364101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2365101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2366101099Srwatson struct componentname *cnp) 2367101099Srwatson{ 2368101099Srwatson struct mac_biba *subj, *obj; 2369101099Srwatson 2370101099Srwatson if (!mac_biba_enabled) 2371101099Srwatson return (0); 2372101099Srwatson 2373101099Srwatson subj = SLOT(&cred->cr_label); 2374101099Srwatson obj = SLOT(dlabel); 2375101099Srwatson 2376101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2377101099Srwatson return (EACCES); 2378101099Srwatson 2379101099Srwatson obj = SLOT(label); 2380101099Srwatson 2381101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2382101099Srwatson return (EACCES); 2383101099Srwatson 2384101099Srwatson return (0); 2385101099Srwatson} 2386101099Srwatson 2387101099Srwatsonstatic int 2388101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2389101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2390101099Srwatson struct componentname *cnp) 2391101099Srwatson{ 2392101099Srwatson struct mac_biba *subj, *obj; 2393101099Srwatson 2394101099Srwatson if (!mac_biba_enabled) 2395101099Srwatson return (0); 2396101099Srwatson 2397101099Srwatson subj = SLOT(&cred->cr_label); 2398101099Srwatson obj = SLOT(dlabel); 2399101099Srwatson 2400101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2401101099Srwatson return (EACCES); 2402101099Srwatson 2403101099Srwatson if (vp != NULL) { 2404101099Srwatson obj = SLOT(label); 2405101099Srwatson 2406101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2407101099Srwatson return (EACCES); 2408101099Srwatson } 2409101099Srwatson 2410101099Srwatson return (0); 2411101099Srwatson} 2412101099Srwatson 2413101099Srwatsonstatic int 2414101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2415101099Srwatson struct label *label) 2416101099Srwatson{ 2417101099Srwatson struct mac_biba *subj, *obj; 2418101099Srwatson 2419101099Srwatson if (!mac_biba_enabled) 2420101099Srwatson return (0); 2421101099Srwatson 2422101099Srwatson subj = SLOT(&cred->cr_label); 2423101099Srwatson obj = SLOT(label); 2424101099Srwatson 2425101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2426101099Srwatson return (EACCES); 2427101099Srwatson 2428101099Srwatson return (0); 2429101099Srwatson} 2430101099Srwatson 2431101099Srwatsonstatic int 2432101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2433101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 2434101099Srwatson{ 2435101099Srwatson struct mac_biba *subj, *obj; 2436101099Srwatson 2437101099Srwatson if (!mac_biba_enabled) 2438101099Srwatson return (0); 2439101099Srwatson 2440101099Srwatson subj = SLOT(&cred->cr_label); 2441101099Srwatson obj = SLOT(label); 2442101099Srwatson 2443101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2444101099Srwatson return (EACCES); 2445101099Srwatson 2446101099Srwatson return (0); 2447101099Srwatson} 2448101099Srwatson 2449101099Srwatsonstatic int 2450101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2451101099Srwatson struct label *vnodelabel, int attrnamespace, const char *name, 2452101099Srwatson struct uio *uio) 2453101099Srwatson{ 2454101099Srwatson struct mac_biba *subj, *obj; 2455101099Srwatson 2456101099Srwatson if (!mac_biba_enabled) 2457101099Srwatson return (0); 2458101099Srwatson 2459101099Srwatson subj = SLOT(&cred->cr_label); 2460101099Srwatson obj = SLOT(vnodelabel); 2461101099Srwatson 2462101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2463101099Srwatson return (EACCES); 2464101099Srwatson 2465101099Srwatson /* XXX: protect the MAC EA in a special way? */ 2466101099Srwatson 2467101099Srwatson return (0); 2468101099Srwatson} 2469101099Srwatson 2470101099Srwatsonstatic int 2471101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2472101099Srwatson struct label *vnodelabel, u_long flags) 2473101099Srwatson{ 2474101099Srwatson struct mac_biba *subj, *obj; 2475101099Srwatson 2476101099Srwatson if (!mac_biba_enabled) 2477101099Srwatson return (0); 2478101099Srwatson 2479101099Srwatson subj = SLOT(&cred->cr_label); 2480101099Srwatson obj = SLOT(vnodelabel); 2481101099Srwatson 2482101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2483101099Srwatson return (EACCES); 2484101099Srwatson 2485101099Srwatson return (0); 2486101099Srwatson} 2487101099Srwatson 2488101099Srwatsonstatic int 2489101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2490101099Srwatson struct label *vnodelabel, mode_t mode) 2491101099Srwatson{ 2492101099Srwatson struct mac_biba *subj, *obj; 2493101099Srwatson 2494101099Srwatson if (!mac_biba_enabled) 2495101099Srwatson return (0); 2496101099Srwatson 2497101099Srwatson subj = SLOT(&cred->cr_label); 2498101099Srwatson obj = SLOT(vnodelabel); 2499101099Srwatson 2500101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2501101099Srwatson return (EACCES); 2502101099Srwatson 2503101099Srwatson return (0); 2504101099Srwatson} 2505101099Srwatson 2506101099Srwatsonstatic int 2507101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2508101099Srwatson struct label *vnodelabel, uid_t uid, gid_t gid) 2509101099Srwatson{ 2510101099Srwatson struct mac_biba *subj, *obj; 2511101099Srwatson 2512101099Srwatson if (!mac_biba_enabled) 2513101099Srwatson return (0); 2514101099Srwatson 2515101099Srwatson subj = SLOT(&cred->cr_label); 2516101099Srwatson obj = SLOT(vnodelabel); 2517101099Srwatson 2518101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2519101099Srwatson return (EACCES); 2520101099Srwatson 2521101099Srwatson return (0); 2522101099Srwatson} 2523101099Srwatson 2524101099Srwatsonstatic int 2525101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2526101099Srwatson struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2527101099Srwatson{ 2528101099Srwatson struct mac_biba *subj, *obj; 2529101099Srwatson 2530101099Srwatson if (!mac_biba_enabled) 2531101099Srwatson return (0); 2532101099Srwatson 2533101099Srwatson subj = SLOT(&cred->cr_label); 2534101099Srwatson obj = SLOT(vnodelabel); 2535101099Srwatson 2536101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2537101099Srwatson return (EACCES); 2538101099Srwatson 2539101099Srwatson return (0); 2540101099Srwatson} 2541101099Srwatson 2542101099Srwatsonstatic int 2543102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2544102129Srwatson struct vnode *vp, struct label *vnodelabel) 2545101099Srwatson{ 2546101099Srwatson struct mac_biba *subj, *obj; 2547101099Srwatson 2548101099Srwatson if (!mac_biba_enabled) 2549101099Srwatson return (0); 2550101099Srwatson 2551102129Srwatson subj = SLOT(&active_cred->cr_label); 2552101099Srwatson obj = SLOT(vnodelabel); 2553101099Srwatson 2554101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2555101099Srwatson return (EACCES); 2556101099Srwatson 2557101099Srwatson return (0); 2558101099Srwatson} 2559101099Srwatson 2560102112Srwatsonstatic int 2561102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred, 2562102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 2563102112Srwatson{ 2564102112Srwatson struct mac_biba *subj, *obj; 2565102112Srwatson 2566105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2567102112Srwatson return (0); 2568102112Srwatson 2569102129Srwatson subj = SLOT(&active_cred->cr_label); 2570102112Srwatson obj = SLOT(label); 2571102112Srwatson 2572102112Srwatson if (!mac_biba_dominate_single(subj, obj)) 2573102112Srwatson return (EACCES); 2574102112Srwatson 2575102112Srwatson return (0); 2576102112Srwatson} 2577102112Srwatson 2578106217Srwatsonstatic struct mac_policy_ops mac_biba_ops = 2579101099Srwatson{ 2580106217Srwatson .mpo_destroy = mac_biba_destroy, 2581106217Srwatson .mpo_init = mac_biba_init, 2582106217Srwatson .mpo_init_bpfdesc_label = mac_biba_init_label, 2583106217Srwatson .mpo_init_cred_label = mac_biba_init_label, 2584106217Srwatson .mpo_init_devfsdirent_label = mac_biba_init_label, 2585106217Srwatson .mpo_init_ifnet_label = mac_biba_init_label, 2586106217Srwatson .mpo_init_ipq_label = mac_biba_init_label, 2587106217Srwatson .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2588106217Srwatson .mpo_init_mount_label = mac_biba_init_label, 2589106217Srwatson .mpo_init_mount_fs_label = mac_biba_init_label, 2590106217Srwatson .mpo_init_pipe_label = mac_biba_init_label, 2591106217Srwatson .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2592106217Srwatson .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2593106217Srwatson .mpo_init_vnode_label = mac_biba_init_label, 2594106217Srwatson .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2595106217Srwatson .mpo_destroy_cred_label = mac_biba_destroy_label, 2596106217Srwatson .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2597106217Srwatson .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2598106217Srwatson .mpo_destroy_ipq_label = mac_biba_destroy_label, 2599106217Srwatson .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2600106217Srwatson .mpo_destroy_mount_label = mac_biba_destroy_label, 2601106217Srwatson .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2602106217Srwatson .mpo_destroy_pipe_label = mac_biba_destroy_label, 2603106217Srwatson .mpo_destroy_socket_label = mac_biba_destroy_label, 2604106217Srwatson .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2605106217Srwatson .mpo_destroy_vnode_label = mac_biba_destroy_label, 2606106217Srwatson .mpo_copy_pipe_label = mac_biba_copy_label, 2607106217Srwatson .mpo_copy_vnode_label = mac_biba_copy_label, 2608106217Srwatson .mpo_externalize_cred_label = mac_biba_externalize_label, 2609106217Srwatson .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2610106217Srwatson .mpo_externalize_pipe_label = mac_biba_externalize_label, 2611106217Srwatson .mpo_externalize_socket_label = mac_biba_externalize_label, 2612106217Srwatson .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2613106217Srwatson .mpo_externalize_vnode_label = mac_biba_externalize_label, 2614106217Srwatson .mpo_internalize_cred_label = mac_biba_internalize_label, 2615106217Srwatson .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2616106217Srwatson .mpo_internalize_pipe_label = mac_biba_internalize_label, 2617106217Srwatson .mpo_internalize_socket_label = mac_biba_internalize_label, 2618106217Srwatson .mpo_internalize_vnode_label = mac_biba_internalize_label, 2619106217Srwatson .mpo_create_devfs_device = mac_biba_create_devfs_device, 2620106217Srwatson .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2621106217Srwatson .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2622106217Srwatson .mpo_create_mount = mac_biba_create_mount, 2623106217Srwatson .mpo_create_root_mount = mac_biba_create_root_mount, 2624106217Srwatson .mpo_relabel_vnode = mac_biba_relabel_vnode, 2625106217Srwatson .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2626106217Srwatson .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2627106217Srwatson .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2628106217Srwatson .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2629106217Srwatson .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2630106217Srwatson .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2631106217Srwatson .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2632106217Srwatson .mpo_create_pipe = mac_biba_create_pipe, 2633106217Srwatson .mpo_create_socket = mac_biba_create_socket, 2634106217Srwatson .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2635106217Srwatson .mpo_relabel_pipe = mac_biba_relabel_pipe, 2636106217Srwatson .mpo_relabel_socket = mac_biba_relabel_socket, 2637106217Srwatson .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2638106217Srwatson .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2639106217Srwatson .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2640106217Srwatson .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2641106217Srwatson .mpo_create_fragment = mac_biba_create_fragment, 2642106217Srwatson .mpo_create_ifnet = mac_biba_create_ifnet, 2643106217Srwatson .mpo_create_ipq = mac_biba_create_ipq, 2644106217Srwatson .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2645106217Srwatson .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2646106217Srwatson .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2647106217Srwatson .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2648106217Srwatson .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2649106217Srwatson .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2650106217Srwatson .mpo_fragment_match = mac_biba_fragment_match, 2651106217Srwatson .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2652106217Srwatson .mpo_update_ipq = mac_biba_update_ipq, 2653106217Srwatson .mpo_create_cred = mac_biba_create_cred, 2654106217Srwatson .mpo_create_proc0 = mac_biba_create_proc0, 2655106217Srwatson .mpo_create_proc1 = mac_biba_create_proc1, 2656106217Srwatson .mpo_relabel_cred = mac_biba_relabel_cred, 2657106217Srwatson .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2658106217Srwatson .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2659106217Srwatson .mpo_check_cred_visible = mac_biba_check_cred_visible, 2660106217Srwatson .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2661106217Srwatson .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2662110354Srwatson .mpo_check_kld_load = mac_biba_check_kld_load, 2663110354Srwatson .mpo_check_kld_unload = mac_biba_check_kld_unload, 2664106217Srwatson .mpo_check_mount_stat = mac_biba_check_mount_stat, 2665106217Srwatson .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2666106217Srwatson .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2667106217Srwatson .mpo_check_pipe_read = mac_biba_check_pipe_read, 2668106217Srwatson .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2669106217Srwatson .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2670106217Srwatson .mpo_check_pipe_write = mac_biba_check_pipe_write, 2671106217Srwatson .mpo_check_proc_debug = mac_biba_check_proc_debug, 2672106217Srwatson .mpo_check_proc_sched = mac_biba_check_proc_sched, 2673106217Srwatson .mpo_check_proc_signal = mac_biba_check_proc_signal, 2674106217Srwatson .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2675106217Srwatson .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2676106217Srwatson .mpo_check_socket_visible = mac_biba_check_socket_visible, 2677106418Srwatson .mpo_check_system_acct = mac_biba_check_system_acct, 2678106418Srwatson .mpo_check_system_settime = mac_biba_check_system_settime, 2679106217Srwatson .mpo_check_system_swapon = mac_biba_check_system_swapon, 2680106217Srwatson .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2681106217Srwatson .mpo_check_vnode_access = mac_biba_check_vnode_open, 2682106217Srwatson .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2683106217Srwatson .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2684106217Srwatson .mpo_check_vnode_create = mac_biba_check_vnode_create, 2685106217Srwatson .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2686106217Srwatson .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2687106217Srwatson .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2688106217Srwatson .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2689106217Srwatson .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2690106217Srwatson .mpo_check_vnode_link = mac_biba_check_vnode_link, 2691106217Srwatson .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2692106217Srwatson .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2693106217Srwatson .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2694106217Srwatson .mpo_check_vnode_open = mac_biba_check_vnode_open, 2695106217Srwatson .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2696106217Srwatson .mpo_check_vnode_read = mac_biba_check_vnode_read, 2697106217Srwatson .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2698106217Srwatson .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2699106217Srwatson .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2700106217Srwatson .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2701106217Srwatson .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2702106217Srwatson .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2703106217Srwatson .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2704106217Srwatson .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2705106217Srwatson .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2706106217Srwatson .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2707106217Srwatson .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2708106217Srwatson .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2709106217Srwatson .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2710106217Srwatson .mpo_check_vnode_write = mac_biba_check_vnode_write, 2711101099Srwatson}; 2712101099Srwatson 2713106217SrwatsonMAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2714101099Srwatson MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot); 2715