mac_biba.c revision 112675
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 112675 2003-03-26 15:12:03Z rwatson $ 35101099Srwatson */ 36101099Srwatson 37101099Srwatson/* 38101099Srwatson * Developed by the TrustedBSD Project. 39101099Srwatson * Biba fixed label mandatory integrity policy. 40101099Srwatson */ 41101099Srwatson 42101099Srwatson#include <sys/types.h> 43101099Srwatson#include <sys/param.h> 44101099Srwatson#include <sys/acl.h> 45101099Srwatson#include <sys/conf.h> 46105988Srwatson#include <sys/extattr.h> 47101099Srwatson#include <sys/kernel.h> 48101099Srwatson#include <sys/mac.h> 49103183Sbde#include <sys/malloc.h> 50101099Srwatson#include <sys/mount.h> 51101099Srwatson#include <sys/proc.h> 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 1881112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred) 1882112574Srwatson{ 1883112574Srwatson struct mac_biba *subj; 1884112574Srwatson int error; 1885112574Srwatson 1886112574Srwatson if (!mac_biba_enabled) 1887112574Srwatson return (0); 1888112574Srwatson 1889112574Srwatson subj = SLOT(&cred->cr_label); 1890112574Srwatson 1891112574Srwatson error = mac_biba_subject_privileged(subj); 1892112574Srwatson if (error) 1893112574Srwatson return (error); 1894112574Srwatson 1895112574Srwatson return (0); 1896112574Srwatson} 1897112574Srwatson 1898112574Srwatsonstatic int 1899106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1900106418Srwatson struct label *label) 1901106418Srwatson{ 1902106418Srwatson struct mac_biba *subj, *obj; 1903106418Srwatson int error; 1904106418Srwatson 1905106418Srwatson if (!mac_biba_enabled) 1906106418Srwatson return (0); 1907106418Srwatson 1908106418Srwatson subj = SLOT(&cred->cr_label); 1909106418Srwatson 1910106418Srwatson error = mac_biba_subject_privileged(subj); 1911106418Srwatson if (error) 1912106418Srwatson return (error); 1913106418Srwatson 1914106418Srwatson if (label == NULL) 1915106418Srwatson return (0); 1916106418Srwatson 1917106418Srwatson obj = SLOT(label); 1918106418Srwatson if (!mac_biba_high_single(obj)) 1919106418Srwatson return (EACCES); 1920106418Srwatson 1921106418Srwatson return (0); 1922106418Srwatson} 1923106418Srwatson 1924106418Srwatsonstatic int 1925106418Srwatsonmac_biba_check_system_settime(struct ucred *cred) 1926106418Srwatson{ 1927106418Srwatson struct mac_biba *subj; 1928106418Srwatson int error; 1929106418Srwatson 1930106418Srwatson if (!mac_biba_enabled) 1931106418Srwatson return (0); 1932106418Srwatson 1933106418Srwatson subj = SLOT(&cred->cr_label); 1934106418Srwatson 1935106418Srwatson error = mac_biba_subject_privileged(subj); 1936106418Srwatson if (error) 1937106418Srwatson return (error); 1938106418Srwatson 1939106418Srwatson return (0); 1940106418Srwatson} 1941106418Srwatson 1942106418Srwatsonstatic int 1943106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1944106161Srwatson struct label *label) 1945106161Srwatson{ 1946106161Srwatson struct mac_biba *subj, *obj; 1947106416Srwatson int error; 1948106161Srwatson 1949106161Srwatson if (!mac_biba_enabled) 1950106161Srwatson return (0); 1951106161Srwatson 1952106161Srwatson subj = SLOT(&cred->cr_label); 1953106161Srwatson obj = SLOT(label); 1954106161Srwatson 1955106416Srwatson error = mac_biba_subject_privileged(subj); 1956106416Srwatson if (error) 1957106416Srwatson return (error); 1958106161Srwatson 1959106161Srwatson if (!mac_biba_high_single(obj)) 1960106161Srwatson return (EACCES); 1961106161Srwatson 1962106161Srwatson return (0); 1963106161Srwatson} 1964106161Srwatson 1965106161Srwatsonstatic int 1966112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 1967112574Srwatson struct label *label) 1968112574Srwatson{ 1969112574Srwatson struct mac_biba *subj, *obj; 1970112574Srwatson int error; 1971112574Srwatson 1972112574Srwatson if (!mac_biba_enabled) 1973112574Srwatson return (0); 1974112574Srwatson 1975112574Srwatson subj = SLOT(&cred->cr_label); 1976112574Srwatson obj = SLOT(label); 1977112574Srwatson 1978112574Srwatson error = mac_biba_subject_privileged(subj); 1979112574Srwatson if (error) 1980112574Srwatson return (error); 1981112574Srwatson 1982112574Srwatson return (0); 1983112574Srwatson} 1984112574Srwatson 1985112574Srwatsonstatic int 1986106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1987106161Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1988106161Srwatson{ 1989106161Srwatson struct mac_biba *subj; 1990106161Srwatson int error; 1991106161Srwatson 1992106161Srwatson if (!mac_biba_enabled) 1993106161Srwatson return (0); 1994106161Srwatson 1995106161Srwatson subj = SLOT(&cred->cr_label); 1996106161Srwatson 1997106161Srwatson /* 1998106161Srwatson * In general, treat sysctl variables as biba/high, but also 1999106161Srwatson * require privilege to change them, since they are a 2000106161Srwatson * communications channel between grades. Exempt MIB 2001106161Srwatson * queries from this due to undocmented sysctl magic. 2002106161Srwatson * XXXMAC: This probably requires some more review. 2003106161Srwatson */ 2004106161Srwatson if (new != NULL) { 2005106161Srwatson if (namelen > 0 && name[0] == 0) 2006106161Srwatson return (0); 2007106161Srwatson 2008106161Srwatson if (!mac_biba_subject_dominate_high(subj)) 2009106161Srwatson return (EACCES); 2010106161Srwatson 2011106161Srwatson error = mac_biba_subject_privileged(subj); 2012106161Srwatson if (error) 2013106161Srwatson return (error); 2014106161Srwatson } 2015106161Srwatson 2016106161Srwatson return (0); 2017106161Srwatson} 2018106161Srwatson 2019106161Srwatsonstatic int 2020101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2021101099Srwatson struct label *dlabel) 2022101099Srwatson{ 2023101099Srwatson struct mac_biba *subj, *obj; 2024101099Srwatson 2025101099Srwatson if (!mac_biba_enabled) 2026101099Srwatson return (0); 2027101099Srwatson 2028101099Srwatson subj = SLOT(&cred->cr_label); 2029101099Srwatson obj = SLOT(dlabel); 2030101099Srwatson 2031101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2032101099Srwatson return (EACCES); 2033101099Srwatson 2034101099Srwatson return (0); 2035101099Srwatson} 2036101099Srwatson 2037101099Srwatsonstatic int 2038101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2039101099Srwatson struct label *dlabel) 2040101099Srwatson{ 2041101099Srwatson struct mac_biba *subj, *obj; 2042101099Srwatson 2043101099Srwatson if (!mac_biba_enabled) 2044101099Srwatson return (0); 2045101099Srwatson 2046101099Srwatson subj = SLOT(&cred->cr_label); 2047101099Srwatson obj = SLOT(dlabel); 2048101099Srwatson 2049101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2050101099Srwatson return (EACCES); 2051101099Srwatson 2052101099Srwatson return (0); 2053101099Srwatson} 2054101099Srwatson 2055101099Srwatsonstatic int 2056101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2057101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2058101099Srwatson{ 2059101099Srwatson struct mac_biba *subj, *obj; 2060101099Srwatson 2061101099Srwatson if (!mac_biba_enabled) 2062101099Srwatson return (0); 2063101099Srwatson 2064101099Srwatson subj = SLOT(&cred->cr_label); 2065101099Srwatson obj = SLOT(dlabel); 2066101099Srwatson 2067101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2068101099Srwatson return (EACCES); 2069101099Srwatson 2070101099Srwatson return (0); 2071101099Srwatson} 2072101099Srwatson 2073101099Srwatsonstatic int 2074101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2075101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2076101099Srwatson struct componentname *cnp) 2077101099Srwatson{ 2078101099Srwatson struct mac_biba *subj, *obj; 2079101099Srwatson 2080101099Srwatson if (!mac_biba_enabled) 2081101099Srwatson return (0); 2082101099Srwatson 2083101099Srwatson subj = SLOT(&cred->cr_label); 2084101099Srwatson obj = SLOT(dlabel); 2085101099Srwatson 2086101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2087101099Srwatson return (EACCES); 2088101099Srwatson 2089101099Srwatson obj = SLOT(label); 2090101099Srwatson 2091101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2092101099Srwatson return (EACCES); 2093101099Srwatson 2094101099Srwatson return (0); 2095101099Srwatson} 2096101099Srwatson 2097101099Srwatsonstatic int 2098101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2099101099Srwatson struct label *label, acl_type_t type) 2100101099Srwatson{ 2101101099Srwatson struct mac_biba *subj, *obj; 2102101099Srwatson 2103101099Srwatson if (!mac_biba_enabled) 2104101099Srwatson return (0); 2105101099Srwatson 2106101099Srwatson subj = SLOT(&cred->cr_label); 2107101099Srwatson obj = SLOT(label); 2108101099Srwatson 2109101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2110101099Srwatson return (EACCES); 2111101099Srwatson 2112101099Srwatson return (0); 2113101099Srwatson} 2114101099Srwatson 2115101099Srwatsonstatic int 2116101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2117106648Srwatson struct label *label, struct image_params *imgp, 2118106648Srwatson struct label *execlabel) 2119101099Srwatson{ 2120106648Srwatson struct mac_biba *subj, *obj, *exec; 2121106648Srwatson int error; 2122101099Srwatson 2123106648Srwatson if (execlabel != NULL) { 2124106648Srwatson /* 2125106648Srwatson * We currently don't permit labels to be changed at 2126106648Srwatson * exec-time as part of Biba, so disallow non-NULL 2127106648Srwatson * Biba label elements in the execlabel. 2128106648Srwatson */ 2129106648Srwatson exec = SLOT(execlabel); 2130106648Srwatson error = biba_atmostflags(exec, 0); 2131106648Srwatson if (error) 2132106648Srwatson return (error); 2133106648Srwatson } 2134106648Srwatson 2135101099Srwatson if (!mac_biba_enabled) 2136101099Srwatson return (0); 2137101099Srwatson 2138101099Srwatson subj = SLOT(&cred->cr_label); 2139101099Srwatson obj = SLOT(label); 2140101099Srwatson 2141101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2142101099Srwatson return (EACCES); 2143101099Srwatson 2144101099Srwatson return (0); 2145101099Srwatson} 2146101099Srwatson 2147101099Srwatsonstatic int 2148101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2149101099Srwatson struct label *label, acl_type_t type) 2150101099Srwatson{ 2151101099Srwatson struct mac_biba *subj, *obj; 2152101099Srwatson 2153101099Srwatson if (!mac_biba_enabled) 2154101099Srwatson return (0); 2155101099Srwatson 2156101099Srwatson subj = SLOT(&cred->cr_label); 2157101099Srwatson obj = SLOT(label); 2158101099Srwatson 2159101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2160101099Srwatson return (EACCES); 2161101099Srwatson 2162101099Srwatson return (0); 2163101099Srwatson} 2164101099Srwatson 2165101099Srwatsonstatic int 2166101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2167101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 2168101099Srwatson{ 2169101099Srwatson struct mac_biba *subj, *obj; 2170101099Srwatson 2171101099Srwatson if (!mac_biba_enabled) 2172101099Srwatson return (0); 2173101099Srwatson 2174101099Srwatson subj = SLOT(&cred->cr_label); 2175101099Srwatson obj = SLOT(label); 2176101099Srwatson 2177101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2178101099Srwatson return (EACCES); 2179101099Srwatson 2180101099Srwatson return (0); 2181101099Srwatson} 2182101099Srwatson 2183101099Srwatsonstatic int 2184104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2185104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2186104530Srwatson struct componentname *cnp) 2187104530Srwatson{ 2188104530Srwatson struct mac_biba *subj, *obj; 2189104530Srwatson 2190104530Srwatson if (!mac_biba_enabled) 2191104530Srwatson return (0); 2192104530Srwatson 2193104530Srwatson subj = SLOT(&cred->cr_label); 2194104530Srwatson obj = SLOT(dlabel); 2195104530Srwatson 2196104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2197104530Srwatson return (EACCES); 2198104530Srwatson 2199104530Srwatson obj = SLOT(label); 2200104530Srwatson 2201104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2202104530Srwatson return (EACCES); 2203104530Srwatson 2204104530Srwatson return (0); 2205104530Srwatson} 2206104530Srwatson 2207104530Srwatsonstatic int 2208103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2209101099Srwatson struct label *dlabel, struct componentname *cnp) 2210101099Srwatson{ 2211101099Srwatson struct mac_biba *subj, *obj; 2212103759Srwatson 2213101099Srwatson if (!mac_biba_enabled) 2214101099Srwatson return (0); 2215103759Srwatson 2216101099Srwatson subj = SLOT(&cred->cr_label); 2217101099Srwatson obj = SLOT(dlabel); 2218103759Srwatson 2219101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2220101099Srwatson return (EACCES); 2221101099Srwatson 2222103759Srwatson return (0); 2223101099Srwatson} 2224101099Srwatson 2225101099Srwatsonstatic int 2226104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2227104546Srwatson struct label *label, int prot) 2228104546Srwatson{ 2229104546Srwatson struct mac_biba *subj, *obj; 2230104546Srwatson 2231104546Srwatson /* 2232104546Srwatson * Rely on the use of open()-time protections to handle 2233104546Srwatson * non-revocation cases. 2234104546Srwatson */ 2235105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2236104546Srwatson return (0); 2237104546Srwatson 2238104546Srwatson subj = SLOT(&cred->cr_label); 2239104546Srwatson obj = SLOT(label); 2240104546Srwatson 2241104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2242104546Srwatson if (!mac_biba_dominate_single(obj, subj)) 2243104546Srwatson return (EACCES); 2244104546Srwatson } 2245104546Srwatson if (prot & VM_PROT_WRITE) { 2246104546Srwatson if (!mac_biba_dominate_single(subj, obj)) 2247104546Srwatson return (EACCES); 2248104546Srwatson } 2249104546Srwatson 2250104569Srwatson return (0); 2251104546Srwatson} 2252104546Srwatson 2253104546Srwatsonstatic int 2254101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2255106212Srwatson struct label *vnodelabel, int acc_mode) 2256101099Srwatson{ 2257101099Srwatson struct mac_biba *subj, *obj; 2258101099Srwatson 2259101099Srwatson if (!mac_biba_enabled) 2260101099Srwatson return (0); 2261101099Srwatson 2262101099Srwatson subj = SLOT(&cred->cr_label); 2263101099Srwatson obj = SLOT(vnodelabel); 2264101099Srwatson 2265101099Srwatson /* XXX privilege override for admin? */ 2266101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2267101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2268101099Srwatson return (EACCES); 2269101099Srwatson } 2270101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2271101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2272101099Srwatson return (EACCES); 2273101099Srwatson } 2274101099Srwatson 2275101099Srwatson return (0); 2276101099Srwatson} 2277101099Srwatson 2278101099Srwatsonstatic int 2279102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2280102129Srwatson struct vnode *vp, struct label *label) 2281102112Srwatson{ 2282102112Srwatson struct mac_biba *subj, *obj; 2283102112Srwatson 2284105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2285102112Srwatson return (0); 2286102112Srwatson 2287102129Srwatson subj = SLOT(&active_cred->cr_label); 2288102112Srwatson obj = SLOT(label); 2289102112Srwatson 2290102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2291102112Srwatson return (EACCES); 2292102112Srwatson 2293102112Srwatson return (0); 2294102112Srwatson} 2295102112Srwatson 2296102112Srwatsonstatic int 2297102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2298102129Srwatson struct vnode *vp, struct label *label) 2299102112Srwatson{ 2300102112Srwatson struct mac_biba *subj, *obj; 2301102112Srwatson 2302105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2303102112Srwatson return (0); 2304102112Srwatson 2305102129Srwatson subj = SLOT(&active_cred->cr_label); 2306102112Srwatson obj = SLOT(label); 2307102112Srwatson 2308102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2309102112Srwatson return (EACCES); 2310102112Srwatson 2311102112Srwatson return (0); 2312102112Srwatson} 2313102112Srwatson 2314102112Srwatsonstatic int 2315101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2316101099Srwatson struct label *dlabel) 2317101099Srwatson{ 2318101099Srwatson struct mac_biba *subj, *obj; 2319101099Srwatson 2320101099Srwatson if (!mac_biba_enabled) 2321101099Srwatson return (0); 2322101099Srwatson 2323101099Srwatson subj = SLOT(&cred->cr_label); 2324101099Srwatson obj = SLOT(dlabel); 2325101099Srwatson 2326101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2327101099Srwatson return (EACCES); 2328101099Srwatson 2329101099Srwatson return (0); 2330101099Srwatson} 2331101099Srwatson 2332101099Srwatsonstatic int 2333101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2334101099Srwatson struct label *label) 2335101099Srwatson{ 2336101099Srwatson struct mac_biba *subj, *obj; 2337101099Srwatson 2338101099Srwatson if (!mac_biba_enabled) 2339101099Srwatson return (0); 2340101099Srwatson 2341101099Srwatson subj = SLOT(&cred->cr_label); 2342101099Srwatson obj = SLOT(label); 2343101099Srwatson 2344101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2345101099Srwatson return (EACCES); 2346101099Srwatson 2347101099Srwatson return (0); 2348101099Srwatson} 2349101099Srwatson 2350101099Srwatsonstatic int 2351101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2352101099Srwatson struct label *vnodelabel, struct label *newlabel) 2353101099Srwatson{ 2354101099Srwatson struct mac_biba *old, *new, *subj; 2355105634Srwatson int error; 2356101099Srwatson 2357101099Srwatson old = SLOT(vnodelabel); 2358101099Srwatson new = SLOT(newlabel); 2359101099Srwatson subj = SLOT(&cred->cr_label); 2360101099Srwatson 2361101099Srwatson /* 2362105634Srwatson * If there is a Biba label update for the vnode, it must be a 2363105634Srwatson * single label. 2364101099Srwatson */ 2365105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2366105634Srwatson if (error) 2367105634Srwatson return (error); 2368101099Srwatson 2369101099Srwatson /* 2370105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2371105634Srwatson * authorize the relabel. 2372101099Srwatson */ 2373105634Srwatson if (!mac_biba_single_in_range(old, subj)) 2374101099Srwatson return (EPERM); 2375101099Srwatson 2376101099Srwatson /* 2377105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2378101099Srwatson */ 2379105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2380105634Srwatson /* 2381105634Srwatson * To change the Biba label on a vnode, the new vnode label 2382105634Srwatson * must be in the subject range. 2383105634Srwatson */ 2384105634Srwatson if (!mac_biba_single_in_range(new, subj)) 2385105634Srwatson return (EPERM); 2386101099Srwatson 2387105634Srwatson /* 2388105634Srwatson * To change the Biba label on the vnode to be EQUAL, 2389105634Srwatson * the subject must have appropriate privilege. 2390105634Srwatson */ 2391105634Srwatson if (mac_biba_contains_equal(new)) { 2392106090Srwatson error = mac_biba_subject_privileged(subj); 2393105634Srwatson if (error) 2394105634Srwatson return (error); 2395105634Srwatson } 2396105634Srwatson } 2397105634Srwatson 2398105634Srwatson return (0); 2399101099Srwatson} 2400101099Srwatson 2401101099Srwatsonstatic int 2402101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2403101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2404101099Srwatson struct componentname *cnp) 2405101099Srwatson{ 2406101099Srwatson struct mac_biba *subj, *obj; 2407101099Srwatson 2408101099Srwatson if (!mac_biba_enabled) 2409101099Srwatson return (0); 2410101099Srwatson 2411101099Srwatson subj = SLOT(&cred->cr_label); 2412101099Srwatson obj = SLOT(dlabel); 2413101099Srwatson 2414101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2415101099Srwatson return (EACCES); 2416101099Srwatson 2417101099Srwatson obj = SLOT(label); 2418101099Srwatson 2419101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2420101099Srwatson return (EACCES); 2421101099Srwatson 2422101099Srwatson return (0); 2423101099Srwatson} 2424101099Srwatson 2425101099Srwatsonstatic int 2426101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2427101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2428101099Srwatson struct componentname *cnp) 2429101099Srwatson{ 2430101099Srwatson struct mac_biba *subj, *obj; 2431101099Srwatson 2432101099Srwatson if (!mac_biba_enabled) 2433101099Srwatson return (0); 2434101099Srwatson 2435101099Srwatson subj = SLOT(&cred->cr_label); 2436101099Srwatson obj = SLOT(dlabel); 2437101099Srwatson 2438101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2439101099Srwatson return (EACCES); 2440101099Srwatson 2441101099Srwatson if (vp != NULL) { 2442101099Srwatson obj = SLOT(label); 2443101099Srwatson 2444101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2445101099Srwatson return (EACCES); 2446101099Srwatson } 2447101099Srwatson 2448101099Srwatson return (0); 2449101099Srwatson} 2450101099Srwatson 2451101099Srwatsonstatic int 2452101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2453101099Srwatson struct label *label) 2454101099Srwatson{ 2455101099Srwatson struct mac_biba *subj, *obj; 2456101099Srwatson 2457101099Srwatson if (!mac_biba_enabled) 2458101099Srwatson return (0); 2459101099Srwatson 2460101099Srwatson subj = SLOT(&cred->cr_label); 2461101099Srwatson obj = SLOT(label); 2462101099Srwatson 2463101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2464101099Srwatson return (EACCES); 2465101099Srwatson 2466101099Srwatson return (0); 2467101099Srwatson} 2468101099Srwatson 2469101099Srwatsonstatic int 2470101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2471101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 2472101099Srwatson{ 2473101099Srwatson struct mac_biba *subj, *obj; 2474101099Srwatson 2475101099Srwatson if (!mac_biba_enabled) 2476101099Srwatson return (0); 2477101099Srwatson 2478101099Srwatson subj = SLOT(&cred->cr_label); 2479101099Srwatson obj = SLOT(label); 2480101099Srwatson 2481101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2482101099Srwatson return (EACCES); 2483101099Srwatson 2484101099Srwatson return (0); 2485101099Srwatson} 2486101099Srwatson 2487101099Srwatsonstatic int 2488101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2489101099Srwatson struct label *vnodelabel, int attrnamespace, const char *name, 2490101099Srwatson struct uio *uio) 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 /* XXX: protect the MAC EA in a special way? */ 2504101099Srwatson 2505101099Srwatson return (0); 2506101099Srwatson} 2507101099Srwatson 2508101099Srwatsonstatic int 2509101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2510101099Srwatson struct label *vnodelabel, u_long flags) 2511101099Srwatson{ 2512101099Srwatson struct mac_biba *subj, *obj; 2513101099Srwatson 2514101099Srwatson if (!mac_biba_enabled) 2515101099Srwatson return (0); 2516101099Srwatson 2517101099Srwatson subj = SLOT(&cred->cr_label); 2518101099Srwatson obj = SLOT(vnodelabel); 2519101099Srwatson 2520101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2521101099Srwatson return (EACCES); 2522101099Srwatson 2523101099Srwatson return (0); 2524101099Srwatson} 2525101099Srwatson 2526101099Srwatsonstatic int 2527101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2528101099Srwatson struct label *vnodelabel, mode_t mode) 2529101099Srwatson{ 2530101099Srwatson struct mac_biba *subj, *obj; 2531101099Srwatson 2532101099Srwatson if (!mac_biba_enabled) 2533101099Srwatson return (0); 2534101099Srwatson 2535101099Srwatson subj = SLOT(&cred->cr_label); 2536101099Srwatson obj = SLOT(vnodelabel); 2537101099Srwatson 2538101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2539101099Srwatson return (EACCES); 2540101099Srwatson 2541101099Srwatson return (0); 2542101099Srwatson} 2543101099Srwatson 2544101099Srwatsonstatic int 2545101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2546101099Srwatson struct label *vnodelabel, uid_t uid, gid_t gid) 2547101099Srwatson{ 2548101099Srwatson struct mac_biba *subj, *obj; 2549101099Srwatson 2550101099Srwatson if (!mac_biba_enabled) 2551101099Srwatson return (0); 2552101099Srwatson 2553101099Srwatson subj = SLOT(&cred->cr_label); 2554101099Srwatson obj = SLOT(vnodelabel); 2555101099Srwatson 2556101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2557101099Srwatson return (EACCES); 2558101099Srwatson 2559101099Srwatson return (0); 2560101099Srwatson} 2561101099Srwatson 2562101099Srwatsonstatic int 2563101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2564101099Srwatson struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2565101099Srwatson{ 2566101099Srwatson struct mac_biba *subj, *obj; 2567101099Srwatson 2568101099Srwatson if (!mac_biba_enabled) 2569101099Srwatson return (0); 2570101099Srwatson 2571101099Srwatson subj = SLOT(&cred->cr_label); 2572101099Srwatson obj = SLOT(vnodelabel); 2573101099Srwatson 2574101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2575101099Srwatson return (EACCES); 2576101099Srwatson 2577101099Srwatson return (0); 2578101099Srwatson} 2579101099Srwatson 2580101099Srwatsonstatic int 2581102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2582102129Srwatson struct vnode *vp, struct label *vnodelabel) 2583101099Srwatson{ 2584101099Srwatson struct mac_biba *subj, *obj; 2585101099Srwatson 2586101099Srwatson if (!mac_biba_enabled) 2587101099Srwatson return (0); 2588101099Srwatson 2589102129Srwatson subj = SLOT(&active_cred->cr_label); 2590101099Srwatson obj = SLOT(vnodelabel); 2591101099Srwatson 2592101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2593101099Srwatson return (EACCES); 2594101099Srwatson 2595101099Srwatson return (0); 2596101099Srwatson} 2597101099Srwatson 2598102112Srwatsonstatic int 2599102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred, 2600102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 2601102112Srwatson{ 2602102112Srwatson struct mac_biba *subj, *obj; 2603102112Srwatson 2604105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2605102112Srwatson return (0); 2606102112Srwatson 2607102129Srwatson subj = SLOT(&active_cred->cr_label); 2608102112Srwatson obj = SLOT(label); 2609102112Srwatson 2610102112Srwatson if (!mac_biba_dominate_single(subj, obj)) 2611102112Srwatson return (EACCES); 2612102112Srwatson 2613102112Srwatson return (0); 2614102112Srwatson} 2615102112Srwatson 2616106217Srwatsonstatic struct mac_policy_ops mac_biba_ops = 2617101099Srwatson{ 2618106217Srwatson .mpo_destroy = mac_biba_destroy, 2619106217Srwatson .mpo_init = mac_biba_init, 2620106217Srwatson .mpo_init_bpfdesc_label = mac_biba_init_label, 2621106217Srwatson .mpo_init_cred_label = mac_biba_init_label, 2622106217Srwatson .mpo_init_devfsdirent_label = mac_biba_init_label, 2623106217Srwatson .mpo_init_ifnet_label = mac_biba_init_label, 2624112675Srwatson .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 2625106217Srwatson .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2626106217Srwatson .mpo_init_mount_label = mac_biba_init_label, 2627106217Srwatson .mpo_init_mount_fs_label = mac_biba_init_label, 2628106217Srwatson .mpo_init_pipe_label = mac_biba_init_label, 2629106217Srwatson .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2630106217Srwatson .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2631106217Srwatson .mpo_init_vnode_label = mac_biba_init_label, 2632106217Srwatson .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2633106217Srwatson .mpo_destroy_cred_label = mac_biba_destroy_label, 2634106217Srwatson .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2635106217Srwatson .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2636106217Srwatson .mpo_destroy_ipq_label = mac_biba_destroy_label, 2637106217Srwatson .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2638106217Srwatson .mpo_destroy_mount_label = mac_biba_destroy_label, 2639106217Srwatson .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2640106217Srwatson .mpo_destroy_pipe_label = mac_biba_destroy_label, 2641106217Srwatson .mpo_destroy_socket_label = mac_biba_destroy_label, 2642106217Srwatson .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2643106217Srwatson .mpo_destroy_vnode_label = mac_biba_destroy_label, 2644106217Srwatson .mpo_copy_pipe_label = mac_biba_copy_label, 2645106217Srwatson .mpo_copy_vnode_label = mac_biba_copy_label, 2646106217Srwatson .mpo_externalize_cred_label = mac_biba_externalize_label, 2647106217Srwatson .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2648106217Srwatson .mpo_externalize_pipe_label = mac_biba_externalize_label, 2649106217Srwatson .mpo_externalize_socket_label = mac_biba_externalize_label, 2650106217Srwatson .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2651106217Srwatson .mpo_externalize_vnode_label = mac_biba_externalize_label, 2652106217Srwatson .mpo_internalize_cred_label = mac_biba_internalize_label, 2653106217Srwatson .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2654106217Srwatson .mpo_internalize_pipe_label = mac_biba_internalize_label, 2655106217Srwatson .mpo_internalize_socket_label = mac_biba_internalize_label, 2656106217Srwatson .mpo_internalize_vnode_label = mac_biba_internalize_label, 2657106217Srwatson .mpo_create_devfs_device = mac_biba_create_devfs_device, 2658106217Srwatson .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2659106217Srwatson .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2660106217Srwatson .mpo_create_mount = mac_biba_create_mount, 2661106217Srwatson .mpo_create_root_mount = mac_biba_create_root_mount, 2662106217Srwatson .mpo_relabel_vnode = mac_biba_relabel_vnode, 2663106217Srwatson .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2664106217Srwatson .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2665106217Srwatson .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2666106217Srwatson .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2667106217Srwatson .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2668106217Srwatson .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2669106217Srwatson .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2670106217Srwatson .mpo_create_pipe = mac_biba_create_pipe, 2671106217Srwatson .mpo_create_socket = mac_biba_create_socket, 2672106217Srwatson .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2673106217Srwatson .mpo_relabel_pipe = mac_biba_relabel_pipe, 2674106217Srwatson .mpo_relabel_socket = mac_biba_relabel_socket, 2675106217Srwatson .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2676106217Srwatson .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2677106217Srwatson .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2678106217Srwatson .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2679106217Srwatson .mpo_create_fragment = mac_biba_create_fragment, 2680106217Srwatson .mpo_create_ifnet = mac_biba_create_ifnet, 2681106217Srwatson .mpo_create_ipq = mac_biba_create_ipq, 2682106217Srwatson .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2683106217Srwatson .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2684106217Srwatson .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2685106217Srwatson .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2686106217Srwatson .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2687106217Srwatson .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2688106217Srwatson .mpo_fragment_match = mac_biba_fragment_match, 2689106217Srwatson .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2690106217Srwatson .mpo_update_ipq = mac_biba_update_ipq, 2691106217Srwatson .mpo_create_cred = mac_biba_create_cred, 2692106217Srwatson .mpo_create_proc0 = mac_biba_create_proc0, 2693106217Srwatson .mpo_create_proc1 = mac_biba_create_proc1, 2694106217Srwatson .mpo_relabel_cred = mac_biba_relabel_cred, 2695106217Srwatson .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2696106217Srwatson .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2697106217Srwatson .mpo_check_cred_visible = mac_biba_check_cred_visible, 2698106217Srwatson .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2699106217Srwatson .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2700110354Srwatson .mpo_check_kld_load = mac_biba_check_kld_load, 2701110354Srwatson .mpo_check_kld_unload = mac_biba_check_kld_unload, 2702106217Srwatson .mpo_check_mount_stat = mac_biba_check_mount_stat, 2703106217Srwatson .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2704106217Srwatson .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2705106217Srwatson .mpo_check_pipe_read = mac_biba_check_pipe_read, 2706106217Srwatson .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2707106217Srwatson .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2708106217Srwatson .mpo_check_pipe_write = mac_biba_check_pipe_write, 2709106217Srwatson .mpo_check_proc_debug = mac_biba_check_proc_debug, 2710106217Srwatson .mpo_check_proc_sched = mac_biba_check_proc_sched, 2711106217Srwatson .mpo_check_proc_signal = mac_biba_check_proc_signal, 2712106217Srwatson .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2713106217Srwatson .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2714106217Srwatson .mpo_check_socket_visible = mac_biba_check_socket_visible, 2715112574Srwatson .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 2716106418Srwatson .mpo_check_system_acct = mac_biba_check_system_acct, 2717106418Srwatson .mpo_check_system_settime = mac_biba_check_system_settime, 2718106217Srwatson .mpo_check_system_swapon = mac_biba_check_system_swapon, 2719112574Srwatson .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 2720106217Srwatson .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2721106217Srwatson .mpo_check_vnode_access = mac_biba_check_vnode_open, 2722106217Srwatson .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2723106217Srwatson .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2724106217Srwatson .mpo_check_vnode_create = mac_biba_check_vnode_create, 2725106217Srwatson .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2726106217Srwatson .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2727106217Srwatson .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2728106217Srwatson .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2729106217Srwatson .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2730106217Srwatson .mpo_check_vnode_link = mac_biba_check_vnode_link, 2731106217Srwatson .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2732106217Srwatson .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2733106217Srwatson .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2734106217Srwatson .mpo_check_vnode_open = mac_biba_check_vnode_open, 2735106217Srwatson .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2736106217Srwatson .mpo_check_vnode_read = mac_biba_check_vnode_read, 2737106217Srwatson .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2738106217Srwatson .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2739106217Srwatson .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2740106217Srwatson .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2741106217Srwatson .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2742106217Srwatson .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2743106217Srwatson .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2744106217Srwatson .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2745106217Srwatson .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2746106217Srwatson .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2747106217Srwatson .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2748106217Srwatson .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2749106217Srwatson .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2750106217Srwatson .mpo_check_vnode_write = mac_biba_check_vnode_write, 2751101099Srwatson}; 2752101099Srwatson 2753106217SrwatsonMAC_POLICY_SET(&mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2754101099Srwatson MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot); 2755