mac_biba.c revision 115707
1101099Srwatson/*- 2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3115497Srwatson * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. 4101099Srwatson * All rights reserved. 5101099Srwatson * 6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 7101099Srwatson * 8106393Srwatson * This software was developed for the FreeBSD Project in part by Network 9106393Srwatson * Associates Laboratories, the Security Research Division of Network 10106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 11106393Srwatson * as part of the DARPA CHATS research program. 12101099Srwatson * 13101099Srwatson * Redistribution and use in source and binary forms, with or without 14101099Srwatson * modification, are permitted provided that the following conditions 15101099Srwatson * are met: 16101099Srwatson * 1. Redistributions of source code must retain the above copyright 17101099Srwatson * notice, this list of conditions and the following disclaimer. 18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright 19101099Srwatson * notice, this list of conditions and the following disclaimer in the 20101099Srwatson * documentation and/or other materials provided with the distribution. 21101099Srwatson * 22101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32101099Srwatson * SUCH DAMAGE. 33101099Srwatson * 34101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 115707 2003-06-02 17:21:38Z rwatson $ 35101099Srwatson */ 36101099Srwatson 37101099Srwatson/* 38101099Srwatson * Developed by the TrustedBSD Project. 39101099Srwatson * Biba fixed label mandatory integrity policy. 40101099Srwatson */ 41101099Srwatson 42101099Srwatson#include <sys/types.h> 43101099Srwatson#include <sys/param.h> 44101099Srwatson#include <sys/acl.h> 45101099Srwatson#include <sys/conf.h> 46105988Srwatson#include <sys/extattr.h> 47101099Srwatson#include <sys/kernel.h> 48101099Srwatson#include <sys/mac.h> 49103183Sbde#include <sys/malloc.h> 50101099Srwatson#include <sys/mount.h> 51101099Srwatson#include <sys/proc.h> 52115497Srwatson#include <sys/sbuf.h> 53101099Srwatson#include <sys/systm.h> 54101099Srwatson#include <sys/sysproto.h> 55101099Srwatson#include <sys/sysent.h> 56105696Srwatson#include <sys/systm.h> 57101099Srwatson#include <sys/vnode.h> 58101099Srwatson#include <sys/file.h> 59101099Srwatson#include <sys/socket.h> 60101099Srwatson#include <sys/socketvar.h> 61101099Srwatson#include <sys/pipe.h> 62101099Srwatson#include <sys/sysctl.h> 63101099Srwatson 64101099Srwatson#include <fs/devfs/devfs.h> 65101099Srwatson 66101099Srwatson#include <net/bpfdesc.h> 67101099Srwatson#include <net/if.h> 68101099Srwatson#include <net/if_types.h> 69101099Srwatson#include <net/if_var.h> 70101099Srwatson 71101099Srwatson#include <netinet/in.h> 72101099Srwatson#include <netinet/ip_var.h> 73101099Srwatson 74101099Srwatson#include <vm/vm.h> 75101099Srwatson 76101099Srwatson#include <sys/mac_policy.h> 77101099Srwatson 78101099Srwatson#include <security/mac_biba/mac_biba.h> 79101099Srwatson 80101099SrwatsonSYSCTL_DECL(_security_mac); 81101099Srwatson 82101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 83101099Srwatson "TrustedBSD mac_biba policy controls"); 84101099Srwatson 85105988Srwatsonstatic int mac_biba_label_size = sizeof(struct mac_biba); 86105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 87105988Srwatson &mac_biba_label_size, 0, "Size of struct mac_biba"); 88105988Srwatson 89107731Srwatsonstatic int mac_biba_enabled = 1; 90101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 91101099Srwatson &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 92102980SrwatsonTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 93101099Srwatson 94101099Srwatsonstatic int destroyed_not_inited; 95101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 96101099Srwatson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 97101099Srwatson 98101099Srwatsonstatic int trust_all_interfaces = 0; 99101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 100101099Srwatson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 101101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 102101099Srwatson 103101099Srwatsonstatic char trusted_interfaces[128]; 104101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 105101099Srwatson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 106101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 107101099Srwatson sizeof(trusted_interfaces)); 108101099Srwatson 109105643Srwatsonstatic int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 110105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 111105643Srwatson &max_compartments, 0, "Maximum supported compartments"); 112105643Srwatson 113105606Srwatsonstatic int ptys_equal = 0; 114105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 115105606Srwatson &ptys_equal, 0, "Label pty devices as biba/equal on create"); 116105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 117105606Srwatson 118105637Srwatsonstatic int revocation_enabled = 0; 119101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 120105637Srwatson &revocation_enabled, 0, "Revoke access to objects on relabel"); 121105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 122101099Srwatson 123101099Srwatsonstatic int mac_biba_slot; 124101099Srwatson#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 125101099Srwatson 126101099SrwatsonMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels"); 127101099Srwatson 128105643Srwatsonstatic __inline int 129105643Srwatsonbiba_bit_set_empty(u_char *set) { 130105643Srwatson int i; 131105643Srwatson 132105643Srwatson for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 133105643Srwatson if (set[i] != 0) 134105643Srwatson return (0); 135105643Srwatson return (1); 136105643Srwatson} 137105643Srwatson 138101099Srwatsonstatic struct mac_biba * 139104514Srwatsonbiba_alloc(int flag) 140101099Srwatson{ 141101099Srwatson struct mac_biba *mac_biba; 142101099Srwatson 143104514Srwatson mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag); 144101099Srwatson 145101099Srwatson return (mac_biba); 146101099Srwatson} 147101099Srwatson 148101099Srwatsonstatic void 149101099Srwatsonbiba_free(struct mac_biba *mac_biba) 150101099Srwatson{ 151101099Srwatson 152101099Srwatson if (mac_biba != NULL) 153101099Srwatson free(mac_biba, M_MACBIBA); 154101099Srwatson else 155101099Srwatson atomic_add_int(&destroyed_not_inited, 1); 156101099Srwatson} 157101099Srwatson 158101099Srwatsonstatic int 159105634Srwatsonbiba_atmostflags(struct mac_biba *mac_biba, int flags) 160105634Srwatson{ 161105634Srwatson 162105634Srwatson if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 163105634Srwatson return (EINVAL); 164105634Srwatson return (0); 165105634Srwatson} 166105634Srwatson 167105634Srwatsonstatic int 168101099Srwatsonmac_biba_dominate_element(struct mac_biba_element *a, 169101099Srwatson struct mac_biba_element *b) 170101099Srwatson{ 171105643Srwatson int bit; 172101099Srwatson 173105736Srwatson switch (a->mbe_type) { 174101099Srwatson case MAC_BIBA_TYPE_EQUAL: 175101099Srwatson case MAC_BIBA_TYPE_HIGH: 176101099Srwatson return (1); 177101099Srwatson 178101099Srwatson case MAC_BIBA_TYPE_LOW: 179101099Srwatson switch (b->mbe_type) { 180101099Srwatson case MAC_BIBA_TYPE_GRADE: 181101099Srwatson case MAC_BIBA_TYPE_HIGH: 182101099Srwatson return (0); 183101099Srwatson 184101099Srwatson case MAC_BIBA_TYPE_EQUAL: 185101099Srwatson case MAC_BIBA_TYPE_LOW: 186101099Srwatson return (1); 187101099Srwatson 188101099Srwatson default: 189101099Srwatson panic("mac_biba_dominate_element: b->mbe_type invalid"); 190101099Srwatson } 191101099Srwatson 192101099Srwatson case MAC_BIBA_TYPE_GRADE: 193101099Srwatson switch (b->mbe_type) { 194101099Srwatson case MAC_BIBA_TYPE_EQUAL: 195101099Srwatson case MAC_BIBA_TYPE_LOW: 196101099Srwatson return (1); 197101099Srwatson 198101099Srwatson case MAC_BIBA_TYPE_HIGH: 199101099Srwatson return (0); 200101099Srwatson 201101099Srwatson case MAC_BIBA_TYPE_GRADE: 202105643Srwatson for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 203105643Srwatson if (!MAC_BIBA_BIT_TEST(bit, 204105643Srwatson a->mbe_compartments) && 205105643Srwatson MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 206105643Srwatson return (0); 207101099Srwatson return (a->mbe_grade >= b->mbe_grade); 208101099Srwatson 209101099Srwatson default: 210101099Srwatson panic("mac_biba_dominate_element: b->mbe_type invalid"); 211101099Srwatson } 212101099Srwatson 213101099Srwatson default: 214101099Srwatson panic("mac_biba_dominate_element: a->mbe_type invalid"); 215101099Srwatson } 216101099Srwatson 217101099Srwatson return (0); 218101099Srwatson} 219101099Srwatson 220101099Srwatsonstatic int 221105988Srwatsonmac_biba_subject_dominate_high(struct mac_biba *mac_biba) 222105988Srwatson{ 223105988Srwatson struct mac_biba_element *element; 224105988Srwatson 225106174Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 226105988Srwatson ("mac_biba_single_in_range: mac_biba not single")); 227105988Srwatson element = &mac_biba->mb_single; 228105988Srwatson 229105988Srwatson return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 230105988Srwatson element->mbe_type == MAC_BIBA_TYPE_HIGH); 231105988Srwatson} 232105988Srwatson 233105988Srwatsonstatic int 234101099Srwatsonmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 235101099Srwatson{ 236101099Srwatson 237101099Srwatson return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 238101099Srwatson &rangea->mb_rangehigh) && 239101099Srwatson mac_biba_dominate_element(&rangea->mb_rangelow, 240101099Srwatson &rangeb->mb_rangelow)); 241101099Srwatson} 242101099Srwatson 243101099Srwatsonstatic int 244101099Srwatsonmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range) 245101099Srwatson{ 246101099Srwatson 247103750Srwatson KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 248101099Srwatson ("mac_biba_single_in_range: a not single")); 249103750Srwatson KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 250101099Srwatson ("mac_biba_single_in_range: b not range")); 251101099Srwatson 252101099Srwatson return (mac_biba_dominate_element(&range->mb_rangehigh, 253101099Srwatson &single->mb_single) && 254101099Srwatson mac_biba_dominate_element(&single->mb_single, 255101099Srwatson &range->mb_rangelow)); 256101099Srwatson 257101099Srwatson return (1); 258101099Srwatson} 259101099Srwatson 260101099Srwatsonstatic int 261101099Srwatsonmac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b) 262101099Srwatson{ 263101099Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 264101099Srwatson ("mac_biba_dominate_single: a not single")); 265101099Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 266101099Srwatson ("mac_biba_dominate_single: b not single")); 267101099Srwatson 268101099Srwatson return (mac_biba_dominate_element(&a->mb_single, &b->mb_single)); 269101099Srwatson} 270101099Srwatson 271101099Srwatsonstatic int 272101099Srwatsonmac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 273101099Srwatson{ 274101099Srwatson 275101099Srwatson if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 276101099Srwatson b->mbe_type == MAC_BIBA_TYPE_EQUAL) 277101099Srwatson return (1); 278101099Srwatson 279101099Srwatson return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 280101099Srwatson} 281101099Srwatson 282101099Srwatsonstatic int 283101099Srwatsonmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b) 284101099Srwatson{ 285101099Srwatson 286101099Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 287101099Srwatson ("mac_biba_equal_single: a not single")); 288101099Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 289101099Srwatson ("mac_biba_equal_single: b not single")); 290101099Srwatson 291101099Srwatson return (mac_biba_equal_element(&a->mb_single, &b->mb_single)); 292101099Srwatson} 293101099Srwatson 294101099Srwatsonstatic int 295105634Srwatsonmac_biba_contains_equal(struct mac_biba *mac_biba) 296105634Srwatson{ 297105634Srwatson 298105634Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) 299105634Srwatson if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 300105634Srwatson return (1); 301105634Srwatson 302105634Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 303105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 304105634Srwatson return (1); 305105634Srwatson if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 306105637Srwatson return (1); 307105634Srwatson } 308105634Srwatson 309105634Srwatson return (0); 310105634Srwatson} 311105634Srwatson 312105634Srwatsonstatic int 313106090Srwatsonmac_biba_subject_privileged(struct mac_biba *mac_biba) 314105634Srwatson{ 315105634Srwatson 316105634Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 317105634Srwatson MAC_BIBA_FLAGS_BOTH, 318106090Srwatson ("mac_biba_subject_privileged: subject doesn't have both labels")); 319105634Srwatson 320105634Srwatson /* If the single is EQUAL, it's ok. */ 321105634Srwatson if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 322105634Srwatson return (0); 323105634Srwatson 324105634Srwatson /* If either range endpoint is EQUAL, it's ok. */ 325105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 326105634Srwatson mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 327105634Srwatson return (0); 328105634Srwatson 329105634Srwatson /* If the range is low-high, it's ok. */ 330105634Srwatson if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 331105634Srwatson mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 332105634Srwatson return (0); 333105634Srwatson 334105634Srwatson /* It's not ok. */ 335105634Srwatson return (EPERM); 336105634Srwatson} 337105634Srwatson 338106091Srwatsonstatic int 339105988Srwatsonmac_biba_high_single(struct mac_biba *mac_biba) 340105988Srwatson{ 341105988Srwatson 342105988Srwatson KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 343105988Srwatson ("mac_biba_equal_single: mac_biba not single")); 344105988Srwatson 345105988Srwatson return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH); 346105988Srwatson} 347105988Srwatson 348105634Srwatsonstatic int 349101099Srwatsonmac_biba_valid(struct mac_biba *mac_biba) 350101099Srwatson{ 351101099Srwatson 352101099Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 353101099Srwatson switch (mac_biba->mb_single.mbe_type) { 354101099Srwatson case MAC_BIBA_TYPE_GRADE: 355101099Srwatson break; 356101099Srwatson 357101099Srwatson case MAC_BIBA_TYPE_EQUAL: 358101099Srwatson case MAC_BIBA_TYPE_HIGH: 359101099Srwatson case MAC_BIBA_TYPE_LOW: 360105643Srwatson if (mac_biba->mb_single.mbe_grade != 0 || 361105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 362105643Srwatson mac_biba->mb_single.mbe_compartments)) 363101099Srwatson return (EINVAL); 364101099Srwatson break; 365101099Srwatson 366101099Srwatson default: 367101099Srwatson return (EINVAL); 368101099Srwatson } 369101099Srwatson } else { 370101099Srwatson if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 371101099Srwatson return (EINVAL); 372101099Srwatson } 373101099Srwatson 374101099Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 375101099Srwatson switch (mac_biba->mb_rangelow.mbe_type) { 376101099Srwatson case MAC_BIBA_TYPE_GRADE: 377101099Srwatson break; 378101099Srwatson 379101099Srwatson case MAC_BIBA_TYPE_EQUAL: 380101099Srwatson case MAC_BIBA_TYPE_HIGH: 381101099Srwatson case MAC_BIBA_TYPE_LOW: 382105643Srwatson if (mac_biba->mb_rangelow.mbe_grade != 0 || 383105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 384105643Srwatson mac_biba->mb_rangelow.mbe_compartments)) 385101099Srwatson return (EINVAL); 386101099Srwatson break; 387101099Srwatson 388101099Srwatson default: 389101099Srwatson return (EINVAL); 390101099Srwatson } 391101099Srwatson 392101099Srwatson switch (mac_biba->mb_rangehigh.mbe_type) { 393101099Srwatson case MAC_BIBA_TYPE_GRADE: 394101099Srwatson break; 395101099Srwatson 396101099Srwatson case MAC_BIBA_TYPE_EQUAL: 397101099Srwatson case MAC_BIBA_TYPE_HIGH: 398101099Srwatson case MAC_BIBA_TYPE_LOW: 399105643Srwatson if (mac_biba->mb_rangehigh.mbe_grade != 0 || 400105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 401105643Srwatson mac_biba->mb_rangehigh.mbe_compartments)) 402101099Srwatson return (EINVAL); 403101099Srwatson break; 404101099Srwatson 405101099Srwatson default: 406101099Srwatson return (EINVAL); 407101099Srwatson } 408101099Srwatson if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 409101099Srwatson &mac_biba->mb_rangelow)) 410101099Srwatson return (EINVAL); 411101099Srwatson } else { 412101099Srwatson if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 413101099Srwatson mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 414101099Srwatson return (EINVAL); 415101099Srwatson } 416101099Srwatson 417101099Srwatson return (0); 418101099Srwatson} 419101099Srwatson 420101099Srwatsonstatic void 421101099Srwatsonmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 422105643Srwatson u_short gradelow, u_char *compartmentslow, u_short typehigh, 423105643Srwatson u_short gradehigh, u_char *compartmentshigh) 424101099Srwatson{ 425101099Srwatson 426101099Srwatson mac_biba->mb_rangelow.mbe_type = typelow; 427101099Srwatson mac_biba->mb_rangelow.mbe_grade = gradelow; 428105643Srwatson if (compartmentslow != NULL) 429105643Srwatson memcpy(mac_biba->mb_rangelow.mbe_compartments, 430105643Srwatson compartmentslow, 431105643Srwatson sizeof(mac_biba->mb_rangelow.mbe_compartments)); 432101099Srwatson mac_biba->mb_rangehigh.mbe_type = typehigh; 433101099Srwatson mac_biba->mb_rangehigh.mbe_grade = gradehigh; 434105643Srwatson if (compartmentshigh != NULL) 435105643Srwatson memcpy(mac_biba->mb_rangehigh.mbe_compartments, 436105643Srwatson compartmentshigh, 437105643Srwatson sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 438101099Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 439101099Srwatson} 440101099Srwatson 441101099Srwatsonstatic void 442105643Srwatsonmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 443105643Srwatson u_char *compartments) 444101099Srwatson{ 445101099Srwatson 446101099Srwatson mac_biba->mb_single.mbe_type = type; 447101099Srwatson mac_biba->mb_single.mbe_grade = grade; 448105643Srwatson if (compartments != NULL) 449105643Srwatson memcpy(mac_biba->mb_single.mbe_compartments, compartments, 450105643Srwatson sizeof(mac_biba->mb_single.mbe_compartments)); 451101099Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 452101099Srwatson} 453101099Srwatson 454101099Srwatsonstatic void 455101099Srwatsonmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 456101099Srwatson{ 457105643Srwatson 458101099Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 459101099Srwatson ("mac_biba_copy_range: labelfrom not range")); 460101099Srwatson 461101099Srwatson labelto->mb_rangelow = labelfrom->mb_rangelow; 462101099Srwatson labelto->mb_rangehigh = labelfrom->mb_rangehigh; 463101099Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 464101099Srwatson} 465101099Srwatson 466101099Srwatsonstatic void 467101099Srwatsonmac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 468101099Srwatson{ 469101099Srwatson 470101099Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 471101099Srwatson ("mac_biba_copy_single: labelfrom not single")); 472101099Srwatson 473101099Srwatson labelto->mb_single = labelfrom->mb_single; 474101099Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 475101099Srwatson} 476101099Srwatson 477105656Srwatsonstatic void 478105656Srwatsonmac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 479105656Srwatson{ 480105656Srwatson 481105656Srwatson if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 482105656Srwatson mac_biba_copy_single(source, dest); 483105656Srwatson if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 484105656Srwatson mac_biba_copy_range(source, dest); 485105656Srwatson} 486105656Srwatson 487101099Srwatson/* 488101099Srwatson * Policy module operations. 489101099Srwatson */ 490101099Srwatsonstatic void 491101099Srwatsonmac_biba_destroy(struct mac_policy_conf *conf) 492101099Srwatson{ 493101099Srwatson 494101099Srwatson} 495101099Srwatson 496101099Srwatsonstatic void 497101099Srwatsonmac_biba_init(struct mac_policy_conf *conf) 498101099Srwatson{ 499101099Srwatson 500101099Srwatson} 501101099Srwatson 502101099Srwatson/* 503101099Srwatson * Label operations. 504101099Srwatson */ 505101099Srwatsonstatic void 506104514Srwatsonmac_biba_init_label(struct label *label) 507101099Srwatson{ 508101099Srwatson 509111119Simp SLOT(label) = biba_alloc(M_WAITOK); 510101099Srwatson} 511101099Srwatson 512101099Srwatsonstatic int 513104514Srwatsonmac_biba_init_label_waitcheck(struct label *label, int flag) 514101099Srwatson{ 515101099Srwatson 516104514Srwatson SLOT(label) = biba_alloc(flag); 517101099Srwatson if (SLOT(label) == NULL) 518101099Srwatson return (ENOMEM); 519101099Srwatson 520101099Srwatson return (0); 521101099Srwatson} 522101099Srwatson 523101099Srwatsonstatic void 524104514Srwatsonmac_biba_destroy_label(struct label *label) 525101099Srwatson{ 526101099Srwatson 527101099Srwatson biba_free(SLOT(label)); 528101099Srwatson SLOT(label) = NULL; 529101099Srwatson} 530101099Srwatson 531105696Srwatson/* 532115497Srwatson * mac_biba_element_to_string() accepts an sbuf and Biba element. It 533115497Srwatson * converts the Biba element to a string and stores the result in the 534115497Srwatson * sbuf; if there isn't space in the sbuf, -1 is returned. 535105696Srwatson */ 536115497Srwatsonstatic int 537115497Srwatsonmac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element) 538105696Srwatson{ 539115497Srwatson int i, first; 540105696Srwatson 541105696Srwatson switch (element->mbe_type) { 542105696Srwatson case MAC_BIBA_TYPE_HIGH: 543115497Srwatson return (sbuf_printf(sb, "high")); 544105696Srwatson 545105696Srwatson case MAC_BIBA_TYPE_LOW: 546115497Srwatson return (sbuf_printf(sb, "low")); 547105696Srwatson 548105696Srwatson case MAC_BIBA_TYPE_EQUAL: 549115497Srwatson return (sbuf_printf(sb, "equal")); 550105696Srwatson 551105696Srwatson case MAC_BIBA_TYPE_GRADE: 552115497Srwatson if (sbuf_printf(sb, "%d", element->mbe_grade) == -1) 553115497Srwatson return (-1); 554115497Srwatson 555115497Srwatson first = 1; 556115497Srwatson for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) { 557115497Srwatson if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) { 558115497Srwatson if (first) { 559115497Srwatson if (sbuf_putc(sb, ':') == -1) 560115497Srwatson return (-1); 561115497Srwatson if (sbuf_printf(sb, "%d", i) == -1) 562115497Srwatson return (-1); 563115497Srwatson first = 0; 564115497Srwatson } else { 565115497Srwatson if (sbuf_printf(sb, "+%d", i) == -1) 566115497Srwatson return (-1); 567115497Srwatson } 568115497Srwatson } 569105696Srwatson } 570115497Srwatson return (0); 571105696Srwatson 572105696Srwatson default: 573105696Srwatson panic("mac_biba_element_to_string: invalid type (%d)", 574105696Srwatson element->mbe_type); 575105696Srwatson } 576105696Srwatson} 577105696Srwatson 578115497Srwatson/* 579115497Srwatson * mac_biba_to_string() converts an Biba label to a string, placing the 580115497Srwatson * results in the passed string buffer. It returns 0 on success, 581115497Srwatson * or EINVAL if there isn't room in the buffer. The size of the 582115497Srwatson * string appended, leaving out the nul termination, is returned to 583115497Srwatson * the caller via *caller_len. Eventually, we should expose the 584115497Srwatson * sbuf to the caller rather than using C strings at this layer. 585115497Srwatson */ 586101099Srwatsonstatic int 587105696Srwatsonmac_biba_to_string(char *string, size_t size, size_t *caller_len, 588105696Srwatson struct mac_biba *mac_biba) 589101099Srwatson{ 590115497Srwatson struct sbuf sb; 591105696Srwatson 592115497Srwatson sbuf_new(&sb, string, size, SBUF_FIXEDLEN); 593105696Srwatson 594105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 595115497Srwatson if (mac_biba_element_to_string(&sb, &mac_biba->mb_single) 596115497Srwatson == -1) 597105696Srwatson return (EINVAL); 598105696Srwatson } 599105696Srwatson 600105696Srwatson if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 601115497Srwatson if (sbuf_putc(&sb, '(') == -1) 602105696Srwatson return (EINVAL); 603105696Srwatson 604115497Srwatson if (mac_biba_element_to_string(&sb, &mac_biba->mb_rangelow) 605115497Srwatson == -1) 606105696Srwatson return (EINVAL); 607105696Srwatson 608115497Srwatson if (sbuf_putc(&sb, '-') == -1) 609105696Srwatson return (EINVAL); 610105696Srwatson 611115497Srwatson if (mac_biba_element_to_string(&sb, &mac_biba->mb_rangehigh) 612115497Srwatson == -1) 613105696Srwatson return (EINVAL); 614105696Srwatson 615115497Srwatson if (sbuf_putc(&sb, ')') == -1) 616105696Srwatson return (EINVAL); 617105696Srwatson } 618105696Srwatson 619115497Srwatson sbuf_finish(&sb); 620105696Srwatson *caller_len = strlen(string); 621105696Srwatson return (0); 622105696Srwatson} 623105696Srwatson 624105696Srwatsonstatic int 625105696Srwatsonmac_biba_externalize_label(struct label *label, char *element_name, 626105696Srwatson char *element_data, size_t size, size_t *len, int *claimed) 627105696Srwatson{ 628101099Srwatson struct mac_biba *mac_biba; 629105696Srwatson int error; 630101099Srwatson 631105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 632105696Srwatson return (0); 633105696Srwatson 634105696Srwatson (*claimed)++; 635105696Srwatson 636101099Srwatson mac_biba = SLOT(label); 637105696Srwatson error = mac_biba_to_string(element_data, size, len, mac_biba); 638105696Srwatson if (error) 639105696Srwatson return (error); 640101099Srwatson 641105696Srwatson return (0); 642105696Srwatson} 643105696Srwatson 644105696Srwatsonstatic int 645105696Srwatsonmac_biba_parse_element(struct mac_biba_element *element, char *string) 646101099Srwatson{ 647115395Srwatson char *compartment, *end, *grade; 648115395Srwatson int value; 649105696Srwatson 650105696Srwatson if (strcmp(string, "high") == 0 || 651105696Srwatson strcmp(string, "hi") == 0) { 652105696Srwatson element->mbe_type = MAC_BIBA_TYPE_HIGH; 653105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 654105696Srwatson } else if (strcmp(string, "low") == 0 || 655105696Srwatson strcmp(string, "lo") == 0) { 656105696Srwatson element->mbe_type = MAC_BIBA_TYPE_LOW; 657105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 658105696Srwatson } else if (strcmp(string, "equal") == 0 || 659105696Srwatson strcmp(string, "eq") == 0) { 660105696Srwatson element->mbe_type = MAC_BIBA_TYPE_EQUAL; 661105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 662105696Srwatson } else { 663115395Srwatson element->mbe_type = MAC_BIBA_TYPE_GRADE; 664105696Srwatson 665115395Srwatson /* 666115395Srwatson * Numeric grade piece of the element. 667115395Srwatson */ 668115395Srwatson grade = strsep(&string, ":"); 669115395Srwatson value = strtol(grade, &end, 10); 670115395Srwatson if (end == grade || *end != '\0') 671105696Srwatson return (EINVAL); 672115395Srwatson if (value < 0 || value > 65535) 673115395Srwatson return (EINVAL); 674115395Srwatson element->mbe_grade = value; 675105696Srwatson 676115395Srwatson /* 677115395Srwatson * Optional compartment piece of the element. If none 678115395Srwatson * are included, we assume that the label has no 679115395Srwatson * compartments. 680115395Srwatson */ 681115395Srwatson if (string == NULL) 682115395Srwatson return (0); 683115395Srwatson if (*string == '\0') 684115395Srwatson return (0); 685105696Srwatson 686115395Srwatson while ((compartment = strsep(&string, "+")) != NULL) { 687115395Srwatson value = strtol(compartment, &end, 10); 688115395Srwatson if (compartment == end || *end != '\0') 689105696Srwatson return (EINVAL); 690115395Srwatson if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 691105696Srwatson return (EINVAL); 692115395Srwatson MAC_BIBA_BIT_SET(value, element->mbe_compartments); 693105696Srwatson } 694105696Srwatson } 695105696Srwatson 696105696Srwatson return (0); 697105696Srwatson} 698105696Srwatson 699105696Srwatson/* 700105696Srwatson * Note: destructively consumes the string, make a local copy before 701105696Srwatson * calling if that's a problem. 702105696Srwatson */ 703105696Srwatsonstatic int 704105696Srwatsonmac_biba_parse(struct mac_biba *mac_biba, char *string) 705105696Srwatson{ 706115395Srwatson char *rangehigh, *rangelow, *single; 707101099Srwatson int error; 708101099Srwatson 709115395Srwatson single = strsep(&string, "("); 710115395Srwatson if (*single == '\0') 711105696Srwatson single = NULL; 712115395Srwatson 713115395Srwatson if (string != NULL) { 714115395Srwatson rangelow = strsep(&string, "-"); 715115395Srwatson if (string == NULL) 716105696Srwatson return (EINVAL); 717115395Srwatson rangehigh = strsep(&string, ")"); 718115395Srwatson if (string == NULL) 719105696Srwatson return (EINVAL); 720115395Srwatson if (*string != '\0') 721105696Srwatson return (EINVAL); 722115395Srwatson } else { 723115395Srwatson rangelow = NULL; 724115395Srwatson rangehigh = NULL; 725105696Srwatson } 726115395Srwatson 727105696Srwatson KASSERT((rangelow != NULL && rangehigh != NULL) || 728105696Srwatson (rangelow == NULL && rangehigh == NULL), 729115395Srwatson ("mac_biba_parse: range mismatch")); 730101099Srwatson 731105696Srwatson bzero(mac_biba, sizeof(*mac_biba)); 732105696Srwatson if (single != NULL) { 733105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_single, single); 734105696Srwatson if (error) 735105696Srwatson return (error); 736105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 737105696Srwatson } 738105696Srwatson 739105696Srwatson if (rangelow != NULL) { 740105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangelow, 741105696Srwatson rangelow); 742105696Srwatson if (error) 743105696Srwatson return (error); 744105696Srwatson error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 745105696Srwatson rangehigh); 746105696Srwatson if (error) 747105696Srwatson return (error); 748105696Srwatson mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 749105696Srwatson } 750105696Srwatson 751101099Srwatson error = mac_biba_valid(mac_biba); 752101099Srwatson if (error) 753101099Srwatson return (error); 754101099Srwatson 755105696Srwatson return (0); 756105696Srwatson} 757101099Srwatson 758105696Srwatsonstatic int 759105696Srwatsonmac_biba_internalize_label(struct label *label, char *element_name, 760105696Srwatson char *element_data, int *claimed) 761105696Srwatson{ 762105696Srwatson struct mac_biba *mac_biba, mac_biba_temp; 763105696Srwatson int error; 764105696Srwatson 765105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 766105696Srwatson return (0); 767105696Srwatson 768105696Srwatson (*claimed)++; 769105696Srwatson 770105696Srwatson error = mac_biba_parse(&mac_biba_temp, element_data); 771105696Srwatson if (error) 772105696Srwatson return (error); 773105696Srwatson 774105696Srwatson mac_biba = SLOT(label); 775105696Srwatson *mac_biba = mac_biba_temp; 776105696Srwatson 777101099Srwatson return (0); 778101099Srwatson} 779101099Srwatson 780105696Srwatsonstatic void 781105696Srwatsonmac_biba_copy_label(struct label *src, struct label *dest) 782105696Srwatson{ 783105696Srwatson 784105696Srwatson *SLOT(dest) = *SLOT(src); 785105696Srwatson} 786105696Srwatson 787101099Srwatson/* 788101099Srwatson * Labeling event operations: file system objects, and things that look 789101099Srwatson * a lot like file system objects. 790101099Srwatson */ 791101099Srwatsonstatic void 792107698Srwatsonmac_biba_create_devfs_device(struct mount *mp, dev_t dev, 793107698Srwatson struct devfs_dirent *devfs_dirent, struct label *label) 794101099Srwatson{ 795101099Srwatson struct mac_biba *mac_biba; 796101099Srwatson int biba_type; 797101099Srwatson 798101099Srwatson mac_biba = SLOT(label); 799101099Srwatson if (strcmp(dev->si_name, "null") == 0 || 800101099Srwatson strcmp(dev->si_name, "zero") == 0 || 801101099Srwatson strcmp(dev->si_name, "random") == 0 || 802101099Srwatson strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 803101099Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 804105606Srwatson else if (ptys_equal && 805105606Srwatson (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 806105606Srwatson strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 807105606Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 808101099Srwatson else 809101099Srwatson biba_type = MAC_BIBA_TYPE_HIGH; 810105643Srwatson mac_biba_set_single(mac_biba, biba_type, 0, NULL); 811101099Srwatson} 812101099Srwatson 813101099Srwatsonstatic void 814107698Srwatsonmac_biba_create_devfs_directory(struct mount *mp, char *dirname, 815107698Srwatson int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 816101099Srwatson{ 817101099Srwatson struct mac_biba *mac_biba; 818101099Srwatson 819101099Srwatson mac_biba = SLOT(label); 820105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 821101099Srwatson} 822101099Srwatson 823101099Srwatsonstatic void 824107698Srwatsonmac_biba_create_devfs_symlink(struct ucred *cred, struct mount *mp, 825107698Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 826107698Srwatson struct label *delabel) 827104535Srwatson{ 828104535Srwatson struct mac_biba *source, *dest; 829104535Srwatson 830104535Srwatson source = SLOT(&cred->cr_label); 831104535Srwatson dest = SLOT(delabel); 832104535Srwatson 833104535Srwatson mac_biba_copy_single(source, dest); 834104535Srwatson} 835104535Srwatson 836104535Srwatsonstatic void 837101099Srwatsonmac_biba_create_mount(struct ucred *cred, struct mount *mp, 838101099Srwatson struct label *mntlabel, struct label *fslabel) 839101099Srwatson{ 840101099Srwatson struct mac_biba *source, *dest; 841101099Srwatson 842101099Srwatson source = SLOT(&cred->cr_label); 843101099Srwatson dest = SLOT(mntlabel); 844101099Srwatson mac_biba_copy_single(source, dest); 845101099Srwatson dest = SLOT(fslabel); 846101099Srwatson mac_biba_copy_single(source, dest); 847101099Srwatson} 848101099Srwatson 849101099Srwatsonstatic void 850101099Srwatsonmac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 851101099Srwatson struct label *mntlabel, struct label *fslabel) 852101099Srwatson{ 853101099Srwatson struct mac_biba *mac_biba; 854101099Srwatson 855101099Srwatson /* Always mount root as high integrity. */ 856101099Srwatson mac_biba = SLOT(fslabel); 857105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 858101099Srwatson mac_biba = SLOT(mntlabel); 859105643Srwatson mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 860101099Srwatson} 861101099Srwatson 862101099Srwatsonstatic void 863101099Srwatsonmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 864101099Srwatson struct label *vnodelabel, struct label *label) 865101099Srwatson{ 866101099Srwatson struct mac_biba *source, *dest; 867101099Srwatson 868101099Srwatson source = SLOT(label); 869101099Srwatson dest = SLOT(vnodelabel); 870101099Srwatson 871105656Srwatson mac_biba_copy(source, dest); 872101099Srwatson} 873101099Srwatson 874101099Srwatsonstatic void 875107698Srwatsonmac_biba_update_devfsdirent(struct mount *mp, 876107698Srwatson struct devfs_dirent *devfs_dirent, struct label *direntlabel, 877107698Srwatson struct vnode *vp, struct label *vnodelabel) 878101099Srwatson{ 879101099Srwatson struct mac_biba *source, *dest; 880101099Srwatson 881101099Srwatson source = SLOT(vnodelabel); 882101099Srwatson dest = SLOT(direntlabel); 883101099Srwatson 884105656Srwatson mac_biba_copy(source, dest); 885101099Srwatson} 886101099Srwatson 887101099Srwatsonstatic void 888105988Srwatsonmac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 889105988Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 890105988Srwatson struct label *vlabel) 891101099Srwatson{ 892101099Srwatson struct mac_biba *source, *dest; 893101099Srwatson 894105988Srwatson source = SLOT(delabel); 895105988Srwatson dest = SLOT(vlabel); 896101099Srwatson 897101099Srwatson mac_biba_copy_single(source, dest); 898101099Srwatson} 899101099Srwatson 900101099Srwatsonstatic int 901105988Srwatsonmac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 902105988Srwatson struct vnode *vp, struct label *vlabel) 903101099Srwatson{ 904105988Srwatson struct mac_biba temp, *source, *dest; 905106354Smux int buflen, error; 906101099Srwatson 907105988Srwatson source = SLOT(fslabel); 908105988Srwatson dest = SLOT(vlabel); 909101099Srwatson 910105988Srwatson buflen = sizeof(temp); 911105988Srwatson bzero(&temp, buflen); 912105988Srwatson 913105988Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 914105988Srwatson MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 915105988Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 916105988Srwatson /* Fall back to the fslabel. */ 917105988Srwatson mac_biba_copy_single(source, dest); 918105988Srwatson return (0); 919105988Srwatson } else if (error) 920101099Srwatson return (error); 921101099Srwatson 922105988Srwatson if (buflen != sizeof(temp)) { 923105988Srwatson printf("mac_biba_associate_vnode_extattr: bad size %d\n", 924105988Srwatson buflen); 925105988Srwatson return (EPERM); 926105988Srwatson } 927105988Srwatson if (mac_biba_valid(&temp) != 0) { 928105988Srwatson printf("mac_biba_associate_vnode_extattr: invalid\n"); 929105988Srwatson return (EPERM); 930105988Srwatson } 931105988Srwatson if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 932105988Srwatson printf("mac_biba_associate_vnode_extattr: not single\n"); 933105988Srwatson return (EPERM); 934105988Srwatson } 935101099Srwatson 936105988Srwatson mac_biba_copy_single(&temp, dest); 937101099Srwatson return (0); 938101099Srwatson} 939101099Srwatson 940101099Srwatsonstatic void 941105988Srwatsonmac_biba_associate_vnode_singlelabel(struct mount *mp, 942105988Srwatson struct label *fslabel, struct vnode *vp, struct label *vlabel) 943101099Srwatson{ 944101099Srwatson struct mac_biba *source, *dest; 945101099Srwatson 946101099Srwatson source = SLOT(fslabel); 947105988Srwatson dest = SLOT(vlabel); 948101099Srwatson 949101099Srwatson mac_biba_copy_single(source, dest); 950101099Srwatson} 951101099Srwatson 952105988Srwatsonstatic int 953105988Srwatsonmac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 954105988Srwatson struct label *fslabel, struct vnode *dvp, struct label *dlabel, 955105988Srwatson struct vnode *vp, struct label *vlabel, struct componentname *cnp) 956105988Srwatson{ 957105988Srwatson struct mac_biba *source, *dest, temp; 958105988Srwatson size_t buflen; 959105988Srwatson int error; 960105988Srwatson 961105988Srwatson buflen = sizeof(temp); 962105988Srwatson bzero(&temp, buflen); 963105988Srwatson 964105988Srwatson source = SLOT(&cred->cr_label); 965105988Srwatson dest = SLOT(vlabel); 966105988Srwatson mac_biba_copy_single(source, &temp); 967105988Srwatson 968105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 969105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 970105988Srwatson if (error == 0) 971105988Srwatson mac_biba_copy_single(source, dest); 972105988Srwatson return (error); 973105988Srwatson} 974105988Srwatson 975105988Srwatsonstatic int 976105988Srwatsonmac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 977105988Srwatson struct label *vlabel, struct label *intlabel) 978105988Srwatson{ 979105988Srwatson struct mac_biba *source, temp; 980105988Srwatson size_t buflen; 981105988Srwatson int error; 982105988Srwatson 983105988Srwatson buflen = sizeof(temp); 984105988Srwatson bzero(&temp, buflen); 985105988Srwatson 986105988Srwatson source = SLOT(intlabel); 987105988Srwatson if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 988105988Srwatson return (0); 989105988Srwatson 990105988Srwatson mac_biba_copy_single(source, &temp); 991105988Srwatson 992105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 993105988Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 994105988Srwatson return (error); 995105988Srwatson} 996105988Srwatson 997101099Srwatson/* 998101099Srwatson * Labeling event operations: IPC object. 999101099Srwatson */ 1000101099Srwatsonstatic void 1001101099Srwatsonmac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1002101099Srwatson struct mbuf *m, struct label *mbuflabel) 1003101099Srwatson{ 1004101099Srwatson struct mac_biba *source, *dest; 1005101099Srwatson 1006101099Srwatson source = SLOT(socketlabel); 1007101099Srwatson dest = SLOT(mbuflabel); 1008101099Srwatson 1009101099Srwatson mac_biba_copy_single(source, dest); 1010101099Srwatson} 1011101099Srwatson 1012101099Srwatsonstatic void 1013101099Srwatsonmac_biba_create_socket(struct ucred *cred, struct socket *socket, 1014101099Srwatson struct label *socketlabel) 1015101099Srwatson{ 1016101099Srwatson struct mac_biba *source, *dest; 1017101099Srwatson 1018101099Srwatson source = SLOT(&cred->cr_label); 1019101099Srwatson dest = SLOT(socketlabel); 1020101099Srwatson 1021101099Srwatson mac_biba_copy_single(source, dest); 1022101099Srwatson} 1023101099Srwatson 1024101099Srwatsonstatic void 1025101099Srwatsonmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1026101099Srwatson struct label *pipelabel) 1027101099Srwatson{ 1028101099Srwatson struct mac_biba *source, *dest; 1029101099Srwatson 1030101099Srwatson source = SLOT(&cred->cr_label); 1031101099Srwatson dest = SLOT(pipelabel); 1032101099Srwatson 1033101099Srwatson mac_biba_copy_single(source, dest); 1034101099Srwatson} 1035101099Srwatson 1036101099Srwatsonstatic void 1037101099Srwatsonmac_biba_create_socket_from_socket(struct socket *oldsocket, 1038101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1039101099Srwatson struct label *newsocketlabel) 1040101099Srwatson{ 1041101099Srwatson struct mac_biba *source, *dest; 1042101099Srwatson 1043101099Srwatson source = SLOT(oldsocketlabel); 1044101099Srwatson dest = SLOT(newsocketlabel); 1045101099Srwatson 1046101099Srwatson mac_biba_copy_single(source, dest); 1047101099Srwatson} 1048101099Srwatson 1049101099Srwatsonstatic void 1050101099Srwatsonmac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1051101099Srwatson struct label *socketlabel, struct label *newlabel) 1052101099Srwatson{ 1053101099Srwatson struct mac_biba *source, *dest; 1054101099Srwatson 1055101099Srwatson source = SLOT(newlabel); 1056101099Srwatson dest = SLOT(socketlabel); 1057101099Srwatson 1058105656Srwatson mac_biba_copy(source, dest); 1059101099Srwatson} 1060101099Srwatson 1061101099Srwatsonstatic void 1062101099Srwatsonmac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1063101099Srwatson struct label *pipelabel, struct label *newlabel) 1064101099Srwatson{ 1065101099Srwatson struct mac_biba *source, *dest; 1066101099Srwatson 1067101099Srwatson source = SLOT(newlabel); 1068101099Srwatson dest = SLOT(pipelabel); 1069101099Srwatson 1070105656Srwatson mac_biba_copy(source, dest); 1071101099Srwatson} 1072101099Srwatson 1073101099Srwatsonstatic void 1074101099Srwatsonmac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1075101099Srwatson struct socket *socket, struct label *socketpeerlabel) 1076101099Srwatson{ 1077101099Srwatson struct mac_biba *source, *dest; 1078101099Srwatson 1079101099Srwatson source = SLOT(mbuflabel); 1080101099Srwatson dest = SLOT(socketpeerlabel); 1081101099Srwatson 1082101099Srwatson mac_biba_copy_single(source, dest); 1083101099Srwatson} 1084101099Srwatson 1085101099Srwatson/* 1086101099Srwatson * Labeling event operations: network objects. 1087101099Srwatson */ 1088101099Srwatsonstatic void 1089101099Srwatsonmac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1090101099Srwatson struct label *oldsocketlabel, struct socket *newsocket, 1091101099Srwatson struct label *newsocketpeerlabel) 1092101099Srwatson{ 1093101099Srwatson struct mac_biba *source, *dest; 1094101099Srwatson 1095101099Srwatson source = SLOT(oldsocketlabel); 1096101099Srwatson dest = SLOT(newsocketpeerlabel); 1097101099Srwatson 1098101099Srwatson mac_biba_copy_single(source, dest); 1099101099Srwatson} 1100101099Srwatson 1101101099Srwatsonstatic void 1102101099Srwatsonmac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1103101099Srwatson struct label *bpflabel) 1104101099Srwatson{ 1105101099Srwatson struct mac_biba *source, *dest; 1106101099Srwatson 1107101099Srwatson source = SLOT(&cred->cr_label); 1108101099Srwatson dest = SLOT(bpflabel); 1109101099Srwatson 1110101099Srwatson mac_biba_copy_single(source, dest); 1111101099Srwatson} 1112101099Srwatson 1113101099Srwatsonstatic void 1114101099Srwatsonmac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1115101099Srwatson{ 1116101099Srwatson char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1117101099Srwatson char tiflist[sizeof(trusted_interfaces)]; 1118101099Srwatson struct mac_biba *dest; 1119110350Srwatson int len, type; 1120101099Srwatson 1121101099Srwatson dest = SLOT(ifnetlabel); 1122101099Srwatson 1123101099Srwatson if (ifnet->if_type == IFT_LOOP) { 1124110350Srwatson type = MAC_BIBA_TYPE_EQUAL; 1125101099Srwatson goto set; 1126101099Srwatson } 1127101099Srwatson 1128101099Srwatson if (trust_all_interfaces) { 1129110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1130101099Srwatson goto set; 1131101099Srwatson } 1132101099Srwatson 1133110350Srwatson type = MAC_BIBA_TYPE_LOW; 1134101099Srwatson 1135101099Srwatson if (trusted_interfaces[0] == '\0' || 1136101099Srwatson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1137101099Srwatson goto set; 1138101099Srwatson 1139106089Srwatson bzero(tiflist, sizeof(tiflist)); 1140101099Srwatson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1141101099Srwatson if(*p != ' ' && *p != '\t') 1142101099Srwatson *q = *p; 1143101099Srwatson 1144101099Srwatson snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1145101099Srwatson 1146101099Srwatson for (p = q = tiflist;; p++) { 1147101099Srwatson if (*p == ',' || *p == '\0') { 1148101099Srwatson len = p - q; 1149101099Srwatson if (len < IFNAMSIZ) { 1150101099Srwatson bzero(tifname, sizeof(tifname)); 1151101099Srwatson bcopy(q, tifname, len); 1152101099Srwatson if (strcmp(tifname, ifname) == 0) { 1153110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1154101099Srwatson break; 1155101099Srwatson } 1156106089Srwatson } else { 1157106089Srwatson *p = '\0'; 1158106089Srwatson printf("mac_biba warning: interface name " 1159106089Srwatson "\"%s\" is too long (must be < %d)\n", 1160106089Srwatson q, IFNAMSIZ); 1161101099Srwatson } 1162101099Srwatson if (*p == '\0') 1163101099Srwatson break; 1164101099Srwatson q = p + 1; 1165101099Srwatson } 1166101099Srwatson } 1167101099Srwatsonset: 1168110350Srwatson mac_biba_set_single(dest, type, 0, NULL); 1169110350Srwatson mac_biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1170101099Srwatson} 1171101099Srwatson 1172101099Srwatsonstatic void 1173101099Srwatsonmac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1174101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1175101099Srwatson{ 1176101099Srwatson struct mac_biba *source, *dest; 1177101099Srwatson 1178101099Srwatson source = SLOT(fragmentlabel); 1179101099Srwatson dest = SLOT(ipqlabel); 1180101099Srwatson 1181101099Srwatson mac_biba_copy_single(source, dest); 1182101099Srwatson} 1183101099Srwatson 1184101099Srwatsonstatic void 1185101099Srwatsonmac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1186101099Srwatson struct mbuf *datagram, struct label *datagramlabel) 1187101099Srwatson{ 1188101099Srwatson struct mac_biba *source, *dest; 1189101099Srwatson 1190101099Srwatson source = SLOT(ipqlabel); 1191101099Srwatson dest = SLOT(datagramlabel); 1192101099Srwatson 1193101099Srwatson /* Just use the head, since we require them all to match. */ 1194101099Srwatson mac_biba_copy_single(source, dest); 1195101099Srwatson} 1196101099Srwatson 1197101099Srwatsonstatic void 1198101099Srwatsonmac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1199101099Srwatson struct mbuf *fragment, struct label *fragmentlabel) 1200101099Srwatson{ 1201101099Srwatson struct mac_biba *source, *dest; 1202101099Srwatson 1203101099Srwatson source = SLOT(datagramlabel); 1204101099Srwatson dest = SLOT(fragmentlabel); 1205101099Srwatson 1206101099Srwatson mac_biba_copy_single(source, dest); 1207101099Srwatson} 1208101099Srwatson 1209101099Srwatsonstatic void 1210101099Srwatsonmac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1211101099Srwatson struct label *oldmbuflabel, struct mbuf *newmbuf, 1212101099Srwatson struct label *newmbuflabel) 1213101099Srwatson{ 1214101099Srwatson struct mac_biba *source, *dest; 1215101099Srwatson 1216101099Srwatson source = SLOT(oldmbuflabel); 1217101099Srwatson dest = SLOT(newmbuflabel); 1218101099Srwatson 1219105656Srwatson /* 1220105656Srwatson * Because the source mbuf may not yet have been "created", 1221105696Srwatson * just initialized, we do a conditional copy. Since we don't 1222105656Srwatson * allow mbufs to have ranges, do a KASSERT to make sure that 1223105656Srwatson * doesn't happen. 1224105656Srwatson */ 1225105656Srwatson KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1226105656Srwatson ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1227105656Srwatson mac_biba_copy(source, dest); 1228101099Srwatson} 1229101099Srwatson 1230101099Srwatsonstatic void 1231101099Srwatsonmac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1232101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1233101099Srwatson{ 1234101099Srwatson struct mac_biba *dest; 1235101099Srwatson 1236101099Srwatson dest = SLOT(mbuflabel); 1237101099Srwatson 1238105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1239101099Srwatson} 1240101099Srwatson 1241101099Srwatsonstatic void 1242101099Srwatsonmac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1243101099Srwatson struct mbuf *mbuf, struct label *mbuflabel) 1244101099Srwatson{ 1245101099Srwatson struct mac_biba *source, *dest; 1246101099Srwatson 1247101099Srwatson source = SLOT(bpflabel); 1248101099Srwatson dest = SLOT(mbuflabel); 1249101099Srwatson 1250101099Srwatson mac_biba_copy_single(source, dest); 1251101099Srwatson} 1252101099Srwatson 1253101099Srwatsonstatic void 1254101099Srwatsonmac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1255101099Srwatson struct mbuf *m, struct label *mbuflabel) 1256101099Srwatson{ 1257101099Srwatson struct mac_biba *source, *dest; 1258101099Srwatson 1259101099Srwatson source = SLOT(ifnetlabel); 1260101099Srwatson dest = SLOT(mbuflabel); 1261101099Srwatson 1262101099Srwatson mac_biba_copy_single(source, dest); 1263101099Srwatson} 1264101099Srwatson 1265101099Srwatsonstatic void 1266101099Srwatsonmac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1267101099Srwatson struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1268101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1269101099Srwatson{ 1270101099Srwatson struct mac_biba *source, *dest; 1271101099Srwatson 1272101099Srwatson source = SLOT(oldmbuflabel); 1273101099Srwatson dest = SLOT(newmbuflabel); 1274101099Srwatson 1275101099Srwatson mac_biba_copy_single(source, dest); 1276101099Srwatson} 1277101099Srwatson 1278101099Srwatsonstatic void 1279101099Srwatsonmac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1280101099Srwatson struct mbuf *newmbuf, struct label *newmbuflabel) 1281101099Srwatson{ 1282101099Srwatson struct mac_biba *source, *dest; 1283101099Srwatson 1284101099Srwatson source = SLOT(oldmbuflabel); 1285101099Srwatson dest = SLOT(newmbuflabel); 1286101099Srwatson 1287101099Srwatson mac_biba_copy_single(source, dest); 1288101099Srwatson} 1289101099Srwatson 1290101099Srwatsonstatic int 1291101099Srwatsonmac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1292101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1293101099Srwatson{ 1294101099Srwatson struct mac_biba *a, *b; 1295101099Srwatson 1296101099Srwatson a = SLOT(ipqlabel); 1297101099Srwatson b = SLOT(fragmentlabel); 1298101099Srwatson 1299101099Srwatson return (mac_biba_equal_single(a, b)); 1300101099Srwatson} 1301101099Srwatson 1302101099Srwatsonstatic void 1303101099Srwatsonmac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1304101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1305101099Srwatson{ 1306101099Srwatson struct mac_biba *source, *dest; 1307101099Srwatson 1308101099Srwatson source = SLOT(newlabel); 1309101099Srwatson dest = SLOT(ifnetlabel); 1310101099Srwatson 1311105656Srwatson mac_biba_copy(source, dest); 1312101099Srwatson} 1313101099Srwatson 1314101099Srwatsonstatic void 1315101099Srwatsonmac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1316101099Srwatson struct ipq *ipq, struct label *ipqlabel) 1317101099Srwatson{ 1318101099Srwatson 1319101099Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1320101099Srwatson} 1321101099Srwatson 1322101099Srwatson/* 1323101099Srwatson * Labeling event operations: processes. 1324101099Srwatson */ 1325101099Srwatsonstatic void 1326101099Srwatsonmac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1327101099Srwatson{ 1328101099Srwatson struct mac_biba *source, *dest; 1329101099Srwatson 1330101099Srwatson source = SLOT(&cred_parent->cr_label); 1331101099Srwatson dest = SLOT(&cred_child->cr_label); 1332101099Srwatson 1333101099Srwatson mac_biba_copy_single(source, dest); 1334101099Srwatson mac_biba_copy_range(source, dest); 1335101099Srwatson} 1336101099Srwatson 1337101099Srwatsonstatic void 1338101099Srwatsonmac_biba_create_proc0(struct ucred *cred) 1339101099Srwatson{ 1340101099Srwatson struct mac_biba *dest; 1341101099Srwatson 1342101099Srwatson dest = SLOT(&cred->cr_label); 1343101099Srwatson 1344105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1345105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1346105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1347101099Srwatson} 1348101099Srwatson 1349101099Srwatsonstatic void 1350101099Srwatsonmac_biba_create_proc1(struct ucred *cred) 1351101099Srwatson{ 1352101099Srwatson struct mac_biba *dest; 1353101099Srwatson 1354101099Srwatson dest = SLOT(&cred->cr_label); 1355101099Srwatson 1356105643Srwatson mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1357105643Srwatson mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1358105643Srwatson MAC_BIBA_TYPE_HIGH, 0, NULL); 1359101099Srwatson} 1360101099Srwatson 1361101099Srwatsonstatic void 1362101099Srwatsonmac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1363101099Srwatson{ 1364101099Srwatson struct mac_biba *source, *dest; 1365101099Srwatson 1366101099Srwatson source = SLOT(newlabel); 1367101099Srwatson dest = SLOT(&cred->cr_label); 1368101099Srwatson 1369105656Srwatson mac_biba_copy(source, dest); 1370101099Srwatson} 1371101099Srwatson 1372101099Srwatson/* 1373101099Srwatson * Access control checks. 1374101099Srwatson */ 1375101099Srwatsonstatic int 1376101099Srwatsonmac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1377101099Srwatson struct ifnet *ifnet, struct label *ifnetlabel) 1378101099Srwatson{ 1379101099Srwatson struct mac_biba *a, *b; 1380101099Srwatson 1381101099Srwatson if (!mac_biba_enabled) 1382101099Srwatson return (0); 1383101099Srwatson 1384101099Srwatson a = SLOT(bpflabel); 1385101099Srwatson b = SLOT(ifnetlabel); 1386101099Srwatson 1387101099Srwatson if (mac_biba_equal_single(a, b)) 1388101099Srwatson return (0); 1389101099Srwatson return (EACCES); 1390101099Srwatson} 1391101099Srwatson 1392101099Srwatsonstatic int 1393101099Srwatsonmac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1394101099Srwatson{ 1395101099Srwatson struct mac_biba *subj, *new; 1396105634Srwatson int error; 1397101099Srwatson 1398101099Srwatson subj = SLOT(&cred->cr_label); 1399101099Srwatson new = SLOT(newlabel); 1400101099Srwatson 1401101099Srwatson /* 1402105634Srwatson * If there is a Biba label update for the credential, it may 1403105634Srwatson * be an update of the single, range, or both. 1404101099Srwatson */ 1405105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1406105634Srwatson if (error) 1407105634Srwatson return (error); 1408101099Srwatson 1409101099Srwatson /* 1410105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1411101099Srwatson */ 1412105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1413105634Srwatson /* 1414110351Srwatson * If the change request modifies both the Biba label 1415110351Srwatson * single and range, check that the new single will be 1416110351Srwatson * in the new range. 1417110351Srwatson */ 1418110351Srwatson if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1419110351Srwatson MAC_BIBA_FLAGS_BOTH && 1420110351Srwatson !mac_biba_single_in_range(new, new)) 1421110351Srwatson return (EINVAL); 1422110351Srwatson 1423110351Srwatson /* 1424105634Srwatson * To change the Biba single label on a credential, the 1425105634Srwatson * new single label must be in the current range. 1426105634Srwatson */ 1427105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1428105634Srwatson !mac_biba_single_in_range(new, subj)) 1429105634Srwatson return (EPERM); 1430101099Srwatson 1431105634Srwatson /* 1432105634Srwatson * To change the Biba range on a credential, the new 1433105634Srwatson * range label must be in the current range. 1434105634Srwatson */ 1435105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1436105634Srwatson !mac_biba_range_in_range(new, subj)) 1437105634Srwatson return (EPERM); 1438101099Srwatson 1439105634Srwatson /* 1440105634Srwatson * To have EQUAL in any component of the new credential 1441105634Srwatson * Biba label, the subject must already have EQUAL in 1442105634Srwatson * their label. 1443105634Srwatson */ 1444105634Srwatson if (mac_biba_contains_equal(new)) { 1445106090Srwatson error = mac_biba_subject_privileged(subj); 1446105634Srwatson if (error) 1447105634Srwatson return (error); 1448105634Srwatson } 1449105634Srwatson } 1450105634Srwatson 1451101099Srwatson return (0); 1452101099Srwatson} 1453101099Srwatson 1454101099Srwatsonstatic int 1455101099Srwatsonmac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1456101099Srwatson{ 1457101099Srwatson struct mac_biba *subj, *obj; 1458101099Srwatson 1459101099Srwatson if (!mac_biba_enabled) 1460101099Srwatson return (0); 1461101099Srwatson 1462101099Srwatson subj = SLOT(&u1->cr_label); 1463101099Srwatson obj = SLOT(&u2->cr_label); 1464101099Srwatson 1465101099Srwatson /* XXX: range */ 1466101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1467101099Srwatson return (ESRCH); 1468101099Srwatson 1469101099Srwatson return (0); 1470101099Srwatson} 1471101099Srwatson 1472101099Srwatsonstatic int 1473101099Srwatsonmac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1474101099Srwatson struct label *ifnetlabel, struct label *newlabel) 1475101099Srwatson{ 1476101099Srwatson struct mac_biba *subj, *new; 1477105634Srwatson int error; 1478101099Srwatson 1479101099Srwatson subj = SLOT(&cred->cr_label); 1480101099Srwatson new = SLOT(newlabel); 1481101099Srwatson 1482105634Srwatson /* 1483105634Srwatson * If there is a Biba label update for the interface, it may 1484105634Srwatson * be an update of the single, range, or both. 1485105634Srwatson */ 1486105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1487105634Srwatson if (error) 1488105634Srwatson return (error); 1489101099Srwatson 1490105634Srwatson /* 1491106160Srwatson * Relabling network interfaces requires Biba privilege. 1492106160Srwatson */ 1493106160Srwatson error = mac_biba_subject_privileged(subj); 1494106160Srwatson if (error) 1495106160Srwatson return (error); 1496106160Srwatson 1497106160Srwatson /* 1498105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1499105634Srwatson */ 1500105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1501105634Srwatson /* 1502105634Srwatson * Rely on the traditional superuser status for the Biba 1503105634Srwatson * interface relabel requirements. XXXMAC: This will go 1504105634Srwatson * away. 1505105634Srwatson */ 1506105634Srwatson error = suser_cred(cred, 0); 1507105634Srwatson if (error) 1508105634Srwatson return (EPERM); 1509105634Srwatson 1510105634Srwatson /* 1511105634Srwatson * XXXMAC: Additional consistency tests regarding the single 1512105634Srwatson * and the range of the new label might be performed here. 1513105634Srwatson */ 1514105634Srwatson } 1515105634Srwatson 1516105634Srwatson return (0); 1517101099Srwatson} 1518101099Srwatson 1519103759Srwatsonstatic int 1520101099Srwatsonmac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1521101099Srwatson struct mbuf *m, struct label *mbuflabel) 1522101099Srwatson{ 1523101099Srwatson struct mac_biba *p, *i; 1524103761Srwatson 1525101099Srwatson if (!mac_biba_enabled) 1526101099Srwatson return (0); 1527101099Srwatson 1528101099Srwatson p = SLOT(mbuflabel); 1529101099Srwatson i = SLOT(ifnetlabel); 1530103759Srwatson 1531101099Srwatson return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1532101099Srwatson} 1533101099Srwatson 1534101099Srwatsonstatic int 1535110354Srwatsonmac_biba_check_kld_load(struct ucred *cred, struct vnode *vp, 1536110354Srwatson struct label *label) 1537110354Srwatson{ 1538110354Srwatson struct mac_biba *subj, *obj; 1539110354Srwatson int error; 1540110354Srwatson 1541110354Srwatson if (!mac_biba_enabled) 1542110354Srwatson return (0); 1543110354Srwatson 1544110354Srwatson subj = SLOT(&cred->cr_label); 1545110354Srwatson 1546110354Srwatson error = mac_biba_subject_privileged(subj); 1547110354Srwatson if (error) 1548110354Srwatson return (error); 1549110354Srwatson 1550110354Srwatson obj = SLOT(label); 1551110354Srwatson if (!mac_biba_high_single(obj)) 1552110354Srwatson return (EACCES); 1553110354Srwatson 1554110354Srwatson return (0); 1555110354Srwatson} 1556110354Srwatson 1557110354Srwatson 1558110354Srwatsonstatic int 1559110354Srwatsonmac_biba_check_kld_unload(struct ucred *cred) 1560110354Srwatson{ 1561110354Srwatson struct mac_biba *subj; 1562110354Srwatson 1563110354Srwatson if (!mac_biba_enabled) 1564110354Srwatson return (0); 1565110354Srwatson 1566110354Srwatson subj = SLOT(&cred->cr_label); 1567110354Srwatson 1568110354Srwatson return (mac_biba_subject_privileged(subj)); 1569110354Srwatson} 1570110354Srwatson 1571110354Srwatsonstatic int 1572101099Srwatsonmac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1573101099Srwatson struct label *mntlabel) 1574101099Srwatson{ 1575101099Srwatson struct mac_biba *subj, *obj; 1576101099Srwatson 1577101099Srwatson if (!mac_biba_enabled) 1578101099Srwatson return (0); 1579101099Srwatson 1580101099Srwatson subj = SLOT(&cred->cr_label); 1581101099Srwatson obj = SLOT(mntlabel); 1582101099Srwatson 1583101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1584101099Srwatson return (EACCES); 1585101099Srwatson 1586101099Srwatson return (0); 1587101099Srwatson} 1588101099Srwatson 1589101099Srwatsonstatic int 1590101099Srwatsonmac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1591101099Srwatson struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1592101099Srwatson{ 1593103759Srwatson 1594101099Srwatson if(!mac_biba_enabled) 1595101099Srwatson return (0); 1596101099Srwatson 1597101099Srwatson /* XXX: This will be implemented soon... */ 1598101099Srwatson 1599101099Srwatson return (0); 1600101099Srwatson} 1601101099Srwatson 1602101099Srwatsonstatic int 1603102115Srwatsonmac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1604102115Srwatson struct label *pipelabel) 1605101099Srwatson{ 1606101099Srwatson struct mac_biba *subj, *obj; 1607101099Srwatson 1608101099Srwatson if (!mac_biba_enabled) 1609101099Srwatson return (0); 1610101099Srwatson 1611101099Srwatson subj = SLOT(&cred->cr_label); 1612101099Srwatson obj = SLOT((pipelabel)); 1613101099Srwatson 1614102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1615102115Srwatson return (EACCES); 1616101099Srwatson 1617101099Srwatson return (0); 1618101099Srwatson} 1619101099Srwatson 1620101099Srwatsonstatic int 1621102115Srwatsonmac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1622102115Srwatson struct label *pipelabel) 1623102115Srwatson{ 1624102115Srwatson struct mac_biba *subj, *obj; 1625102115Srwatson 1626102115Srwatson if (!mac_biba_enabled) 1627102115Srwatson return (0); 1628102115Srwatson 1629102115Srwatson subj = SLOT(&cred->cr_label); 1630102115Srwatson obj = SLOT((pipelabel)); 1631102115Srwatson 1632102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1633102115Srwatson return (EACCES); 1634102115Srwatson 1635102115Srwatson return (0); 1636102115Srwatson} 1637102115Srwatson 1638102115Srwatsonstatic int 1639101099Srwatsonmac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1640101099Srwatson struct label *pipelabel, struct label *newlabel) 1641101099Srwatson{ 1642101099Srwatson struct mac_biba *subj, *obj, *new; 1643105634Srwatson int error; 1644101099Srwatson 1645101099Srwatson new = SLOT(newlabel); 1646101099Srwatson subj = SLOT(&cred->cr_label); 1647101099Srwatson obj = SLOT(pipelabel); 1648101099Srwatson 1649101099Srwatson /* 1650105634Srwatson * If there is a Biba label update for a pipe, it must be a 1651105634Srwatson * single update. 1652101099Srwatson */ 1653105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1654105634Srwatson if (error) 1655105634Srwatson return (error); 1656101099Srwatson 1657101099Srwatson /* 1658105634Srwatson * To perform a relabel of a pipe (Biba label or not), Biba must 1659105634Srwatson * authorize the relabel. 1660101099Srwatson */ 1661105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1662101099Srwatson return (EPERM); 1663101099Srwatson 1664101099Srwatson /* 1665105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1666101099Srwatson */ 1667105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1668105634Srwatson /* 1669105634Srwatson * To change the Biba label on a pipe, the new pipe label 1670105634Srwatson * must be in the subject range. 1671105634Srwatson */ 1672105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1673105634Srwatson return (EPERM); 1674101099Srwatson 1675105634Srwatson /* 1676105634Srwatson * To change the Biba label on a pipe to be EQUAL, the 1677105634Srwatson * subject must have appropriate privilege. 1678105634Srwatson */ 1679105634Srwatson if (mac_biba_contains_equal(new)) { 1680106090Srwatson error = mac_biba_subject_privileged(subj); 1681105634Srwatson if (error) 1682105634Srwatson return (error); 1683105634Srwatson } 1684105634Srwatson } 1685105634Srwatson 1686101099Srwatson return (0); 1687101099Srwatson} 1688101099Srwatson 1689101099Srwatsonstatic int 1690102115Srwatsonmac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1691102115Srwatson struct label *pipelabel) 1692102115Srwatson{ 1693102115Srwatson struct mac_biba *subj, *obj; 1694102115Srwatson 1695102115Srwatson if (!mac_biba_enabled) 1696102115Srwatson return (0); 1697102115Srwatson 1698102115Srwatson subj = SLOT(&cred->cr_label); 1699102115Srwatson obj = SLOT((pipelabel)); 1700102115Srwatson 1701102115Srwatson if (!mac_biba_dominate_single(obj, subj)) 1702102115Srwatson return (EACCES); 1703102115Srwatson 1704102115Srwatson return (0); 1705102115Srwatson} 1706102115Srwatson 1707102115Srwatsonstatic int 1708102115Srwatsonmac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1709102115Srwatson struct label *pipelabel) 1710102115Srwatson{ 1711102115Srwatson struct mac_biba *subj, *obj; 1712102115Srwatson 1713102115Srwatson if (!mac_biba_enabled) 1714102115Srwatson return (0); 1715102115Srwatson 1716102115Srwatson subj = SLOT(&cred->cr_label); 1717102115Srwatson obj = SLOT((pipelabel)); 1718102115Srwatson 1719102115Srwatson if (!mac_biba_dominate_single(subj, obj)) 1720102115Srwatson return (EACCES); 1721102115Srwatson 1722102115Srwatson return (0); 1723102115Srwatson} 1724102115Srwatson 1725102115Srwatsonstatic int 1726101099Srwatsonmac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1727101099Srwatson{ 1728101099Srwatson struct mac_biba *subj, *obj; 1729101099Srwatson 1730101099Srwatson if (!mac_biba_enabled) 1731101099Srwatson return (0); 1732101099Srwatson 1733101099Srwatson subj = SLOT(&cred->cr_label); 1734101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1735101099Srwatson 1736101099Srwatson /* XXX: range checks */ 1737101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1738101099Srwatson return (ESRCH); 1739101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1740101099Srwatson return (EACCES); 1741101099Srwatson 1742101099Srwatson return (0); 1743101099Srwatson} 1744101099Srwatson 1745101099Srwatsonstatic int 1746101099Srwatsonmac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1747101099Srwatson{ 1748101099Srwatson struct mac_biba *subj, *obj; 1749103759Srwatson 1750101099Srwatson if (!mac_biba_enabled) 1751101099Srwatson return (0); 1752101099Srwatson 1753101099Srwatson subj = SLOT(&cred->cr_label); 1754101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1755103759Srwatson 1756101099Srwatson /* XXX: range checks */ 1757101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1758101099Srwatson return (ESRCH); 1759101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1760101099Srwatson return (EACCES); 1761101099Srwatson 1762101099Srwatson return (0); 1763101099Srwatson} 1764101099Srwatson 1765101099Srwatsonstatic int 1766101099Srwatsonmac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1767101099Srwatson{ 1768101099Srwatson struct mac_biba *subj, *obj; 1769103759Srwatson 1770101099Srwatson if (!mac_biba_enabled) 1771101099Srwatson return (0); 1772101099Srwatson 1773101099Srwatson subj = SLOT(&cred->cr_label); 1774101099Srwatson obj = SLOT(&proc->p_ucred->cr_label); 1775103759Srwatson 1776101099Srwatson /* XXX: range checks */ 1777101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1778101099Srwatson return (ESRCH); 1779101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 1780101099Srwatson return (EACCES); 1781101099Srwatson 1782101099Srwatson return (0); 1783101099Srwatson} 1784101099Srwatson 1785101099Srwatsonstatic int 1786101934Srwatsonmac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1787101099Srwatson struct mbuf *m, struct label *mbuflabel) 1788101099Srwatson{ 1789101099Srwatson struct mac_biba *p, *s; 1790101099Srwatson 1791101099Srwatson if (!mac_biba_enabled) 1792101099Srwatson return (0); 1793101099Srwatson 1794101099Srwatson p = SLOT(mbuflabel); 1795101099Srwatson s = SLOT(socketlabel); 1796101099Srwatson 1797101099Srwatson return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1798101099Srwatson} 1799101099Srwatson 1800101099Srwatsonstatic int 1801106214Srwatsonmac_biba_check_socket_relabel(struct ucred *cred, struct socket *so, 1802101099Srwatson struct label *socketlabel, struct label *newlabel) 1803101099Srwatson{ 1804101099Srwatson struct mac_biba *subj, *obj, *new; 1805105634Srwatson int error; 1806101099Srwatson 1807101099Srwatson new = SLOT(newlabel); 1808101099Srwatson subj = SLOT(&cred->cr_label); 1809101099Srwatson obj = SLOT(socketlabel); 1810101099Srwatson 1811101099Srwatson /* 1812105634Srwatson * If there is a Biba label update for the socket, it may be 1813105634Srwatson * an update of single. 1814101099Srwatson */ 1815105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1816105634Srwatson if (error) 1817105634Srwatson return (error); 1818101099Srwatson 1819101099Srwatson /* 1820105634Srwatson * To relabel a socket, the old socket single must be in the subject 1821101099Srwatson * range. 1822101099Srwatson */ 1823105634Srwatson if (!mac_biba_single_in_range(obj, subj)) 1824101099Srwatson return (EPERM); 1825101099Srwatson 1826101099Srwatson /* 1827105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1828101099Srwatson */ 1829105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1830105634Srwatson /* 1831105634Srwatson * To relabel a socket, the new socket single must be in 1832105634Srwatson * the subject range. 1833105634Srwatson */ 1834105634Srwatson if (!mac_biba_single_in_range(new, subj)) 1835105634Srwatson return (EPERM); 1836101099Srwatson 1837105634Srwatson /* 1838105634Srwatson * To change the Biba label on the socket to contain EQUAL, 1839105634Srwatson * the subject must have appropriate privilege. 1840105634Srwatson */ 1841105634Srwatson if (mac_biba_contains_equal(new)) { 1842106090Srwatson error = mac_biba_subject_privileged(subj); 1843105634Srwatson if (error) 1844105634Srwatson return (error); 1845105634Srwatson } 1846105634Srwatson } 1847105634Srwatson 1848101099Srwatson return (0); 1849101099Srwatson} 1850101099Srwatson 1851101099Srwatsonstatic int 1852101099Srwatsonmac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1853101099Srwatson struct label *socketlabel) 1854101099Srwatson{ 1855101099Srwatson struct mac_biba *subj, *obj; 1856101099Srwatson 1857105722Srwatson if (!mac_biba_enabled) 1858105722Srwatson return (0); 1859105722Srwatson 1860101099Srwatson subj = SLOT(&cred->cr_label); 1861101099Srwatson obj = SLOT(socketlabel); 1862101099Srwatson 1863101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 1864101099Srwatson return (ENOENT); 1865101099Srwatson 1866101099Srwatson return (0); 1867101099Srwatson} 1868101099Srwatson 1869101099Srwatsonstatic int 1870112574Srwatsonmac_biba_check_sysarch_ioperm(struct ucred *cred) 1871112574Srwatson{ 1872112574Srwatson struct mac_biba *subj; 1873112574Srwatson int error; 1874112574Srwatson 1875112574Srwatson if (!mac_biba_enabled) 1876112574Srwatson return (0); 1877112574Srwatson 1878112574Srwatson subj = SLOT(&cred->cr_label); 1879112574Srwatson 1880112574Srwatson error = mac_biba_subject_privileged(subj); 1881112574Srwatson if (error) 1882112574Srwatson return (error); 1883112574Srwatson 1884112574Srwatson return (0); 1885112574Srwatson} 1886112574Srwatson 1887112574Srwatsonstatic int 1888106418Srwatsonmac_biba_check_system_acct(struct ucred *cred, struct vnode *vp, 1889106418Srwatson struct label *label) 1890106418Srwatson{ 1891106418Srwatson struct mac_biba *subj, *obj; 1892106418Srwatson int error; 1893106418Srwatson 1894106418Srwatson if (!mac_biba_enabled) 1895106418Srwatson return (0); 1896106418Srwatson 1897106418Srwatson subj = SLOT(&cred->cr_label); 1898106418Srwatson 1899106418Srwatson error = mac_biba_subject_privileged(subj); 1900106418Srwatson if (error) 1901106418Srwatson return (error); 1902106418Srwatson 1903106418Srwatson if (label == NULL) 1904106418Srwatson return (0); 1905106418Srwatson 1906106418Srwatson obj = SLOT(label); 1907106418Srwatson if (!mac_biba_high_single(obj)) 1908106418Srwatson return (EACCES); 1909106418Srwatson 1910106418Srwatson return (0); 1911106418Srwatson} 1912106418Srwatson 1913106418Srwatsonstatic int 1914106418Srwatsonmac_biba_check_system_settime(struct ucred *cred) 1915106418Srwatson{ 1916106418Srwatson struct mac_biba *subj; 1917106418Srwatson int error; 1918106418Srwatson 1919106418Srwatson if (!mac_biba_enabled) 1920106418Srwatson return (0); 1921106418Srwatson 1922106418Srwatson subj = SLOT(&cred->cr_label); 1923106418Srwatson 1924106418Srwatson error = mac_biba_subject_privileged(subj); 1925106418Srwatson if (error) 1926106418Srwatson return (error); 1927106418Srwatson 1928106418Srwatson return (0); 1929106418Srwatson} 1930106418Srwatson 1931106418Srwatsonstatic int 1932106161Srwatsonmac_biba_check_system_swapon(struct ucred *cred, struct vnode *vp, 1933106161Srwatson struct label *label) 1934106161Srwatson{ 1935106161Srwatson struct mac_biba *subj, *obj; 1936106416Srwatson int error; 1937106161Srwatson 1938106161Srwatson if (!mac_biba_enabled) 1939106161Srwatson return (0); 1940106161Srwatson 1941106161Srwatson subj = SLOT(&cred->cr_label); 1942106161Srwatson obj = SLOT(label); 1943106161Srwatson 1944106416Srwatson error = mac_biba_subject_privileged(subj); 1945106416Srwatson if (error) 1946106416Srwatson return (error); 1947106161Srwatson 1948106161Srwatson if (!mac_biba_high_single(obj)) 1949106161Srwatson return (EACCES); 1950106161Srwatson 1951106161Srwatson return (0); 1952106161Srwatson} 1953106161Srwatson 1954106161Srwatsonstatic int 1955112574Srwatsonmac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp, 1956112574Srwatson struct label *label) 1957112574Srwatson{ 1958112574Srwatson struct mac_biba *subj, *obj; 1959112574Srwatson int error; 1960112574Srwatson 1961112574Srwatson if (!mac_biba_enabled) 1962112574Srwatson return (0); 1963112574Srwatson 1964112574Srwatson subj = SLOT(&cred->cr_label); 1965112574Srwatson obj = SLOT(label); 1966112574Srwatson 1967112574Srwatson error = mac_biba_subject_privileged(subj); 1968112574Srwatson if (error) 1969112574Srwatson return (error); 1970112574Srwatson 1971112574Srwatson return (0); 1972112574Srwatson} 1973112574Srwatson 1974112574Srwatsonstatic int 1975106161Srwatsonmac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 1976106161Srwatson void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 1977106161Srwatson{ 1978106161Srwatson struct mac_biba *subj; 1979106161Srwatson int error; 1980106161Srwatson 1981106161Srwatson if (!mac_biba_enabled) 1982106161Srwatson return (0); 1983106161Srwatson 1984106161Srwatson subj = SLOT(&cred->cr_label); 1985106161Srwatson 1986106161Srwatson /* 1987106161Srwatson * In general, treat sysctl variables as biba/high, but also 1988106161Srwatson * require privilege to change them, since they are a 1989106161Srwatson * communications channel between grades. Exempt MIB 1990106161Srwatson * queries from this due to undocmented sysctl magic. 1991106161Srwatson * XXXMAC: This probably requires some more review. 1992106161Srwatson */ 1993106161Srwatson if (new != NULL) { 1994106161Srwatson if (namelen > 0 && name[0] == 0) 1995106161Srwatson return (0); 1996106161Srwatson 1997106161Srwatson if (!mac_biba_subject_dominate_high(subj)) 1998106161Srwatson return (EACCES); 1999106161Srwatson 2000106161Srwatson error = mac_biba_subject_privileged(subj); 2001106161Srwatson if (error) 2002106161Srwatson return (error); 2003106161Srwatson } 2004106161Srwatson 2005106161Srwatson return (0); 2006106161Srwatson} 2007106161Srwatson 2008106161Srwatsonstatic int 2009101099Srwatsonmac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 2010101099Srwatson struct label *dlabel) 2011101099Srwatson{ 2012101099Srwatson struct mac_biba *subj, *obj; 2013101099Srwatson 2014101099Srwatson if (!mac_biba_enabled) 2015101099Srwatson return (0); 2016101099Srwatson 2017101099Srwatson subj = SLOT(&cred->cr_label); 2018101099Srwatson obj = SLOT(dlabel); 2019101099Srwatson 2020101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2021101099Srwatson return (EACCES); 2022101099Srwatson 2023101099Srwatson return (0); 2024101099Srwatson} 2025101099Srwatson 2026101099Srwatsonstatic int 2027101099Srwatsonmac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 2028101099Srwatson struct label *dlabel) 2029101099Srwatson{ 2030101099Srwatson struct mac_biba *subj, *obj; 2031101099Srwatson 2032101099Srwatson if (!mac_biba_enabled) 2033101099Srwatson return (0); 2034101099Srwatson 2035101099Srwatson subj = SLOT(&cred->cr_label); 2036101099Srwatson obj = SLOT(dlabel); 2037101099Srwatson 2038101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2039101099Srwatson return (EACCES); 2040101099Srwatson 2041101099Srwatson return (0); 2042101099Srwatson} 2043101099Srwatson 2044101099Srwatsonstatic int 2045101099Srwatsonmac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2046101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2047101099Srwatson{ 2048101099Srwatson struct mac_biba *subj, *obj; 2049101099Srwatson 2050101099Srwatson if (!mac_biba_enabled) 2051101099Srwatson return (0); 2052101099Srwatson 2053101099Srwatson subj = SLOT(&cred->cr_label); 2054101099Srwatson obj = SLOT(dlabel); 2055101099Srwatson 2056101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2057101099Srwatson return (EACCES); 2058101099Srwatson 2059101099Srwatson return (0); 2060101099Srwatson} 2061101099Srwatson 2062101099Srwatsonstatic int 2063101099Srwatsonmac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2064101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2065101099Srwatson struct componentname *cnp) 2066101099Srwatson{ 2067101099Srwatson struct mac_biba *subj, *obj; 2068101099Srwatson 2069101099Srwatson if (!mac_biba_enabled) 2070101099Srwatson return (0); 2071101099Srwatson 2072101099Srwatson subj = SLOT(&cred->cr_label); 2073101099Srwatson obj = SLOT(dlabel); 2074101099Srwatson 2075101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2076101099Srwatson return (EACCES); 2077101099Srwatson 2078101099Srwatson obj = SLOT(label); 2079101099Srwatson 2080101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2081101099Srwatson return (EACCES); 2082101099Srwatson 2083101099Srwatson return (0); 2084101099Srwatson} 2085101099Srwatson 2086101099Srwatsonstatic int 2087101099Srwatsonmac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2088101099Srwatson struct label *label, acl_type_t type) 2089101099Srwatson{ 2090101099Srwatson struct mac_biba *subj, *obj; 2091101099Srwatson 2092101099Srwatson if (!mac_biba_enabled) 2093101099Srwatson return (0); 2094101099Srwatson 2095101099Srwatson subj = SLOT(&cred->cr_label); 2096101099Srwatson obj = SLOT(label); 2097101099Srwatson 2098101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2099101099Srwatson return (EACCES); 2100101099Srwatson 2101101099Srwatson return (0); 2102101099Srwatson} 2103101099Srwatson 2104101099Srwatsonstatic int 2105101099Srwatsonmac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 2106106648Srwatson struct label *label, struct image_params *imgp, 2107106648Srwatson struct label *execlabel) 2108101099Srwatson{ 2109106648Srwatson struct mac_biba *subj, *obj, *exec; 2110106648Srwatson int error; 2111101099Srwatson 2112106648Srwatson if (execlabel != NULL) { 2113106648Srwatson /* 2114106648Srwatson * We currently don't permit labels to be changed at 2115106648Srwatson * exec-time as part of Biba, so disallow non-NULL 2116106648Srwatson * Biba label elements in the execlabel. 2117106648Srwatson */ 2118106648Srwatson exec = SLOT(execlabel); 2119106648Srwatson error = biba_atmostflags(exec, 0); 2120106648Srwatson if (error) 2121106648Srwatson return (error); 2122106648Srwatson } 2123106648Srwatson 2124101099Srwatson if (!mac_biba_enabled) 2125101099Srwatson return (0); 2126101099Srwatson 2127101099Srwatson subj = SLOT(&cred->cr_label); 2128101099Srwatson obj = SLOT(label); 2129101099Srwatson 2130101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2131101099Srwatson return (EACCES); 2132101099Srwatson 2133101099Srwatson return (0); 2134101099Srwatson} 2135101099Srwatson 2136101099Srwatsonstatic int 2137101099Srwatsonmac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 2138101099Srwatson struct label *label, acl_type_t type) 2139101099Srwatson{ 2140101099Srwatson struct mac_biba *subj, *obj; 2141101099Srwatson 2142101099Srwatson if (!mac_biba_enabled) 2143101099Srwatson return (0); 2144101099Srwatson 2145101099Srwatson subj = SLOT(&cred->cr_label); 2146101099Srwatson obj = SLOT(label); 2147101099Srwatson 2148101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2149101099Srwatson return (EACCES); 2150101099Srwatson 2151101099Srwatson return (0); 2152101099Srwatson} 2153101099Srwatson 2154101099Srwatsonstatic int 2155101099Srwatsonmac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2156101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 2157101099Srwatson{ 2158101099Srwatson struct mac_biba *subj, *obj; 2159101099Srwatson 2160101099Srwatson if (!mac_biba_enabled) 2161101099Srwatson return (0); 2162101099Srwatson 2163101099Srwatson subj = SLOT(&cred->cr_label); 2164101099Srwatson obj = SLOT(label); 2165101099Srwatson 2166101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2167101099Srwatson return (EACCES); 2168101099Srwatson 2169101099Srwatson return (0); 2170101099Srwatson} 2171101099Srwatson 2172101099Srwatsonstatic int 2173104530Srwatsonmac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2174104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2175104530Srwatson struct componentname *cnp) 2176104530Srwatson{ 2177104530Srwatson struct mac_biba *subj, *obj; 2178104530Srwatson 2179104530Srwatson if (!mac_biba_enabled) 2180104530Srwatson return (0); 2181104530Srwatson 2182104530Srwatson subj = SLOT(&cred->cr_label); 2183104530Srwatson obj = SLOT(dlabel); 2184104530Srwatson 2185104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2186104530Srwatson return (EACCES); 2187104530Srwatson 2188104530Srwatson obj = SLOT(label); 2189104530Srwatson 2190104530Srwatson if (!mac_biba_dominate_single(subj, obj)) 2191104530Srwatson return (EACCES); 2192104530Srwatson 2193104530Srwatson return (0); 2194104530Srwatson} 2195104530Srwatson 2196104530Srwatsonstatic int 2197103759Srwatsonmac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2198101099Srwatson struct label *dlabel, struct componentname *cnp) 2199101099Srwatson{ 2200101099Srwatson struct mac_biba *subj, *obj; 2201103759Srwatson 2202101099Srwatson if (!mac_biba_enabled) 2203101099Srwatson return (0); 2204103759Srwatson 2205101099Srwatson subj = SLOT(&cred->cr_label); 2206101099Srwatson obj = SLOT(dlabel); 2207103759Srwatson 2208101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2209101099Srwatson return (EACCES); 2210101099Srwatson 2211103759Srwatson return (0); 2212101099Srwatson} 2213101099Srwatson 2214101099Srwatsonstatic int 2215104546Srwatsonmac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2216104546Srwatson struct label *label, int prot) 2217104546Srwatson{ 2218104546Srwatson struct mac_biba *subj, *obj; 2219104546Srwatson 2220104546Srwatson /* 2221104546Srwatson * Rely on the use of open()-time protections to handle 2222104546Srwatson * non-revocation cases. 2223104546Srwatson */ 2224105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2225104546Srwatson return (0); 2226104546Srwatson 2227104546Srwatson subj = SLOT(&cred->cr_label); 2228104546Srwatson obj = SLOT(label); 2229104546Srwatson 2230104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2231104546Srwatson if (!mac_biba_dominate_single(obj, subj)) 2232104546Srwatson return (EACCES); 2233104546Srwatson } 2234104546Srwatson if (prot & VM_PROT_WRITE) { 2235104546Srwatson if (!mac_biba_dominate_single(subj, obj)) 2236104546Srwatson return (EACCES); 2237104546Srwatson } 2238104546Srwatson 2239104569Srwatson return (0); 2240104546Srwatson} 2241104546Srwatson 2242104546Srwatsonstatic int 2243101099Srwatsonmac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2244106212Srwatson struct label *vnodelabel, int acc_mode) 2245101099Srwatson{ 2246101099Srwatson struct mac_biba *subj, *obj; 2247101099Srwatson 2248101099Srwatson if (!mac_biba_enabled) 2249101099Srwatson return (0); 2250101099Srwatson 2251101099Srwatson subj = SLOT(&cred->cr_label); 2252101099Srwatson obj = SLOT(vnodelabel); 2253101099Srwatson 2254101099Srwatson /* XXX privilege override for admin? */ 2255101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2256101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2257101099Srwatson return (EACCES); 2258101099Srwatson } 2259101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2260101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2261101099Srwatson return (EACCES); 2262101099Srwatson } 2263101099Srwatson 2264101099Srwatson return (0); 2265101099Srwatson} 2266101099Srwatson 2267101099Srwatsonstatic int 2268102129Srwatsonmac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2269102129Srwatson struct vnode *vp, struct label *label) 2270102112Srwatson{ 2271102112Srwatson struct mac_biba *subj, *obj; 2272102112Srwatson 2273105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2274102112Srwatson return (0); 2275102112Srwatson 2276102129Srwatson subj = SLOT(&active_cred->cr_label); 2277102112Srwatson obj = SLOT(label); 2278102112Srwatson 2279102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2280102112Srwatson return (EACCES); 2281102112Srwatson 2282102112Srwatson return (0); 2283102112Srwatson} 2284102112Srwatson 2285102112Srwatsonstatic int 2286102129Srwatsonmac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2287102129Srwatson struct vnode *vp, struct label *label) 2288102112Srwatson{ 2289102112Srwatson struct mac_biba *subj, *obj; 2290102112Srwatson 2291105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2292102112Srwatson return (0); 2293102112Srwatson 2294102129Srwatson subj = SLOT(&active_cred->cr_label); 2295102112Srwatson obj = SLOT(label); 2296102112Srwatson 2297102112Srwatson if (!mac_biba_dominate_single(obj, subj)) 2298102112Srwatson return (EACCES); 2299102112Srwatson 2300102112Srwatson return (0); 2301102112Srwatson} 2302102112Srwatson 2303102112Srwatsonstatic int 2304101099Srwatsonmac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2305101099Srwatson struct label *dlabel) 2306101099Srwatson{ 2307101099Srwatson struct mac_biba *subj, *obj; 2308101099Srwatson 2309101099Srwatson if (!mac_biba_enabled) 2310101099Srwatson return (0); 2311101099Srwatson 2312101099Srwatson subj = SLOT(&cred->cr_label); 2313101099Srwatson obj = SLOT(dlabel); 2314101099Srwatson 2315101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2316101099Srwatson return (EACCES); 2317101099Srwatson 2318101099Srwatson return (0); 2319101099Srwatson} 2320101099Srwatson 2321101099Srwatsonstatic int 2322101099Srwatsonmac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2323101099Srwatson struct label *label) 2324101099Srwatson{ 2325101099Srwatson struct mac_biba *subj, *obj; 2326101099Srwatson 2327101099Srwatson if (!mac_biba_enabled) 2328101099Srwatson return (0); 2329101099Srwatson 2330101099Srwatson subj = SLOT(&cred->cr_label); 2331101099Srwatson obj = SLOT(label); 2332101099Srwatson 2333101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2334101099Srwatson return (EACCES); 2335101099Srwatson 2336101099Srwatson return (0); 2337101099Srwatson} 2338101099Srwatson 2339101099Srwatsonstatic int 2340101099Srwatsonmac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2341101099Srwatson struct label *vnodelabel, struct label *newlabel) 2342101099Srwatson{ 2343101099Srwatson struct mac_biba *old, *new, *subj; 2344105634Srwatson int error; 2345101099Srwatson 2346101099Srwatson old = SLOT(vnodelabel); 2347101099Srwatson new = SLOT(newlabel); 2348101099Srwatson subj = SLOT(&cred->cr_label); 2349101099Srwatson 2350101099Srwatson /* 2351105634Srwatson * If there is a Biba label update for the vnode, it must be a 2352105634Srwatson * single label. 2353101099Srwatson */ 2354105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2355105634Srwatson if (error) 2356105634Srwatson return (error); 2357101099Srwatson 2358101099Srwatson /* 2359105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2360105634Srwatson * authorize the relabel. 2361101099Srwatson */ 2362105634Srwatson if (!mac_biba_single_in_range(old, subj)) 2363101099Srwatson return (EPERM); 2364101099Srwatson 2365101099Srwatson /* 2366105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2367101099Srwatson */ 2368105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2369105634Srwatson /* 2370105634Srwatson * To change the Biba label on a vnode, the new vnode label 2371105634Srwatson * must be in the subject range. 2372105634Srwatson */ 2373105634Srwatson if (!mac_biba_single_in_range(new, subj)) 2374105634Srwatson return (EPERM); 2375101099Srwatson 2376105634Srwatson /* 2377105634Srwatson * To change the Biba label on the vnode to be EQUAL, 2378105634Srwatson * the subject must have appropriate privilege. 2379105634Srwatson */ 2380105634Srwatson if (mac_biba_contains_equal(new)) { 2381106090Srwatson error = mac_biba_subject_privileged(subj); 2382105634Srwatson if (error) 2383105634Srwatson return (error); 2384105634Srwatson } 2385105634Srwatson } 2386105634Srwatson 2387105634Srwatson return (0); 2388101099Srwatson} 2389101099Srwatson 2390101099Srwatsonstatic int 2391101099Srwatsonmac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2392101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 2393101099Srwatson struct componentname *cnp) 2394101099Srwatson{ 2395101099Srwatson struct mac_biba *subj, *obj; 2396101099Srwatson 2397101099Srwatson if (!mac_biba_enabled) 2398101099Srwatson return (0); 2399101099Srwatson 2400101099Srwatson subj = SLOT(&cred->cr_label); 2401101099Srwatson obj = SLOT(dlabel); 2402101099Srwatson 2403101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2404101099Srwatson return (EACCES); 2405101099Srwatson 2406101099Srwatson obj = SLOT(label); 2407101099Srwatson 2408101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2409101099Srwatson return (EACCES); 2410101099Srwatson 2411101099Srwatson return (0); 2412101099Srwatson} 2413101099Srwatson 2414101099Srwatsonstatic int 2415101099Srwatsonmac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2416101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2417101099Srwatson struct componentname *cnp) 2418101099Srwatson{ 2419101099Srwatson struct mac_biba *subj, *obj; 2420101099Srwatson 2421101099Srwatson if (!mac_biba_enabled) 2422101099Srwatson return (0); 2423101099Srwatson 2424101099Srwatson subj = SLOT(&cred->cr_label); 2425101099Srwatson obj = SLOT(dlabel); 2426101099Srwatson 2427101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2428101099Srwatson return (EACCES); 2429101099Srwatson 2430101099Srwatson if (vp != NULL) { 2431101099Srwatson obj = SLOT(label); 2432101099Srwatson 2433101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2434101099Srwatson return (EACCES); 2435101099Srwatson } 2436101099Srwatson 2437101099Srwatson return (0); 2438101099Srwatson} 2439101099Srwatson 2440101099Srwatsonstatic int 2441101099Srwatsonmac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2442101099Srwatson struct label *label) 2443101099Srwatson{ 2444101099Srwatson struct mac_biba *subj, *obj; 2445101099Srwatson 2446101099Srwatson if (!mac_biba_enabled) 2447101099Srwatson return (0); 2448101099Srwatson 2449101099Srwatson subj = SLOT(&cred->cr_label); 2450101099Srwatson obj = SLOT(label); 2451101099Srwatson 2452101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2453101099Srwatson return (EACCES); 2454101099Srwatson 2455101099Srwatson return (0); 2456101099Srwatson} 2457101099Srwatson 2458101099Srwatsonstatic int 2459101099Srwatsonmac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2460101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 2461101099Srwatson{ 2462101099Srwatson struct mac_biba *subj, *obj; 2463101099Srwatson 2464101099Srwatson if (!mac_biba_enabled) 2465101099Srwatson return (0); 2466101099Srwatson 2467101099Srwatson subj = SLOT(&cred->cr_label); 2468101099Srwatson obj = SLOT(label); 2469101099Srwatson 2470101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2471101099Srwatson return (EACCES); 2472101099Srwatson 2473101099Srwatson return (0); 2474101099Srwatson} 2475101099Srwatson 2476101099Srwatsonstatic int 2477101099Srwatsonmac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2478101099Srwatson struct label *vnodelabel, int attrnamespace, const char *name, 2479101099Srwatson struct uio *uio) 2480101099Srwatson{ 2481101099Srwatson struct mac_biba *subj, *obj; 2482101099Srwatson 2483101099Srwatson if (!mac_biba_enabled) 2484101099Srwatson return (0); 2485101099Srwatson 2486101099Srwatson subj = SLOT(&cred->cr_label); 2487101099Srwatson obj = SLOT(vnodelabel); 2488101099Srwatson 2489101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2490101099Srwatson return (EACCES); 2491101099Srwatson 2492101099Srwatson /* XXX: protect the MAC EA in a special way? */ 2493101099Srwatson 2494101099Srwatson return (0); 2495101099Srwatson} 2496101099Srwatson 2497101099Srwatsonstatic int 2498101099Srwatsonmac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2499101099Srwatson struct label *vnodelabel, u_long flags) 2500101099Srwatson{ 2501101099Srwatson struct mac_biba *subj, *obj; 2502101099Srwatson 2503101099Srwatson if (!mac_biba_enabled) 2504101099Srwatson return (0); 2505101099Srwatson 2506101099Srwatson subj = SLOT(&cred->cr_label); 2507101099Srwatson obj = SLOT(vnodelabel); 2508101099Srwatson 2509101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2510101099Srwatson return (EACCES); 2511101099Srwatson 2512101099Srwatson return (0); 2513101099Srwatson} 2514101099Srwatson 2515101099Srwatsonstatic int 2516101099Srwatsonmac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2517101099Srwatson struct label *vnodelabel, mode_t mode) 2518101099Srwatson{ 2519101099Srwatson struct mac_biba *subj, *obj; 2520101099Srwatson 2521101099Srwatson if (!mac_biba_enabled) 2522101099Srwatson return (0); 2523101099Srwatson 2524101099Srwatson subj = SLOT(&cred->cr_label); 2525101099Srwatson obj = SLOT(vnodelabel); 2526101099Srwatson 2527101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2528101099Srwatson return (EACCES); 2529101099Srwatson 2530101099Srwatson return (0); 2531101099Srwatson} 2532101099Srwatson 2533101099Srwatsonstatic int 2534101099Srwatsonmac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2535101099Srwatson struct label *vnodelabel, uid_t uid, gid_t gid) 2536101099Srwatson{ 2537101099Srwatson struct mac_biba *subj, *obj; 2538101099Srwatson 2539101099Srwatson if (!mac_biba_enabled) 2540101099Srwatson return (0); 2541101099Srwatson 2542101099Srwatson subj = SLOT(&cred->cr_label); 2543101099Srwatson obj = SLOT(vnodelabel); 2544101099Srwatson 2545101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2546101099Srwatson return (EACCES); 2547101099Srwatson 2548101099Srwatson return (0); 2549101099Srwatson} 2550101099Srwatson 2551101099Srwatsonstatic int 2552101099Srwatsonmac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2553101099Srwatson struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2554101099Srwatson{ 2555101099Srwatson struct mac_biba *subj, *obj; 2556101099Srwatson 2557101099Srwatson if (!mac_biba_enabled) 2558101099Srwatson return (0); 2559101099Srwatson 2560101099Srwatson subj = SLOT(&cred->cr_label); 2561101099Srwatson obj = SLOT(vnodelabel); 2562101099Srwatson 2563101099Srwatson if (!mac_biba_dominate_single(subj, obj)) 2564101099Srwatson return (EACCES); 2565101099Srwatson 2566101099Srwatson return (0); 2567101099Srwatson} 2568101099Srwatson 2569101099Srwatsonstatic int 2570102129Srwatsonmac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2571102129Srwatson struct vnode *vp, struct label *vnodelabel) 2572101099Srwatson{ 2573101099Srwatson struct mac_biba *subj, *obj; 2574101099Srwatson 2575101099Srwatson if (!mac_biba_enabled) 2576101099Srwatson return (0); 2577101099Srwatson 2578102129Srwatson subj = SLOT(&active_cred->cr_label); 2579101099Srwatson obj = SLOT(vnodelabel); 2580101099Srwatson 2581101099Srwatson if (!mac_biba_dominate_single(obj, subj)) 2582101099Srwatson return (EACCES); 2583101099Srwatson 2584101099Srwatson return (0); 2585101099Srwatson} 2586101099Srwatson 2587102112Srwatsonstatic int 2588102129Srwatsonmac_biba_check_vnode_write(struct ucred *active_cred, 2589102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 2590102112Srwatson{ 2591102112Srwatson struct mac_biba *subj, *obj; 2592102112Srwatson 2593105637Srwatson if (!mac_biba_enabled || !revocation_enabled) 2594102112Srwatson return (0); 2595102112Srwatson 2596102129Srwatson subj = SLOT(&active_cred->cr_label); 2597102112Srwatson obj = SLOT(label); 2598102112Srwatson 2599102112Srwatson if (!mac_biba_dominate_single(subj, obj)) 2600102112Srwatson return (EACCES); 2601102112Srwatson 2602102112Srwatson return (0); 2603102112Srwatson} 2604102112Srwatson 2605106217Srwatsonstatic struct mac_policy_ops mac_biba_ops = 2606101099Srwatson{ 2607106217Srwatson .mpo_destroy = mac_biba_destroy, 2608106217Srwatson .mpo_init = mac_biba_init, 2609106217Srwatson .mpo_init_bpfdesc_label = mac_biba_init_label, 2610106217Srwatson .mpo_init_cred_label = mac_biba_init_label, 2611106217Srwatson .mpo_init_devfsdirent_label = mac_biba_init_label, 2612106217Srwatson .mpo_init_ifnet_label = mac_biba_init_label, 2613112675Srwatson .mpo_init_ipq_label = mac_biba_init_label_waitcheck, 2614106217Srwatson .mpo_init_mbuf_label = mac_biba_init_label_waitcheck, 2615106217Srwatson .mpo_init_mount_label = mac_biba_init_label, 2616106217Srwatson .mpo_init_mount_fs_label = mac_biba_init_label, 2617106217Srwatson .mpo_init_pipe_label = mac_biba_init_label, 2618106217Srwatson .mpo_init_socket_label = mac_biba_init_label_waitcheck, 2619106217Srwatson .mpo_init_socket_peer_label = mac_biba_init_label_waitcheck, 2620106217Srwatson .mpo_init_vnode_label = mac_biba_init_label, 2621106217Srwatson .mpo_destroy_bpfdesc_label = mac_biba_destroy_label, 2622106217Srwatson .mpo_destroy_cred_label = mac_biba_destroy_label, 2623106217Srwatson .mpo_destroy_devfsdirent_label = mac_biba_destroy_label, 2624106217Srwatson .mpo_destroy_ifnet_label = mac_biba_destroy_label, 2625106217Srwatson .mpo_destroy_ipq_label = mac_biba_destroy_label, 2626106217Srwatson .mpo_destroy_mbuf_label = mac_biba_destroy_label, 2627106217Srwatson .mpo_destroy_mount_label = mac_biba_destroy_label, 2628106217Srwatson .mpo_destroy_mount_fs_label = mac_biba_destroy_label, 2629106217Srwatson .mpo_destroy_pipe_label = mac_biba_destroy_label, 2630106217Srwatson .mpo_destroy_socket_label = mac_biba_destroy_label, 2631106217Srwatson .mpo_destroy_socket_peer_label = mac_biba_destroy_label, 2632106217Srwatson .mpo_destroy_vnode_label = mac_biba_destroy_label, 2633115707Srwatson .mpo_copy_mbuf_label = mac_biba_copy_label, 2634106217Srwatson .mpo_copy_pipe_label = mac_biba_copy_label, 2635106217Srwatson .mpo_copy_vnode_label = mac_biba_copy_label, 2636106217Srwatson .mpo_externalize_cred_label = mac_biba_externalize_label, 2637106217Srwatson .mpo_externalize_ifnet_label = mac_biba_externalize_label, 2638106217Srwatson .mpo_externalize_pipe_label = mac_biba_externalize_label, 2639106217Srwatson .mpo_externalize_socket_label = mac_biba_externalize_label, 2640106217Srwatson .mpo_externalize_socket_peer_label = mac_biba_externalize_label, 2641106217Srwatson .mpo_externalize_vnode_label = mac_biba_externalize_label, 2642106217Srwatson .mpo_internalize_cred_label = mac_biba_internalize_label, 2643106217Srwatson .mpo_internalize_ifnet_label = mac_biba_internalize_label, 2644106217Srwatson .mpo_internalize_pipe_label = mac_biba_internalize_label, 2645106217Srwatson .mpo_internalize_socket_label = mac_biba_internalize_label, 2646106217Srwatson .mpo_internalize_vnode_label = mac_biba_internalize_label, 2647106217Srwatson .mpo_create_devfs_device = mac_biba_create_devfs_device, 2648106217Srwatson .mpo_create_devfs_directory = mac_biba_create_devfs_directory, 2649106217Srwatson .mpo_create_devfs_symlink = mac_biba_create_devfs_symlink, 2650106217Srwatson .mpo_create_mount = mac_biba_create_mount, 2651106217Srwatson .mpo_create_root_mount = mac_biba_create_root_mount, 2652106217Srwatson .mpo_relabel_vnode = mac_biba_relabel_vnode, 2653106217Srwatson .mpo_update_devfsdirent = mac_biba_update_devfsdirent, 2654106217Srwatson .mpo_associate_vnode_devfs = mac_biba_associate_vnode_devfs, 2655106217Srwatson .mpo_associate_vnode_extattr = mac_biba_associate_vnode_extattr, 2656106217Srwatson .mpo_associate_vnode_singlelabel = mac_biba_associate_vnode_singlelabel, 2657106217Srwatson .mpo_create_vnode_extattr = mac_biba_create_vnode_extattr, 2658106217Srwatson .mpo_setlabel_vnode_extattr = mac_biba_setlabel_vnode_extattr, 2659106217Srwatson .mpo_create_mbuf_from_socket = mac_biba_create_mbuf_from_socket, 2660106217Srwatson .mpo_create_pipe = mac_biba_create_pipe, 2661106217Srwatson .mpo_create_socket = mac_biba_create_socket, 2662106217Srwatson .mpo_create_socket_from_socket = mac_biba_create_socket_from_socket, 2663106217Srwatson .mpo_relabel_pipe = mac_biba_relabel_pipe, 2664106217Srwatson .mpo_relabel_socket = mac_biba_relabel_socket, 2665106217Srwatson .mpo_set_socket_peer_from_mbuf = mac_biba_set_socket_peer_from_mbuf, 2666106217Srwatson .mpo_set_socket_peer_from_socket = mac_biba_set_socket_peer_from_socket, 2667106217Srwatson .mpo_create_bpfdesc = mac_biba_create_bpfdesc, 2668106217Srwatson .mpo_create_datagram_from_ipq = mac_biba_create_datagram_from_ipq, 2669106217Srwatson .mpo_create_fragment = mac_biba_create_fragment, 2670106217Srwatson .mpo_create_ifnet = mac_biba_create_ifnet, 2671106217Srwatson .mpo_create_ipq = mac_biba_create_ipq, 2672106217Srwatson .mpo_create_mbuf_from_mbuf = mac_biba_create_mbuf_from_mbuf, 2673106217Srwatson .mpo_create_mbuf_linklayer = mac_biba_create_mbuf_linklayer, 2674106217Srwatson .mpo_create_mbuf_from_bpfdesc = mac_biba_create_mbuf_from_bpfdesc, 2675106217Srwatson .mpo_create_mbuf_from_ifnet = mac_biba_create_mbuf_from_ifnet, 2676106217Srwatson .mpo_create_mbuf_multicast_encap = mac_biba_create_mbuf_multicast_encap, 2677106217Srwatson .mpo_create_mbuf_netlayer = mac_biba_create_mbuf_netlayer, 2678106217Srwatson .mpo_fragment_match = mac_biba_fragment_match, 2679106217Srwatson .mpo_relabel_ifnet = mac_biba_relabel_ifnet, 2680106217Srwatson .mpo_update_ipq = mac_biba_update_ipq, 2681106217Srwatson .mpo_create_cred = mac_biba_create_cred, 2682106217Srwatson .mpo_create_proc0 = mac_biba_create_proc0, 2683106217Srwatson .mpo_create_proc1 = mac_biba_create_proc1, 2684106217Srwatson .mpo_relabel_cred = mac_biba_relabel_cred, 2685106217Srwatson .mpo_check_bpfdesc_receive = mac_biba_check_bpfdesc_receive, 2686106217Srwatson .mpo_check_cred_relabel = mac_biba_check_cred_relabel, 2687106217Srwatson .mpo_check_cred_visible = mac_biba_check_cred_visible, 2688106217Srwatson .mpo_check_ifnet_relabel = mac_biba_check_ifnet_relabel, 2689106217Srwatson .mpo_check_ifnet_transmit = mac_biba_check_ifnet_transmit, 2690110354Srwatson .mpo_check_kld_load = mac_biba_check_kld_load, 2691110354Srwatson .mpo_check_kld_unload = mac_biba_check_kld_unload, 2692106217Srwatson .mpo_check_mount_stat = mac_biba_check_mount_stat, 2693106217Srwatson .mpo_check_pipe_ioctl = mac_biba_check_pipe_ioctl, 2694106217Srwatson .mpo_check_pipe_poll = mac_biba_check_pipe_poll, 2695106217Srwatson .mpo_check_pipe_read = mac_biba_check_pipe_read, 2696106217Srwatson .mpo_check_pipe_relabel = mac_biba_check_pipe_relabel, 2697106217Srwatson .mpo_check_pipe_stat = mac_biba_check_pipe_stat, 2698106217Srwatson .mpo_check_pipe_write = mac_biba_check_pipe_write, 2699106217Srwatson .mpo_check_proc_debug = mac_biba_check_proc_debug, 2700106217Srwatson .mpo_check_proc_sched = mac_biba_check_proc_sched, 2701106217Srwatson .mpo_check_proc_signal = mac_biba_check_proc_signal, 2702106217Srwatson .mpo_check_socket_deliver = mac_biba_check_socket_deliver, 2703106217Srwatson .mpo_check_socket_relabel = mac_biba_check_socket_relabel, 2704106217Srwatson .mpo_check_socket_visible = mac_biba_check_socket_visible, 2705112574Srwatson .mpo_check_sysarch_ioperm = mac_biba_check_sysarch_ioperm, 2706106418Srwatson .mpo_check_system_acct = mac_biba_check_system_acct, 2707106418Srwatson .mpo_check_system_settime = mac_biba_check_system_settime, 2708106217Srwatson .mpo_check_system_swapon = mac_biba_check_system_swapon, 2709112574Srwatson .mpo_check_system_swapoff = mac_biba_check_system_swapoff, 2710106217Srwatson .mpo_check_system_sysctl = mac_biba_check_system_sysctl, 2711106217Srwatson .mpo_check_vnode_access = mac_biba_check_vnode_open, 2712106217Srwatson .mpo_check_vnode_chdir = mac_biba_check_vnode_chdir, 2713106217Srwatson .mpo_check_vnode_chroot = mac_biba_check_vnode_chroot, 2714106217Srwatson .mpo_check_vnode_create = mac_biba_check_vnode_create, 2715106217Srwatson .mpo_check_vnode_delete = mac_biba_check_vnode_delete, 2716106217Srwatson .mpo_check_vnode_deleteacl = mac_biba_check_vnode_deleteacl, 2717106217Srwatson .mpo_check_vnode_exec = mac_biba_check_vnode_exec, 2718106217Srwatson .mpo_check_vnode_getacl = mac_biba_check_vnode_getacl, 2719106217Srwatson .mpo_check_vnode_getextattr = mac_biba_check_vnode_getextattr, 2720106217Srwatson .mpo_check_vnode_link = mac_biba_check_vnode_link, 2721106217Srwatson .mpo_check_vnode_lookup = mac_biba_check_vnode_lookup, 2722106217Srwatson .mpo_check_vnode_mmap = mac_biba_check_vnode_mmap, 2723106217Srwatson .mpo_check_vnode_mprotect = mac_biba_check_vnode_mmap, 2724106217Srwatson .mpo_check_vnode_open = mac_biba_check_vnode_open, 2725106217Srwatson .mpo_check_vnode_poll = mac_biba_check_vnode_poll, 2726106217Srwatson .mpo_check_vnode_read = mac_biba_check_vnode_read, 2727106217Srwatson .mpo_check_vnode_readdir = mac_biba_check_vnode_readdir, 2728106217Srwatson .mpo_check_vnode_readlink = mac_biba_check_vnode_readlink, 2729106217Srwatson .mpo_check_vnode_relabel = mac_biba_check_vnode_relabel, 2730106217Srwatson .mpo_check_vnode_rename_from = mac_biba_check_vnode_rename_from, 2731106217Srwatson .mpo_check_vnode_rename_to = mac_biba_check_vnode_rename_to, 2732106217Srwatson .mpo_check_vnode_revoke = mac_biba_check_vnode_revoke, 2733106217Srwatson .mpo_check_vnode_setacl = mac_biba_check_vnode_setacl, 2734106217Srwatson .mpo_check_vnode_setextattr = mac_biba_check_vnode_setextattr, 2735106217Srwatson .mpo_check_vnode_setflags = mac_biba_check_vnode_setflags, 2736106217Srwatson .mpo_check_vnode_setmode = mac_biba_check_vnode_setmode, 2737106217Srwatson .mpo_check_vnode_setowner = mac_biba_check_vnode_setowner, 2738106217Srwatson .mpo_check_vnode_setutimes = mac_biba_check_vnode_setutimes, 2739106217Srwatson .mpo_check_vnode_stat = mac_biba_check_vnode_stat, 2740106217Srwatson .mpo_check_vnode_write = mac_biba_check_vnode_write, 2741101099Srwatson}; 2742101099Srwatson 2743112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 2744113531Srwatson MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mac_biba_slot); 2745