mac_biba.c revision 172955
1101099Srwatson/*- 2166533Srwatson * Copyright (c) 1999-2002, 2007 Robert N. M. Watson 3140628Srwatson * Copyright (c) 2001-2005 McAfee, Inc. 4172930Srwatson * Copyright (c) 2006 SPARTA, Inc. 5101099Srwatson * All rights reserved. 6101099Srwatson * 7101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 8101099Srwatson * 9140628Srwatson * This software was developed for the FreeBSD Project in part by McAfee 10140628Srwatson * Research, the Security Research Division of McAfee, Inc. under 11140628Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 12140628Srwatson * CHATS research program. 13101099Srwatson * 14172930Srwatson * This software was enhanced by SPARTA ISSO under SPAWAR contract 15172930Srwatson * N66001-04-C-6019 ("SEFOS"). 16172930Srwatson * 17101099Srwatson * Redistribution and use in source and binary forms, with or without 18101099Srwatson * modification, are permitted provided that the following conditions 19101099Srwatson * are met: 20101099Srwatson * 1. Redistributions of source code must retain the above copyright 21101099Srwatson * notice, this list of conditions and the following disclaimer. 22101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright 23101099Srwatson * notice, this list of conditions and the following disclaimer in the 24101099Srwatson * documentation and/or other materials provided with the distribution. 25101099Srwatson * 26101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 30101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36101099Srwatson * SUCH DAMAGE. 37101099Srwatson * 38101099Srwatson * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 172955 2007-10-25 11:31:11Z rwatson $ 39101099Srwatson */ 40101099Srwatson 41101099Srwatson/* 42101099Srwatson * Developed by the TrustedBSD Project. 43168951Srwatson * 44101099Srwatson * Biba fixed label mandatory integrity policy. 45101099Srwatson */ 46101099Srwatson 47101099Srwatson#include <sys/param.h> 48101099Srwatson#include <sys/conf.h> 49105988Srwatson#include <sys/extattr.h> 50101099Srwatson#include <sys/kernel.h> 51164184Strhodes#include <sys/ksem.h> 52103183Sbde#include <sys/malloc.h> 53145076Scsjp#include <sys/mman.h> 54101099Srwatson#include <sys/mount.h> 55168951Srwatson#include <sys/priv.h> 56101099Srwatson#include <sys/proc.h> 57115497Srwatson#include <sys/sbuf.h> 58101099Srwatson#include <sys/systm.h> 59101099Srwatson#include <sys/sysproto.h> 60101099Srwatson#include <sys/sysent.h> 61105696Srwatson#include <sys/systm.h> 62101099Srwatson#include <sys/vnode.h> 63101099Srwatson#include <sys/file.h> 64101099Srwatson#include <sys/socket.h> 65101099Srwatson#include <sys/socketvar.h> 66101099Srwatson#include <sys/pipe.h> 67150340Sphk#include <sys/sx.h> 68101099Srwatson#include <sys/sysctl.h> 69140628Srwatson#include <sys/msg.h> 70140628Srwatson#include <sys/sem.h> 71140628Srwatson#include <sys/shm.h> 72101099Srwatson 73101099Srwatson#include <fs/devfs/devfs.h> 74101099Srwatson 75101099Srwatson#include <net/bpfdesc.h> 76101099Srwatson#include <net/if.h> 77101099Srwatson#include <net/if_types.h> 78101099Srwatson#include <net/if_var.h> 79101099Srwatson 80101099Srwatson#include <netinet/in.h> 81122875Srwatson#include <netinet/in_pcb.h> 82101099Srwatson#include <netinet/ip_var.h> 83101099Srwatson 84122879Srwatson#include <vm/uma.h> 85101099Srwatson#include <vm/vm.h> 86101099Srwatson 87165469Srwatson#include <security/mac/mac_policy.h> 88101099Srwatson#include <security/mac_biba/mac_biba.h> 89101099Srwatson 90101099SrwatsonSYSCTL_DECL(_security_mac); 91101099Srwatson 92101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 93101099Srwatson "TrustedBSD mac_biba policy controls"); 94101099Srwatson 95172955Srwatsonstatic int biba_label_size = sizeof(struct mac_biba); 96105988SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 97172955Srwatson &biba_label_size, 0, "Size of struct mac_biba"); 98105988Srwatson 99172955Srwatsonstatic int biba_enabled = 1; 100172955SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, &biba_enabled, 101172955Srwatson 0, "Enforce MAC/Biba policy"); 102172955SrwatsonTUNABLE_INT("security.mac.biba.enabled", &biba_enabled); 103101099Srwatson 104101099Srwatsonstatic int destroyed_not_inited; 105101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 106101099Srwatson &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 107101099Srwatson 108101099Srwatsonstatic int trust_all_interfaces = 0; 109101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 110101099Srwatson &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 111101099SrwatsonTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 112101099Srwatson 113101099Srwatsonstatic char trusted_interfaces[128]; 114101099SrwatsonSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 115101099Srwatson trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 116101099SrwatsonTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 117101099Srwatson sizeof(trusted_interfaces)); 118101099Srwatson 119105643Srwatsonstatic int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 120105643SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 121105643Srwatson &max_compartments, 0, "Maximum supported compartments"); 122105643Srwatson 123105606Srwatsonstatic int ptys_equal = 0; 124105606SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 125105606Srwatson &ptys_equal, 0, "Label pty devices as biba/equal on create"); 126105606SrwatsonTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 127105606Srwatson 128153927Scsjpstatic int interfaces_equal; 129153927ScsjpSYSCTL_INT(_security_mac_biba, OID_AUTO, interfaces_equal, CTLFLAG_RW, 130153927Scsjp &interfaces_equal, 0, "Label network interfaces as biba/equal on create"); 131153927ScsjpTUNABLE_INT("security.mac.biba.interfaces_equal", &interfaces_equal); 132153927Scsjp 133105637Srwatsonstatic int revocation_enabled = 0; 134101099SrwatsonSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 135105637Srwatson &revocation_enabled, 0, "Revoke access to objects on relabel"); 136105637SrwatsonTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 137101099Srwatson 138172955Srwatsonstatic int biba_slot; 139172955Srwatson#define SLOT(l) ((struct mac_biba *)mac_label_get((l), biba_slot)) 140172955Srwatson#define SLOT_SET(l, val) mac_label_set((l), biba_slot, (uintptr_t)(val)) 141101099Srwatson 142122879Srwatsonstatic uma_zone_t zone_biba; 143101099Srwatson 144105643Srwatsonstatic __inline int 145105643Srwatsonbiba_bit_set_empty(u_char *set) { 146105643Srwatson int i; 147105643Srwatson 148105643Srwatson for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 149105643Srwatson if (set[i] != 0) 150105643Srwatson return (0); 151105643Srwatson return (1); 152105643Srwatson} 153105643Srwatson 154101099Srwatsonstatic struct mac_biba * 155104514Srwatsonbiba_alloc(int flag) 156101099Srwatson{ 157101099Srwatson 158122879Srwatson return (uma_zalloc(zone_biba, flag | M_ZERO)); 159101099Srwatson} 160101099Srwatson 161101099Srwatsonstatic void 162172955Srwatsonbiba_free(struct mac_biba *mb) 163101099Srwatson{ 164101099Srwatson 165172955Srwatson if (mb != NULL) 166172955Srwatson uma_zfree(zone_biba, mb); 167101099Srwatson else 168101099Srwatson atomic_add_int(&destroyed_not_inited, 1); 169101099Srwatson} 170101099Srwatson 171101099Srwatsonstatic int 172172955Srwatsonbiba_atmostflags(struct mac_biba *mb, int flags) 173105634Srwatson{ 174105634Srwatson 175172955Srwatson if ((mb->mb_flags & flags) != mb->mb_flags) 176105634Srwatson return (EINVAL); 177105634Srwatson return (0); 178105634Srwatson} 179105634Srwatson 180105634Srwatsonstatic int 181172955Srwatsonbiba_dominate_element(struct mac_biba_element *a, struct mac_biba_element *b) 182101099Srwatson{ 183105643Srwatson int bit; 184101099Srwatson 185105736Srwatson switch (a->mbe_type) { 186101099Srwatson case MAC_BIBA_TYPE_EQUAL: 187101099Srwatson case MAC_BIBA_TYPE_HIGH: 188101099Srwatson return (1); 189101099Srwatson 190101099Srwatson case MAC_BIBA_TYPE_LOW: 191101099Srwatson switch (b->mbe_type) { 192101099Srwatson case MAC_BIBA_TYPE_GRADE: 193101099Srwatson case MAC_BIBA_TYPE_HIGH: 194101099Srwatson return (0); 195101099Srwatson 196101099Srwatson case MAC_BIBA_TYPE_EQUAL: 197101099Srwatson case MAC_BIBA_TYPE_LOW: 198101099Srwatson return (1); 199101099Srwatson 200101099Srwatson default: 201172955Srwatson panic("biba_dominate_element: b->mbe_type invalid"); 202101099Srwatson } 203101099Srwatson 204101099Srwatson case MAC_BIBA_TYPE_GRADE: 205101099Srwatson switch (b->mbe_type) { 206101099Srwatson case MAC_BIBA_TYPE_EQUAL: 207101099Srwatson case MAC_BIBA_TYPE_LOW: 208101099Srwatson return (1); 209101099Srwatson 210101099Srwatson case MAC_BIBA_TYPE_HIGH: 211101099Srwatson return (0); 212101099Srwatson 213101099Srwatson case MAC_BIBA_TYPE_GRADE: 214105643Srwatson for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 215105643Srwatson if (!MAC_BIBA_BIT_TEST(bit, 216105643Srwatson a->mbe_compartments) && 217105643Srwatson MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 218105643Srwatson return (0); 219101099Srwatson return (a->mbe_grade >= b->mbe_grade); 220101099Srwatson 221101099Srwatson default: 222172955Srwatson panic("biba_dominate_element: b->mbe_type invalid"); 223101099Srwatson } 224101099Srwatson 225101099Srwatson default: 226172955Srwatson panic("biba_dominate_element: a->mbe_type invalid"); 227101099Srwatson } 228101099Srwatson 229101099Srwatson return (0); 230101099Srwatson} 231101099Srwatson 232101099Srwatsonstatic int 233172955Srwatsonbiba_subject_dominate_high(struct mac_biba *mb) 234105988Srwatson{ 235105988Srwatson struct mac_biba_element *element; 236105988Srwatson 237172955Srwatson KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 238172955Srwatson ("biba_effective_in_range: mb not effective")); 239172955Srwatson element = &mb->mb_effective; 240105988Srwatson 241105988Srwatson return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 242105988Srwatson element->mbe_type == MAC_BIBA_TYPE_HIGH); 243105988Srwatson} 244105988Srwatson 245105988Srwatsonstatic int 246172955Srwatsonbiba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 247101099Srwatson{ 248101099Srwatson 249172955Srwatson return (biba_dominate_element(&rangeb->mb_rangehigh, 250101099Srwatson &rangea->mb_rangehigh) && 251172955Srwatson biba_dominate_element(&rangea->mb_rangelow, 252101099Srwatson &rangeb->mb_rangelow)); 253101099Srwatson} 254101099Srwatson 255101099Srwatsonstatic int 256172955Srwatsonbiba_effective_in_range(struct mac_biba *effective, struct mac_biba *range) 257101099Srwatson{ 258101099Srwatson 259132232Srwatson KASSERT((effective->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 260172955Srwatson ("biba_effective_in_range: a not effective")); 261103750Srwatson KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 262172955Srwatson ("biba_effective_in_range: b not range")); 263101099Srwatson 264172955Srwatson return (biba_dominate_element(&range->mb_rangehigh, 265132232Srwatson &effective->mb_effective) && 266172955Srwatson biba_dominate_element(&effective->mb_effective, 267101099Srwatson &range->mb_rangelow)); 268101099Srwatson 269101099Srwatson return (1); 270101099Srwatson} 271101099Srwatson 272101099Srwatsonstatic int 273172955Srwatsonbiba_dominate_effective(struct mac_biba *a, struct mac_biba *b) 274101099Srwatson{ 275132232Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 276172955Srwatson ("biba_dominate_effective: a not effective")); 277132232Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 278172955Srwatson ("biba_dominate_effective: b not effective")); 279101099Srwatson 280172955Srwatson return (biba_dominate_element(&a->mb_effective, &b->mb_effective)); 281101099Srwatson} 282101099Srwatson 283101099Srwatsonstatic int 284172955Srwatsonbiba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 285101099Srwatson{ 286101099Srwatson 287101099Srwatson if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 288101099Srwatson b->mbe_type == MAC_BIBA_TYPE_EQUAL) 289101099Srwatson return (1); 290101099Srwatson 291101099Srwatson return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 292101099Srwatson} 293101099Srwatson 294101099Srwatsonstatic int 295172955Srwatsonbiba_equal_effective(struct mac_biba *a, struct mac_biba *b) 296101099Srwatson{ 297101099Srwatson 298132232Srwatson KASSERT((a->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 299172955Srwatson ("biba_equal_effective: a not effective")); 300132232Srwatson KASSERT((b->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 301172955Srwatson ("biba_equal_effective: b not effective")); 302101099Srwatson 303172955Srwatson return (biba_equal_element(&a->mb_effective, &b->mb_effective)); 304101099Srwatson} 305101099Srwatson 306101099Srwatsonstatic int 307172955Srwatsonbiba_contains_equal(struct mac_biba *mb) 308105634Srwatson{ 309105634Srwatson 310172955Srwatson if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 311172955Srwatson if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 312105634Srwatson return (1); 313172955Srwatson } 314105634Srwatson 315172955Srwatson if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 316172955Srwatson if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 317105634Srwatson return (1); 318172955Srwatson if (mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 319105637Srwatson return (1); 320105634Srwatson } 321105634Srwatson 322105634Srwatson return (0); 323105634Srwatson} 324105634Srwatson 325105634Srwatsonstatic int 326172955Srwatsonbiba_subject_privileged(struct mac_biba *mb) 327105634Srwatson{ 328105634Srwatson 329172955Srwatson KASSERT((mb->mb_flags & MAC_BIBA_FLAGS_BOTH) == MAC_BIBA_FLAGS_BOTH, 330172955Srwatson ("biba_subject_privileged: subject doesn't have both labels")); 331105634Srwatson 332132232Srwatson /* If the effective is EQUAL, it's ok. */ 333172955Srwatson if (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_EQUAL) 334105634Srwatson return (0); 335105634Srwatson 336105634Srwatson /* If either range endpoint is EQUAL, it's ok. */ 337172955Srwatson if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 338172955Srwatson mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 339105634Srwatson return (0); 340105634Srwatson 341105634Srwatson /* If the range is low-high, it's ok. */ 342172955Srwatson if (mb->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 343172955Srwatson mb->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 344105634Srwatson return (0); 345105634Srwatson 346105634Srwatson /* It's not ok. */ 347105634Srwatson return (EPERM); 348105634Srwatson} 349105634Srwatson 350106091Srwatsonstatic int 351172955Srwatsonbiba_high_effective(struct mac_biba *mb) 352105988Srwatson{ 353105988Srwatson 354172955Srwatson KASSERT((mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 355172955Srwatson ("biba_equal_effective: mb not effective")); 356105988Srwatson 357172955Srwatson return (mb->mb_effective.mbe_type == MAC_BIBA_TYPE_HIGH); 358105988Srwatson} 359105988Srwatson 360105634Srwatsonstatic int 361172955Srwatsonbiba_valid(struct mac_biba *mb) 362101099Srwatson{ 363101099Srwatson 364172955Srwatson if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 365172955Srwatson switch (mb->mb_effective.mbe_type) { 366101099Srwatson case MAC_BIBA_TYPE_GRADE: 367101099Srwatson break; 368101099Srwatson 369101099Srwatson case MAC_BIBA_TYPE_EQUAL: 370101099Srwatson case MAC_BIBA_TYPE_HIGH: 371101099Srwatson case MAC_BIBA_TYPE_LOW: 372172955Srwatson if (mb->mb_effective.mbe_grade != 0 || 373105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 374172955Srwatson mb->mb_effective.mbe_compartments)) 375101099Srwatson return (EINVAL); 376101099Srwatson break; 377101099Srwatson 378101099Srwatson default: 379101099Srwatson return (EINVAL); 380101099Srwatson } 381101099Srwatson } else { 382172955Srwatson if (mb->mb_effective.mbe_type != MAC_BIBA_TYPE_UNDEF) 383101099Srwatson return (EINVAL); 384101099Srwatson } 385101099Srwatson 386172955Srwatson if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 387172955Srwatson switch (mb->mb_rangelow.mbe_type) { 388101099Srwatson case MAC_BIBA_TYPE_GRADE: 389101099Srwatson break; 390101099Srwatson 391101099Srwatson case MAC_BIBA_TYPE_EQUAL: 392101099Srwatson case MAC_BIBA_TYPE_HIGH: 393101099Srwatson case MAC_BIBA_TYPE_LOW: 394172955Srwatson if (mb->mb_rangelow.mbe_grade != 0 || 395105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 396172955Srwatson mb->mb_rangelow.mbe_compartments)) 397101099Srwatson return (EINVAL); 398101099Srwatson break; 399101099Srwatson 400101099Srwatson default: 401101099Srwatson return (EINVAL); 402101099Srwatson } 403101099Srwatson 404172955Srwatson switch (mb->mb_rangehigh.mbe_type) { 405101099Srwatson case MAC_BIBA_TYPE_GRADE: 406101099Srwatson break; 407101099Srwatson 408101099Srwatson case MAC_BIBA_TYPE_EQUAL: 409101099Srwatson case MAC_BIBA_TYPE_HIGH: 410101099Srwatson case MAC_BIBA_TYPE_LOW: 411172955Srwatson if (mb->mb_rangehigh.mbe_grade != 0 || 412105643Srwatson !MAC_BIBA_BIT_SET_EMPTY( 413172955Srwatson mb->mb_rangehigh.mbe_compartments)) 414101099Srwatson return (EINVAL); 415101099Srwatson break; 416101099Srwatson 417101099Srwatson default: 418101099Srwatson return (EINVAL); 419101099Srwatson } 420172955Srwatson if (!biba_dominate_element(&mb->mb_rangehigh, 421172955Srwatson &mb->mb_rangelow)) 422101099Srwatson return (EINVAL); 423101099Srwatson } else { 424172955Srwatson if (mb->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 425172955Srwatson mb->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 426101099Srwatson return (EINVAL); 427101099Srwatson } 428101099Srwatson 429101099Srwatson return (0); 430101099Srwatson} 431101099Srwatson 432101099Srwatsonstatic void 433172955Srwatsonbiba_set_range(struct mac_biba *mb, u_short typelow, u_short gradelow, 434172955Srwatson u_char *compartmentslow, u_short typehigh, u_short gradehigh, 435172955Srwatson u_char *compartmentshigh) 436101099Srwatson{ 437101099Srwatson 438172955Srwatson mb->mb_rangelow.mbe_type = typelow; 439172955Srwatson mb->mb_rangelow.mbe_grade = gradelow; 440105643Srwatson if (compartmentslow != NULL) 441172955Srwatson memcpy(mb->mb_rangelow.mbe_compartments, compartmentslow, 442172955Srwatson sizeof(mb->mb_rangelow.mbe_compartments)); 443172955Srwatson mb->mb_rangehigh.mbe_type = typehigh; 444172955Srwatson mb->mb_rangehigh.mbe_grade = gradehigh; 445105643Srwatson if (compartmentshigh != NULL) 446172955Srwatson memcpy(mb->mb_rangehigh.mbe_compartments, compartmentshigh, 447172955Srwatson sizeof(mb->mb_rangehigh.mbe_compartments)); 448172955Srwatson mb->mb_flags |= MAC_BIBA_FLAG_RANGE; 449101099Srwatson} 450101099Srwatson 451101099Srwatsonstatic void 452172955Srwatsonbiba_set_effective(struct mac_biba *mb, u_short type, u_short grade, 453105643Srwatson u_char *compartments) 454101099Srwatson{ 455101099Srwatson 456172955Srwatson mb->mb_effective.mbe_type = type; 457172955Srwatson mb->mb_effective.mbe_grade = grade; 458105643Srwatson if (compartments != NULL) 459172955Srwatson memcpy(mb->mb_effective.mbe_compartments, compartments, 460172955Srwatson sizeof(mb->mb_effective.mbe_compartments)); 461172955Srwatson mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 462101099Srwatson} 463101099Srwatson 464101099Srwatsonstatic void 465172955Srwatsonbiba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 466101099Srwatson{ 467105643Srwatson 468101099Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 469172955Srwatson ("biba_copy_range: labelfrom not range")); 470101099Srwatson 471101099Srwatson labelto->mb_rangelow = labelfrom->mb_rangelow; 472101099Srwatson labelto->mb_rangehigh = labelfrom->mb_rangehigh; 473101099Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 474101099Srwatson} 475101099Srwatson 476101099Srwatsonstatic void 477172955Srwatsonbiba_copy_effective(struct mac_biba *labelfrom, struct mac_biba *labelto) 478101099Srwatson{ 479101099Srwatson 480132232Srwatson KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) != 0, 481172955Srwatson ("biba_copy_effective: labelfrom not effective")); 482101099Srwatson 483132232Srwatson labelto->mb_effective = labelfrom->mb_effective; 484132232Srwatson labelto->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 485101099Srwatson} 486101099Srwatson 487105656Srwatsonstatic void 488172955Srwatsonbiba_copy(struct mac_biba *source, struct mac_biba *dest) 489105656Srwatson{ 490105656Srwatson 491132232Srwatson if (source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) 492172955Srwatson biba_copy_effective(source, dest); 493105656Srwatson if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 494172955Srwatson biba_copy_range(source, dest); 495105656Srwatson} 496105656Srwatson 497101099Srwatson/* 498101099Srwatson * Policy module operations. 499101099Srwatson */ 500101099Srwatsonstatic void 501172955Srwatsonbiba_init(struct mac_policy_conf *conf) 502101099Srwatson{ 503101099Srwatson 504122879Srwatson zone_biba = uma_zcreate("mac_biba", sizeof(struct mac_biba), NULL, 505122879Srwatson NULL, NULL, NULL, UMA_ALIGN_PTR, 0); 506101099Srwatson} 507101099Srwatson 508101099Srwatson/* 509101099Srwatson * Label operations. 510101099Srwatson */ 511101099Srwatsonstatic void 512172955Srwatsonbiba_init_label(struct label *label) 513101099Srwatson{ 514101099Srwatson 515132781Skan SLOT_SET(label, biba_alloc(M_WAITOK)); 516101099Srwatson} 517101099Srwatson 518101099Srwatsonstatic int 519172955Srwatsonbiba_init_label_waitcheck(struct label *label, int flag) 520101099Srwatson{ 521101099Srwatson 522132781Skan SLOT_SET(label, biba_alloc(flag)); 523101099Srwatson if (SLOT(label) == NULL) 524101099Srwatson return (ENOMEM); 525101099Srwatson 526101099Srwatson return (0); 527101099Srwatson} 528101099Srwatson 529101099Srwatsonstatic void 530172955Srwatsonbiba_destroy_label(struct label *label) 531101099Srwatson{ 532101099Srwatson 533101099Srwatson biba_free(SLOT(label)); 534132781Skan SLOT_SET(label, NULL); 535101099Srwatson} 536101099Srwatson 537105696Srwatson/* 538172955Srwatson * biba_element_to_string() accepts an sbuf and Biba element. It converts 539172955Srwatson * the Biba element to a string and stores the result in the sbuf; if there 540172955Srwatson * isn't space in the sbuf, -1 is returned. 541105696Srwatson */ 542115497Srwatsonstatic int 543172955Srwatsonbiba_element_to_string(struct sbuf *sb, struct mac_biba_element *element) 544105696Srwatson{ 545115497Srwatson int i, first; 546105696Srwatson 547105696Srwatson switch (element->mbe_type) { 548105696Srwatson case MAC_BIBA_TYPE_HIGH: 549115497Srwatson return (sbuf_printf(sb, "high")); 550105696Srwatson 551105696Srwatson case MAC_BIBA_TYPE_LOW: 552115497Srwatson return (sbuf_printf(sb, "low")); 553105696Srwatson 554105696Srwatson case MAC_BIBA_TYPE_EQUAL: 555115497Srwatson return (sbuf_printf(sb, "equal")); 556105696Srwatson 557105696Srwatson case MAC_BIBA_TYPE_GRADE: 558115497Srwatson if (sbuf_printf(sb, "%d", element->mbe_grade) == -1) 559115497Srwatson return (-1); 560115497Srwatson 561115497Srwatson first = 1; 562115497Srwatson for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) { 563115497Srwatson if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) { 564115497Srwatson if (first) { 565115497Srwatson if (sbuf_putc(sb, ':') == -1) 566115497Srwatson return (-1); 567115497Srwatson if (sbuf_printf(sb, "%d", i) == -1) 568115497Srwatson return (-1); 569115497Srwatson first = 0; 570115497Srwatson } else { 571115497Srwatson if (sbuf_printf(sb, "+%d", i) == -1) 572115497Srwatson return (-1); 573115497Srwatson } 574115497Srwatson } 575105696Srwatson } 576115497Srwatson return (0); 577105696Srwatson 578105696Srwatson default: 579172955Srwatson panic("biba_element_to_string: invalid type (%d)", 580105696Srwatson element->mbe_type); 581105696Srwatson } 582105696Srwatson} 583105696Srwatson 584115497Srwatson/* 585172955Srwatson * biba_to_string() converts a Biba label to a string, and places the results 586172955Srwatson * in the passed sbuf. It returns 0 on success, or EINVAL if there isn't 587172955Srwatson * room in the sbuf. Note: the sbuf will be modified even in a failure case, 588172955Srwatson * so the caller may need to revert the sbuf by restoring the offset if 589172955Srwatson * that's undesired. 590115497Srwatson */ 591101099Srwatsonstatic int 592172955Srwatsonbiba_to_string(struct sbuf *sb, struct mac_biba *mb) 593101099Srwatson{ 594105696Srwatson 595172955Srwatson if (mb->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 596172955Srwatson if (biba_element_to_string(sb, &mb->mb_effective) == -1) 597105696Srwatson return (EINVAL); 598105696Srwatson } 599105696Srwatson 600172955Srwatson if (mb->mb_flags & MAC_BIBA_FLAG_RANGE) { 601116701Srwatson if (sbuf_putc(sb, '(') == -1) 602105696Srwatson return (EINVAL); 603105696Srwatson 604172955Srwatson if (biba_element_to_string(sb, &mb->mb_rangelow) == -1) 605105696Srwatson return (EINVAL); 606105696Srwatson 607116701Srwatson if (sbuf_putc(sb, '-') == -1) 608105696Srwatson return (EINVAL); 609105696Srwatson 610172955Srwatson if (biba_element_to_string(sb, &mb->mb_rangehigh) == -1) 611105696Srwatson return (EINVAL); 612105696Srwatson 613116701Srwatson if (sbuf_putc(sb, ')') == -1) 614105696Srwatson return (EINVAL); 615105696Srwatson } 616105696Srwatson 617105696Srwatson return (0); 618105696Srwatson} 619105696Srwatson 620105696Srwatsonstatic int 621172955Srwatsonbiba_externalize_label(struct label *label, char *element_name, 622116701Srwatson struct sbuf *sb, int *claimed) 623105696Srwatson{ 624172955Srwatson struct mac_biba *mb; 625101099Srwatson 626105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 627105696Srwatson return (0); 628105696Srwatson 629105696Srwatson (*claimed)++; 630105696Srwatson 631172955Srwatson mb = SLOT(label); 632172955Srwatson return (biba_to_string(sb, mb)); 633105696Srwatson} 634105696Srwatson 635105696Srwatsonstatic int 636172955Srwatsonbiba_parse_element(struct mac_biba_element *element, char *string) 637101099Srwatson{ 638115395Srwatson char *compartment, *end, *grade; 639115395Srwatson int value; 640105696Srwatson 641105696Srwatson if (strcmp(string, "high") == 0 || 642105696Srwatson strcmp(string, "hi") == 0) { 643105696Srwatson element->mbe_type = MAC_BIBA_TYPE_HIGH; 644105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 645105696Srwatson } else if (strcmp(string, "low") == 0 || 646105696Srwatson strcmp(string, "lo") == 0) { 647105696Srwatson element->mbe_type = MAC_BIBA_TYPE_LOW; 648105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 649105696Srwatson } else if (strcmp(string, "equal") == 0 || 650105696Srwatson strcmp(string, "eq") == 0) { 651105696Srwatson element->mbe_type = MAC_BIBA_TYPE_EQUAL; 652105696Srwatson element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 653105696Srwatson } else { 654115395Srwatson element->mbe_type = MAC_BIBA_TYPE_GRADE; 655105696Srwatson 656115395Srwatson /* 657115395Srwatson * Numeric grade piece of the element. 658115395Srwatson */ 659115395Srwatson grade = strsep(&string, ":"); 660115395Srwatson value = strtol(grade, &end, 10); 661115395Srwatson if (end == grade || *end != '\0') 662105696Srwatson return (EINVAL); 663115395Srwatson if (value < 0 || value > 65535) 664115395Srwatson return (EINVAL); 665115395Srwatson element->mbe_grade = value; 666105696Srwatson 667115395Srwatson /* 668115395Srwatson * Optional compartment piece of the element. If none 669115395Srwatson * are included, we assume that the label has no 670115395Srwatson * compartments. 671115395Srwatson */ 672115395Srwatson if (string == NULL) 673115395Srwatson return (0); 674115395Srwatson if (*string == '\0') 675115395Srwatson return (0); 676105696Srwatson 677115395Srwatson while ((compartment = strsep(&string, "+")) != NULL) { 678115395Srwatson value = strtol(compartment, &end, 10); 679115395Srwatson if (compartment == end || *end != '\0') 680105696Srwatson return (EINVAL); 681115395Srwatson if (value < 1 || value > MAC_BIBA_MAX_COMPARTMENTS) 682105696Srwatson return (EINVAL); 683115395Srwatson MAC_BIBA_BIT_SET(value, element->mbe_compartments); 684105696Srwatson } 685105696Srwatson } 686105696Srwatson 687105696Srwatson return (0); 688105696Srwatson} 689105696Srwatson 690105696Srwatson/* 691105696Srwatson * Note: destructively consumes the string, make a local copy before 692105696Srwatson * calling if that's a problem. 693105696Srwatson */ 694105696Srwatsonstatic int 695172955Srwatsonbiba_parse(struct mac_biba *mb, char *string) 696105696Srwatson{ 697132232Srwatson char *rangehigh, *rangelow, *effective; 698101099Srwatson int error; 699101099Srwatson 700132232Srwatson effective = strsep(&string, "("); 701132232Srwatson if (*effective == '\0') 702132232Srwatson effective = NULL; 703115395Srwatson 704115395Srwatson if (string != NULL) { 705115395Srwatson rangelow = strsep(&string, "-"); 706115395Srwatson if (string == NULL) 707105696Srwatson return (EINVAL); 708115395Srwatson rangehigh = strsep(&string, ")"); 709115395Srwatson if (string == NULL) 710105696Srwatson return (EINVAL); 711115395Srwatson if (*string != '\0') 712105696Srwatson return (EINVAL); 713115395Srwatson } else { 714115395Srwatson rangelow = NULL; 715115395Srwatson rangehigh = NULL; 716105696Srwatson } 717115395Srwatson 718105696Srwatson KASSERT((rangelow != NULL && rangehigh != NULL) || 719105696Srwatson (rangelow == NULL && rangehigh == NULL), 720172955Srwatson ("biba_parse: range mismatch")); 721101099Srwatson 722172955Srwatson bzero(mb, sizeof(*mb)); 723132232Srwatson if (effective != NULL) { 724172955Srwatson error = biba_parse_element(&mb->mb_effective, effective); 725105696Srwatson if (error) 726105696Srwatson return (error); 727172955Srwatson mb->mb_flags |= MAC_BIBA_FLAG_EFFECTIVE; 728105696Srwatson } 729105696Srwatson 730105696Srwatson if (rangelow != NULL) { 731172955Srwatson error = biba_parse_element(&mb->mb_rangelow, rangelow); 732105696Srwatson if (error) 733105696Srwatson return (error); 734172955Srwatson error = biba_parse_element(&mb->mb_rangehigh, rangehigh); 735105696Srwatson if (error) 736105696Srwatson return (error); 737172955Srwatson mb->mb_flags |= MAC_BIBA_FLAG_RANGE; 738105696Srwatson } 739105696Srwatson 740172955Srwatson error = biba_valid(mb); 741101099Srwatson if (error) 742101099Srwatson return (error); 743101099Srwatson 744105696Srwatson return (0); 745105696Srwatson} 746101099Srwatson 747105696Srwatsonstatic int 748172955Srwatsonbiba_internalize_label(struct label *label, char *element_name, 749105696Srwatson char *element_data, int *claimed) 750105696Srwatson{ 751172955Srwatson struct mac_biba *mb, mb_temp; 752105696Srwatson int error; 753105696Srwatson 754105696Srwatson if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 755105696Srwatson return (0); 756105696Srwatson 757105696Srwatson (*claimed)++; 758105696Srwatson 759172955Srwatson error = biba_parse(&mb_temp, element_data); 760105696Srwatson if (error) 761105696Srwatson return (error); 762105696Srwatson 763172955Srwatson mb = SLOT(label); 764172955Srwatson *mb = mb_temp; 765105696Srwatson 766101099Srwatson return (0); 767101099Srwatson} 768101099Srwatson 769105696Srwatsonstatic void 770172955Srwatsonbiba_copy_label(struct label *src, struct label *dest) 771105696Srwatson{ 772105696Srwatson 773105696Srwatson *SLOT(dest) = *SLOT(src); 774105696Srwatson} 775105696Srwatson 776101099Srwatson/* 777172955Srwatson * Labeling event operations: file system objects, and things that look a lot 778172955Srwatson * like file system objects. 779101099Srwatson */ 780101099Srwatsonstatic void 781172955Srwatsonbiba_devfs_create_device(struct ucred *cred, struct mount *mp, 782168976Srwatson struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 783101099Srwatson{ 784172955Srwatson struct mac_biba *mb; 785101099Srwatson int biba_type; 786101099Srwatson 787172955Srwatson mb = SLOT(delabel); 788101099Srwatson if (strcmp(dev->si_name, "null") == 0 || 789101099Srwatson strcmp(dev->si_name, "zero") == 0 || 790101099Srwatson strcmp(dev->si_name, "random") == 0 || 791101099Srwatson strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 792101099Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 793105606Srwatson else if (ptys_equal && 794105606Srwatson (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 795105606Srwatson strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 796105606Srwatson biba_type = MAC_BIBA_TYPE_EQUAL; 797101099Srwatson else 798101099Srwatson biba_type = MAC_BIBA_TYPE_HIGH; 799172955Srwatson biba_set_effective(mb, biba_type, 0, NULL); 800101099Srwatson} 801101099Srwatson 802101099Srwatsonstatic void 803172955Srwatsonbiba_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 804172955Srwatson struct devfs_dirent *de, struct label *delabel) 805101099Srwatson{ 806172955Srwatson struct mac_biba *mb; 807101099Srwatson 808172955Srwatson mb = SLOT(delabel); 809172955Srwatson 810172955Srwatson biba_set_effective(mb, MAC_BIBA_TYPE_HIGH, 0, NULL); 811101099Srwatson} 812101099Srwatson 813101099Srwatsonstatic void 814172955Srwatsonbiba_devfs_create_symlink(struct ucred *cred, struct mount *mp, 815107698Srwatson struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 816122563Srwatson struct label *delabel) 817104535Srwatson{ 818104535Srwatson struct mac_biba *source, *dest; 819104535Srwatson 820122524Srwatson source = SLOT(cred->cr_label); 821104535Srwatson dest = SLOT(delabel); 822104535Srwatson 823172955Srwatson biba_copy_effective(source, dest); 824104535Srwatson} 825104535Srwatson 826104535Srwatsonstatic void 827172955Srwatsonbiba_mount_create(struct ucred *cred, struct mount *mp, 828168976Srwatson struct label *mplabel) 829101099Srwatson{ 830101099Srwatson struct mac_biba *source, *dest; 831101099Srwatson 832122524Srwatson source = SLOT(cred->cr_label); 833168976Srwatson dest = SLOT(mplabel); 834172955Srwatson 835172955Srwatson biba_copy_effective(source, dest); 836101099Srwatson} 837101099Srwatson 838101099Srwatsonstatic void 839172955Srwatsonbiba_vnode_relabel(struct ucred *cred, struct vnode *vp, 840168976Srwatson struct label *vplabel, struct label *newlabel) 841101099Srwatson{ 842101099Srwatson struct mac_biba *source, *dest; 843101099Srwatson 844168976Srwatson source = SLOT(newlabel); 845168976Srwatson dest = SLOT(vplabel); 846101099Srwatson 847172955Srwatson biba_copy(source, dest); 848101099Srwatson} 849101099Srwatson 850101099Srwatsonstatic void 851172955Srwatsonbiba_devfs_update(struct mount *mp, struct devfs_dirent *de, 852168976Srwatson struct label *delabel, struct vnode *vp, struct label *vplabel) 853101099Srwatson{ 854101099Srwatson struct mac_biba *source, *dest; 855101099Srwatson 856168976Srwatson source = SLOT(vplabel); 857168976Srwatson dest = SLOT(delabel); 858101099Srwatson 859172955Srwatson biba_copy(source, dest); 860101099Srwatson} 861101099Srwatson 862101099Srwatsonstatic void 863172955Srwatsonbiba_devfs_vnode_associate(struct mount *mp, struct label *mntlabel, 864105988Srwatson struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 865168976Srwatson struct label *vplabel) 866101099Srwatson{ 867101099Srwatson struct mac_biba *source, *dest; 868101099Srwatson 869105988Srwatson source = SLOT(delabel); 870168976Srwatson dest = SLOT(vplabel); 871101099Srwatson 872172955Srwatson biba_copy_effective(source, dest); 873101099Srwatson} 874101099Srwatson 875101099Srwatsonstatic int 876172955Srwatsonbiba_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 877168976Srwatson struct vnode *vp, struct label *vplabel) 878101099Srwatson{ 879172955Srwatson struct mac_biba mb_temp, *source, *dest; 880106354Smux int buflen, error; 881101099Srwatson 882168976Srwatson source = SLOT(mplabel); 883168976Srwatson dest = SLOT(vplabel); 884101099Srwatson 885172955Srwatson buflen = sizeof(mb_temp); 886172955Srwatson bzero(&mb_temp, buflen); 887105988Srwatson 888105988Srwatson error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 889172955Srwatson MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &mb_temp, curthread); 890105988Srwatson if (error == ENOATTR || error == EOPNOTSUPP) { 891168954Srwatson /* Fall back to the mntlabel. */ 892172955Srwatson biba_copy_effective(source, dest); 893105988Srwatson return (0); 894105988Srwatson } else if (error) 895101099Srwatson return (error); 896101099Srwatson 897172955Srwatson if (buflen != sizeof(mb_temp)) { 898172955Srwatson printf("biba_vnode_associate_extattr: bad size %d\n", 899105988Srwatson buflen); 900105988Srwatson return (EPERM); 901105988Srwatson } 902172955Srwatson if (biba_valid(&mb_temp) != 0) { 903172955Srwatson printf("biba_vnode_associate_extattr: invalid\n"); 904105988Srwatson return (EPERM); 905105988Srwatson } 906172955Srwatson if ((mb_temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != 907172955Srwatson MAC_BIBA_FLAG_EFFECTIVE) { 908172955Srwatson printf("biba_vnode_associate_extattr: not effective\n"); 909105988Srwatson return (EPERM); 910105988Srwatson } 911101099Srwatson 912172955Srwatson biba_copy_effective(&mb_temp, dest); 913101099Srwatson return (0); 914101099Srwatson} 915101099Srwatson 916101099Srwatsonstatic void 917172955Srwatsonbiba_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 918172955Srwatson struct vnode *vp, struct label *vplabel) 919101099Srwatson{ 920101099Srwatson struct mac_biba *source, *dest; 921101099Srwatson 922168976Srwatson source = SLOT(mplabel); 923168976Srwatson dest = SLOT(vplabel); 924101099Srwatson 925172955Srwatson biba_copy_effective(source, dest); 926101099Srwatson} 927101099Srwatson 928105988Srwatsonstatic int 929172955Srwatsonbiba_vnode_create_extattr(struct ucred *cred, struct mount *mp, 930168976Srwatson struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 931168976Srwatson struct vnode *vp, struct label *vplabel, struct componentname *cnp) 932105988Srwatson{ 933172955Srwatson struct mac_biba *source, *dest, mb_temp; 934105988Srwatson size_t buflen; 935105988Srwatson int error; 936105988Srwatson 937172955Srwatson buflen = sizeof(mb_temp); 938172955Srwatson bzero(&mb_temp, buflen); 939105988Srwatson 940122524Srwatson source = SLOT(cred->cr_label); 941168976Srwatson dest = SLOT(vplabel); 942172955Srwatson biba_copy_effective(source, &mb_temp); 943105988Srwatson 944105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 945172955Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread); 946105988Srwatson if (error == 0) 947172955Srwatson biba_copy_effective(source, dest); 948105988Srwatson return (error); 949105988Srwatson} 950105988Srwatson 951105988Srwatsonstatic int 952172955Srwatsonbiba_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 953168976Srwatson struct label *vplabel, struct label *intlabel) 954105988Srwatson{ 955172955Srwatson struct mac_biba *source, mb_temp; 956105988Srwatson size_t buflen; 957105988Srwatson int error; 958105988Srwatson 959172955Srwatson buflen = sizeof(mb_temp); 960172955Srwatson bzero(&mb_temp, buflen); 961105988Srwatson 962105988Srwatson source = SLOT(intlabel); 963132232Srwatson if ((source->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) == 0) 964105988Srwatson return (0); 965105988Srwatson 966172955Srwatson biba_copy_effective(source, &mb_temp); 967105988Srwatson 968105988Srwatson error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 969172955Srwatson MAC_BIBA_EXTATTR_NAME, buflen, (char *) &mb_temp, curthread); 970105988Srwatson return (error); 971105988Srwatson} 972105988Srwatson 973101099Srwatson/* 974101099Srwatson * Labeling event operations: IPC object. 975101099Srwatson */ 976101099Srwatsonstatic void 977172955Srwatsonbiba_inpcb_create(struct socket *so, struct label *solabel, 978122875Srwatson struct inpcb *inp, struct label *inplabel) 979122875Srwatson{ 980122875Srwatson struct mac_biba *source, *dest; 981122875Srwatson 982122875Srwatson source = SLOT(solabel); 983122875Srwatson dest = SLOT(inplabel); 984122875Srwatson 985172955Srwatson biba_copy_effective(source, dest); 986122875Srwatson} 987122875Srwatson 988122875Srwatsonstatic void 989172955Srwatsonbiba_socket_create_mbuf(struct socket *so, struct label *solabel, 990168976Srwatson struct mbuf *m, struct label *mlabel) 991101099Srwatson{ 992101099Srwatson struct mac_biba *source, *dest; 993101099Srwatson 994168976Srwatson source = SLOT(solabel); 995168976Srwatson dest = SLOT(mlabel); 996101099Srwatson 997172955Srwatson biba_copy_effective(source, dest); 998101099Srwatson} 999101099Srwatson 1000101099Srwatsonstatic void 1001172955Srwatsonbiba_socket_create(struct ucred *cred, struct socket *so, 1002168976Srwatson struct label *solabel) 1003101099Srwatson{ 1004101099Srwatson struct mac_biba *source, *dest; 1005101099Srwatson 1006122524Srwatson source = SLOT(cred->cr_label); 1007168976Srwatson dest = SLOT(solabel); 1008101099Srwatson 1009172955Srwatson biba_copy_effective(source, dest); 1010101099Srwatson} 1011101099Srwatson 1012101099Srwatsonstatic void 1013172955Srwatsonbiba_pipe_create(struct ucred *cred, struct pipepair *pp, 1014168976Srwatson struct label *pplabel) 1015101099Srwatson{ 1016101099Srwatson struct mac_biba *source, *dest; 1017101099Srwatson 1018122524Srwatson source = SLOT(cred->cr_label); 1019168976Srwatson dest = SLOT(pplabel); 1020101099Srwatson 1021172955Srwatson biba_copy_effective(source, dest); 1022101099Srwatson} 1023101099Srwatson 1024101099Srwatsonstatic void 1025172955Srwatsonbiba_posixsem_create(struct ucred *cred, struct ksem *ks, 1026172850Srwatson struct label *kslabel) 1027145855Srwatson{ 1028145855Srwatson struct mac_biba *source, *dest; 1029145855Srwatson 1030145855Srwatson source = SLOT(cred->cr_label); 1031172850Srwatson dest = SLOT(kslabel); 1032145855Srwatson 1033172955Srwatson biba_copy_effective(source, dest); 1034145855Srwatson} 1035145855Srwatson 1036145855Srwatsonstatic void 1037172955Srwatsonbiba_socket_newconn(struct socket *oldso, struct label *oldsolabel, 1038172930Srwatson struct socket *newso, struct label *newsolabel) 1039101099Srwatson{ 1040101099Srwatson struct mac_biba *source, *dest; 1041101099Srwatson 1042168976Srwatson source = SLOT(oldsolabel); 1043168976Srwatson dest = SLOT(newsolabel); 1044101099Srwatson 1045172955Srwatson biba_copy_effective(source, dest); 1046101099Srwatson} 1047101099Srwatson 1048101099Srwatsonstatic void 1049172955Srwatsonbiba_socket_relabel(struct ucred *cred, struct socket *so, 1050168976Srwatson struct label *solabel, struct label *newlabel) 1051101099Srwatson{ 1052101099Srwatson struct mac_biba *source, *dest; 1053101099Srwatson 1054101099Srwatson source = SLOT(newlabel); 1055168976Srwatson dest = SLOT(solabel); 1056101099Srwatson 1057172955Srwatson biba_copy(source, dest); 1058101099Srwatson} 1059101099Srwatson 1060101099Srwatsonstatic void 1061172955Srwatsonbiba_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1062168976Srwatson struct label *pplabel, struct label *newlabel) 1063101099Srwatson{ 1064101099Srwatson struct mac_biba *source, *dest; 1065101099Srwatson 1066101099Srwatson source = SLOT(newlabel); 1067168976Srwatson dest = SLOT(pplabel); 1068101099Srwatson 1069172955Srwatson biba_copy(source, dest); 1070101099Srwatson} 1071101099Srwatson 1072101099Srwatsonstatic void 1073172955Srwatsonbiba_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 1074168976Srwatson struct socket *so, struct label *sopeerlabel) 1075101099Srwatson{ 1076101099Srwatson struct mac_biba *source, *dest; 1077101099Srwatson 1078168976Srwatson source = SLOT(mlabel); 1079168976Srwatson dest = SLOT(sopeerlabel); 1080101099Srwatson 1081172955Srwatson biba_copy_effective(source, dest); 1082101099Srwatson} 1083101099Srwatson 1084101099Srwatson/* 1085140628Srwatson * Labeling event operations: System V IPC objects. 1086140628Srwatson */ 1087140628Srwatsonstatic void 1088172955Srwatsonbiba_sysvmsg_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1089140628Srwatson struct label *msqlabel, struct msg *msgptr, struct label *msglabel) 1090140628Srwatson{ 1091140628Srwatson struct mac_biba *source, *dest; 1092140628Srwatson 1093140628Srwatson /* Ignore the msgq label */ 1094140628Srwatson source = SLOT(cred->cr_label); 1095140628Srwatson dest = SLOT(msglabel); 1096140628Srwatson 1097172955Srwatson biba_copy_effective(source, dest); 1098140628Srwatson} 1099140628Srwatson 1100140628Srwatsonstatic void 1101172955Srwatsonbiba_sysvmsq_create(struct ucred *cred, struct msqid_kernel *msqkptr, 1102172955Srwatson struct label *msqlabel) 1103140628Srwatson{ 1104140628Srwatson struct mac_biba *source, *dest; 1105140628Srwatson 1106140628Srwatson source = SLOT(cred->cr_label); 1107140628Srwatson dest = SLOT(msqlabel); 1108140628Srwatson 1109172955Srwatson biba_copy_effective(source, dest); 1110140628Srwatson} 1111140628Srwatson 1112140628Srwatsonstatic void 1113172955Srwatsonbiba_sysvsem_create(struct ucred *cred, struct semid_kernel *semakptr, 1114140628Srwatson struct label *semalabel) 1115140628Srwatson{ 1116140628Srwatson struct mac_biba *source, *dest; 1117140628Srwatson 1118140628Srwatson source = SLOT(cred->cr_label); 1119140628Srwatson dest = SLOT(semalabel); 1120140628Srwatson 1121172955Srwatson biba_copy_effective(source, dest); 1122140628Srwatson} 1123140628Srwatson 1124140628Srwatsonstatic void 1125172955Srwatsonbiba_sysvshm_create(struct ucred *cred, struct shmid_kernel *shmsegptr, 1126140628Srwatson struct label *shmlabel) 1127140628Srwatson{ 1128140628Srwatson struct mac_biba *source, *dest; 1129140628Srwatson 1130140628Srwatson source = SLOT(cred->cr_label); 1131140628Srwatson dest = SLOT(shmlabel); 1132140628Srwatson 1133172955Srwatson biba_copy_effective(source, dest); 1134140628Srwatson} 1135140628Srwatson 1136140628Srwatson/* 1137101099Srwatson * Labeling event operations: network objects. 1138101099Srwatson */ 1139101099Srwatsonstatic void 1140172955Srwatsonbiba_socketpeer_set_from_socket(struct socket *oldso, 1141168976Srwatson struct label *oldsolabel, struct socket *newso, 1142168976Srwatson struct label *newsopeerlabel) 1143101099Srwatson{ 1144101099Srwatson struct mac_biba *source, *dest; 1145101099Srwatson 1146168976Srwatson source = SLOT(oldsolabel); 1147168976Srwatson dest = SLOT(newsopeerlabel); 1148101099Srwatson 1149172955Srwatson biba_copy_effective(source, dest); 1150101099Srwatson} 1151101099Srwatson 1152101099Srwatsonstatic void 1153172955Srwatsonbiba_bpfdesc_create(struct ucred *cred, struct bpf_d *d, 1154168976Srwatson struct label *dlabel) 1155101099Srwatson{ 1156101099Srwatson struct mac_biba *source, *dest; 1157101099Srwatson 1158122524Srwatson source = SLOT(cred->cr_label); 1159168976Srwatson dest = SLOT(dlabel); 1160101099Srwatson 1161172955Srwatson biba_copy_effective(source, dest); 1162101099Srwatson} 1163101099Srwatson 1164101099Srwatsonstatic void 1165172955Srwatsonbiba_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1166101099Srwatson{ 1167121816Sbrooks char tifname[IFNAMSIZ], *p, *q; 1168101099Srwatson char tiflist[sizeof(trusted_interfaces)]; 1169101099Srwatson struct mac_biba *dest; 1170110350Srwatson int len, type; 1171101099Srwatson 1172168976Srwatson dest = SLOT(ifplabel); 1173101099Srwatson 1174168976Srwatson if (ifp->if_type == IFT_LOOP || interfaces_equal != 0) { 1175110350Srwatson type = MAC_BIBA_TYPE_EQUAL; 1176101099Srwatson goto set; 1177101099Srwatson } 1178101099Srwatson 1179101099Srwatson if (trust_all_interfaces) { 1180110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1181101099Srwatson goto set; 1182101099Srwatson } 1183101099Srwatson 1184110350Srwatson type = MAC_BIBA_TYPE_LOW; 1185101099Srwatson 1186101099Srwatson if (trusted_interfaces[0] == '\0' || 1187101099Srwatson !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1188101099Srwatson goto set; 1189101099Srwatson 1190106089Srwatson bzero(tiflist, sizeof(tiflist)); 1191101099Srwatson for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1192101099Srwatson if(*p != ' ' && *p != '\t') 1193101099Srwatson *q = *p; 1194101099Srwatson 1195101099Srwatson for (p = q = tiflist;; p++) { 1196101099Srwatson if (*p == ',' || *p == '\0') { 1197101099Srwatson len = p - q; 1198101099Srwatson if (len < IFNAMSIZ) { 1199101099Srwatson bzero(tifname, sizeof(tifname)); 1200101099Srwatson bcopy(q, tifname, len); 1201168976Srwatson if (strcmp(tifname, ifp->if_xname) == 0) { 1202110350Srwatson type = MAC_BIBA_TYPE_HIGH; 1203101099Srwatson break; 1204101099Srwatson } 1205106089Srwatson } else { 1206106089Srwatson *p = '\0'; 1207106089Srwatson printf("mac_biba warning: interface name " 1208106089Srwatson "\"%s\" is too long (must be < %d)\n", 1209106089Srwatson q, IFNAMSIZ); 1210101099Srwatson } 1211101099Srwatson if (*p == '\0') 1212101099Srwatson break; 1213101099Srwatson q = p + 1; 1214101099Srwatson } 1215101099Srwatson } 1216101099Srwatsonset: 1217172955Srwatson biba_set_effective(dest, type, 0, NULL); 1218172955Srwatson biba_set_range(dest, type, 0, NULL, type, 0, NULL); 1219101099Srwatson} 1220101099Srwatson 1221101099Srwatsonstatic void 1222172955Srwatsonbiba_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 1223168976Srwatson struct label *ipqlabel) 1224101099Srwatson{ 1225101099Srwatson struct mac_biba *source, *dest; 1226101099Srwatson 1227168976Srwatson source = SLOT(mlabel); 1228101099Srwatson dest = SLOT(ipqlabel); 1229101099Srwatson 1230172955Srwatson biba_copy_effective(source, dest); 1231101099Srwatson} 1232101099Srwatson 1233101099Srwatsonstatic void 1234172955Srwatsonbiba_ipq_reassemble(struct ipq *ipq, struct label *ipqlabel, struct mbuf *m, 1235172955Srwatson struct label *mlabel) 1236101099Srwatson{ 1237101099Srwatson struct mac_biba *source, *dest; 1238101099Srwatson 1239101099Srwatson source = SLOT(ipqlabel); 1240168976Srwatson dest = SLOT(mlabel); 1241101099Srwatson 1242101099Srwatson /* Just use the head, since we require them all to match. */ 1243172955Srwatson biba_copy_effective(source, dest); 1244101099Srwatson} 1245101099Srwatson 1246101099Srwatsonstatic void 1247172955Srwatsonbiba_netinet_fragment(struct mbuf *m, struct label *mlabel, 1248168976Srwatson struct mbuf *frag, struct label *fraglabel) 1249101099Srwatson{ 1250101099Srwatson struct mac_biba *source, *dest; 1251101099Srwatson 1252168976Srwatson source = SLOT(mlabel); 1253168976Srwatson dest = SLOT(fraglabel); 1254101099Srwatson 1255172955Srwatson biba_copy_effective(source, dest); 1256101099Srwatson} 1257101099Srwatson 1258101099Srwatsonstatic void 1259172955Srwatsonbiba_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1260123607Srwatson struct mbuf *m, struct label *mlabel) 1261123607Srwatson{ 1262123607Srwatson struct mac_biba *source, *dest; 1263123607Srwatson 1264123607Srwatson source = SLOT(inplabel); 1265123607Srwatson dest = SLOT(mlabel); 1266123607Srwatson 1267172955Srwatson biba_copy_effective(source, dest); 1268123607Srwatson} 1269123607Srwatson 1270123607Srwatsonstatic void 1271172955Srwatsonbiba_create_mbuf_linklayer(struct ifnet *ifp, struct label *ifplabel, 1272168976Srwatson struct mbuf *m, struct label *mlabel) 1273101099Srwatson{ 1274101099Srwatson struct mac_biba *dest; 1275101099Srwatson 1276168976Srwatson dest = SLOT(mlabel); 1277101099Srwatson 1278172955Srwatson biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1279101099Srwatson} 1280101099Srwatson 1281101099Srwatsonstatic void 1282172955Srwatsonbiba_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 1283168976Srwatson struct mbuf *m, struct label *mlabel) 1284101099Srwatson{ 1285101099Srwatson struct mac_biba *source, *dest; 1286101099Srwatson 1287168976Srwatson source = SLOT(dlabel); 1288168976Srwatson dest = SLOT(mlabel); 1289101099Srwatson 1290172955Srwatson biba_copy_effective(source, dest); 1291101099Srwatson} 1292101099Srwatson 1293101099Srwatsonstatic void 1294172955Srwatsonbiba_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1295168976Srwatson struct mbuf *m, struct label *mlabel) 1296101099Srwatson{ 1297101099Srwatson struct mac_biba *source, *dest; 1298101099Srwatson 1299168976Srwatson source = SLOT(ifplabel); 1300168976Srwatson dest = SLOT(mlabel); 1301101099Srwatson 1302172955Srwatson biba_copy_effective(source, dest); 1303101099Srwatson} 1304101099Srwatson 1305101099Srwatsonstatic void 1306172955Srwatsonbiba_mbuf_create_multicast_encap(struct mbuf *m, struct label *mlabel, 1307168976Srwatson struct ifnet *ifp, struct label *ifplabel, struct mbuf *mnew, 1308168976Srwatson struct label *mnewlabel) 1309101099Srwatson{ 1310101099Srwatson struct mac_biba *source, *dest; 1311101099Srwatson 1312168976Srwatson source = SLOT(mlabel); 1313168976Srwatson dest = SLOT(mnewlabel); 1314101099Srwatson 1315172955Srwatson biba_copy_effective(source, dest); 1316101099Srwatson} 1317101099Srwatson 1318101099Srwatsonstatic void 1319172955Srwatsonbiba_mbuf_create_netlayer(struct mbuf *m, struct label *mlabel, 1320168976Srwatson struct mbuf *newm, struct label *mnewlabel) 1321101099Srwatson{ 1322101099Srwatson struct mac_biba *source, *dest; 1323101099Srwatson 1324168976Srwatson source = SLOT(mlabel); 1325168976Srwatson dest = SLOT(mnewlabel); 1326101099Srwatson 1327172955Srwatson biba_copy_effective(source, dest); 1328101099Srwatson} 1329101099Srwatson 1330101099Srwatsonstatic int 1331172955Srwatsonbiba_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 1332172930Srwatson struct label *ipqlabel) 1333101099Srwatson{ 1334101099Srwatson struct mac_biba *a, *b; 1335101099Srwatson 1336101099Srwatson a = SLOT(ipqlabel); 1337168976Srwatson b = SLOT(mlabel); 1338101099Srwatson 1339172955Srwatson return (biba_equal_effective(a, b)); 1340101099Srwatson} 1341101099Srwatson 1342101099Srwatsonstatic void 1343172955Srwatsonbiba_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1344168976Srwatson struct label *ifplabel, struct label *newlabel) 1345101099Srwatson{ 1346101099Srwatson struct mac_biba *source, *dest; 1347101099Srwatson 1348101099Srwatson source = SLOT(newlabel); 1349168976Srwatson dest = SLOT(ifplabel); 1350101099Srwatson 1351172955Srwatson biba_copy(source, dest); 1352101099Srwatson} 1353101099Srwatson 1354101099Srwatsonstatic void 1355172955Srwatsonbiba_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *ipq, 1356168976Srwatson struct label *ipqlabel) 1357101099Srwatson{ 1358101099Srwatson 1359101099Srwatson /* NOOP: we only accept matching labels, so no need to update */ 1360101099Srwatson} 1361101099Srwatson 1362122875Srwatsonstatic void 1363172955Srwatsonbiba_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1364122875Srwatson struct inpcb *inp, struct label *inplabel) 1365122875Srwatson{ 1366122875Srwatson struct mac_biba *source, *dest; 1367122875Srwatson 1368122875Srwatson source = SLOT(solabel); 1369122875Srwatson dest = SLOT(inplabel); 1370122875Srwatson 1371172955Srwatson biba_copy(source, dest); 1372122875Srwatson} 1373122875Srwatson 1374162238Scsjpstatic void 1375172955Srwatsonbiba_mbuf_create_from_firewall(struct mbuf *m, struct label *label) 1376162238Scsjp{ 1377162238Scsjp struct mac_biba *dest; 1378162238Scsjp 1379162238Scsjp dest = SLOT(label); 1380162238Scsjp 1381162238Scsjp /* XXX: where is the label for the firewall really comming from? */ 1382172955Srwatson biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1383162238Scsjp} 1384162238Scsjp 1385101099Srwatson/* 1386101099Srwatson * Labeling event operations: processes. 1387101099Srwatson */ 1388101099Srwatsonstatic void 1389172955Srwatsonbiba_proc_create_swapper(struct ucred *cred) 1390101099Srwatson{ 1391101099Srwatson struct mac_biba *dest; 1392101099Srwatson 1393122524Srwatson dest = SLOT(cred->cr_label); 1394101099Srwatson 1395172955Srwatson biba_set_effective(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1396172955Srwatson biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 1397172955Srwatson 0, NULL); 1398101099Srwatson} 1399101099Srwatson 1400101099Srwatsonstatic void 1401172955Srwatsonbiba_proc_create_init(struct ucred *cred) 1402101099Srwatson{ 1403101099Srwatson struct mac_biba *dest; 1404101099Srwatson 1405122524Srwatson dest = SLOT(cred->cr_label); 1406101099Srwatson 1407172955Srwatson biba_set_effective(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1408172955Srwatson biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 1409172955Srwatson 0, NULL); 1410101099Srwatson} 1411101099Srwatson 1412101099Srwatsonstatic void 1413172955Srwatsonbiba_cred_relabel(struct ucred *cred, struct label *newlabel) 1414101099Srwatson{ 1415101099Srwatson struct mac_biba *source, *dest; 1416101099Srwatson 1417101099Srwatson source = SLOT(newlabel); 1418122524Srwatson dest = SLOT(cred->cr_label); 1419101099Srwatson 1420172955Srwatson biba_copy(source, dest); 1421101099Srwatson} 1422101099Srwatson 1423101099Srwatson/* 1424140628Srwatson * Label cleanup/flush operations 1425140628Srwatson */ 1426140628Srwatsonstatic void 1427172955Srwatsonbiba_sysvmsg_cleanup(struct label *msglabel) 1428140628Srwatson{ 1429140628Srwatson 1430140628Srwatson bzero(SLOT(msglabel), sizeof(struct mac_biba)); 1431140628Srwatson} 1432140628Srwatson 1433140628Srwatsonstatic void 1434172955Srwatsonbiba_sysvmsq_cleanup(struct label *msqlabel) 1435140628Srwatson{ 1436140628Srwatson 1437140628Srwatson bzero(SLOT(msqlabel), sizeof(struct mac_biba)); 1438140628Srwatson} 1439140628Srwatson 1440140628Srwatsonstatic void 1441172955Srwatsonbiba_sysvsem_cleanup(struct label *semalabel) 1442140628Srwatson{ 1443140628Srwatson 1444140628Srwatson bzero(SLOT(semalabel), sizeof(struct mac_biba)); 1445140628Srwatson} 1446140628Srwatson 1447140628Srwatsonstatic void 1448172955Srwatsonbiba_sysvshm_cleanup(struct label *shmlabel) 1449140628Srwatson{ 1450140628Srwatson bzero(SLOT(shmlabel), sizeof(struct mac_biba)); 1451140628Srwatson} 1452140628Srwatson 1453140628Srwatson/* 1454101099Srwatson * Access control checks. 1455101099Srwatson */ 1456101099Srwatsonstatic int 1457172955Srwatsonbiba_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 1458168976Srwatson struct ifnet *ifp, struct label *ifplabel) 1459101099Srwatson{ 1460101099Srwatson struct mac_biba *a, *b; 1461101099Srwatson 1462172955Srwatson if (!biba_enabled) 1463101099Srwatson return (0); 1464101099Srwatson 1465168976Srwatson a = SLOT(dlabel); 1466168976Srwatson b = SLOT(ifplabel); 1467101099Srwatson 1468172955Srwatson if (biba_equal_effective(a, b)) 1469101099Srwatson return (0); 1470101099Srwatson return (EACCES); 1471101099Srwatson} 1472101099Srwatson 1473101099Srwatsonstatic int 1474172955Srwatsonbiba_cred_check_relabel(struct ucred *cred, struct label *newlabel) 1475101099Srwatson{ 1476101099Srwatson struct mac_biba *subj, *new; 1477105634Srwatson int error; 1478101099Srwatson 1479122524Srwatson subj = SLOT(cred->cr_label); 1480101099Srwatson new = SLOT(newlabel); 1481101099Srwatson 1482101099Srwatson /* 1483105634Srwatson * If there is a Biba label update for the credential, it may 1484132232Srwatson * be an update of the effective, range, or both. 1485101099Srwatson */ 1486105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1487105634Srwatson if (error) 1488105634Srwatson return (error); 1489101099Srwatson 1490101099Srwatson /* 1491105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1492101099Srwatson */ 1493105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1494105634Srwatson /* 1495110351Srwatson * If the change request modifies both the Biba label 1496132232Srwatson * effective and range, check that the new effective will be 1497110351Srwatson * in the new range. 1498110351Srwatson */ 1499110351Srwatson if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1500110351Srwatson MAC_BIBA_FLAGS_BOTH && 1501172955Srwatson !biba_effective_in_range(new, new)) 1502110351Srwatson return (EINVAL); 1503110351Srwatson 1504110351Srwatson /* 1505132232Srwatson * To change the Biba effective label on a credential, the 1506132232Srwatson * new effective label must be in the current range. 1507105634Srwatson */ 1508132232Srwatson if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE && 1509172955Srwatson !biba_effective_in_range(new, subj)) 1510105634Srwatson return (EPERM); 1511101099Srwatson 1512105634Srwatson /* 1513172955Srwatson * To change the Biba range on a credential, the new range 1514172955Srwatson * label must be in the current range. 1515105634Srwatson */ 1516105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1517172955Srwatson !biba_range_in_range(new, subj)) 1518105634Srwatson return (EPERM); 1519101099Srwatson 1520105634Srwatson /* 1521172955Srwatson * To have EQUAL in any component of the new credential Biba 1522172955Srwatson * label, the subject must already have EQUAL in their label. 1523105634Srwatson */ 1524172955Srwatson if (biba_contains_equal(new)) { 1525172955Srwatson error = biba_subject_privileged(subj); 1526105634Srwatson if (error) 1527105634Srwatson return (error); 1528105634Srwatson } 1529105634Srwatson } 1530105634Srwatson 1531101099Srwatson return (0); 1532101099Srwatson} 1533101099Srwatson 1534101099Srwatsonstatic int 1535172955Srwatsonbiba_cred_check_visible(struct ucred *u1, struct ucred *u2) 1536101099Srwatson{ 1537101099Srwatson struct mac_biba *subj, *obj; 1538101099Srwatson 1539172955Srwatson if (!biba_enabled) 1540101099Srwatson return (0); 1541101099Srwatson 1542122524Srwatson subj = SLOT(u1->cr_label); 1543122524Srwatson obj = SLOT(u2->cr_label); 1544101099Srwatson 1545101099Srwatson /* XXX: range */ 1546172955Srwatson if (!biba_dominate_effective(obj, subj)) 1547101099Srwatson return (ESRCH); 1548101099Srwatson 1549101099Srwatson return (0); 1550101099Srwatson} 1551101099Srwatson 1552101099Srwatsonstatic int 1553172955Srwatsonbiba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1554168976Srwatson struct label *ifplabel, struct label *newlabel) 1555101099Srwatson{ 1556101099Srwatson struct mac_biba *subj, *new; 1557105634Srwatson int error; 1558101099Srwatson 1559122524Srwatson subj = SLOT(cred->cr_label); 1560101099Srwatson new = SLOT(newlabel); 1561101099Srwatson 1562105634Srwatson /* 1563172955Srwatson * If there is a Biba label update for the interface, it may be an 1564172955Srwatson * update of the effective, range, or both. 1565105634Srwatson */ 1566105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1567105634Srwatson if (error) 1568105634Srwatson return (error); 1569101099Srwatson 1570105634Srwatson /* 1571106160Srwatson * Relabling network interfaces requires Biba privilege. 1572106160Srwatson */ 1573172955Srwatson error = biba_subject_privileged(subj); 1574106160Srwatson if (error) 1575106160Srwatson return (error); 1576106160Srwatson 1577105634Srwatson return (0); 1578101099Srwatson} 1579101099Srwatson 1580103759Srwatsonstatic int 1581172955Srwatsonbiba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1582168976Srwatson struct mbuf *m, struct label *mlabel) 1583101099Srwatson{ 1584101099Srwatson struct mac_biba *p, *i; 1585103761Srwatson 1586172955Srwatson if (!biba_enabled) 1587101099Srwatson return (0); 1588101099Srwatson 1589168976Srwatson p = SLOT(mlabel); 1590168976Srwatson i = SLOT(ifplabel); 1591103759Srwatson 1592172955Srwatson return (biba_effective_in_range(p, i) ? 0 : EACCES); 1593101099Srwatson} 1594101099Srwatson 1595101099Srwatsonstatic int 1596172955Srwatsonbiba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1597122875Srwatson struct mbuf *m, struct label *mlabel) 1598122875Srwatson{ 1599122875Srwatson struct mac_biba *p, *i; 1600122875Srwatson 1601172955Srwatson if (!biba_enabled) 1602122875Srwatson return (0); 1603122875Srwatson 1604122875Srwatson p = SLOT(mlabel); 1605122875Srwatson i = SLOT(inplabel); 1606122875Srwatson 1607172955Srwatson return (biba_equal_effective(p, i) ? 0 : EACCES); 1608122875Srwatson} 1609122875Srwatson 1610122875Srwatsonstatic int 1611172955Srwatsonbiba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 1612140628Srwatson struct label *msglabel) 1613140628Srwatson{ 1614140628Srwatson struct mac_biba *subj, *obj; 1615140628Srwatson 1616172955Srwatson if (!biba_enabled) 1617140628Srwatson return (0); 1618140628Srwatson 1619140628Srwatson subj = SLOT(cred->cr_label); 1620140628Srwatson obj = SLOT(msglabel); 1621140628Srwatson 1622172955Srwatson if (!biba_dominate_effective(obj, subj)) 1623140628Srwatson return (EACCES); 1624140628Srwatson 1625140628Srwatson return (0); 1626140628Srwatson} 1627140628Srwatson 1628140628Srwatsonstatic int 1629172955Srwatsonbiba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 1630140628Srwatson struct label *msglabel) 1631140628Srwatson{ 1632140628Srwatson struct mac_biba *subj, *obj; 1633140628Srwatson 1634172955Srwatson if (!biba_enabled) 1635140628Srwatson return (0); 1636140628Srwatson 1637140628Srwatson subj = SLOT(cred->cr_label); 1638140628Srwatson obj = SLOT(msglabel); 1639140628Srwatson 1640172955Srwatson if (!biba_dominate_effective(subj, obj)) 1641140628Srwatson return (EACCES); 1642140628Srwatson 1643140628Srwatson return (0); 1644140628Srwatson} 1645140628Srwatson 1646140628Srwatsonstatic int 1647172955Srwatsonbiba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1648172955Srwatson struct label *msqklabel) 1649140628Srwatson{ 1650140628Srwatson struct mac_biba *subj, *obj; 1651140628Srwatson 1652172955Srwatson if (!biba_enabled) 1653140628Srwatson return (0); 1654140628Srwatson 1655140628Srwatson subj = SLOT(cred->cr_label); 1656140628Srwatson obj = SLOT(msqklabel); 1657140628Srwatson 1658172955Srwatson if (!biba_dominate_effective(obj, subj)) 1659140628Srwatson return (EACCES); 1660140628Srwatson 1661140628Srwatson return (0); 1662140628Srwatson} 1663140628Srwatson 1664140628Srwatsonstatic int 1665172955Srwatsonbiba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1666172955Srwatson struct label *msqklabel) 1667140628Srwatson{ 1668140628Srwatson struct mac_biba *subj, *obj; 1669140628Srwatson 1670172955Srwatson if (!biba_enabled) 1671140628Srwatson return (0); 1672140628Srwatson 1673140628Srwatson subj = SLOT(cred->cr_label); 1674140628Srwatson obj = SLOT(msqklabel); 1675140628Srwatson 1676172955Srwatson if (!biba_dominate_effective(subj, obj)) 1677140628Srwatson return (EACCES); 1678140628Srwatson 1679140628Srwatson return (0); 1680140628Srwatson} 1681140628Srwatson 1682140628Srwatsonstatic int 1683172955Srwatsonbiba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1684172955Srwatson struct label *msqklabel) 1685140628Srwatson{ 1686140628Srwatson struct mac_biba *subj, *obj; 1687140628Srwatson 1688172955Srwatson if (!biba_enabled) 1689140628Srwatson return (0); 1690140628Srwatson 1691140628Srwatson subj = SLOT(cred->cr_label); 1692140628Srwatson obj = SLOT(msqklabel); 1693140628Srwatson 1694172955Srwatson if (!biba_dominate_effective(obj, subj)) 1695140628Srwatson return (EACCES); 1696140628Srwatson 1697140628Srwatson return (0); 1698140628Srwatson} 1699140628Srwatson 1700140628Srwatsonstatic int 1701172955Srwatsonbiba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1702172955Srwatson struct label *msqklabel, int cmd) 1703140628Srwatson{ 1704140628Srwatson struct mac_biba *subj, *obj; 1705140628Srwatson 1706172955Srwatson if (!biba_enabled) 1707140628Srwatson return (0); 1708140628Srwatson 1709140628Srwatson subj = SLOT(cred->cr_label); 1710140628Srwatson obj = SLOT(msqklabel); 1711140628Srwatson 1712140628Srwatson switch(cmd) { 1713140628Srwatson case IPC_RMID: 1714140628Srwatson case IPC_SET: 1715172955Srwatson if (!biba_dominate_effective(subj, obj)) 1716140628Srwatson return (EACCES); 1717140628Srwatson break; 1718140628Srwatson 1719140628Srwatson case IPC_STAT: 1720172955Srwatson if (!biba_dominate_effective(obj, subj)) 1721140628Srwatson return (EACCES); 1722140628Srwatson break; 1723140628Srwatson 1724140628Srwatson default: 1725140628Srwatson return (EACCES); 1726140628Srwatson } 1727140628Srwatson 1728140628Srwatson return (0); 1729140628Srwatson} 1730140628Srwatson 1731140628Srwatsonstatic int 1732172955Srwatsonbiba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1733172955Srwatson struct label *semaklabel, int cmd) 1734140628Srwatson{ 1735140628Srwatson struct mac_biba *subj, *obj; 1736140628Srwatson 1737172955Srwatson if (!biba_enabled) 1738140628Srwatson return (0); 1739140628Srwatson 1740140628Srwatson subj = SLOT(cred->cr_label); 1741140628Srwatson obj = SLOT(semaklabel); 1742140628Srwatson 1743140628Srwatson switch(cmd) { 1744140628Srwatson case IPC_RMID: 1745140628Srwatson case IPC_SET: 1746140628Srwatson case SETVAL: 1747140628Srwatson case SETALL: 1748172955Srwatson if (!biba_dominate_effective(subj, obj)) 1749140628Srwatson return (EACCES); 1750140628Srwatson break; 1751140628Srwatson 1752140628Srwatson case IPC_STAT: 1753140628Srwatson case GETVAL: 1754140628Srwatson case GETPID: 1755140628Srwatson case GETNCNT: 1756140628Srwatson case GETZCNT: 1757140628Srwatson case GETALL: 1758172955Srwatson if (!biba_dominate_effective(obj, subj)) 1759140628Srwatson return (EACCES); 1760140628Srwatson break; 1761140628Srwatson 1762140628Srwatson default: 1763140628Srwatson return (EACCES); 1764140628Srwatson } 1765140628Srwatson 1766140628Srwatson return (0); 1767140628Srwatson} 1768140628Srwatson 1769140628Srwatsonstatic int 1770172955Srwatsonbiba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 1771172955Srwatson struct label *semaklabel) 1772140628Srwatson{ 1773140628Srwatson struct mac_biba *subj, *obj; 1774140628Srwatson 1775172955Srwatson if (!biba_enabled) 1776140628Srwatson return (0); 1777140628Srwatson 1778140628Srwatson subj = SLOT(cred->cr_label); 1779140628Srwatson obj = SLOT(semaklabel); 1780140628Srwatson 1781172955Srwatson if (!biba_dominate_effective(obj, subj)) 1782140628Srwatson return (EACCES); 1783140628Srwatson 1784140628Srwatson return (0); 1785140628Srwatson} 1786140628Srwatson 1787140628Srwatsonstatic int 1788172955Srwatsonbiba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 1789172955Srwatson struct label *semaklabel, size_t accesstype) 1790140628Srwatson{ 1791140628Srwatson struct mac_biba *subj, *obj; 1792140628Srwatson 1793172955Srwatson if (!biba_enabled) 1794140628Srwatson return (0); 1795140628Srwatson 1796140628Srwatson subj = SLOT(cred->cr_label); 1797140628Srwatson obj = SLOT(semaklabel); 1798140628Srwatson 1799140628Srwatson if (accesstype & SEM_R) 1800172955Srwatson if (!biba_dominate_effective(obj, subj)) 1801140628Srwatson return (EACCES); 1802140628Srwatson 1803140628Srwatson if (accesstype & SEM_A) 1804172955Srwatson if (!biba_dominate_effective(subj, obj)) 1805140628Srwatson return (EACCES); 1806140628Srwatson 1807140628Srwatson return (0); 1808140628Srwatson} 1809140628Srwatson 1810140628Srwatsonstatic int 1811172955Srwatsonbiba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 1812172955Srwatson struct label *shmseglabel, int shmflg) 1813140628Srwatson{ 1814140628Srwatson struct mac_biba *subj, *obj; 1815140628Srwatson 1816172955Srwatson if (!biba_enabled) 1817140628Srwatson return (0); 1818140628Srwatson 1819140628Srwatson subj = SLOT(cred->cr_label); 1820140628Srwatson obj = SLOT(shmseglabel); 1821140628Srwatson 1822172955Srwatson if (!biba_dominate_effective(obj, subj)) 1823140628Srwatson return (EACCES); 1824140628Srwatson if ((shmflg & SHM_RDONLY) == 0) { 1825172955Srwatson if (!biba_dominate_effective(subj, obj)) 1826140628Srwatson return (EACCES); 1827140628Srwatson } 1828140628Srwatson 1829140628Srwatson return (0); 1830140628Srwatson} 1831140628Srwatson 1832140628Srwatsonstatic int 1833172955Srwatsonbiba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 1834172955Srwatson struct label *shmseglabel, int cmd) 1835140628Srwatson{ 1836140628Srwatson struct mac_biba *subj, *obj; 1837140628Srwatson 1838172955Srwatson if (!biba_enabled) 1839140628Srwatson return (0); 1840140628Srwatson 1841140628Srwatson subj = SLOT(cred->cr_label); 1842140628Srwatson obj = SLOT(shmseglabel); 1843140628Srwatson 1844140628Srwatson switch(cmd) { 1845140628Srwatson case IPC_RMID: 1846140628Srwatson case IPC_SET: 1847172955Srwatson if (!biba_dominate_effective(subj, obj)) 1848140628Srwatson return (EACCES); 1849140628Srwatson break; 1850140628Srwatson 1851140628Srwatson case IPC_STAT: 1852140628Srwatson case SHM_STAT: 1853172955Srwatson if (!biba_dominate_effective(obj, subj)) 1854140628Srwatson return (EACCES); 1855140628Srwatson break; 1856140628Srwatson 1857140628Srwatson default: 1858140628Srwatson return (EACCES); 1859140628Srwatson } 1860140628Srwatson 1861140628Srwatson return (0); 1862140628Srwatson} 1863140628Srwatson 1864140628Srwatsonstatic int 1865172955Srwatsonbiba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 1866172955Srwatson struct label *shmseglabel, int shmflg) 1867140628Srwatson{ 1868140628Srwatson struct mac_biba *subj, *obj; 1869140628Srwatson 1870172955Srwatson if (!biba_enabled) 1871140628Srwatson return (0); 1872140628Srwatson 1873140628Srwatson subj = SLOT(cred->cr_label); 1874140628Srwatson obj = SLOT(shmseglabel); 1875140628Srwatson 1876172955Srwatson if (!biba_dominate_effective(obj, subj)) 1877140628Srwatson return (EACCES); 1878140628Srwatson 1879140628Srwatson return (0); 1880140628Srwatson} 1881140628Srwatson 1882140628Srwatsonstatic int 1883172955Srwatsonbiba_kld_check_load(struct ucred *cred, struct vnode *vp, 1884168976Srwatson struct label *vplabel) 1885110354Srwatson{ 1886110354Srwatson struct mac_biba *subj, *obj; 1887110354Srwatson int error; 1888110354Srwatson 1889172955Srwatson if (!biba_enabled) 1890110354Srwatson return (0); 1891110354Srwatson 1892122524Srwatson subj = SLOT(cred->cr_label); 1893110354Srwatson 1894172955Srwatson error = biba_subject_privileged(subj); 1895110354Srwatson if (error) 1896110354Srwatson return (error); 1897110354Srwatson 1898168976Srwatson obj = SLOT(vplabel); 1899172955Srwatson if (!biba_high_effective(obj)) 1900110354Srwatson return (EACCES); 1901110354Srwatson 1902110354Srwatson return (0); 1903110354Srwatson} 1904110354Srwatson 1905110354Srwatsonstatic int 1906172955Srwatsonbiba_mount_check_stat(struct ucred *cred, struct mount *mp, 1907168976Srwatson struct label *mplabel) 1908101099Srwatson{ 1909101099Srwatson struct mac_biba *subj, *obj; 1910101099Srwatson 1911172955Srwatson if (!biba_enabled) 1912101099Srwatson return (0); 1913101099Srwatson 1914122524Srwatson subj = SLOT(cred->cr_label); 1915168976Srwatson obj = SLOT(mplabel); 1916101099Srwatson 1917172955Srwatson if (!biba_dominate_effective(obj, subj)) 1918101099Srwatson return (EACCES); 1919101099Srwatson 1920101099Srwatson return (0); 1921101099Srwatson} 1922101099Srwatson 1923101099Srwatsonstatic int 1924172955Srwatsonbiba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1925168976Srwatson struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1926101099Srwatson{ 1927103759Srwatson 1928172955Srwatson if(!biba_enabled) 1929101099Srwatson return (0); 1930101099Srwatson 1931101099Srwatson /* XXX: This will be implemented soon... */ 1932101099Srwatson 1933101099Srwatson return (0); 1934101099Srwatson} 1935101099Srwatson 1936101099Srwatsonstatic int 1937172955Srwatsonbiba_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1938168976Srwatson struct label *pplabel) 1939101099Srwatson{ 1940101099Srwatson struct mac_biba *subj, *obj; 1941101099Srwatson 1942172955Srwatson if (!biba_enabled) 1943101099Srwatson return (0); 1944101099Srwatson 1945122524Srwatson subj = SLOT(cred->cr_label); 1946168976Srwatson obj = SLOT(pplabel); 1947101099Srwatson 1948172955Srwatson if (!biba_dominate_effective(obj, subj)) 1949102115Srwatson return (EACCES); 1950101099Srwatson 1951101099Srwatson return (0); 1952101099Srwatson} 1953101099Srwatson 1954101099Srwatsonstatic int 1955172955Srwatsonbiba_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1956168976Srwatson struct label *pplabel) 1957102115Srwatson{ 1958102115Srwatson struct mac_biba *subj, *obj; 1959102115Srwatson 1960172955Srwatson if (!biba_enabled) 1961102115Srwatson return (0); 1962102115Srwatson 1963122524Srwatson subj = SLOT(cred->cr_label); 1964168976Srwatson obj = SLOT(pplabel); 1965102115Srwatson 1966172955Srwatson if (!biba_dominate_effective(obj, subj)) 1967102115Srwatson return (EACCES); 1968102115Srwatson 1969102115Srwatson return (0); 1970102115Srwatson} 1971102115Srwatson 1972102115Srwatsonstatic int 1973172955Srwatsonbiba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1974168976Srwatson struct label *pplabel, struct label *newlabel) 1975101099Srwatson{ 1976101099Srwatson struct mac_biba *subj, *obj, *new; 1977105634Srwatson int error; 1978101099Srwatson 1979101099Srwatson new = SLOT(newlabel); 1980122524Srwatson subj = SLOT(cred->cr_label); 1981168976Srwatson obj = SLOT(pplabel); 1982101099Srwatson 1983101099Srwatson /* 1984172955Srwatson * If there is a Biba label update for a pipe, it must be a effective 1985172955Srwatson * update. 1986101099Srwatson */ 1987132232Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 1988105634Srwatson if (error) 1989105634Srwatson return (error); 1990101099Srwatson 1991101099Srwatson /* 1992105634Srwatson * To perform a relabel of a pipe (Biba label or not), Biba must 1993105634Srwatson * authorize the relabel. 1994101099Srwatson */ 1995172955Srwatson if (!biba_effective_in_range(obj, subj)) 1996101099Srwatson return (EPERM); 1997101099Srwatson 1998101099Srwatson /* 1999105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2000101099Srwatson */ 2001132232Srwatson if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2002105634Srwatson /* 2003105634Srwatson * To change the Biba label on a pipe, the new pipe label 2004105634Srwatson * must be in the subject range. 2005105634Srwatson */ 2006172955Srwatson if (!biba_effective_in_range(new, subj)) 2007105634Srwatson return (EPERM); 2008101099Srwatson 2009105634Srwatson /* 2010105634Srwatson * To change the Biba label on a pipe to be EQUAL, the 2011105634Srwatson * subject must have appropriate privilege. 2012105634Srwatson */ 2013172955Srwatson if (biba_contains_equal(new)) { 2014172955Srwatson error = biba_subject_privileged(subj); 2015105634Srwatson if (error) 2016105634Srwatson return (error); 2017105634Srwatson } 2018105634Srwatson } 2019105634Srwatson 2020101099Srwatson return (0); 2021101099Srwatson} 2022101099Srwatson 2023101099Srwatsonstatic int 2024172955Srwatsonbiba_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 2025168976Srwatson struct label *pplabel) 2026102115Srwatson{ 2027102115Srwatson struct mac_biba *subj, *obj; 2028102115Srwatson 2029172955Srwatson if (!biba_enabled) 2030102115Srwatson return (0); 2031102115Srwatson 2032122524Srwatson subj = SLOT(cred->cr_label); 2033168976Srwatson obj = SLOT(pplabel); 2034102115Srwatson 2035172955Srwatson if (!biba_dominate_effective(obj, subj)) 2036102115Srwatson return (EACCES); 2037102115Srwatson 2038102115Srwatson return (0); 2039102115Srwatson} 2040102115Srwatson 2041102115Srwatsonstatic int 2042172955Srwatsonbiba_pipe_check_write(struct ucred *cred, struct pipepair *pp, 2043168976Srwatson struct label *pplabel) 2044102115Srwatson{ 2045102115Srwatson struct mac_biba *subj, *obj; 2046102115Srwatson 2047172955Srwatson if (!biba_enabled) 2048102115Srwatson return (0); 2049102115Srwatson 2050122524Srwatson subj = SLOT(cred->cr_label); 2051168976Srwatson obj = SLOT(pplabel); 2052102115Srwatson 2053172955Srwatson if (!biba_dominate_effective(subj, obj)) 2054102115Srwatson return (EACCES); 2055102115Srwatson 2056102115Srwatson return (0); 2057102115Srwatson} 2058102115Srwatson 2059102115Srwatsonstatic int 2060172955Srwatsonbiba_posixsem_check_write(struct ucred *cred, struct ksem *ks, 2061172850Srwatson struct label *kslabel) 2062145855Srwatson{ 2063145855Srwatson struct mac_biba *subj, *obj; 2064145855Srwatson 2065172955Srwatson if (!biba_enabled) 2066145855Srwatson return (0); 2067145855Srwatson 2068145855Srwatson subj = SLOT(cred->cr_label); 2069172850Srwatson obj = SLOT(kslabel); 2070145855Srwatson 2071172955Srwatson if (!biba_dominate_effective(subj, obj)) 2072145855Srwatson return (EACCES); 2073145855Srwatson 2074145855Srwatson return (0); 2075145855Srwatson} 2076145855Srwatson 2077145855Srwatsonstatic int 2078172955Srwatsonbiba_posixsem_check_rdonly(struct ucred *cred, struct ksem *ks, 2079172850Srwatson struct label *kslabel) 2080145855Srwatson{ 2081145855Srwatson struct mac_biba *subj, *obj; 2082145855Srwatson 2083172955Srwatson if (!biba_enabled) 2084145855Srwatson return (0); 2085145855Srwatson 2086145855Srwatson subj = SLOT(cred->cr_label); 2087172850Srwatson obj = SLOT(kslabel); 2088145855Srwatson 2089172955Srwatson if (!biba_dominate_effective(obj, subj)) 2090145855Srwatson return (EACCES); 2091145855Srwatson 2092145855Srwatson return (0); 2093145855Srwatson} 2094145855Srwatson 2095145855Srwatsonstatic int 2096172955Srwatsonbiba_proc_check_debug(struct ucred *cred, struct proc *p) 2097101099Srwatson{ 2098101099Srwatson struct mac_biba *subj, *obj; 2099101099Srwatson 2100172955Srwatson if (!biba_enabled) 2101101099Srwatson return (0); 2102101099Srwatson 2103122524Srwatson subj = SLOT(cred->cr_label); 2104168976Srwatson obj = SLOT(p->p_ucred->cr_label); 2105101099Srwatson 2106101099Srwatson /* XXX: range checks */ 2107172955Srwatson if (!biba_dominate_effective(obj, subj)) 2108101099Srwatson return (ESRCH); 2109172955Srwatson if (!biba_dominate_effective(subj, obj)) 2110101099Srwatson return (EACCES); 2111101099Srwatson 2112101099Srwatson return (0); 2113101099Srwatson} 2114101099Srwatson 2115101099Srwatsonstatic int 2116172955Srwatsonbiba_proc_check_sched(struct ucred *cred, struct proc *p) 2117101099Srwatson{ 2118101099Srwatson struct mac_biba *subj, *obj; 2119103759Srwatson 2120172955Srwatson if (!biba_enabled) 2121101099Srwatson return (0); 2122101099Srwatson 2123122524Srwatson subj = SLOT(cred->cr_label); 2124168976Srwatson obj = SLOT(p->p_ucred->cr_label); 2125103759Srwatson 2126101099Srwatson /* XXX: range checks */ 2127172955Srwatson if (!biba_dominate_effective(obj, subj)) 2128101099Srwatson return (ESRCH); 2129172955Srwatson if (!biba_dominate_effective(subj, obj)) 2130101099Srwatson return (EACCES); 2131101099Srwatson 2132101099Srwatson return (0); 2133101099Srwatson} 2134101099Srwatson 2135101099Srwatsonstatic int 2136172955Srwatsonbiba_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 2137101099Srwatson{ 2138101099Srwatson struct mac_biba *subj, *obj; 2139103759Srwatson 2140172955Srwatson if (!biba_enabled) 2141101099Srwatson return (0); 2142101099Srwatson 2143122524Srwatson subj = SLOT(cred->cr_label); 2144168976Srwatson obj = SLOT(p->p_ucred->cr_label); 2145103759Srwatson 2146101099Srwatson /* XXX: range checks */ 2147172955Srwatson if (!biba_dominate_effective(obj, subj)) 2148101099Srwatson return (ESRCH); 2149172955Srwatson if (!biba_dominate_effective(subj, obj)) 2150101099Srwatson return (EACCES); 2151101099Srwatson 2152101099Srwatson return (0); 2153101099Srwatson} 2154101099Srwatson 2155101099Srwatsonstatic int 2156172955Srwatsonbiba_socket_check_deliver(struct socket *so, struct label *solabel, 2157168976Srwatson struct mbuf *m, struct label *mlabel) 2158101099Srwatson{ 2159101099Srwatson struct mac_biba *p, *s; 2160101099Srwatson 2161172955Srwatson if (!biba_enabled) 2162101099Srwatson return (0); 2163101099Srwatson 2164168976Srwatson p = SLOT(mlabel); 2165168976Srwatson s = SLOT(solabel); 2166101099Srwatson 2167172955Srwatson return (biba_equal_effective(p, s) ? 0 : EACCES); 2168101099Srwatson} 2169101099Srwatson 2170101099Srwatsonstatic int 2171172955Srwatsonbiba_socket_check_relabel(struct ucred *cred, struct socket *so, 2172168976Srwatson struct label *solabel, struct label *newlabel) 2173101099Srwatson{ 2174101099Srwatson struct mac_biba *subj, *obj, *new; 2175105634Srwatson int error; 2176101099Srwatson 2177101099Srwatson new = SLOT(newlabel); 2178122524Srwatson subj = SLOT(cred->cr_label); 2179168976Srwatson obj = SLOT(solabel); 2180101099Srwatson 2181101099Srwatson /* 2182172955Srwatson * If there is a Biba label update for the socket, it may be an 2183172955Srwatson * update of effective. 2184101099Srwatson */ 2185132232Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2186105634Srwatson if (error) 2187105634Srwatson return (error); 2188101099Srwatson 2189101099Srwatson /* 2190172955Srwatson * To relabel a socket, the old socket effective must be in the 2191172955Srwatson * subject range. 2192101099Srwatson */ 2193172955Srwatson if (!biba_effective_in_range(obj, subj)) 2194101099Srwatson return (EPERM); 2195101099Srwatson 2196101099Srwatson /* 2197105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2198101099Srwatson */ 2199132232Srwatson if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2200105634Srwatson /* 2201132232Srwatson * To relabel a socket, the new socket effective must be in 2202105634Srwatson * the subject range. 2203105634Srwatson */ 2204172955Srwatson if (!biba_effective_in_range(new, subj)) 2205105634Srwatson return (EPERM); 2206101099Srwatson 2207105634Srwatson /* 2208105634Srwatson * To change the Biba label on the socket to contain EQUAL, 2209105634Srwatson * the subject must have appropriate privilege. 2210105634Srwatson */ 2211172955Srwatson if (biba_contains_equal(new)) { 2212172955Srwatson error = biba_subject_privileged(subj); 2213105634Srwatson if (error) 2214105634Srwatson return (error); 2215105634Srwatson } 2216105634Srwatson } 2217105634Srwatson 2218101099Srwatson return (0); 2219101099Srwatson} 2220101099Srwatson 2221101099Srwatsonstatic int 2222172955Srwatsonbiba_socket_check_visible(struct ucred *cred, struct socket *so, 2223168976Srwatson struct label *solabel) 2224101099Srwatson{ 2225101099Srwatson struct mac_biba *subj, *obj; 2226101099Srwatson 2227172955Srwatson if (!biba_enabled) 2228105722Srwatson return (0); 2229105722Srwatson 2230122524Srwatson subj = SLOT(cred->cr_label); 2231168976Srwatson obj = SLOT(solabel); 2232101099Srwatson 2233172955Srwatson if (!biba_dominate_effective(obj, subj)) 2234101099Srwatson return (ENOENT); 2235101099Srwatson 2236101099Srwatson return (0); 2237101099Srwatson} 2238101099Srwatson 2239168951Srwatson/* 2240168951Srwatson * Some system privileges are allowed regardless of integrity grade; others 2241168951Srwatson * are allowed only when running with privilege with respect to the Biba 2242168951Srwatson * policy as they might otherwise allow bypassing of the integrity policy. 2243168951Srwatson */ 2244101099Srwatsonstatic int 2245172955Srwatsonbiba_priv_check(struct ucred *cred, int priv) 2246112574Srwatson{ 2247112574Srwatson struct mac_biba *subj; 2248112574Srwatson int error; 2249112574Srwatson 2250172955Srwatson if (!biba_enabled) 2251112574Srwatson return (0); 2252112574Srwatson 2253168951Srwatson /* 2254168951Srwatson * Exempt only specific privileges from the Biba integrity policy. 2255168951Srwatson */ 2256168951Srwatson switch (priv) { 2257168951Srwatson case PRIV_KTRACE: 2258168951Srwatson case PRIV_MSGBUF: 2259112574Srwatson 2260168951Srwatson /* 2261168951Srwatson * Allow processes to manipulate basic process audit properties, and 2262168951Srwatson * to submit audit records. 2263168951Srwatson */ 2264168951Srwatson case PRIV_AUDIT_GETAUDIT: 2265168951Srwatson case PRIV_AUDIT_SETAUDIT: 2266168951Srwatson case PRIV_AUDIT_SUBMIT: 2267112574Srwatson 2268168951Srwatson /* 2269168951Srwatson * Allow processes to manipulate their regular UNIX credentials. 2270168951Srwatson */ 2271168951Srwatson case PRIV_CRED_SETUID: 2272168951Srwatson case PRIV_CRED_SETEUID: 2273168951Srwatson case PRIV_CRED_SETGID: 2274168951Srwatson case PRIV_CRED_SETEGID: 2275168951Srwatson case PRIV_CRED_SETGROUPS: 2276168951Srwatson case PRIV_CRED_SETREUID: 2277168951Srwatson case PRIV_CRED_SETREGID: 2278168951Srwatson case PRIV_CRED_SETRESUID: 2279168951Srwatson case PRIV_CRED_SETRESGID: 2280168951Srwatson 2281168951Srwatson /* 2282168951Srwatson * Allow processes to perform system monitoring. 2283168951Srwatson */ 2284168951Srwatson case PRIV_SEEOTHERGIDS: 2285168951Srwatson case PRIV_SEEOTHERUIDS: 2286168951Srwatson break; 2287168951Srwatson 2288168951Srwatson /* 2289168951Srwatson * Allow access to general process debugging facilities. We 2290168951Srwatson * separately control debugging based on MAC label. 2291168951Srwatson */ 2292168951Srwatson case PRIV_DEBUG_DIFFCRED: 2293168951Srwatson case PRIV_DEBUG_SUGID: 2294168951Srwatson case PRIV_DEBUG_UNPRIV: 2295168951Srwatson 2296168951Srwatson /* 2297168951Srwatson * Allow manipulating jails. 2298168951Srwatson */ 2299168951Srwatson case PRIV_JAIL_ATTACH: 2300168951Srwatson 2301168951Srwatson /* 2302168951Srwatson * Allow privilege with respect to the Partition policy, but not the 2303168951Srwatson * Privs policy. 2304168951Srwatson */ 2305168951Srwatson case PRIV_MAC_PARTITION: 2306168951Srwatson 2307168951Srwatson /* 2308168951Srwatson * Allow privilege with respect to process resource limits and login 2309168951Srwatson * context. 2310168951Srwatson */ 2311168951Srwatson case PRIV_PROC_LIMIT: 2312168951Srwatson case PRIV_PROC_SETLOGIN: 2313168951Srwatson case PRIV_PROC_SETRLIMIT: 2314168951Srwatson 2315168951Srwatson /* 2316168951Srwatson * Allow System V and POSIX IPC privileges. 2317168951Srwatson */ 2318168951Srwatson case PRIV_IPC_READ: 2319168951Srwatson case PRIV_IPC_WRITE: 2320168951Srwatson case PRIV_IPC_ADMIN: 2321168951Srwatson case PRIV_IPC_MSGSIZE: 2322168951Srwatson case PRIV_MQ_ADMIN: 2323168951Srwatson 2324168951Srwatson /* 2325168951Srwatson * Allow certain scheduler manipulations -- possibly this should be 2326168951Srwatson * controlled by more fine-grained policy, as potentially low 2327168951Srwatson * integrity processes can deny CPU to higher integrity ones. 2328168951Srwatson */ 2329168951Srwatson case PRIV_SCHED_DIFFCRED: 2330168951Srwatson case PRIV_SCHED_SETPRIORITY: 2331168951Srwatson case PRIV_SCHED_RTPRIO: 2332168951Srwatson case PRIV_SCHED_SETPOLICY: 2333168951Srwatson case PRIV_SCHED_SET: 2334168951Srwatson case PRIV_SCHED_SETPARAM: 2335168951Srwatson 2336168951Srwatson /* 2337168951Srwatson * More IPC privileges. 2338168951Srwatson */ 2339168951Srwatson case PRIV_SEM_WRITE: 2340168951Srwatson 2341168951Srwatson /* 2342168951Srwatson * Allow signaling privileges subject to integrity policy. 2343168951Srwatson */ 2344168951Srwatson case PRIV_SIGNAL_DIFFCRED: 2345168951Srwatson case PRIV_SIGNAL_SUGID: 2346168951Srwatson 2347168951Srwatson /* 2348168951Srwatson * Allow access to only limited sysctls from lower integrity levels; 2349168951Srwatson * piggy-back on the Jail definition. 2350168951Srwatson */ 2351168951Srwatson case PRIV_SYSCTL_WRITEJAIL: 2352168951Srwatson 2353168951Srwatson /* 2354168951Srwatson * Allow TTY-based privileges, subject to general device access using 2355168951Srwatson * labels on TTY device nodes, but not console privilege. 2356168951Srwatson */ 2357168951Srwatson case PRIV_TTY_DRAINWAIT: 2358168951Srwatson case PRIV_TTY_DTRWAIT: 2359168951Srwatson case PRIV_TTY_EXCLUSIVE: 2360168951Srwatson case PRIV_TTY_PRISON: 2361168951Srwatson case PRIV_TTY_STI: 2362168951Srwatson case PRIV_TTY_SETA: 2363168951Srwatson 2364168951Srwatson /* 2365168951Srwatson * Grant most VFS privileges, as almost all are in practice bounded 2366168951Srwatson * by more specific checks using labels. 2367168951Srwatson */ 2368168951Srwatson case PRIV_VFS_READ: 2369168951Srwatson case PRIV_VFS_WRITE: 2370168951Srwatson case PRIV_VFS_ADMIN: 2371168951Srwatson case PRIV_VFS_EXEC: 2372168951Srwatson case PRIV_VFS_LOOKUP: 2373168951Srwatson case PRIV_VFS_CHFLAGS_DEV: 2374168951Srwatson case PRIV_VFS_CHOWN: 2375168951Srwatson case PRIV_VFS_CHROOT: 2376168951Srwatson case PRIV_VFS_RETAINSUGID: 2377168951Srwatson case PRIV_VFS_EXCEEDQUOTA: 2378168951Srwatson case PRIV_VFS_FCHROOT: 2379168951Srwatson case PRIV_VFS_FHOPEN: 2380168951Srwatson case PRIV_VFS_FHSTATFS: 2381168951Srwatson case PRIV_VFS_GENERATION: 2382168951Srwatson case PRIV_VFS_GETFH: 2383168951Srwatson case PRIV_VFS_GETQUOTA: 2384168951Srwatson case PRIV_VFS_LINK: 2385168951Srwatson case PRIV_VFS_MOUNT: 2386168951Srwatson case PRIV_VFS_MOUNT_OWNER: 2387168951Srwatson case PRIV_VFS_MOUNT_PERM: 2388168951Srwatson case PRIV_VFS_MOUNT_SUIDDIR: 2389168951Srwatson case PRIV_VFS_MOUNT_NONUSER: 2390168951Srwatson case PRIV_VFS_SETGID: 2391168951Srwatson case PRIV_VFS_STICKYFILE: 2392168951Srwatson case PRIV_VFS_SYSFLAGS: 2393168951Srwatson case PRIV_VFS_UNMOUNT: 2394168951Srwatson 2395168951Srwatson /* 2396168951Srwatson * Allow VM privileges; it would be nice if these were subject to 2397168951Srwatson * resource limits. 2398168951Srwatson */ 2399168951Srwatson case PRIV_VM_MADV_PROTECT: 2400168951Srwatson case PRIV_VM_MLOCK: 2401168951Srwatson case PRIV_VM_MUNLOCK: 2402168951Srwatson 2403168951Srwatson /* 2404168951Srwatson * Allow some but not all network privileges. In general, dont allow 2405168951Srwatson * reconfiguring the network stack, just normal use. 2406168951Srwatson */ 2407168951Srwatson case PRIV_NETATALK_RESERVEDPORT: 2408168951Srwatson case PRIV_NETINET_RESERVEDPORT: 2409168951Srwatson case PRIV_NETINET_RAW: 2410168951Srwatson case PRIV_NETINET_REUSEPORT: 2411168951Srwatson case PRIV_NETIPX_RESERVEDPORT: 2412168951Srwatson case PRIV_NETIPX_RAW: 2413168951Srwatson break; 2414168951Srwatson 2415168951Srwatson /* 2416168951Srwatson * All remaining system privileges are allow only if the process 2417168951Srwatson * holds privilege with respect to the Biba policy. 2418168951Srwatson */ 2419168951Srwatson default: 2420168951Srwatson subj = SLOT(cred->cr_label); 2421172955Srwatson error = biba_subject_privileged(subj); 2422168951Srwatson if (error) 2423168951Srwatson return (error); 2424168951Srwatson } 2425112574Srwatson return (0); 2426112574Srwatson} 2427112574Srwatson 2428112574Srwatsonstatic int 2429172955Srwatsonbiba_system_check_acct(struct ucred *cred, struct vnode *vp, 2430168976Srwatson struct label *vplabel) 2431106418Srwatson{ 2432106418Srwatson struct mac_biba *subj, *obj; 2433106418Srwatson int error; 2434106418Srwatson 2435172955Srwatson if (!biba_enabled) 2436106418Srwatson return (0); 2437106418Srwatson 2438122524Srwatson subj = SLOT(cred->cr_label); 2439106418Srwatson 2440172955Srwatson error = biba_subject_privileged(subj); 2441106418Srwatson if (error) 2442106418Srwatson return (error); 2443106418Srwatson 2444168976Srwatson if (vplabel == NULL) 2445106418Srwatson return (0); 2446106418Srwatson 2447168976Srwatson obj = SLOT(vplabel); 2448172955Srwatson if (!biba_high_effective(obj)) 2449106418Srwatson return (EACCES); 2450106418Srwatson 2451106418Srwatson return (0); 2452106418Srwatson} 2453106418Srwatson 2454106418Srwatsonstatic int 2455172955Srwatsonbiba_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2456168933Srwatson struct label *vplabel) 2457168933Srwatson{ 2458168933Srwatson struct mac_biba *subj, *obj; 2459168933Srwatson int error; 2460168933Srwatson 2461172955Srwatson if (!biba_enabled) 2462168933Srwatson return (0); 2463168933Srwatson 2464168933Srwatson subj = SLOT(cred->cr_label); 2465168933Srwatson 2466172955Srwatson error = biba_subject_privileged(subj); 2467168933Srwatson if (error) 2468168933Srwatson return (error); 2469168933Srwatson 2470168933Srwatson if (vplabel == NULL) 2471168933Srwatson return (0); 2472168933Srwatson 2473168933Srwatson obj = SLOT(vplabel); 2474172955Srwatson if (!biba_high_effective(obj)) 2475168933Srwatson return (EACCES); 2476168933Srwatson 2477168933Srwatson return (0); 2478168933Srwatson} 2479168933Srwatson 2480168933Srwatsonstatic int 2481172955Srwatsonbiba_system_check_auditon(struct ucred *cred, int cmd) 2482168933Srwatson{ 2483168933Srwatson struct mac_biba *subj; 2484168933Srwatson int error; 2485168933Srwatson 2486172955Srwatson if (!biba_enabled) 2487168933Srwatson return (0); 2488168933Srwatson 2489168933Srwatson subj = SLOT(cred->cr_label); 2490168933Srwatson 2491172955Srwatson error = biba_subject_privileged(subj); 2492168933Srwatson if (error) 2493168933Srwatson return (error); 2494168933Srwatson 2495168933Srwatson return (0); 2496168933Srwatson} 2497168933Srwatson 2498168933Srwatsonstatic int 2499172955Srwatsonbiba_system_check_swapon(struct ucred *cred, struct vnode *vp, 2500168976Srwatson struct label *vplabel) 2501106161Srwatson{ 2502106161Srwatson struct mac_biba *subj, *obj; 2503106416Srwatson int error; 2504106161Srwatson 2505172955Srwatson if (!biba_enabled) 2506106161Srwatson return (0); 2507106161Srwatson 2508122524Srwatson subj = SLOT(cred->cr_label); 2509168976Srwatson obj = SLOT(vplabel); 2510106161Srwatson 2511172955Srwatson error = biba_subject_privileged(subj); 2512106416Srwatson if (error) 2513106416Srwatson return (error); 2514106161Srwatson 2515172955Srwatson if (!biba_high_effective(obj)) 2516106161Srwatson return (EACCES); 2517106161Srwatson 2518106161Srwatson return (0); 2519106161Srwatson} 2520106161Srwatson 2521106161Srwatsonstatic int 2522172955Srwatsonbiba_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2523112574Srwatson struct label *label) 2524112574Srwatson{ 2525166617Srwatson struct mac_biba *subj; 2526112574Srwatson int error; 2527112574Srwatson 2528172955Srwatson if (!biba_enabled) 2529112574Srwatson return (0); 2530112574Srwatson 2531122524Srwatson subj = SLOT(cred->cr_label); 2532112574Srwatson 2533172955Srwatson error = biba_subject_privileged(subj); 2534112574Srwatson if (error) 2535112574Srwatson return (error); 2536112574Srwatson 2537112574Srwatson return (0); 2538112574Srwatson} 2539112574Srwatson 2540112574Srwatsonstatic int 2541172955Srwatsonbiba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2542126121Spjd void *arg1, int arg2, struct sysctl_req *req) 2543106161Srwatson{ 2544106161Srwatson struct mac_biba *subj; 2545106161Srwatson int error; 2546106161Srwatson 2547172955Srwatson if (!biba_enabled) 2548106161Srwatson return (0); 2549106161Srwatson 2550122524Srwatson subj = SLOT(cred->cr_label); 2551106161Srwatson 2552106161Srwatson /* 2553172955Srwatson * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high, 2554172955Srwatson * but also require privilege to change them. 2555106161Srwatson */ 2556126121Spjd if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2557172955Srwatson if (!biba_subject_dominate_high(subj)) 2558106161Srwatson return (EACCES); 2559106161Srwatson 2560172955Srwatson error = biba_subject_privileged(subj); 2561106161Srwatson if (error) 2562106161Srwatson return (error); 2563106161Srwatson } 2564106161Srwatson 2565106161Srwatson return (0); 2566106161Srwatson} 2567106161Srwatson 2568106161Srwatsonstatic int 2569172955Srwatsonbiba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2570168976Srwatson struct label *dvplabel) 2571101099Srwatson{ 2572101099Srwatson struct mac_biba *subj, *obj; 2573101099Srwatson 2574172955Srwatson if (!biba_enabled) 2575101099Srwatson return (0); 2576101099Srwatson 2577122524Srwatson subj = SLOT(cred->cr_label); 2578168976Srwatson obj = SLOT(dvplabel); 2579101099Srwatson 2580172955Srwatson if (!biba_dominate_effective(obj, subj)) 2581101099Srwatson return (EACCES); 2582101099Srwatson 2583101099Srwatson return (0); 2584101099Srwatson} 2585101099Srwatson 2586101099Srwatsonstatic int 2587172955Srwatsonbiba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2588168976Srwatson struct label *dvplabel) 2589101099Srwatson{ 2590101099Srwatson struct mac_biba *subj, *obj; 2591101099Srwatson 2592172955Srwatson if (!biba_enabled) 2593101099Srwatson return (0); 2594101099Srwatson 2595122524Srwatson subj = SLOT(cred->cr_label); 2596168976Srwatson obj = SLOT(dvplabel); 2597101099Srwatson 2598172955Srwatson if (!biba_dominate_effective(obj, subj)) 2599101099Srwatson return (EACCES); 2600101099Srwatson 2601101099Srwatson return (0); 2602101099Srwatson} 2603101099Srwatson 2604101099Srwatsonstatic int 2605172955Srwatsonbiba_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2606168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2607101099Srwatson{ 2608101099Srwatson struct mac_biba *subj, *obj; 2609101099Srwatson 2610172955Srwatson if (!biba_enabled) 2611101099Srwatson return (0); 2612101099Srwatson 2613122524Srwatson subj = SLOT(cred->cr_label); 2614168976Srwatson obj = SLOT(dvplabel); 2615101099Srwatson 2616172955Srwatson if (!biba_dominate_effective(subj, obj)) 2617101099Srwatson return (EACCES); 2618101099Srwatson 2619101099Srwatson return (0); 2620101099Srwatson} 2621101099Srwatson 2622101099Srwatsonstatic int 2623172955Srwatsonbiba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2624168976Srwatson struct label *vplabel, acl_type_t type) 2625101099Srwatson{ 2626101099Srwatson struct mac_biba *subj, *obj; 2627101099Srwatson 2628172955Srwatson if (!biba_enabled) 2629101099Srwatson return (0); 2630101099Srwatson 2631122524Srwatson subj = SLOT(cred->cr_label); 2632168976Srwatson obj = SLOT(vplabel); 2633101099Srwatson 2634172955Srwatson if (!biba_dominate_effective(subj, obj)) 2635101099Srwatson return (EACCES); 2636101099Srwatson 2637101099Srwatson return (0); 2638101099Srwatson} 2639101099Srwatson 2640101099Srwatsonstatic int 2641172955Srwatsonbiba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2642168976Srwatson struct label *vplabel, int attrnamespace, const char *name) 2643119202Srwatson{ 2644119202Srwatson struct mac_biba *subj, *obj; 2645119202Srwatson 2646172955Srwatson if (!biba_enabled) 2647119202Srwatson return (0); 2648119202Srwatson 2649122524Srwatson subj = SLOT(cred->cr_label); 2650168976Srwatson obj = SLOT(vplabel); 2651119202Srwatson 2652172955Srwatson if (!biba_dominate_effective(subj, obj)) 2653119202Srwatson return (EACCES); 2654119202Srwatson 2655119202Srwatson return (0); 2656119202Srwatson} 2657119202Srwatson 2658119202Srwatsonstatic int 2659172955Srwatsonbiba_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2660168976Srwatson struct label *vplabel, struct image_params *imgp, 2661106648Srwatson struct label *execlabel) 2662101099Srwatson{ 2663106648Srwatson struct mac_biba *subj, *obj, *exec; 2664106648Srwatson int error; 2665101099Srwatson 2666106648Srwatson if (execlabel != NULL) { 2667106648Srwatson /* 2668106648Srwatson * We currently don't permit labels to be changed at 2669172955Srwatson * exec-time as part of Biba, so disallow non-NULL Biba label 2670172955Srwatson * elements in the execlabel. 2671106648Srwatson */ 2672106648Srwatson exec = SLOT(execlabel); 2673106648Srwatson error = biba_atmostflags(exec, 0); 2674106648Srwatson if (error) 2675106648Srwatson return (error); 2676106648Srwatson } 2677106648Srwatson 2678172955Srwatson if (!biba_enabled) 2679101099Srwatson return (0); 2680101099Srwatson 2681122524Srwatson subj = SLOT(cred->cr_label); 2682168976Srwatson obj = SLOT(vplabel); 2683101099Srwatson 2684172955Srwatson if (!biba_dominate_effective(obj, subj)) 2685101099Srwatson return (EACCES); 2686101099Srwatson 2687101099Srwatson return (0); 2688101099Srwatson} 2689101099Srwatson 2690101099Srwatsonstatic int 2691172955Srwatsonbiba_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2692168976Srwatson struct label *vplabel, acl_type_t type) 2693101099Srwatson{ 2694101099Srwatson struct mac_biba *subj, *obj; 2695101099Srwatson 2696172955Srwatson if (!biba_enabled) 2697101099Srwatson return (0); 2698101099Srwatson 2699122524Srwatson subj = SLOT(cred->cr_label); 2700168976Srwatson obj = SLOT(vplabel); 2701101099Srwatson 2702172955Srwatson if (!biba_dominate_effective(obj, subj)) 2703101099Srwatson return (EACCES); 2704101099Srwatson 2705101099Srwatson return (0); 2706101099Srwatson} 2707101099Srwatson 2708101099Srwatsonstatic int 2709172955Srwatsonbiba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 2710168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 2711168976Srwatson struct uio *uio) 2712101099Srwatson{ 2713101099Srwatson struct mac_biba *subj, *obj; 2714101099Srwatson 2715172955Srwatson if (!biba_enabled) 2716101099Srwatson return (0); 2717101099Srwatson 2718122524Srwatson subj = SLOT(cred->cr_label); 2719168976Srwatson obj = SLOT(vplabel); 2720101099Srwatson 2721172955Srwatson if (!biba_dominate_effective(obj, subj)) 2722101099Srwatson return (EACCES); 2723101099Srwatson 2724101099Srwatson return (0); 2725101099Srwatson} 2726101099Srwatson 2727101099Srwatsonstatic int 2728172955Srwatsonbiba_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2729168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2730104530Srwatson struct componentname *cnp) 2731104530Srwatson{ 2732104530Srwatson struct mac_biba *subj, *obj; 2733104530Srwatson 2734172955Srwatson if (!biba_enabled) 2735104530Srwatson return (0); 2736104530Srwatson 2737122524Srwatson subj = SLOT(cred->cr_label); 2738168976Srwatson obj = SLOT(dvplabel); 2739104530Srwatson 2740172955Srwatson if (!biba_dominate_effective(subj, obj)) 2741104530Srwatson return (EACCES); 2742104530Srwatson 2743168976Srwatson obj = SLOT(vplabel); 2744104530Srwatson 2745172955Srwatson if (!biba_dominate_effective(subj, obj)) 2746104530Srwatson return (EACCES); 2747104530Srwatson 2748104530Srwatson return (0); 2749104530Srwatson} 2750104530Srwatson 2751104530Srwatsonstatic int 2752172955Srwatsonbiba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 2753168976Srwatson struct label *vplabel, int attrnamespace) 2754119202Srwatson{ 2755119202Srwatson struct mac_biba *subj, *obj; 2756119202Srwatson 2757172955Srwatson if (!biba_enabled) 2758119202Srwatson return (0); 2759119202Srwatson 2760122524Srwatson subj = SLOT(cred->cr_label); 2761168976Srwatson obj = SLOT(vplabel); 2762119202Srwatson 2763172955Srwatson if (!biba_dominate_effective(obj, subj)) 2764119202Srwatson return (EACCES); 2765119202Srwatson 2766119202Srwatson return (0); 2767119202Srwatson} 2768119202Srwatson 2769119202Srwatsonstatic int 2770172955Srwatsonbiba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 2771168976Srwatson struct label *dvplabel, struct componentname *cnp) 2772101099Srwatson{ 2773101099Srwatson struct mac_biba *subj, *obj; 2774103759Srwatson 2775172955Srwatson if (!biba_enabled) 2776101099Srwatson return (0); 2777103759Srwatson 2778122524Srwatson subj = SLOT(cred->cr_label); 2779168976Srwatson obj = SLOT(dvplabel); 2780103759Srwatson 2781172955Srwatson if (!biba_dominate_effective(obj, subj)) 2782101099Srwatson return (EACCES); 2783101099Srwatson 2784103759Srwatson return (0); 2785101099Srwatson} 2786101099Srwatson 2787101099Srwatsonstatic int 2788172955Srwatsonbiba_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2789168976Srwatson struct label *vplabel, int prot, int flags) 2790104546Srwatson{ 2791104546Srwatson struct mac_biba *subj, *obj; 2792104546Srwatson 2793104546Srwatson /* 2794104546Srwatson * Rely on the use of open()-time protections to handle 2795104546Srwatson * non-revocation cases. 2796104546Srwatson */ 2797172955Srwatson if (!biba_enabled || !revocation_enabled) 2798104546Srwatson return (0); 2799104546Srwatson 2800122524Srwatson subj = SLOT(cred->cr_label); 2801168976Srwatson obj = SLOT(vplabel); 2802104546Srwatson 2803104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2804172955Srwatson if (!biba_dominate_effective(obj, subj)) 2805104546Srwatson return (EACCES); 2806104546Srwatson } 2807145076Scsjp if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2808172955Srwatson if (!biba_dominate_effective(subj, obj)) 2809104546Srwatson return (EACCES); 2810104546Srwatson } 2811104546Srwatson 2812104569Srwatson return (0); 2813104546Srwatson} 2814104546Srwatson 2815104546Srwatsonstatic int 2816172955Srwatsonbiba_vnode_check_open(struct ucred *cred, struct vnode *vp, 2817168976Srwatson struct label *vplabel, int acc_mode) 2818101099Srwatson{ 2819101099Srwatson struct mac_biba *subj, *obj; 2820101099Srwatson 2821172955Srwatson if (!biba_enabled) 2822101099Srwatson return (0); 2823101099Srwatson 2824122524Srwatson subj = SLOT(cred->cr_label); 2825168976Srwatson obj = SLOT(vplabel); 2826101099Srwatson 2827101099Srwatson /* XXX privilege override for admin? */ 2828101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2829172955Srwatson if (!biba_dominate_effective(obj, subj)) 2830101099Srwatson return (EACCES); 2831101099Srwatson } 2832101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2833172955Srwatson if (!biba_dominate_effective(subj, obj)) 2834101099Srwatson return (EACCES); 2835101099Srwatson } 2836101099Srwatson 2837101099Srwatson return (0); 2838101099Srwatson} 2839101099Srwatson 2840101099Srwatsonstatic int 2841172955Srwatsonbiba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 2842168976Srwatson struct vnode *vp, struct label *vplabel) 2843102112Srwatson{ 2844102112Srwatson struct mac_biba *subj, *obj; 2845102112Srwatson 2846172955Srwatson if (!biba_enabled || !revocation_enabled) 2847102112Srwatson return (0); 2848102112Srwatson 2849122524Srwatson subj = SLOT(active_cred->cr_label); 2850168976Srwatson obj = SLOT(vplabel); 2851102112Srwatson 2852172955Srwatson if (!biba_dominate_effective(obj, subj)) 2853102112Srwatson return (EACCES); 2854102112Srwatson 2855102112Srwatson return (0); 2856102112Srwatson} 2857102112Srwatson 2858102112Srwatsonstatic int 2859172955Srwatsonbiba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2860168976Srwatson struct vnode *vp, struct label *vplabel) 2861102112Srwatson{ 2862102112Srwatson struct mac_biba *subj, *obj; 2863102112Srwatson 2864172955Srwatson if (!biba_enabled || !revocation_enabled) 2865102112Srwatson return (0); 2866102112Srwatson 2867122524Srwatson subj = SLOT(active_cred->cr_label); 2868168976Srwatson obj = SLOT(vplabel); 2869102112Srwatson 2870172955Srwatson if (!biba_dominate_effective(obj, subj)) 2871102112Srwatson return (EACCES); 2872102112Srwatson 2873102112Srwatson return (0); 2874102112Srwatson} 2875102112Srwatson 2876102112Srwatsonstatic int 2877172955Srwatsonbiba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 2878168976Srwatson struct label *dvplabel) 2879101099Srwatson{ 2880101099Srwatson struct mac_biba *subj, *obj; 2881101099Srwatson 2882172955Srwatson if (!biba_enabled) 2883101099Srwatson return (0); 2884101099Srwatson 2885122524Srwatson subj = SLOT(cred->cr_label); 2886168976Srwatson obj = SLOT(dvplabel); 2887101099Srwatson 2888172955Srwatson if (!biba_dominate_effective(obj, subj)) 2889101099Srwatson return (EACCES); 2890101099Srwatson 2891101099Srwatson return (0); 2892101099Srwatson} 2893101099Srwatson 2894101099Srwatsonstatic int 2895172955Srwatsonbiba_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 2896168976Srwatson struct label *vplabel) 2897101099Srwatson{ 2898101099Srwatson struct mac_biba *subj, *obj; 2899101099Srwatson 2900172955Srwatson if (!biba_enabled) 2901101099Srwatson return (0); 2902101099Srwatson 2903122524Srwatson subj = SLOT(cred->cr_label); 2904168976Srwatson obj = SLOT(vplabel); 2905101099Srwatson 2906172955Srwatson if (!biba_dominate_effective(obj, subj)) 2907101099Srwatson return (EACCES); 2908101099Srwatson 2909101099Srwatson return (0); 2910101099Srwatson} 2911101099Srwatson 2912101099Srwatsonstatic int 2913172955Srwatsonbiba_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2914168976Srwatson struct label *vplabel, struct label *newlabel) 2915101099Srwatson{ 2916101099Srwatson struct mac_biba *old, *new, *subj; 2917105634Srwatson int error; 2918101099Srwatson 2919168976Srwatson old = SLOT(vplabel); 2920101099Srwatson new = SLOT(newlabel); 2921122524Srwatson subj = SLOT(cred->cr_label); 2922101099Srwatson 2923101099Srwatson /* 2924105634Srwatson * If there is a Biba label update for the vnode, it must be a 2925132232Srwatson * effective label. 2926101099Srwatson */ 2927132232Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2928105634Srwatson if (error) 2929105634Srwatson return (error); 2930101099Srwatson 2931101099Srwatson /* 2932105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2933105634Srwatson * authorize the relabel. 2934101099Srwatson */ 2935172955Srwatson if (!biba_effective_in_range(old, subj)) 2936101099Srwatson return (EPERM); 2937101099Srwatson 2938101099Srwatson /* 2939105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2940101099Srwatson */ 2941132232Srwatson if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2942105634Srwatson /* 2943105634Srwatson * To change the Biba label on a vnode, the new vnode label 2944105634Srwatson * must be in the subject range. 2945105634Srwatson */ 2946172955Srwatson if (!biba_effective_in_range(new, subj)) 2947105634Srwatson return (EPERM); 2948101099Srwatson 2949105634Srwatson /* 2950172955Srwatson * To change the Biba label on the vnode to be EQUAL, the 2951172955Srwatson * subject must have appropriate privilege. 2952105634Srwatson */ 2953172955Srwatson if (biba_contains_equal(new)) { 2954172955Srwatson error = biba_subject_privileged(subj); 2955105634Srwatson if (error) 2956105634Srwatson return (error); 2957105634Srwatson } 2958105634Srwatson } 2959105634Srwatson 2960105634Srwatson return (0); 2961101099Srwatson} 2962101099Srwatson 2963101099Srwatsonstatic int 2964172955Srwatsonbiba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2965168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2966101099Srwatson struct componentname *cnp) 2967101099Srwatson{ 2968101099Srwatson struct mac_biba *subj, *obj; 2969101099Srwatson 2970172955Srwatson if (!biba_enabled) 2971101099Srwatson return (0); 2972101099Srwatson 2973122524Srwatson subj = SLOT(cred->cr_label); 2974168976Srwatson obj = SLOT(dvplabel); 2975101099Srwatson 2976172955Srwatson if (!biba_dominate_effective(subj, obj)) 2977101099Srwatson return (EACCES); 2978101099Srwatson 2979168976Srwatson obj = SLOT(vplabel); 2980101099Srwatson 2981172955Srwatson if (!biba_dominate_effective(subj, obj)) 2982101099Srwatson return (EACCES); 2983101099Srwatson 2984101099Srwatson return (0); 2985101099Srwatson} 2986101099Srwatson 2987101099Srwatsonstatic int 2988172955Srwatsonbiba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2989168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2990168976Srwatson int samedir, struct componentname *cnp) 2991101099Srwatson{ 2992101099Srwatson struct mac_biba *subj, *obj; 2993101099Srwatson 2994172955Srwatson if (!biba_enabled) 2995101099Srwatson return (0); 2996101099Srwatson 2997122524Srwatson subj = SLOT(cred->cr_label); 2998168976Srwatson obj = SLOT(dvplabel); 2999101099Srwatson 3000172955Srwatson if (!biba_dominate_effective(subj, obj)) 3001101099Srwatson return (EACCES); 3002101099Srwatson 3003101099Srwatson if (vp != NULL) { 3004168976Srwatson obj = SLOT(vplabel); 3005101099Srwatson 3006172955Srwatson if (!biba_dominate_effective(subj, obj)) 3007101099Srwatson return (EACCES); 3008101099Srwatson } 3009101099Srwatson 3010101099Srwatson return (0); 3011101099Srwatson} 3012101099Srwatson 3013101099Srwatsonstatic int 3014172955Srwatsonbiba_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 3015168976Srwatson struct label *vplabel) 3016101099Srwatson{ 3017101099Srwatson struct mac_biba *subj, *obj; 3018101099Srwatson 3019172955Srwatson if (!biba_enabled) 3020101099Srwatson return (0); 3021101099Srwatson 3022122524Srwatson subj = SLOT(cred->cr_label); 3023168976Srwatson obj = SLOT(vplabel); 3024101099Srwatson 3025172955Srwatson if (!biba_dominate_effective(subj, obj)) 3026101099Srwatson return (EACCES); 3027101099Srwatson 3028101099Srwatson return (0); 3029101099Srwatson} 3030101099Srwatson 3031101099Srwatsonstatic int 3032172955Srwatsonbiba_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 3033168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 3034101099Srwatson{ 3035101099Srwatson struct mac_biba *subj, *obj; 3036101099Srwatson 3037172955Srwatson if (!biba_enabled) 3038101099Srwatson return (0); 3039101099Srwatson 3040122524Srwatson subj = SLOT(cred->cr_label); 3041168976Srwatson obj = SLOT(vplabel); 3042101099Srwatson 3043172955Srwatson if (!biba_dominate_effective(subj, obj)) 3044101099Srwatson return (EACCES); 3045101099Srwatson 3046101099Srwatson return (0); 3047101099Srwatson} 3048101099Srwatson 3049101099Srwatsonstatic int 3050172955Srwatsonbiba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 3051168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 3052101099Srwatson struct uio *uio) 3053101099Srwatson{ 3054101099Srwatson struct mac_biba *subj, *obj; 3055101099Srwatson 3056172955Srwatson if (!biba_enabled) 3057101099Srwatson return (0); 3058101099Srwatson 3059122524Srwatson subj = SLOT(cred->cr_label); 3060168976Srwatson obj = SLOT(vplabel); 3061101099Srwatson 3062172955Srwatson if (!biba_dominate_effective(subj, obj)) 3063101099Srwatson return (EACCES); 3064101099Srwatson 3065101099Srwatson /* XXX: protect the MAC EA in a special way? */ 3066101099Srwatson 3067101099Srwatson return (0); 3068101099Srwatson} 3069101099Srwatson 3070101099Srwatsonstatic int 3071172955Srwatsonbiba_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 3072168976Srwatson struct label *vplabel, u_long flags) 3073101099Srwatson{ 3074101099Srwatson struct mac_biba *subj, *obj; 3075101099Srwatson 3076172955Srwatson if (!biba_enabled) 3077101099Srwatson return (0); 3078101099Srwatson 3079122524Srwatson subj = SLOT(cred->cr_label); 3080168976Srwatson obj = SLOT(vplabel); 3081101099Srwatson 3082172955Srwatson if (!biba_dominate_effective(subj, obj)) 3083101099Srwatson return (EACCES); 3084101099Srwatson 3085101099Srwatson return (0); 3086101099Srwatson} 3087101099Srwatson 3088101099Srwatsonstatic int 3089172955Srwatsonbiba_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 3090168976Srwatson struct label *vplabel, mode_t mode) 3091101099Srwatson{ 3092101099Srwatson struct mac_biba *subj, *obj; 3093101099Srwatson 3094172955Srwatson if (!biba_enabled) 3095101099Srwatson return (0); 3096101099Srwatson 3097122524Srwatson subj = SLOT(cred->cr_label); 3098168976Srwatson obj = SLOT(vplabel); 3099101099Srwatson 3100172955Srwatson if (!biba_dominate_effective(subj, obj)) 3101101099Srwatson return (EACCES); 3102101099Srwatson 3103101099Srwatson return (0); 3104101099Srwatson} 3105101099Srwatson 3106101099Srwatsonstatic int 3107172955Srwatsonbiba_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 3108168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 3109101099Srwatson{ 3110101099Srwatson struct mac_biba *subj, *obj; 3111101099Srwatson 3112172955Srwatson if (!biba_enabled) 3113101099Srwatson return (0); 3114101099Srwatson 3115122524Srwatson subj = SLOT(cred->cr_label); 3116168976Srwatson obj = SLOT(vplabel); 3117101099Srwatson 3118172955Srwatson if (!biba_dominate_effective(subj, obj)) 3119101099Srwatson return (EACCES); 3120101099Srwatson 3121101099Srwatson return (0); 3122101099Srwatson} 3123101099Srwatson 3124101099Srwatsonstatic int 3125172955Srwatsonbiba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 3126168976Srwatson struct label *vplabel, struct timespec atime, struct timespec mtime) 3127101099Srwatson{ 3128101099Srwatson struct mac_biba *subj, *obj; 3129101099Srwatson 3130172955Srwatson if (!biba_enabled) 3131101099Srwatson return (0); 3132101099Srwatson 3133122524Srwatson subj = SLOT(cred->cr_label); 3134168976Srwatson obj = SLOT(vplabel); 3135101099Srwatson 3136172955Srwatson if (!biba_dominate_effective(subj, obj)) 3137101099Srwatson return (EACCES); 3138101099Srwatson 3139101099Srwatson return (0); 3140101099Srwatson} 3141101099Srwatson 3142101099Srwatsonstatic int 3143172955Srwatsonbiba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 3144168976Srwatson struct vnode *vp, struct label *vplabel) 3145101099Srwatson{ 3146101099Srwatson struct mac_biba *subj, *obj; 3147101099Srwatson 3148172955Srwatson if (!biba_enabled) 3149101099Srwatson return (0); 3150101099Srwatson 3151122524Srwatson subj = SLOT(active_cred->cr_label); 3152168976Srwatson obj = SLOT(vplabel); 3153101099Srwatson 3154172955Srwatson if (!biba_dominate_effective(obj, subj)) 3155101099Srwatson return (EACCES); 3156101099Srwatson 3157101099Srwatson return (0); 3158101099Srwatson} 3159101099Srwatson 3160102112Srwatsonstatic int 3161172955Srwatsonbiba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 3162172107Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3163172107Srwatson struct componentname *cnp) 3164172107Srwatson{ 3165172107Srwatson struct mac_biba *subj, *obj; 3166172107Srwatson 3167172955Srwatson if (!biba_enabled) 3168172107Srwatson return (0); 3169172107Srwatson 3170172107Srwatson subj = SLOT(cred->cr_label); 3171172107Srwatson obj = SLOT(dvplabel); 3172172107Srwatson 3173172955Srwatson if (!biba_dominate_effective(subj, obj)) 3174172107Srwatson return (EACCES); 3175172107Srwatson 3176172107Srwatson obj = SLOT(vplabel); 3177172107Srwatson 3178172955Srwatson if (!biba_dominate_effective(subj, obj)) 3179172107Srwatson return (EACCES); 3180172107Srwatson 3181172107Srwatson return (0); 3182172107Srwatson} 3183172107Srwatson 3184172107Srwatsonstatic int 3185172955Srwatsonbiba_vnode_check_write(struct ucred *active_cred, 3186168976Srwatson struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 3187102112Srwatson{ 3188102112Srwatson struct mac_biba *subj, *obj; 3189102112Srwatson 3190172955Srwatson if (!biba_enabled || !revocation_enabled) 3191102112Srwatson return (0); 3192102112Srwatson 3193122524Srwatson subj = SLOT(active_cred->cr_label); 3194168976Srwatson obj = SLOT(vplabel); 3195102112Srwatson 3196172955Srwatson if (!biba_dominate_effective(subj, obj)) 3197102112Srwatson return (EACCES); 3198102112Srwatson 3199102112Srwatson return (0); 3200102112Srwatson} 3201102112Srwatson 3202161026Srwatsonstatic void 3203172955Srwatsonbiba_associate_nfsd_label(struct ucred *cred) 3204160243Scsjp{ 3205160243Scsjp struct mac_biba *label; 3206160243Scsjp 3207160243Scsjp label = SLOT(cred->cr_label); 3208172955Srwatson biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL); 3209172955Srwatson biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 3210172955Srwatson 0, NULL); 3211160243Scsjp} 3212160243Scsjp 3213165150Scsjpstatic void 3214172955Srwatsonbiba_init_syncache_from_inpcb(struct label *label, struct inpcb *inp) 3215165150Scsjp{ 3216165150Scsjp struct mac_biba *source, *dest; 3217165150Scsjp 3218165150Scsjp source = SLOT(inp->inp_label); 3219165150Scsjp dest = SLOT(label); 3220172955Srwatson biba_copy_effective(source, dest); 3221165150Scsjp} 3222165150Scsjp 3223165150Scsjpstatic void 3224172955Srwatsonbiba_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m, 3225168976Srwatson struct label *mlabel) 3226165150Scsjp{ 3227165150Scsjp struct mac_biba *source, *dest; 3228165150Scsjp 3229165150Scsjp source = SLOT(sc_label); 3230168976Srwatson dest = SLOT(mlabel); 3231172955Srwatson biba_copy_effective(source, dest); 3232165150Scsjp} 3233165150Scsjp 3234106217Srwatsonstatic struct mac_policy_ops mac_biba_ops = 3235101099Srwatson{ 3236172955Srwatson .mpo_init = biba_init, 3237172955Srwatson .mpo_bpfdesc_init_label = biba_init_label, 3238172955Srwatson .mpo_cred_init_label = biba_init_label, 3239172955Srwatson .mpo_devfs_init_label = biba_init_label, 3240172955Srwatson .mpo_ifnet_init_label = biba_init_label, 3241172955Srwatson .mpo_inpcb_init_label = biba_init_label_waitcheck, 3242172955Srwatson .mpo_init_syncache_label = biba_init_label_waitcheck, 3243172955Srwatson .mpo_sysvmsg_init_label = biba_init_label, 3244172955Srwatson .mpo_sysvmsq_init_label = biba_init_label, 3245172955Srwatson .mpo_sysvsem_init_label = biba_init_label, 3246172955Srwatson .mpo_sysvshm_init_label = biba_init_label, 3247172955Srwatson .mpo_ipq_init_label = biba_init_label_waitcheck, 3248172955Srwatson .mpo_mbuf_init_label = biba_init_label_waitcheck, 3249172955Srwatson .mpo_mount_init_label = biba_init_label, 3250172955Srwatson .mpo_pipe_init_label = biba_init_label, 3251172955Srwatson .mpo_posixsem_init_label = biba_init_label, 3252172955Srwatson .mpo_socket_init_label = biba_init_label_waitcheck, 3253172955Srwatson .mpo_socketpeer_init_label = biba_init_label_waitcheck, 3254172955Srwatson .mpo_init_syncache_from_inpcb = biba_init_syncache_from_inpcb, 3255172955Srwatson .mpo_vnode_init_label = biba_init_label, 3256172955Srwatson .mpo_bpfdesc_destroy_label = biba_destroy_label, 3257172955Srwatson .mpo_cred_destroy_label = biba_destroy_label, 3258172955Srwatson .mpo_devfs_destroy_label = biba_destroy_label, 3259172955Srwatson .mpo_ifnet_destroy_label = biba_destroy_label, 3260172955Srwatson .mpo_inpcb_destroy_label = biba_destroy_label, 3261172955Srwatson .mpo_destroy_syncache_label = biba_destroy_label, 3262172955Srwatson .mpo_sysvmsg_destroy_label = biba_destroy_label, 3263172955Srwatson .mpo_sysvmsq_destroy_label = biba_destroy_label, 3264172955Srwatson .mpo_sysvsem_destroy_label = biba_destroy_label, 3265172955Srwatson .mpo_sysvshm_destroy_label = biba_destroy_label, 3266172955Srwatson .mpo_ipq_destroy_label = biba_destroy_label, 3267172955Srwatson .mpo_mbuf_destroy_label = biba_destroy_label, 3268172955Srwatson .mpo_mount_destroy_label = biba_destroy_label, 3269172955Srwatson .mpo_pipe_destroy_label = biba_destroy_label, 3270172955Srwatson .mpo_posixsem_destroy_label = biba_destroy_label, 3271172955Srwatson .mpo_socket_destroy_label = biba_destroy_label, 3272172955Srwatson .mpo_socketpeer_destroy_label = biba_destroy_label, 3273172955Srwatson .mpo_vnode_destroy_label = biba_destroy_label, 3274172955Srwatson .mpo_cred_copy_label = biba_copy_label, 3275172955Srwatson .mpo_ifnet_copy_label = biba_copy_label, 3276172955Srwatson .mpo_mbuf_copy_label = biba_copy_label, 3277172955Srwatson .mpo_pipe_copy_label = biba_copy_label, 3278172955Srwatson .mpo_socket_copy_label = biba_copy_label, 3279172955Srwatson .mpo_vnode_copy_label = biba_copy_label, 3280172955Srwatson .mpo_cred_externalize_label = biba_externalize_label, 3281172955Srwatson .mpo_ifnet_externalize_label = biba_externalize_label, 3282172955Srwatson .mpo_pipe_externalize_label = biba_externalize_label, 3283172955Srwatson .mpo_socket_externalize_label = biba_externalize_label, 3284172955Srwatson .mpo_socketpeer_externalize_label = biba_externalize_label, 3285172955Srwatson .mpo_vnode_externalize_label = biba_externalize_label, 3286172955Srwatson .mpo_cred_internalize_label = biba_internalize_label, 3287172955Srwatson .mpo_ifnet_internalize_label = biba_internalize_label, 3288172955Srwatson .mpo_pipe_internalize_label = biba_internalize_label, 3289172955Srwatson .mpo_socket_internalize_label = biba_internalize_label, 3290172955Srwatson .mpo_vnode_internalize_label = biba_internalize_label, 3291172955Srwatson .mpo_devfs_create_device = biba_devfs_create_device, 3292172955Srwatson .mpo_devfs_create_directory = biba_devfs_create_directory, 3293172955Srwatson .mpo_devfs_create_symlink = biba_devfs_create_symlink, 3294172955Srwatson .mpo_mount_create = biba_mount_create, 3295172955Srwatson .mpo_vnode_relabel = biba_vnode_relabel, 3296172955Srwatson .mpo_devfs_update = biba_devfs_update, 3297172955Srwatson .mpo_devfs_vnode_associate = biba_devfs_vnode_associate, 3298172955Srwatson .mpo_vnode_associate_extattr = biba_vnode_associate_extattr, 3299172955Srwatson .mpo_vnode_associate_singlelabel = biba_vnode_associate_singlelabel, 3300172955Srwatson .mpo_vnode_create_extattr = biba_vnode_create_extattr, 3301172955Srwatson .mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr, 3302172955Srwatson .mpo_socket_create_mbuf = biba_socket_create_mbuf, 3303172955Srwatson .mpo_create_mbuf_from_syncache = biba_create_mbuf_from_syncache, 3304172955Srwatson .mpo_pipe_create = biba_pipe_create, 3305172955Srwatson .mpo_posixsem_create = biba_posixsem_create, 3306172955Srwatson .mpo_socket_create = biba_socket_create, 3307172955Srwatson .mpo_socket_newconn = biba_socket_newconn, 3308172955Srwatson .mpo_pipe_relabel = biba_pipe_relabel, 3309172955Srwatson .mpo_socket_relabel = biba_socket_relabel, 3310172955Srwatson .mpo_socketpeer_set_from_mbuf = biba_socketpeer_set_from_mbuf, 3311172955Srwatson .mpo_socketpeer_set_from_socket = biba_socketpeer_set_from_socket, 3312172955Srwatson .mpo_bpfdesc_create = biba_bpfdesc_create, 3313172955Srwatson .mpo_ipq_reassemble = biba_ipq_reassemble, 3314172955Srwatson .mpo_netinet_fragment = biba_netinet_fragment, 3315172955Srwatson .mpo_ifnet_create = biba_ifnet_create, 3316172955Srwatson .mpo_inpcb_create = biba_inpcb_create, 3317172955Srwatson .mpo_sysvmsg_create = biba_sysvmsg_create, 3318172955Srwatson .mpo_sysvmsq_create = biba_sysvmsq_create, 3319172955Srwatson .mpo_sysvsem_create = biba_sysvsem_create, 3320172955Srwatson .mpo_sysvshm_create = biba_sysvshm_create, 3321172955Srwatson .mpo_ipq_create = biba_ipq_create, 3322172955Srwatson .mpo_inpcb_create_mbuf = biba_inpcb_create_mbuf, 3323172955Srwatson .mpo_create_mbuf_linklayer = biba_create_mbuf_linklayer, 3324172955Srwatson .mpo_bpfdesc_create_mbuf = biba_bpfdesc_create_mbuf, 3325172955Srwatson .mpo_ifnet_create_mbuf = biba_ifnet_create_mbuf, 3326172955Srwatson .mpo_mbuf_create_multicast_encap = biba_mbuf_create_multicast_encap, 3327172955Srwatson .mpo_mbuf_create_netlayer = biba_mbuf_create_netlayer, 3328172955Srwatson .mpo_ipq_match = biba_ipq_match, 3329172955Srwatson .mpo_ifnet_relabel = biba_ifnet_relabel, 3330172955Srwatson .mpo_ipq_update = biba_ipq_update, 3331172955Srwatson .mpo_inpcb_sosetlabel = biba_inpcb_sosetlabel, 3332172955Srwatson .mpo_proc_create_swapper = biba_proc_create_swapper, 3333172955Srwatson .mpo_proc_create_init = biba_proc_create_init, 3334172955Srwatson .mpo_cred_relabel = biba_cred_relabel, 3335172955Srwatson .mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup, 3336172955Srwatson .mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup, 3337172955Srwatson .mpo_sysvsem_cleanup = biba_sysvsem_cleanup, 3338172955Srwatson .mpo_sysvshm_cleanup = biba_sysvshm_cleanup, 3339172955Srwatson .mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive, 3340172955Srwatson .mpo_cred_check_relabel = biba_cred_check_relabel, 3341172955Srwatson .mpo_cred_check_visible = biba_cred_check_visible, 3342172955Srwatson .mpo_ifnet_check_relabel = biba_ifnet_check_relabel, 3343172955Srwatson .mpo_ifnet_check_transmit = biba_ifnet_check_transmit, 3344172955Srwatson .mpo_inpcb_check_deliver = biba_inpcb_check_deliver, 3345172955Srwatson .mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv, 3346172955Srwatson .mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid, 3347172955Srwatson .mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget, 3348172955Srwatson .mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd, 3349172955Srwatson .mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv, 3350172955Srwatson .mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl, 3351172955Srwatson .mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl, 3352172955Srwatson .mpo_sysvsem_check_semget = biba_sysvsem_check_semget, 3353172955Srwatson .mpo_sysvsem_check_semop = biba_sysvsem_check_semop, 3354172955Srwatson .mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat, 3355172955Srwatson .mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl, 3356172955Srwatson .mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget, 3357172955Srwatson .mpo_kld_check_load = biba_kld_check_load, 3358172955Srwatson .mpo_mount_check_stat = biba_mount_check_stat, 3359172955Srwatson .mpo_pipe_check_ioctl = biba_pipe_check_ioctl, 3360172955Srwatson .mpo_pipe_check_poll = biba_pipe_check_poll, 3361172955Srwatson .mpo_pipe_check_read = biba_pipe_check_read, 3362172955Srwatson .mpo_pipe_check_relabel = biba_pipe_check_relabel, 3363172955Srwatson .mpo_pipe_check_stat = biba_pipe_check_stat, 3364172955Srwatson .mpo_pipe_check_write = biba_pipe_check_write, 3365172955Srwatson .mpo_posixsem_check_destroy = biba_posixsem_check_write, 3366172955Srwatson .mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly, 3367172955Srwatson .mpo_posixsem_check_open = biba_posixsem_check_write, 3368172955Srwatson .mpo_posixsem_check_post = biba_posixsem_check_write, 3369172955Srwatson .mpo_posixsem_check_unlink = biba_posixsem_check_write, 3370172955Srwatson .mpo_posixsem_check_wait = biba_posixsem_check_write, 3371172955Srwatson .mpo_proc_check_debug = biba_proc_check_debug, 3372172955Srwatson .mpo_proc_check_sched = biba_proc_check_sched, 3373172955Srwatson .mpo_proc_check_signal = biba_proc_check_signal, 3374172955Srwatson .mpo_socket_check_deliver = biba_socket_check_deliver, 3375172955Srwatson .mpo_socket_check_relabel = biba_socket_check_relabel, 3376172955Srwatson .mpo_socket_check_visible = biba_socket_check_visible, 3377172955Srwatson .mpo_system_check_acct = biba_system_check_acct, 3378172955Srwatson .mpo_system_check_auditctl = biba_system_check_auditctl, 3379172955Srwatson .mpo_system_check_auditon = biba_system_check_auditon, 3380172955Srwatson .mpo_system_check_swapon = biba_system_check_swapon, 3381172955Srwatson .mpo_system_check_swapoff = biba_system_check_swapoff, 3382172955Srwatson .mpo_system_check_sysctl = biba_system_check_sysctl, 3383172955Srwatson .mpo_vnode_check_access = biba_vnode_check_open, 3384172955Srwatson .mpo_vnode_check_chdir = biba_vnode_check_chdir, 3385172955Srwatson .mpo_vnode_check_chroot = biba_vnode_check_chroot, 3386172955Srwatson .mpo_vnode_check_create = biba_vnode_check_create, 3387172955Srwatson .mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl, 3388172955Srwatson .mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr, 3389172955Srwatson .mpo_vnode_check_exec = biba_vnode_check_exec, 3390172955Srwatson .mpo_vnode_check_getacl = biba_vnode_check_getacl, 3391172955Srwatson .mpo_vnode_check_getextattr = biba_vnode_check_getextattr, 3392172955Srwatson .mpo_vnode_check_link = biba_vnode_check_link, 3393172955Srwatson .mpo_vnode_check_listextattr = biba_vnode_check_listextattr, 3394172955Srwatson .mpo_vnode_check_lookup = biba_vnode_check_lookup, 3395172955Srwatson .mpo_vnode_check_mmap = biba_vnode_check_mmap, 3396172955Srwatson .mpo_vnode_check_open = biba_vnode_check_open, 3397172955Srwatson .mpo_vnode_check_poll = biba_vnode_check_poll, 3398172955Srwatson .mpo_vnode_check_read = biba_vnode_check_read, 3399172955Srwatson .mpo_vnode_check_readdir = biba_vnode_check_readdir, 3400172955Srwatson .mpo_vnode_check_readlink = biba_vnode_check_readlink, 3401172955Srwatson .mpo_vnode_check_relabel = biba_vnode_check_relabel, 3402172955Srwatson .mpo_vnode_check_rename_from = biba_vnode_check_rename_from, 3403172955Srwatson .mpo_vnode_check_rename_to = biba_vnode_check_rename_to, 3404172955Srwatson .mpo_vnode_check_revoke = biba_vnode_check_revoke, 3405172955Srwatson .mpo_vnode_check_setacl = biba_vnode_check_setacl, 3406172955Srwatson .mpo_vnode_check_setextattr = biba_vnode_check_setextattr, 3407172955Srwatson .mpo_vnode_check_setflags = biba_vnode_check_setflags, 3408172955Srwatson .mpo_vnode_check_setmode = biba_vnode_check_setmode, 3409172955Srwatson .mpo_vnode_check_setowner = biba_vnode_check_setowner, 3410172955Srwatson .mpo_vnode_check_setutimes = biba_vnode_check_setutimes, 3411172955Srwatson .mpo_vnode_check_stat = biba_vnode_check_stat, 3412172955Srwatson .mpo_vnode_check_unlink = biba_vnode_check_unlink, 3413172955Srwatson .mpo_vnode_check_write = biba_vnode_check_write, 3414172955Srwatson .mpo_associate_nfsd_label = biba_associate_nfsd_label, 3415172955Srwatson .mpo_mbuf_create_from_firewall = biba_mbuf_create_from_firewall, 3416172955Srwatson .mpo_priv_check = biba_priv_check, 3417101099Srwatson}; 3418101099Srwatson 3419112717SrwatsonMAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba", 3420172955Srwatson MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &biba_slot); 3421