mac_biba.c revision 172957
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 172957 2007-10-25 12:34:14Z 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 1413172957Srwatsonbiba_proc_associate_nfsd(struct ucred *cred) 1414172957Srwatson{ 1415172957Srwatson struct mac_biba *label; 1416172957Srwatson 1417172957Srwatson label = SLOT(cred->cr_label); 1418172957Srwatson biba_set_effective(label, MAC_BIBA_TYPE_LOW, 0, NULL); 1419172957Srwatson biba_set_range(label, MAC_BIBA_TYPE_LOW, 0, NULL, MAC_BIBA_TYPE_HIGH, 1420172957Srwatson 0, NULL); 1421172957Srwatson} 1422172957Srwatson 1423172957Srwatsonstatic void 1424172955Srwatsonbiba_cred_relabel(struct ucred *cred, struct label *newlabel) 1425101099Srwatson{ 1426101099Srwatson struct mac_biba *source, *dest; 1427101099Srwatson 1428101099Srwatson source = SLOT(newlabel); 1429122524Srwatson dest = SLOT(cred->cr_label); 1430101099Srwatson 1431172955Srwatson biba_copy(source, dest); 1432101099Srwatson} 1433101099Srwatson 1434101099Srwatson/* 1435140628Srwatson * Label cleanup/flush operations 1436140628Srwatson */ 1437140628Srwatsonstatic void 1438172955Srwatsonbiba_sysvmsg_cleanup(struct label *msglabel) 1439140628Srwatson{ 1440140628Srwatson 1441140628Srwatson bzero(SLOT(msglabel), sizeof(struct mac_biba)); 1442140628Srwatson} 1443140628Srwatson 1444140628Srwatsonstatic void 1445172955Srwatsonbiba_sysvmsq_cleanup(struct label *msqlabel) 1446140628Srwatson{ 1447140628Srwatson 1448140628Srwatson bzero(SLOT(msqlabel), sizeof(struct mac_biba)); 1449140628Srwatson} 1450140628Srwatson 1451140628Srwatsonstatic void 1452172955Srwatsonbiba_sysvsem_cleanup(struct label *semalabel) 1453140628Srwatson{ 1454140628Srwatson 1455140628Srwatson bzero(SLOT(semalabel), sizeof(struct mac_biba)); 1456140628Srwatson} 1457140628Srwatson 1458140628Srwatsonstatic void 1459172955Srwatsonbiba_sysvshm_cleanup(struct label *shmlabel) 1460140628Srwatson{ 1461140628Srwatson bzero(SLOT(shmlabel), sizeof(struct mac_biba)); 1462140628Srwatson} 1463140628Srwatson 1464140628Srwatson/* 1465101099Srwatson * Access control checks. 1466101099Srwatson */ 1467101099Srwatsonstatic int 1468172955Srwatsonbiba_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 1469168976Srwatson struct ifnet *ifp, struct label *ifplabel) 1470101099Srwatson{ 1471101099Srwatson struct mac_biba *a, *b; 1472101099Srwatson 1473172955Srwatson if (!biba_enabled) 1474101099Srwatson return (0); 1475101099Srwatson 1476168976Srwatson a = SLOT(dlabel); 1477168976Srwatson b = SLOT(ifplabel); 1478101099Srwatson 1479172955Srwatson if (biba_equal_effective(a, b)) 1480101099Srwatson return (0); 1481101099Srwatson return (EACCES); 1482101099Srwatson} 1483101099Srwatson 1484101099Srwatsonstatic int 1485172955Srwatsonbiba_cred_check_relabel(struct ucred *cred, struct label *newlabel) 1486101099Srwatson{ 1487101099Srwatson struct mac_biba *subj, *new; 1488105634Srwatson int error; 1489101099Srwatson 1490122524Srwatson subj = SLOT(cred->cr_label); 1491101099Srwatson new = SLOT(newlabel); 1492101099Srwatson 1493101099Srwatson /* 1494105634Srwatson * If there is a Biba label update for the credential, it may 1495132232Srwatson * be an update of the effective, range, or both. 1496101099Srwatson */ 1497105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1498105634Srwatson if (error) 1499105634Srwatson return (error); 1500101099Srwatson 1501101099Srwatson /* 1502105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 1503101099Srwatson */ 1504105634Srwatson if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1505105634Srwatson /* 1506110351Srwatson * If the change request modifies both the Biba label 1507132232Srwatson * effective and range, check that the new effective will be 1508110351Srwatson * in the new range. 1509110351Srwatson */ 1510110351Srwatson if ((new->mb_flags & MAC_BIBA_FLAGS_BOTH) == 1511110351Srwatson MAC_BIBA_FLAGS_BOTH && 1512172955Srwatson !biba_effective_in_range(new, new)) 1513110351Srwatson return (EINVAL); 1514110351Srwatson 1515110351Srwatson /* 1516132232Srwatson * To change the Biba effective label on a credential, the 1517132232Srwatson * new effective label must be in the current range. 1518105634Srwatson */ 1519132232Srwatson if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE && 1520172955Srwatson !biba_effective_in_range(new, subj)) 1521105634Srwatson return (EPERM); 1522101099Srwatson 1523105634Srwatson /* 1524172955Srwatson * To change the Biba range on a credential, the new range 1525172955Srwatson * label must be in the current range. 1526105634Srwatson */ 1527105634Srwatson if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1528172955Srwatson !biba_range_in_range(new, subj)) 1529105634Srwatson return (EPERM); 1530101099Srwatson 1531105634Srwatson /* 1532172955Srwatson * To have EQUAL in any component of the new credential Biba 1533172955Srwatson * label, the subject must already have EQUAL in their label. 1534105634Srwatson */ 1535172955Srwatson if (biba_contains_equal(new)) { 1536172955Srwatson error = biba_subject_privileged(subj); 1537105634Srwatson if (error) 1538105634Srwatson return (error); 1539105634Srwatson } 1540105634Srwatson } 1541105634Srwatson 1542101099Srwatson return (0); 1543101099Srwatson} 1544101099Srwatson 1545101099Srwatsonstatic int 1546172955Srwatsonbiba_cred_check_visible(struct ucred *u1, struct ucred *u2) 1547101099Srwatson{ 1548101099Srwatson struct mac_biba *subj, *obj; 1549101099Srwatson 1550172955Srwatson if (!biba_enabled) 1551101099Srwatson return (0); 1552101099Srwatson 1553122524Srwatson subj = SLOT(u1->cr_label); 1554122524Srwatson obj = SLOT(u2->cr_label); 1555101099Srwatson 1556101099Srwatson /* XXX: range */ 1557172955Srwatson if (!biba_dominate_effective(obj, subj)) 1558101099Srwatson return (ESRCH); 1559101099Srwatson 1560101099Srwatson return (0); 1561101099Srwatson} 1562101099Srwatson 1563101099Srwatsonstatic int 1564172955Srwatsonbiba_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1565168976Srwatson struct label *ifplabel, struct label *newlabel) 1566101099Srwatson{ 1567101099Srwatson struct mac_biba *subj, *new; 1568105634Srwatson int error; 1569101099Srwatson 1570122524Srwatson subj = SLOT(cred->cr_label); 1571101099Srwatson new = SLOT(newlabel); 1572101099Srwatson 1573105634Srwatson /* 1574172955Srwatson * If there is a Biba label update for the interface, it may be an 1575172955Srwatson * update of the effective, range, or both. 1576105634Srwatson */ 1577105634Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1578105634Srwatson if (error) 1579105634Srwatson return (error); 1580101099Srwatson 1581105634Srwatson /* 1582106160Srwatson * Relabling network interfaces requires Biba privilege. 1583106160Srwatson */ 1584172955Srwatson error = biba_subject_privileged(subj); 1585106160Srwatson if (error) 1586106160Srwatson return (error); 1587106160Srwatson 1588105634Srwatson return (0); 1589101099Srwatson} 1590101099Srwatson 1591103759Srwatsonstatic int 1592172955Srwatsonbiba_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1593168976Srwatson struct mbuf *m, struct label *mlabel) 1594101099Srwatson{ 1595101099Srwatson struct mac_biba *p, *i; 1596103761Srwatson 1597172955Srwatson if (!biba_enabled) 1598101099Srwatson return (0); 1599101099Srwatson 1600168976Srwatson p = SLOT(mlabel); 1601168976Srwatson i = SLOT(ifplabel); 1602103759Srwatson 1603172955Srwatson return (biba_effective_in_range(p, i) ? 0 : EACCES); 1604101099Srwatson} 1605101099Srwatson 1606101099Srwatsonstatic int 1607172955Srwatsonbiba_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1608122875Srwatson struct mbuf *m, struct label *mlabel) 1609122875Srwatson{ 1610122875Srwatson struct mac_biba *p, *i; 1611122875Srwatson 1612172955Srwatson if (!biba_enabled) 1613122875Srwatson return (0); 1614122875Srwatson 1615122875Srwatson p = SLOT(mlabel); 1616122875Srwatson i = SLOT(inplabel); 1617122875Srwatson 1618172955Srwatson return (biba_equal_effective(p, i) ? 0 : EACCES); 1619122875Srwatson} 1620122875Srwatson 1621122875Srwatsonstatic int 1622172955Srwatsonbiba_sysvmsq_check_msgrcv(struct ucred *cred, struct msg *msgptr, 1623140628Srwatson struct label *msglabel) 1624140628Srwatson{ 1625140628Srwatson struct mac_biba *subj, *obj; 1626140628Srwatson 1627172955Srwatson if (!biba_enabled) 1628140628Srwatson return (0); 1629140628Srwatson 1630140628Srwatson subj = SLOT(cred->cr_label); 1631140628Srwatson obj = SLOT(msglabel); 1632140628Srwatson 1633172955Srwatson if (!biba_dominate_effective(obj, subj)) 1634140628Srwatson return (EACCES); 1635140628Srwatson 1636140628Srwatson return (0); 1637140628Srwatson} 1638140628Srwatson 1639140628Srwatsonstatic int 1640172955Srwatsonbiba_sysvmsq_check_msgrmid(struct ucred *cred, struct msg *msgptr, 1641140628Srwatson struct label *msglabel) 1642140628Srwatson{ 1643140628Srwatson struct mac_biba *subj, *obj; 1644140628Srwatson 1645172955Srwatson if (!biba_enabled) 1646140628Srwatson return (0); 1647140628Srwatson 1648140628Srwatson subj = SLOT(cred->cr_label); 1649140628Srwatson obj = SLOT(msglabel); 1650140628Srwatson 1651172955Srwatson if (!biba_dominate_effective(subj, obj)) 1652140628Srwatson return (EACCES); 1653140628Srwatson 1654140628Srwatson return (0); 1655140628Srwatson} 1656140628Srwatson 1657140628Srwatsonstatic int 1658172955Srwatsonbiba_sysvmsq_check_msqget(struct ucred *cred, struct msqid_kernel *msqkptr, 1659172955Srwatson struct label *msqklabel) 1660140628Srwatson{ 1661140628Srwatson struct mac_biba *subj, *obj; 1662140628Srwatson 1663172955Srwatson if (!biba_enabled) 1664140628Srwatson return (0); 1665140628Srwatson 1666140628Srwatson subj = SLOT(cred->cr_label); 1667140628Srwatson obj = SLOT(msqklabel); 1668140628Srwatson 1669172955Srwatson if (!biba_dominate_effective(obj, subj)) 1670140628Srwatson return (EACCES); 1671140628Srwatson 1672140628Srwatson return (0); 1673140628Srwatson} 1674140628Srwatson 1675140628Srwatsonstatic int 1676172955Srwatsonbiba_sysvmsq_check_msqsnd(struct ucred *cred, struct msqid_kernel *msqkptr, 1677172955Srwatson struct label *msqklabel) 1678140628Srwatson{ 1679140628Srwatson struct mac_biba *subj, *obj; 1680140628Srwatson 1681172955Srwatson if (!biba_enabled) 1682140628Srwatson return (0); 1683140628Srwatson 1684140628Srwatson subj = SLOT(cred->cr_label); 1685140628Srwatson obj = SLOT(msqklabel); 1686140628Srwatson 1687172955Srwatson if (!biba_dominate_effective(subj, obj)) 1688140628Srwatson return (EACCES); 1689140628Srwatson 1690140628Srwatson return (0); 1691140628Srwatson} 1692140628Srwatson 1693140628Srwatsonstatic int 1694172955Srwatsonbiba_sysvmsq_check_msqrcv(struct ucred *cred, struct msqid_kernel *msqkptr, 1695172955Srwatson struct label *msqklabel) 1696140628Srwatson{ 1697140628Srwatson struct mac_biba *subj, *obj; 1698140628Srwatson 1699172955Srwatson if (!biba_enabled) 1700140628Srwatson return (0); 1701140628Srwatson 1702140628Srwatson subj = SLOT(cred->cr_label); 1703140628Srwatson obj = SLOT(msqklabel); 1704140628Srwatson 1705172955Srwatson if (!biba_dominate_effective(obj, subj)) 1706140628Srwatson return (EACCES); 1707140628Srwatson 1708140628Srwatson return (0); 1709140628Srwatson} 1710140628Srwatson 1711140628Srwatsonstatic int 1712172955Srwatsonbiba_sysvmsq_check_msqctl(struct ucred *cred, struct msqid_kernel *msqkptr, 1713172955Srwatson struct label *msqklabel, int cmd) 1714140628Srwatson{ 1715140628Srwatson struct mac_biba *subj, *obj; 1716140628Srwatson 1717172955Srwatson if (!biba_enabled) 1718140628Srwatson return (0); 1719140628Srwatson 1720140628Srwatson subj = SLOT(cred->cr_label); 1721140628Srwatson obj = SLOT(msqklabel); 1722140628Srwatson 1723140628Srwatson switch(cmd) { 1724140628Srwatson case IPC_RMID: 1725140628Srwatson case IPC_SET: 1726172955Srwatson if (!biba_dominate_effective(subj, obj)) 1727140628Srwatson return (EACCES); 1728140628Srwatson break; 1729140628Srwatson 1730140628Srwatson case IPC_STAT: 1731172955Srwatson if (!biba_dominate_effective(obj, subj)) 1732140628Srwatson return (EACCES); 1733140628Srwatson break; 1734140628Srwatson 1735140628Srwatson default: 1736140628Srwatson return (EACCES); 1737140628Srwatson } 1738140628Srwatson 1739140628Srwatson return (0); 1740140628Srwatson} 1741140628Srwatson 1742140628Srwatsonstatic int 1743172955Srwatsonbiba_sysvsem_check_semctl(struct ucred *cred, struct semid_kernel *semakptr, 1744172955Srwatson struct label *semaklabel, int cmd) 1745140628Srwatson{ 1746140628Srwatson struct mac_biba *subj, *obj; 1747140628Srwatson 1748172955Srwatson if (!biba_enabled) 1749140628Srwatson return (0); 1750140628Srwatson 1751140628Srwatson subj = SLOT(cred->cr_label); 1752140628Srwatson obj = SLOT(semaklabel); 1753140628Srwatson 1754140628Srwatson switch(cmd) { 1755140628Srwatson case IPC_RMID: 1756140628Srwatson case IPC_SET: 1757140628Srwatson case SETVAL: 1758140628Srwatson case SETALL: 1759172955Srwatson if (!biba_dominate_effective(subj, obj)) 1760140628Srwatson return (EACCES); 1761140628Srwatson break; 1762140628Srwatson 1763140628Srwatson case IPC_STAT: 1764140628Srwatson case GETVAL: 1765140628Srwatson case GETPID: 1766140628Srwatson case GETNCNT: 1767140628Srwatson case GETZCNT: 1768140628Srwatson case GETALL: 1769172955Srwatson if (!biba_dominate_effective(obj, subj)) 1770140628Srwatson return (EACCES); 1771140628Srwatson break; 1772140628Srwatson 1773140628Srwatson default: 1774140628Srwatson return (EACCES); 1775140628Srwatson } 1776140628Srwatson 1777140628Srwatson return (0); 1778140628Srwatson} 1779140628Srwatson 1780140628Srwatsonstatic int 1781172955Srwatsonbiba_sysvsem_check_semget(struct ucred *cred, struct semid_kernel *semakptr, 1782172955Srwatson struct label *semaklabel) 1783140628Srwatson{ 1784140628Srwatson struct mac_biba *subj, *obj; 1785140628Srwatson 1786172955Srwatson if (!biba_enabled) 1787140628Srwatson return (0); 1788140628Srwatson 1789140628Srwatson subj = SLOT(cred->cr_label); 1790140628Srwatson obj = SLOT(semaklabel); 1791140628Srwatson 1792172955Srwatson if (!biba_dominate_effective(obj, subj)) 1793140628Srwatson return (EACCES); 1794140628Srwatson 1795140628Srwatson return (0); 1796140628Srwatson} 1797140628Srwatson 1798140628Srwatsonstatic int 1799172955Srwatsonbiba_sysvsem_check_semop(struct ucred *cred, struct semid_kernel *semakptr, 1800172955Srwatson struct label *semaklabel, size_t accesstype) 1801140628Srwatson{ 1802140628Srwatson struct mac_biba *subj, *obj; 1803140628Srwatson 1804172955Srwatson if (!biba_enabled) 1805140628Srwatson return (0); 1806140628Srwatson 1807140628Srwatson subj = SLOT(cred->cr_label); 1808140628Srwatson obj = SLOT(semaklabel); 1809140628Srwatson 1810140628Srwatson if (accesstype & SEM_R) 1811172955Srwatson if (!biba_dominate_effective(obj, subj)) 1812140628Srwatson return (EACCES); 1813140628Srwatson 1814140628Srwatson if (accesstype & SEM_A) 1815172955Srwatson if (!biba_dominate_effective(subj, obj)) 1816140628Srwatson return (EACCES); 1817140628Srwatson 1818140628Srwatson return (0); 1819140628Srwatson} 1820140628Srwatson 1821140628Srwatsonstatic int 1822172955Srwatsonbiba_sysvshm_check_shmat(struct ucred *cred, struct shmid_kernel *shmsegptr, 1823172955Srwatson struct label *shmseglabel, int shmflg) 1824140628Srwatson{ 1825140628Srwatson struct mac_biba *subj, *obj; 1826140628Srwatson 1827172955Srwatson if (!biba_enabled) 1828140628Srwatson return (0); 1829140628Srwatson 1830140628Srwatson subj = SLOT(cred->cr_label); 1831140628Srwatson obj = SLOT(shmseglabel); 1832140628Srwatson 1833172955Srwatson if (!biba_dominate_effective(obj, subj)) 1834140628Srwatson return (EACCES); 1835140628Srwatson if ((shmflg & SHM_RDONLY) == 0) { 1836172955Srwatson if (!biba_dominate_effective(subj, obj)) 1837140628Srwatson return (EACCES); 1838140628Srwatson } 1839140628Srwatson 1840140628Srwatson return (0); 1841140628Srwatson} 1842140628Srwatson 1843140628Srwatsonstatic int 1844172955Srwatsonbiba_sysvshm_check_shmctl(struct ucred *cred, struct shmid_kernel *shmsegptr, 1845172955Srwatson struct label *shmseglabel, int cmd) 1846140628Srwatson{ 1847140628Srwatson struct mac_biba *subj, *obj; 1848140628Srwatson 1849172955Srwatson if (!biba_enabled) 1850140628Srwatson return (0); 1851140628Srwatson 1852140628Srwatson subj = SLOT(cred->cr_label); 1853140628Srwatson obj = SLOT(shmseglabel); 1854140628Srwatson 1855140628Srwatson switch(cmd) { 1856140628Srwatson case IPC_RMID: 1857140628Srwatson case IPC_SET: 1858172955Srwatson if (!biba_dominate_effective(subj, obj)) 1859140628Srwatson return (EACCES); 1860140628Srwatson break; 1861140628Srwatson 1862140628Srwatson case IPC_STAT: 1863140628Srwatson case SHM_STAT: 1864172955Srwatson if (!biba_dominate_effective(obj, subj)) 1865140628Srwatson return (EACCES); 1866140628Srwatson break; 1867140628Srwatson 1868140628Srwatson default: 1869140628Srwatson return (EACCES); 1870140628Srwatson } 1871140628Srwatson 1872140628Srwatson return (0); 1873140628Srwatson} 1874140628Srwatson 1875140628Srwatsonstatic int 1876172955Srwatsonbiba_sysvshm_check_shmget(struct ucred *cred, struct shmid_kernel *shmsegptr, 1877172955Srwatson struct label *shmseglabel, int shmflg) 1878140628Srwatson{ 1879140628Srwatson struct mac_biba *subj, *obj; 1880140628Srwatson 1881172955Srwatson if (!biba_enabled) 1882140628Srwatson return (0); 1883140628Srwatson 1884140628Srwatson subj = SLOT(cred->cr_label); 1885140628Srwatson obj = SLOT(shmseglabel); 1886140628Srwatson 1887172955Srwatson if (!biba_dominate_effective(obj, subj)) 1888140628Srwatson return (EACCES); 1889140628Srwatson 1890140628Srwatson return (0); 1891140628Srwatson} 1892140628Srwatson 1893140628Srwatsonstatic int 1894172955Srwatsonbiba_kld_check_load(struct ucred *cred, struct vnode *vp, 1895168976Srwatson struct label *vplabel) 1896110354Srwatson{ 1897110354Srwatson struct mac_biba *subj, *obj; 1898110354Srwatson int error; 1899110354Srwatson 1900172955Srwatson if (!biba_enabled) 1901110354Srwatson return (0); 1902110354Srwatson 1903122524Srwatson subj = SLOT(cred->cr_label); 1904110354Srwatson 1905172955Srwatson error = biba_subject_privileged(subj); 1906110354Srwatson if (error) 1907110354Srwatson return (error); 1908110354Srwatson 1909168976Srwatson obj = SLOT(vplabel); 1910172955Srwatson if (!biba_high_effective(obj)) 1911110354Srwatson return (EACCES); 1912110354Srwatson 1913110354Srwatson return (0); 1914110354Srwatson} 1915110354Srwatson 1916110354Srwatsonstatic int 1917172955Srwatsonbiba_mount_check_stat(struct ucred *cred, struct mount *mp, 1918168976Srwatson struct label *mplabel) 1919101099Srwatson{ 1920101099Srwatson struct mac_biba *subj, *obj; 1921101099Srwatson 1922172955Srwatson if (!biba_enabled) 1923101099Srwatson return (0); 1924101099Srwatson 1925122524Srwatson subj = SLOT(cred->cr_label); 1926168976Srwatson obj = SLOT(mplabel); 1927101099Srwatson 1928172955Srwatson if (!biba_dominate_effective(obj, subj)) 1929101099Srwatson return (EACCES); 1930101099Srwatson 1931101099Srwatson return (0); 1932101099Srwatson} 1933101099Srwatson 1934101099Srwatsonstatic int 1935172955Srwatsonbiba_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1936168976Srwatson struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1937101099Srwatson{ 1938103759Srwatson 1939172955Srwatson if(!biba_enabled) 1940101099Srwatson return (0); 1941101099Srwatson 1942101099Srwatson /* XXX: This will be implemented soon... */ 1943101099Srwatson 1944101099Srwatson return (0); 1945101099Srwatson} 1946101099Srwatson 1947101099Srwatsonstatic int 1948172955Srwatsonbiba_pipe_check_poll(struct ucred *cred, struct pipepair *pp, 1949168976Srwatson struct label *pplabel) 1950101099Srwatson{ 1951101099Srwatson struct mac_biba *subj, *obj; 1952101099Srwatson 1953172955Srwatson if (!biba_enabled) 1954101099Srwatson return (0); 1955101099Srwatson 1956122524Srwatson subj = SLOT(cred->cr_label); 1957168976Srwatson obj = SLOT(pplabel); 1958101099Srwatson 1959172955Srwatson if (!biba_dominate_effective(obj, subj)) 1960102115Srwatson return (EACCES); 1961101099Srwatson 1962101099Srwatson return (0); 1963101099Srwatson} 1964101099Srwatson 1965101099Srwatsonstatic int 1966172955Srwatsonbiba_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1967168976Srwatson struct label *pplabel) 1968102115Srwatson{ 1969102115Srwatson struct mac_biba *subj, *obj; 1970102115Srwatson 1971172955Srwatson if (!biba_enabled) 1972102115Srwatson return (0); 1973102115Srwatson 1974122524Srwatson subj = SLOT(cred->cr_label); 1975168976Srwatson obj = SLOT(pplabel); 1976102115Srwatson 1977172955Srwatson if (!biba_dominate_effective(obj, subj)) 1978102115Srwatson return (EACCES); 1979102115Srwatson 1980102115Srwatson return (0); 1981102115Srwatson} 1982102115Srwatson 1983102115Srwatsonstatic int 1984172955Srwatsonbiba_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1985168976Srwatson struct label *pplabel, struct label *newlabel) 1986101099Srwatson{ 1987101099Srwatson struct mac_biba *subj, *obj, *new; 1988105634Srwatson int error; 1989101099Srwatson 1990101099Srwatson new = SLOT(newlabel); 1991122524Srwatson subj = SLOT(cred->cr_label); 1992168976Srwatson obj = SLOT(pplabel); 1993101099Srwatson 1994101099Srwatson /* 1995172955Srwatson * If there is a Biba label update for a pipe, it must be a effective 1996172955Srwatson * update. 1997101099Srwatson */ 1998132232Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 1999105634Srwatson if (error) 2000105634Srwatson return (error); 2001101099Srwatson 2002101099Srwatson /* 2003105634Srwatson * To perform a relabel of a pipe (Biba label or not), Biba must 2004105634Srwatson * authorize the relabel. 2005101099Srwatson */ 2006172955Srwatson if (!biba_effective_in_range(obj, subj)) 2007101099Srwatson return (EPERM); 2008101099Srwatson 2009101099Srwatson /* 2010105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2011101099Srwatson */ 2012132232Srwatson if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2013105634Srwatson /* 2014105634Srwatson * To change the Biba label on a pipe, the new pipe label 2015105634Srwatson * must be in the subject range. 2016105634Srwatson */ 2017172955Srwatson if (!biba_effective_in_range(new, subj)) 2018105634Srwatson return (EPERM); 2019101099Srwatson 2020105634Srwatson /* 2021105634Srwatson * To change the Biba label on a pipe to be EQUAL, the 2022105634Srwatson * subject must have appropriate privilege. 2023105634Srwatson */ 2024172955Srwatson if (biba_contains_equal(new)) { 2025172955Srwatson error = biba_subject_privileged(subj); 2026105634Srwatson if (error) 2027105634Srwatson return (error); 2028105634Srwatson } 2029105634Srwatson } 2030105634Srwatson 2031101099Srwatson return (0); 2032101099Srwatson} 2033101099Srwatson 2034101099Srwatsonstatic int 2035172955Srwatsonbiba_pipe_check_stat(struct ucred *cred, struct pipepair *pp, 2036168976Srwatson struct label *pplabel) 2037102115Srwatson{ 2038102115Srwatson struct mac_biba *subj, *obj; 2039102115Srwatson 2040172955Srwatson if (!biba_enabled) 2041102115Srwatson return (0); 2042102115Srwatson 2043122524Srwatson subj = SLOT(cred->cr_label); 2044168976Srwatson obj = SLOT(pplabel); 2045102115Srwatson 2046172955Srwatson if (!biba_dominate_effective(obj, subj)) 2047102115Srwatson return (EACCES); 2048102115Srwatson 2049102115Srwatson return (0); 2050102115Srwatson} 2051102115Srwatson 2052102115Srwatsonstatic int 2053172955Srwatsonbiba_pipe_check_write(struct ucred *cred, struct pipepair *pp, 2054168976Srwatson struct label *pplabel) 2055102115Srwatson{ 2056102115Srwatson struct mac_biba *subj, *obj; 2057102115Srwatson 2058172955Srwatson if (!biba_enabled) 2059102115Srwatson return (0); 2060102115Srwatson 2061122524Srwatson subj = SLOT(cred->cr_label); 2062168976Srwatson obj = SLOT(pplabel); 2063102115Srwatson 2064172955Srwatson if (!biba_dominate_effective(subj, obj)) 2065102115Srwatson return (EACCES); 2066102115Srwatson 2067102115Srwatson return (0); 2068102115Srwatson} 2069102115Srwatson 2070102115Srwatsonstatic int 2071172955Srwatsonbiba_posixsem_check_write(struct ucred *cred, struct ksem *ks, 2072172850Srwatson struct label *kslabel) 2073145855Srwatson{ 2074145855Srwatson struct mac_biba *subj, *obj; 2075145855Srwatson 2076172955Srwatson if (!biba_enabled) 2077145855Srwatson return (0); 2078145855Srwatson 2079145855Srwatson subj = SLOT(cred->cr_label); 2080172850Srwatson obj = SLOT(kslabel); 2081145855Srwatson 2082172955Srwatson if (!biba_dominate_effective(subj, obj)) 2083145855Srwatson return (EACCES); 2084145855Srwatson 2085145855Srwatson return (0); 2086145855Srwatson} 2087145855Srwatson 2088145855Srwatsonstatic int 2089172955Srwatsonbiba_posixsem_check_rdonly(struct ucred *cred, struct ksem *ks, 2090172850Srwatson struct label *kslabel) 2091145855Srwatson{ 2092145855Srwatson struct mac_biba *subj, *obj; 2093145855Srwatson 2094172955Srwatson if (!biba_enabled) 2095145855Srwatson return (0); 2096145855Srwatson 2097145855Srwatson subj = SLOT(cred->cr_label); 2098172850Srwatson obj = SLOT(kslabel); 2099145855Srwatson 2100172955Srwatson if (!biba_dominate_effective(obj, subj)) 2101145855Srwatson return (EACCES); 2102145855Srwatson 2103145855Srwatson return (0); 2104145855Srwatson} 2105145855Srwatson 2106145855Srwatsonstatic int 2107172955Srwatsonbiba_proc_check_debug(struct ucred *cred, struct proc *p) 2108101099Srwatson{ 2109101099Srwatson struct mac_biba *subj, *obj; 2110101099Srwatson 2111172955Srwatson if (!biba_enabled) 2112101099Srwatson return (0); 2113101099Srwatson 2114122524Srwatson subj = SLOT(cred->cr_label); 2115168976Srwatson obj = SLOT(p->p_ucred->cr_label); 2116101099Srwatson 2117101099Srwatson /* XXX: range checks */ 2118172955Srwatson if (!biba_dominate_effective(obj, subj)) 2119101099Srwatson return (ESRCH); 2120172955Srwatson if (!biba_dominate_effective(subj, obj)) 2121101099Srwatson return (EACCES); 2122101099Srwatson 2123101099Srwatson return (0); 2124101099Srwatson} 2125101099Srwatson 2126101099Srwatsonstatic int 2127172955Srwatsonbiba_proc_check_sched(struct ucred *cred, struct proc *p) 2128101099Srwatson{ 2129101099Srwatson struct mac_biba *subj, *obj; 2130103759Srwatson 2131172955Srwatson if (!biba_enabled) 2132101099Srwatson return (0); 2133101099Srwatson 2134122524Srwatson subj = SLOT(cred->cr_label); 2135168976Srwatson obj = SLOT(p->p_ucred->cr_label); 2136103759Srwatson 2137101099Srwatson /* XXX: range checks */ 2138172955Srwatson if (!biba_dominate_effective(obj, subj)) 2139101099Srwatson return (ESRCH); 2140172955Srwatson if (!biba_dominate_effective(subj, obj)) 2141101099Srwatson return (EACCES); 2142101099Srwatson 2143101099Srwatson return (0); 2144101099Srwatson} 2145101099Srwatson 2146101099Srwatsonstatic int 2147172955Srwatsonbiba_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 2148101099Srwatson{ 2149101099Srwatson struct mac_biba *subj, *obj; 2150103759Srwatson 2151172955Srwatson if (!biba_enabled) 2152101099Srwatson return (0); 2153101099Srwatson 2154122524Srwatson subj = SLOT(cred->cr_label); 2155168976Srwatson obj = SLOT(p->p_ucred->cr_label); 2156103759Srwatson 2157101099Srwatson /* XXX: range checks */ 2158172955Srwatson if (!biba_dominate_effective(obj, subj)) 2159101099Srwatson return (ESRCH); 2160172955Srwatson if (!biba_dominate_effective(subj, obj)) 2161101099Srwatson return (EACCES); 2162101099Srwatson 2163101099Srwatson return (0); 2164101099Srwatson} 2165101099Srwatson 2166101099Srwatsonstatic int 2167172955Srwatsonbiba_socket_check_deliver(struct socket *so, struct label *solabel, 2168168976Srwatson struct mbuf *m, struct label *mlabel) 2169101099Srwatson{ 2170101099Srwatson struct mac_biba *p, *s; 2171101099Srwatson 2172172955Srwatson if (!biba_enabled) 2173101099Srwatson return (0); 2174101099Srwatson 2175168976Srwatson p = SLOT(mlabel); 2176168976Srwatson s = SLOT(solabel); 2177101099Srwatson 2178172955Srwatson return (biba_equal_effective(p, s) ? 0 : EACCES); 2179101099Srwatson} 2180101099Srwatson 2181101099Srwatsonstatic int 2182172955Srwatsonbiba_socket_check_relabel(struct ucred *cred, struct socket *so, 2183168976Srwatson struct label *solabel, struct label *newlabel) 2184101099Srwatson{ 2185101099Srwatson struct mac_biba *subj, *obj, *new; 2186105634Srwatson int error; 2187101099Srwatson 2188101099Srwatson new = SLOT(newlabel); 2189122524Srwatson subj = SLOT(cred->cr_label); 2190168976Srwatson obj = SLOT(solabel); 2191101099Srwatson 2192101099Srwatson /* 2193172955Srwatson * If there is a Biba label update for the socket, it may be an 2194172955Srwatson * update of effective. 2195101099Srwatson */ 2196132232Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2197105634Srwatson if (error) 2198105634Srwatson return (error); 2199101099Srwatson 2200101099Srwatson /* 2201172955Srwatson * To relabel a socket, the old socket effective must be in the 2202172955Srwatson * subject range. 2203101099Srwatson */ 2204172955Srwatson if (!biba_effective_in_range(obj, subj)) 2205101099Srwatson return (EPERM); 2206101099Srwatson 2207101099Srwatson /* 2208105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2209101099Srwatson */ 2210132232Srwatson if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2211105634Srwatson /* 2212132232Srwatson * To relabel a socket, the new socket effective must be in 2213105634Srwatson * the subject range. 2214105634Srwatson */ 2215172955Srwatson if (!biba_effective_in_range(new, subj)) 2216105634Srwatson return (EPERM); 2217101099Srwatson 2218105634Srwatson /* 2219105634Srwatson * To change the Biba label on the socket to contain EQUAL, 2220105634Srwatson * the subject must have appropriate privilege. 2221105634Srwatson */ 2222172955Srwatson if (biba_contains_equal(new)) { 2223172955Srwatson error = biba_subject_privileged(subj); 2224105634Srwatson if (error) 2225105634Srwatson return (error); 2226105634Srwatson } 2227105634Srwatson } 2228105634Srwatson 2229101099Srwatson return (0); 2230101099Srwatson} 2231101099Srwatson 2232101099Srwatsonstatic int 2233172955Srwatsonbiba_socket_check_visible(struct ucred *cred, struct socket *so, 2234168976Srwatson struct label *solabel) 2235101099Srwatson{ 2236101099Srwatson struct mac_biba *subj, *obj; 2237101099Srwatson 2238172955Srwatson if (!biba_enabled) 2239105722Srwatson return (0); 2240105722Srwatson 2241122524Srwatson subj = SLOT(cred->cr_label); 2242168976Srwatson obj = SLOT(solabel); 2243101099Srwatson 2244172955Srwatson if (!biba_dominate_effective(obj, subj)) 2245101099Srwatson return (ENOENT); 2246101099Srwatson 2247101099Srwatson return (0); 2248101099Srwatson} 2249101099Srwatson 2250168951Srwatson/* 2251168951Srwatson * Some system privileges are allowed regardless of integrity grade; others 2252168951Srwatson * are allowed only when running with privilege with respect to the Biba 2253168951Srwatson * policy as they might otherwise allow bypassing of the integrity policy. 2254168951Srwatson */ 2255101099Srwatsonstatic int 2256172955Srwatsonbiba_priv_check(struct ucred *cred, int priv) 2257112574Srwatson{ 2258112574Srwatson struct mac_biba *subj; 2259112574Srwatson int error; 2260112574Srwatson 2261172955Srwatson if (!biba_enabled) 2262112574Srwatson return (0); 2263112574Srwatson 2264168951Srwatson /* 2265168951Srwatson * Exempt only specific privileges from the Biba integrity policy. 2266168951Srwatson */ 2267168951Srwatson switch (priv) { 2268168951Srwatson case PRIV_KTRACE: 2269168951Srwatson case PRIV_MSGBUF: 2270112574Srwatson 2271168951Srwatson /* 2272168951Srwatson * Allow processes to manipulate basic process audit properties, and 2273168951Srwatson * to submit audit records. 2274168951Srwatson */ 2275168951Srwatson case PRIV_AUDIT_GETAUDIT: 2276168951Srwatson case PRIV_AUDIT_SETAUDIT: 2277168951Srwatson case PRIV_AUDIT_SUBMIT: 2278112574Srwatson 2279168951Srwatson /* 2280168951Srwatson * Allow processes to manipulate their regular UNIX credentials. 2281168951Srwatson */ 2282168951Srwatson case PRIV_CRED_SETUID: 2283168951Srwatson case PRIV_CRED_SETEUID: 2284168951Srwatson case PRIV_CRED_SETGID: 2285168951Srwatson case PRIV_CRED_SETEGID: 2286168951Srwatson case PRIV_CRED_SETGROUPS: 2287168951Srwatson case PRIV_CRED_SETREUID: 2288168951Srwatson case PRIV_CRED_SETREGID: 2289168951Srwatson case PRIV_CRED_SETRESUID: 2290168951Srwatson case PRIV_CRED_SETRESGID: 2291168951Srwatson 2292168951Srwatson /* 2293168951Srwatson * Allow processes to perform system monitoring. 2294168951Srwatson */ 2295168951Srwatson case PRIV_SEEOTHERGIDS: 2296168951Srwatson case PRIV_SEEOTHERUIDS: 2297168951Srwatson break; 2298168951Srwatson 2299168951Srwatson /* 2300168951Srwatson * Allow access to general process debugging facilities. We 2301168951Srwatson * separately control debugging based on MAC label. 2302168951Srwatson */ 2303168951Srwatson case PRIV_DEBUG_DIFFCRED: 2304168951Srwatson case PRIV_DEBUG_SUGID: 2305168951Srwatson case PRIV_DEBUG_UNPRIV: 2306168951Srwatson 2307168951Srwatson /* 2308168951Srwatson * Allow manipulating jails. 2309168951Srwatson */ 2310168951Srwatson case PRIV_JAIL_ATTACH: 2311168951Srwatson 2312168951Srwatson /* 2313168951Srwatson * Allow privilege with respect to the Partition policy, but not the 2314168951Srwatson * Privs policy. 2315168951Srwatson */ 2316168951Srwatson case PRIV_MAC_PARTITION: 2317168951Srwatson 2318168951Srwatson /* 2319168951Srwatson * Allow privilege with respect to process resource limits and login 2320168951Srwatson * context. 2321168951Srwatson */ 2322168951Srwatson case PRIV_PROC_LIMIT: 2323168951Srwatson case PRIV_PROC_SETLOGIN: 2324168951Srwatson case PRIV_PROC_SETRLIMIT: 2325168951Srwatson 2326168951Srwatson /* 2327168951Srwatson * Allow System V and POSIX IPC privileges. 2328168951Srwatson */ 2329168951Srwatson case PRIV_IPC_READ: 2330168951Srwatson case PRIV_IPC_WRITE: 2331168951Srwatson case PRIV_IPC_ADMIN: 2332168951Srwatson case PRIV_IPC_MSGSIZE: 2333168951Srwatson case PRIV_MQ_ADMIN: 2334168951Srwatson 2335168951Srwatson /* 2336168951Srwatson * Allow certain scheduler manipulations -- possibly this should be 2337168951Srwatson * controlled by more fine-grained policy, as potentially low 2338168951Srwatson * integrity processes can deny CPU to higher integrity ones. 2339168951Srwatson */ 2340168951Srwatson case PRIV_SCHED_DIFFCRED: 2341168951Srwatson case PRIV_SCHED_SETPRIORITY: 2342168951Srwatson case PRIV_SCHED_RTPRIO: 2343168951Srwatson case PRIV_SCHED_SETPOLICY: 2344168951Srwatson case PRIV_SCHED_SET: 2345168951Srwatson case PRIV_SCHED_SETPARAM: 2346168951Srwatson 2347168951Srwatson /* 2348168951Srwatson * More IPC privileges. 2349168951Srwatson */ 2350168951Srwatson case PRIV_SEM_WRITE: 2351168951Srwatson 2352168951Srwatson /* 2353168951Srwatson * Allow signaling privileges subject to integrity policy. 2354168951Srwatson */ 2355168951Srwatson case PRIV_SIGNAL_DIFFCRED: 2356168951Srwatson case PRIV_SIGNAL_SUGID: 2357168951Srwatson 2358168951Srwatson /* 2359168951Srwatson * Allow access to only limited sysctls from lower integrity levels; 2360168951Srwatson * piggy-back on the Jail definition. 2361168951Srwatson */ 2362168951Srwatson case PRIV_SYSCTL_WRITEJAIL: 2363168951Srwatson 2364168951Srwatson /* 2365168951Srwatson * Allow TTY-based privileges, subject to general device access using 2366168951Srwatson * labels on TTY device nodes, but not console privilege. 2367168951Srwatson */ 2368168951Srwatson case PRIV_TTY_DRAINWAIT: 2369168951Srwatson case PRIV_TTY_DTRWAIT: 2370168951Srwatson case PRIV_TTY_EXCLUSIVE: 2371168951Srwatson case PRIV_TTY_PRISON: 2372168951Srwatson case PRIV_TTY_STI: 2373168951Srwatson case PRIV_TTY_SETA: 2374168951Srwatson 2375168951Srwatson /* 2376168951Srwatson * Grant most VFS privileges, as almost all are in practice bounded 2377168951Srwatson * by more specific checks using labels. 2378168951Srwatson */ 2379168951Srwatson case PRIV_VFS_READ: 2380168951Srwatson case PRIV_VFS_WRITE: 2381168951Srwatson case PRIV_VFS_ADMIN: 2382168951Srwatson case PRIV_VFS_EXEC: 2383168951Srwatson case PRIV_VFS_LOOKUP: 2384168951Srwatson case PRIV_VFS_CHFLAGS_DEV: 2385168951Srwatson case PRIV_VFS_CHOWN: 2386168951Srwatson case PRIV_VFS_CHROOT: 2387168951Srwatson case PRIV_VFS_RETAINSUGID: 2388168951Srwatson case PRIV_VFS_EXCEEDQUOTA: 2389168951Srwatson case PRIV_VFS_FCHROOT: 2390168951Srwatson case PRIV_VFS_FHOPEN: 2391168951Srwatson case PRIV_VFS_FHSTATFS: 2392168951Srwatson case PRIV_VFS_GENERATION: 2393168951Srwatson case PRIV_VFS_GETFH: 2394168951Srwatson case PRIV_VFS_GETQUOTA: 2395168951Srwatson case PRIV_VFS_LINK: 2396168951Srwatson case PRIV_VFS_MOUNT: 2397168951Srwatson case PRIV_VFS_MOUNT_OWNER: 2398168951Srwatson case PRIV_VFS_MOUNT_PERM: 2399168951Srwatson case PRIV_VFS_MOUNT_SUIDDIR: 2400168951Srwatson case PRIV_VFS_MOUNT_NONUSER: 2401168951Srwatson case PRIV_VFS_SETGID: 2402168951Srwatson case PRIV_VFS_STICKYFILE: 2403168951Srwatson case PRIV_VFS_SYSFLAGS: 2404168951Srwatson case PRIV_VFS_UNMOUNT: 2405168951Srwatson 2406168951Srwatson /* 2407168951Srwatson * Allow VM privileges; it would be nice if these were subject to 2408168951Srwatson * resource limits. 2409168951Srwatson */ 2410168951Srwatson case PRIV_VM_MADV_PROTECT: 2411168951Srwatson case PRIV_VM_MLOCK: 2412168951Srwatson case PRIV_VM_MUNLOCK: 2413168951Srwatson 2414168951Srwatson /* 2415168951Srwatson * Allow some but not all network privileges. In general, dont allow 2416168951Srwatson * reconfiguring the network stack, just normal use. 2417168951Srwatson */ 2418168951Srwatson case PRIV_NETATALK_RESERVEDPORT: 2419168951Srwatson case PRIV_NETINET_RESERVEDPORT: 2420168951Srwatson case PRIV_NETINET_RAW: 2421168951Srwatson case PRIV_NETINET_REUSEPORT: 2422168951Srwatson case PRIV_NETIPX_RESERVEDPORT: 2423168951Srwatson case PRIV_NETIPX_RAW: 2424168951Srwatson break; 2425168951Srwatson 2426168951Srwatson /* 2427168951Srwatson * All remaining system privileges are allow only if the process 2428168951Srwatson * holds privilege with respect to the Biba policy. 2429168951Srwatson */ 2430168951Srwatson default: 2431168951Srwatson subj = SLOT(cred->cr_label); 2432172955Srwatson error = biba_subject_privileged(subj); 2433168951Srwatson if (error) 2434168951Srwatson return (error); 2435168951Srwatson } 2436112574Srwatson return (0); 2437112574Srwatson} 2438112574Srwatson 2439112574Srwatsonstatic int 2440172955Srwatsonbiba_system_check_acct(struct ucred *cred, struct vnode *vp, 2441168976Srwatson struct label *vplabel) 2442106418Srwatson{ 2443106418Srwatson struct mac_biba *subj, *obj; 2444106418Srwatson int error; 2445106418Srwatson 2446172955Srwatson if (!biba_enabled) 2447106418Srwatson return (0); 2448106418Srwatson 2449122524Srwatson subj = SLOT(cred->cr_label); 2450106418Srwatson 2451172955Srwatson error = biba_subject_privileged(subj); 2452106418Srwatson if (error) 2453106418Srwatson return (error); 2454106418Srwatson 2455168976Srwatson if (vplabel == NULL) 2456106418Srwatson return (0); 2457106418Srwatson 2458168976Srwatson obj = SLOT(vplabel); 2459172955Srwatson if (!biba_high_effective(obj)) 2460106418Srwatson return (EACCES); 2461106418Srwatson 2462106418Srwatson return (0); 2463106418Srwatson} 2464106418Srwatson 2465106418Srwatsonstatic int 2466172955Srwatsonbiba_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2467168933Srwatson struct label *vplabel) 2468168933Srwatson{ 2469168933Srwatson struct mac_biba *subj, *obj; 2470168933Srwatson int error; 2471168933Srwatson 2472172955Srwatson if (!biba_enabled) 2473168933Srwatson return (0); 2474168933Srwatson 2475168933Srwatson subj = SLOT(cred->cr_label); 2476168933Srwatson 2477172955Srwatson error = biba_subject_privileged(subj); 2478168933Srwatson if (error) 2479168933Srwatson return (error); 2480168933Srwatson 2481168933Srwatson if (vplabel == NULL) 2482168933Srwatson return (0); 2483168933Srwatson 2484168933Srwatson obj = SLOT(vplabel); 2485172955Srwatson if (!biba_high_effective(obj)) 2486168933Srwatson return (EACCES); 2487168933Srwatson 2488168933Srwatson return (0); 2489168933Srwatson} 2490168933Srwatson 2491168933Srwatsonstatic int 2492172955Srwatsonbiba_system_check_auditon(struct ucred *cred, int cmd) 2493168933Srwatson{ 2494168933Srwatson struct mac_biba *subj; 2495168933Srwatson int error; 2496168933Srwatson 2497172955Srwatson if (!biba_enabled) 2498168933Srwatson return (0); 2499168933Srwatson 2500168933Srwatson subj = SLOT(cred->cr_label); 2501168933Srwatson 2502172955Srwatson error = biba_subject_privileged(subj); 2503168933Srwatson if (error) 2504168933Srwatson return (error); 2505168933Srwatson 2506168933Srwatson return (0); 2507168933Srwatson} 2508168933Srwatson 2509168933Srwatsonstatic int 2510172955Srwatsonbiba_system_check_swapon(struct ucred *cred, struct vnode *vp, 2511168976Srwatson struct label *vplabel) 2512106161Srwatson{ 2513106161Srwatson struct mac_biba *subj, *obj; 2514106416Srwatson int error; 2515106161Srwatson 2516172955Srwatson if (!biba_enabled) 2517106161Srwatson return (0); 2518106161Srwatson 2519122524Srwatson subj = SLOT(cred->cr_label); 2520168976Srwatson obj = SLOT(vplabel); 2521106161Srwatson 2522172955Srwatson error = biba_subject_privileged(subj); 2523106416Srwatson if (error) 2524106416Srwatson return (error); 2525106161Srwatson 2526172955Srwatson if (!biba_high_effective(obj)) 2527106161Srwatson return (EACCES); 2528106161Srwatson 2529106161Srwatson return (0); 2530106161Srwatson} 2531106161Srwatson 2532106161Srwatsonstatic int 2533172955Srwatsonbiba_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2534112574Srwatson struct label *label) 2535112574Srwatson{ 2536166617Srwatson struct mac_biba *subj; 2537112574Srwatson int error; 2538112574Srwatson 2539172955Srwatson if (!biba_enabled) 2540112574Srwatson return (0); 2541112574Srwatson 2542122524Srwatson subj = SLOT(cred->cr_label); 2543112574Srwatson 2544172955Srwatson error = biba_subject_privileged(subj); 2545112574Srwatson if (error) 2546112574Srwatson return (error); 2547112574Srwatson 2548112574Srwatson return (0); 2549112574Srwatson} 2550112574Srwatson 2551112574Srwatsonstatic int 2552172955Srwatsonbiba_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2553126121Spjd void *arg1, int arg2, struct sysctl_req *req) 2554106161Srwatson{ 2555106161Srwatson struct mac_biba *subj; 2556106161Srwatson int error; 2557106161Srwatson 2558172955Srwatson if (!biba_enabled) 2559106161Srwatson return (0); 2560106161Srwatson 2561122524Srwatson subj = SLOT(cred->cr_label); 2562106161Srwatson 2563106161Srwatson /* 2564172955Srwatson * Treat sysctl variables without CTLFLAG_ANYBODY flag as biba/high, 2565172955Srwatson * but also require privilege to change them. 2566106161Srwatson */ 2567126121Spjd if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2568172955Srwatson if (!biba_subject_dominate_high(subj)) 2569106161Srwatson return (EACCES); 2570106161Srwatson 2571172955Srwatson error = biba_subject_privileged(subj); 2572106161Srwatson if (error) 2573106161Srwatson return (error); 2574106161Srwatson } 2575106161Srwatson 2576106161Srwatson return (0); 2577106161Srwatson} 2578106161Srwatson 2579106161Srwatsonstatic int 2580172955Srwatsonbiba_vnode_check_chdir(struct ucred *cred, struct vnode *dvp, 2581168976Srwatson struct label *dvplabel) 2582101099Srwatson{ 2583101099Srwatson struct mac_biba *subj, *obj; 2584101099Srwatson 2585172955Srwatson if (!biba_enabled) 2586101099Srwatson return (0); 2587101099Srwatson 2588122524Srwatson subj = SLOT(cred->cr_label); 2589168976Srwatson obj = SLOT(dvplabel); 2590101099Srwatson 2591172955Srwatson if (!biba_dominate_effective(obj, subj)) 2592101099Srwatson return (EACCES); 2593101099Srwatson 2594101099Srwatson return (0); 2595101099Srwatson} 2596101099Srwatson 2597101099Srwatsonstatic int 2598172955Srwatsonbiba_vnode_check_chroot(struct ucred *cred, struct vnode *dvp, 2599168976Srwatson struct label *dvplabel) 2600101099Srwatson{ 2601101099Srwatson struct mac_biba *subj, *obj; 2602101099Srwatson 2603172955Srwatson if (!biba_enabled) 2604101099Srwatson return (0); 2605101099Srwatson 2606122524Srwatson subj = SLOT(cred->cr_label); 2607168976Srwatson obj = SLOT(dvplabel); 2608101099Srwatson 2609172955Srwatson if (!biba_dominate_effective(obj, subj)) 2610101099Srwatson return (EACCES); 2611101099Srwatson 2612101099Srwatson return (0); 2613101099Srwatson} 2614101099Srwatson 2615101099Srwatsonstatic int 2616172955Srwatsonbiba_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2617168976Srwatson struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2618101099Srwatson{ 2619101099Srwatson struct mac_biba *subj, *obj; 2620101099Srwatson 2621172955Srwatson if (!biba_enabled) 2622101099Srwatson return (0); 2623101099Srwatson 2624122524Srwatson subj = SLOT(cred->cr_label); 2625168976Srwatson obj = SLOT(dvplabel); 2626101099Srwatson 2627172955Srwatson if (!biba_dominate_effective(subj, obj)) 2628101099Srwatson return (EACCES); 2629101099Srwatson 2630101099Srwatson return (0); 2631101099Srwatson} 2632101099Srwatson 2633101099Srwatsonstatic int 2634172955Srwatsonbiba_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2635168976Srwatson struct label *vplabel, acl_type_t type) 2636101099Srwatson{ 2637101099Srwatson struct mac_biba *subj, *obj; 2638101099Srwatson 2639172955Srwatson if (!biba_enabled) 2640101099Srwatson return (0); 2641101099Srwatson 2642122524Srwatson subj = SLOT(cred->cr_label); 2643168976Srwatson obj = SLOT(vplabel); 2644101099Srwatson 2645172955Srwatson if (!biba_dominate_effective(subj, obj)) 2646101099Srwatson return (EACCES); 2647101099Srwatson 2648101099Srwatson return (0); 2649101099Srwatson} 2650101099Srwatson 2651101099Srwatsonstatic int 2652172955Srwatsonbiba_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp, 2653168976Srwatson struct label *vplabel, int attrnamespace, const char *name) 2654119202Srwatson{ 2655119202Srwatson struct mac_biba *subj, *obj; 2656119202Srwatson 2657172955Srwatson if (!biba_enabled) 2658119202Srwatson return (0); 2659119202Srwatson 2660122524Srwatson subj = SLOT(cred->cr_label); 2661168976Srwatson obj = SLOT(vplabel); 2662119202Srwatson 2663172955Srwatson if (!biba_dominate_effective(subj, obj)) 2664119202Srwatson return (EACCES); 2665119202Srwatson 2666119202Srwatson return (0); 2667119202Srwatson} 2668119202Srwatson 2669119202Srwatsonstatic int 2670172955Srwatsonbiba_vnode_check_exec(struct ucred *cred, struct vnode *vp, 2671168976Srwatson struct label *vplabel, struct image_params *imgp, 2672106648Srwatson struct label *execlabel) 2673101099Srwatson{ 2674106648Srwatson struct mac_biba *subj, *obj, *exec; 2675106648Srwatson int error; 2676101099Srwatson 2677106648Srwatson if (execlabel != NULL) { 2678106648Srwatson /* 2679106648Srwatson * We currently don't permit labels to be changed at 2680172955Srwatson * exec-time as part of Biba, so disallow non-NULL Biba label 2681172955Srwatson * elements in the execlabel. 2682106648Srwatson */ 2683106648Srwatson exec = SLOT(execlabel); 2684106648Srwatson error = biba_atmostflags(exec, 0); 2685106648Srwatson if (error) 2686106648Srwatson return (error); 2687106648Srwatson } 2688106648Srwatson 2689172955Srwatson if (!biba_enabled) 2690101099Srwatson return (0); 2691101099Srwatson 2692122524Srwatson subj = SLOT(cred->cr_label); 2693168976Srwatson obj = SLOT(vplabel); 2694101099Srwatson 2695172955Srwatson if (!biba_dominate_effective(obj, subj)) 2696101099Srwatson return (EACCES); 2697101099Srwatson 2698101099Srwatson return (0); 2699101099Srwatson} 2700101099Srwatson 2701101099Srwatsonstatic int 2702172955Srwatsonbiba_vnode_check_getacl(struct ucred *cred, struct vnode *vp, 2703168976Srwatson struct label *vplabel, acl_type_t type) 2704101099Srwatson{ 2705101099Srwatson struct mac_biba *subj, *obj; 2706101099Srwatson 2707172955Srwatson if (!biba_enabled) 2708101099Srwatson return (0); 2709101099Srwatson 2710122524Srwatson subj = SLOT(cred->cr_label); 2711168976Srwatson obj = SLOT(vplabel); 2712101099Srwatson 2713172955Srwatson if (!biba_dominate_effective(obj, subj)) 2714101099Srwatson return (EACCES); 2715101099Srwatson 2716101099Srwatson return (0); 2717101099Srwatson} 2718101099Srwatson 2719101099Srwatsonstatic int 2720172955Srwatsonbiba_vnode_check_getextattr(struct ucred *cred, struct vnode *vp, 2721168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 2722168976Srwatson struct uio *uio) 2723101099Srwatson{ 2724101099Srwatson struct mac_biba *subj, *obj; 2725101099Srwatson 2726172955Srwatson if (!biba_enabled) 2727101099Srwatson return (0); 2728101099Srwatson 2729122524Srwatson subj = SLOT(cred->cr_label); 2730168976Srwatson obj = SLOT(vplabel); 2731101099Srwatson 2732172955Srwatson if (!biba_dominate_effective(obj, subj)) 2733101099Srwatson return (EACCES); 2734101099Srwatson 2735101099Srwatson return (0); 2736101099Srwatson} 2737101099Srwatson 2738101099Srwatsonstatic int 2739172955Srwatsonbiba_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2740168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2741104530Srwatson struct componentname *cnp) 2742104530Srwatson{ 2743104530Srwatson struct mac_biba *subj, *obj; 2744104530Srwatson 2745172955Srwatson if (!biba_enabled) 2746104530Srwatson return (0); 2747104530Srwatson 2748122524Srwatson subj = SLOT(cred->cr_label); 2749168976Srwatson obj = SLOT(dvplabel); 2750104530Srwatson 2751172955Srwatson if (!biba_dominate_effective(subj, obj)) 2752104530Srwatson return (EACCES); 2753104530Srwatson 2754168976Srwatson obj = SLOT(vplabel); 2755104530Srwatson 2756172955Srwatson if (!biba_dominate_effective(subj, obj)) 2757104530Srwatson return (EACCES); 2758104530Srwatson 2759104530Srwatson return (0); 2760104530Srwatson} 2761104530Srwatson 2762104530Srwatsonstatic int 2763172955Srwatsonbiba_vnode_check_listextattr(struct ucred *cred, struct vnode *vp, 2764168976Srwatson struct label *vplabel, int attrnamespace) 2765119202Srwatson{ 2766119202Srwatson struct mac_biba *subj, *obj; 2767119202Srwatson 2768172955Srwatson if (!biba_enabled) 2769119202Srwatson return (0); 2770119202Srwatson 2771122524Srwatson subj = SLOT(cred->cr_label); 2772168976Srwatson obj = SLOT(vplabel); 2773119202Srwatson 2774172955Srwatson if (!biba_dominate_effective(obj, subj)) 2775119202Srwatson return (EACCES); 2776119202Srwatson 2777119202Srwatson return (0); 2778119202Srwatson} 2779119202Srwatson 2780119202Srwatsonstatic int 2781172955Srwatsonbiba_vnode_check_lookup(struct ucred *cred, struct vnode *dvp, 2782168976Srwatson struct label *dvplabel, struct componentname *cnp) 2783101099Srwatson{ 2784101099Srwatson struct mac_biba *subj, *obj; 2785103759Srwatson 2786172955Srwatson if (!biba_enabled) 2787101099Srwatson return (0); 2788103759Srwatson 2789122524Srwatson subj = SLOT(cred->cr_label); 2790168976Srwatson obj = SLOT(dvplabel); 2791103759Srwatson 2792172955Srwatson if (!biba_dominate_effective(obj, subj)) 2793101099Srwatson return (EACCES); 2794101099Srwatson 2795103759Srwatson return (0); 2796101099Srwatson} 2797101099Srwatson 2798101099Srwatsonstatic int 2799172955Srwatsonbiba_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2800168976Srwatson struct label *vplabel, int prot, int flags) 2801104546Srwatson{ 2802104546Srwatson struct mac_biba *subj, *obj; 2803104546Srwatson 2804104546Srwatson /* 2805104546Srwatson * Rely on the use of open()-time protections to handle 2806104546Srwatson * non-revocation cases. 2807104546Srwatson */ 2808172955Srwatson if (!biba_enabled || !revocation_enabled) 2809104546Srwatson return (0); 2810104546Srwatson 2811122524Srwatson subj = SLOT(cred->cr_label); 2812168976Srwatson obj = SLOT(vplabel); 2813104546Srwatson 2814104546Srwatson if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2815172955Srwatson if (!biba_dominate_effective(obj, subj)) 2816104546Srwatson return (EACCES); 2817104546Srwatson } 2818145076Scsjp if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2819172955Srwatson if (!biba_dominate_effective(subj, obj)) 2820104546Srwatson return (EACCES); 2821104546Srwatson } 2822104546Srwatson 2823104569Srwatson return (0); 2824104546Srwatson} 2825104546Srwatson 2826104546Srwatsonstatic int 2827172955Srwatsonbiba_vnode_check_open(struct ucred *cred, struct vnode *vp, 2828168976Srwatson struct label *vplabel, int acc_mode) 2829101099Srwatson{ 2830101099Srwatson struct mac_biba *subj, *obj; 2831101099Srwatson 2832172955Srwatson if (!biba_enabled) 2833101099Srwatson return (0); 2834101099Srwatson 2835122524Srwatson subj = SLOT(cred->cr_label); 2836168976Srwatson obj = SLOT(vplabel); 2837101099Srwatson 2838101099Srwatson /* XXX privilege override for admin? */ 2839101099Srwatson if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2840172955Srwatson if (!biba_dominate_effective(obj, subj)) 2841101099Srwatson return (EACCES); 2842101099Srwatson } 2843101099Srwatson if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2844172955Srwatson if (!biba_dominate_effective(subj, obj)) 2845101099Srwatson return (EACCES); 2846101099Srwatson } 2847101099Srwatson 2848101099Srwatson return (0); 2849101099Srwatson} 2850101099Srwatson 2851101099Srwatsonstatic int 2852172955Srwatsonbiba_vnode_check_poll(struct ucred *active_cred, struct ucred *file_cred, 2853168976Srwatson struct vnode *vp, struct label *vplabel) 2854102112Srwatson{ 2855102112Srwatson struct mac_biba *subj, *obj; 2856102112Srwatson 2857172955Srwatson if (!biba_enabled || !revocation_enabled) 2858102112Srwatson return (0); 2859102112Srwatson 2860122524Srwatson subj = SLOT(active_cred->cr_label); 2861168976Srwatson obj = SLOT(vplabel); 2862102112Srwatson 2863172955Srwatson if (!biba_dominate_effective(obj, subj)) 2864102112Srwatson return (EACCES); 2865102112Srwatson 2866102112Srwatson return (0); 2867102112Srwatson} 2868102112Srwatson 2869102112Srwatsonstatic int 2870172955Srwatsonbiba_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2871168976Srwatson struct vnode *vp, struct label *vplabel) 2872102112Srwatson{ 2873102112Srwatson struct mac_biba *subj, *obj; 2874102112Srwatson 2875172955Srwatson if (!biba_enabled || !revocation_enabled) 2876102112Srwatson return (0); 2877102112Srwatson 2878122524Srwatson subj = SLOT(active_cred->cr_label); 2879168976Srwatson obj = SLOT(vplabel); 2880102112Srwatson 2881172955Srwatson if (!biba_dominate_effective(obj, subj)) 2882102112Srwatson return (EACCES); 2883102112Srwatson 2884102112Srwatson return (0); 2885102112Srwatson} 2886102112Srwatson 2887102112Srwatsonstatic int 2888172955Srwatsonbiba_vnode_check_readdir(struct ucred *cred, struct vnode *dvp, 2889168976Srwatson struct label *dvplabel) 2890101099Srwatson{ 2891101099Srwatson struct mac_biba *subj, *obj; 2892101099Srwatson 2893172955Srwatson if (!biba_enabled) 2894101099Srwatson return (0); 2895101099Srwatson 2896122524Srwatson subj = SLOT(cred->cr_label); 2897168976Srwatson obj = SLOT(dvplabel); 2898101099Srwatson 2899172955Srwatson if (!biba_dominate_effective(obj, subj)) 2900101099Srwatson return (EACCES); 2901101099Srwatson 2902101099Srwatson return (0); 2903101099Srwatson} 2904101099Srwatson 2905101099Srwatsonstatic int 2906172955Srwatsonbiba_vnode_check_readlink(struct ucred *cred, struct vnode *vp, 2907168976Srwatson struct label *vplabel) 2908101099Srwatson{ 2909101099Srwatson struct mac_biba *subj, *obj; 2910101099Srwatson 2911172955Srwatson if (!biba_enabled) 2912101099Srwatson return (0); 2913101099Srwatson 2914122524Srwatson subj = SLOT(cred->cr_label); 2915168976Srwatson obj = SLOT(vplabel); 2916101099Srwatson 2917172955Srwatson if (!biba_dominate_effective(obj, subj)) 2918101099Srwatson return (EACCES); 2919101099Srwatson 2920101099Srwatson return (0); 2921101099Srwatson} 2922101099Srwatson 2923101099Srwatsonstatic int 2924172955Srwatsonbiba_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2925168976Srwatson struct label *vplabel, struct label *newlabel) 2926101099Srwatson{ 2927101099Srwatson struct mac_biba *old, *new, *subj; 2928105634Srwatson int error; 2929101099Srwatson 2930168976Srwatson old = SLOT(vplabel); 2931101099Srwatson new = SLOT(newlabel); 2932122524Srwatson subj = SLOT(cred->cr_label); 2933101099Srwatson 2934101099Srwatson /* 2935105634Srwatson * If there is a Biba label update for the vnode, it must be a 2936132232Srwatson * effective label. 2937101099Srwatson */ 2938132232Srwatson error = biba_atmostflags(new, MAC_BIBA_FLAG_EFFECTIVE); 2939105634Srwatson if (error) 2940105634Srwatson return (error); 2941101099Srwatson 2942101099Srwatson /* 2943105634Srwatson * To perform a relabel of the vnode (Biba label or not), Biba must 2944105634Srwatson * authorize the relabel. 2945101099Srwatson */ 2946172955Srwatson if (!biba_effective_in_range(old, subj)) 2947101099Srwatson return (EPERM); 2948101099Srwatson 2949101099Srwatson /* 2950105634Srwatson * If the Biba label is to be changed, authorize as appropriate. 2951101099Srwatson */ 2952132232Srwatson if (new->mb_flags & MAC_BIBA_FLAG_EFFECTIVE) { 2953105634Srwatson /* 2954105634Srwatson * To change the Biba label on a vnode, the new vnode label 2955105634Srwatson * must be in the subject range. 2956105634Srwatson */ 2957172955Srwatson if (!biba_effective_in_range(new, subj)) 2958105634Srwatson return (EPERM); 2959101099Srwatson 2960105634Srwatson /* 2961172955Srwatson * To change the Biba label on the vnode to be EQUAL, the 2962172955Srwatson * subject must have appropriate privilege. 2963105634Srwatson */ 2964172955Srwatson if (biba_contains_equal(new)) { 2965172955Srwatson error = biba_subject_privileged(subj); 2966105634Srwatson if (error) 2967105634Srwatson return (error); 2968105634Srwatson } 2969105634Srwatson } 2970105634Srwatson 2971105634Srwatson return (0); 2972101099Srwatson} 2973101099Srwatson 2974101099Srwatsonstatic int 2975172955Srwatsonbiba_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2976168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2977101099Srwatson struct componentname *cnp) 2978101099Srwatson{ 2979101099Srwatson struct mac_biba *subj, *obj; 2980101099Srwatson 2981172955Srwatson if (!biba_enabled) 2982101099Srwatson return (0); 2983101099Srwatson 2984122524Srwatson subj = SLOT(cred->cr_label); 2985168976Srwatson obj = SLOT(dvplabel); 2986101099Srwatson 2987172955Srwatson if (!biba_dominate_effective(subj, obj)) 2988101099Srwatson return (EACCES); 2989101099Srwatson 2990168976Srwatson obj = SLOT(vplabel); 2991101099Srwatson 2992172955Srwatson if (!biba_dominate_effective(subj, obj)) 2993101099Srwatson return (EACCES); 2994101099Srwatson 2995101099Srwatson return (0); 2996101099Srwatson} 2997101099Srwatson 2998101099Srwatsonstatic int 2999172955Srwatsonbiba_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 3000168976Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3001168976Srwatson int samedir, struct componentname *cnp) 3002101099Srwatson{ 3003101099Srwatson struct mac_biba *subj, *obj; 3004101099Srwatson 3005172955Srwatson if (!biba_enabled) 3006101099Srwatson return (0); 3007101099Srwatson 3008122524Srwatson subj = SLOT(cred->cr_label); 3009168976Srwatson obj = SLOT(dvplabel); 3010101099Srwatson 3011172955Srwatson if (!biba_dominate_effective(subj, obj)) 3012101099Srwatson return (EACCES); 3013101099Srwatson 3014101099Srwatson if (vp != NULL) { 3015168976Srwatson obj = SLOT(vplabel); 3016101099Srwatson 3017172955Srwatson if (!biba_dominate_effective(subj, obj)) 3018101099Srwatson return (EACCES); 3019101099Srwatson } 3020101099Srwatson 3021101099Srwatson return (0); 3022101099Srwatson} 3023101099Srwatson 3024101099Srwatsonstatic int 3025172955Srwatsonbiba_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 3026168976Srwatson struct label *vplabel) 3027101099Srwatson{ 3028101099Srwatson struct mac_biba *subj, *obj; 3029101099Srwatson 3030172955Srwatson if (!biba_enabled) 3031101099Srwatson return (0); 3032101099Srwatson 3033122524Srwatson subj = SLOT(cred->cr_label); 3034168976Srwatson obj = SLOT(vplabel); 3035101099Srwatson 3036172955Srwatson if (!biba_dominate_effective(subj, obj)) 3037101099Srwatson return (EACCES); 3038101099Srwatson 3039101099Srwatson return (0); 3040101099Srwatson} 3041101099Srwatson 3042101099Srwatsonstatic int 3043172955Srwatsonbiba_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 3044168976Srwatson struct label *vplabel, acl_type_t type, struct acl *acl) 3045101099Srwatson{ 3046101099Srwatson struct mac_biba *subj, *obj; 3047101099Srwatson 3048172955Srwatson if (!biba_enabled) 3049101099Srwatson return (0); 3050101099Srwatson 3051122524Srwatson subj = SLOT(cred->cr_label); 3052168976Srwatson obj = SLOT(vplabel); 3053101099Srwatson 3054172955Srwatson if (!biba_dominate_effective(subj, obj)) 3055101099Srwatson return (EACCES); 3056101099Srwatson 3057101099Srwatson return (0); 3058101099Srwatson} 3059101099Srwatson 3060101099Srwatsonstatic int 3061172955Srwatsonbiba_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 3062168976Srwatson struct label *vplabel, int attrnamespace, const char *name, 3063101099Srwatson struct uio *uio) 3064101099Srwatson{ 3065101099Srwatson struct mac_biba *subj, *obj; 3066101099Srwatson 3067172955Srwatson if (!biba_enabled) 3068101099Srwatson return (0); 3069101099Srwatson 3070122524Srwatson subj = SLOT(cred->cr_label); 3071168976Srwatson obj = SLOT(vplabel); 3072101099Srwatson 3073172955Srwatson if (!biba_dominate_effective(subj, obj)) 3074101099Srwatson return (EACCES); 3075101099Srwatson 3076101099Srwatson /* XXX: protect the MAC EA in a special way? */ 3077101099Srwatson 3078101099Srwatson return (0); 3079101099Srwatson} 3080101099Srwatson 3081101099Srwatsonstatic int 3082172955Srwatsonbiba_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 3083168976Srwatson struct label *vplabel, u_long flags) 3084101099Srwatson{ 3085101099Srwatson struct mac_biba *subj, *obj; 3086101099Srwatson 3087172955Srwatson if (!biba_enabled) 3088101099Srwatson return (0); 3089101099Srwatson 3090122524Srwatson subj = SLOT(cred->cr_label); 3091168976Srwatson obj = SLOT(vplabel); 3092101099Srwatson 3093172955Srwatson if (!biba_dominate_effective(subj, obj)) 3094101099Srwatson return (EACCES); 3095101099Srwatson 3096101099Srwatson return (0); 3097101099Srwatson} 3098101099Srwatson 3099101099Srwatsonstatic int 3100172955Srwatsonbiba_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 3101168976Srwatson struct label *vplabel, mode_t mode) 3102101099Srwatson{ 3103101099Srwatson struct mac_biba *subj, *obj; 3104101099Srwatson 3105172955Srwatson if (!biba_enabled) 3106101099Srwatson return (0); 3107101099Srwatson 3108122524Srwatson subj = SLOT(cred->cr_label); 3109168976Srwatson obj = SLOT(vplabel); 3110101099Srwatson 3111172955Srwatson if (!biba_dominate_effective(subj, obj)) 3112101099Srwatson return (EACCES); 3113101099Srwatson 3114101099Srwatson return (0); 3115101099Srwatson} 3116101099Srwatson 3117101099Srwatsonstatic int 3118172955Srwatsonbiba_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 3119168976Srwatson struct label *vplabel, uid_t uid, gid_t gid) 3120101099Srwatson{ 3121101099Srwatson struct mac_biba *subj, *obj; 3122101099Srwatson 3123172955Srwatson if (!biba_enabled) 3124101099Srwatson return (0); 3125101099Srwatson 3126122524Srwatson subj = SLOT(cred->cr_label); 3127168976Srwatson obj = SLOT(vplabel); 3128101099Srwatson 3129172955Srwatson if (!biba_dominate_effective(subj, obj)) 3130101099Srwatson return (EACCES); 3131101099Srwatson 3132101099Srwatson return (0); 3133101099Srwatson} 3134101099Srwatson 3135101099Srwatsonstatic int 3136172955Srwatsonbiba_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 3137168976Srwatson struct label *vplabel, struct timespec atime, struct timespec mtime) 3138101099Srwatson{ 3139101099Srwatson struct mac_biba *subj, *obj; 3140101099Srwatson 3141172955Srwatson if (!biba_enabled) 3142101099Srwatson return (0); 3143101099Srwatson 3144122524Srwatson subj = SLOT(cred->cr_label); 3145168976Srwatson obj = SLOT(vplabel); 3146101099Srwatson 3147172955Srwatson if (!biba_dominate_effective(subj, obj)) 3148101099Srwatson return (EACCES); 3149101099Srwatson 3150101099Srwatson return (0); 3151101099Srwatson} 3152101099Srwatson 3153101099Srwatsonstatic int 3154172955Srwatsonbiba_vnode_check_stat(struct ucred *active_cred, struct ucred *file_cred, 3155168976Srwatson struct vnode *vp, struct label *vplabel) 3156101099Srwatson{ 3157101099Srwatson struct mac_biba *subj, *obj; 3158101099Srwatson 3159172955Srwatson if (!biba_enabled) 3160101099Srwatson return (0); 3161101099Srwatson 3162122524Srwatson subj = SLOT(active_cred->cr_label); 3163168976Srwatson obj = SLOT(vplabel); 3164101099Srwatson 3165172955Srwatson if (!biba_dominate_effective(obj, subj)) 3166101099Srwatson return (EACCES); 3167101099Srwatson 3168101099Srwatson return (0); 3169101099Srwatson} 3170101099Srwatson 3171102112Srwatsonstatic int 3172172955Srwatsonbiba_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 3173172107Srwatson struct label *dvplabel, struct vnode *vp, struct label *vplabel, 3174172107Srwatson struct componentname *cnp) 3175172107Srwatson{ 3176172107Srwatson struct mac_biba *subj, *obj; 3177172107Srwatson 3178172955Srwatson if (!biba_enabled) 3179172107Srwatson return (0); 3180172107Srwatson 3181172107Srwatson subj = SLOT(cred->cr_label); 3182172107Srwatson obj = SLOT(dvplabel); 3183172107Srwatson 3184172955Srwatson if (!biba_dominate_effective(subj, obj)) 3185172107Srwatson return (EACCES); 3186172107Srwatson 3187172107Srwatson obj = SLOT(vplabel); 3188172107Srwatson 3189172955Srwatson if (!biba_dominate_effective(subj, obj)) 3190172107Srwatson return (EACCES); 3191172107Srwatson 3192172107Srwatson return (0); 3193172107Srwatson} 3194172107Srwatson 3195172107Srwatsonstatic int 3196172955Srwatsonbiba_vnode_check_write(struct ucred *active_cred, 3197168976Srwatson struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 3198102112Srwatson{ 3199102112Srwatson struct mac_biba *subj, *obj; 3200102112Srwatson 3201172955Srwatson if (!biba_enabled || !revocation_enabled) 3202102112Srwatson return (0); 3203102112Srwatson 3204122524Srwatson subj = SLOT(active_cred->cr_label); 3205168976Srwatson obj = SLOT(vplabel); 3206102112Srwatson 3207172955Srwatson if (!biba_dominate_effective(subj, obj)) 3208102112Srwatson return (EACCES); 3209102112Srwatson 3210102112Srwatson return (0); 3211102112Srwatson} 3212102112Srwatson 3213161026Srwatsonstatic 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, 3334172957Srwatson .mpo_proc_associate_nfsd = biba_proc_associate_nfsd, 3335172955Srwatson .mpo_cred_relabel = biba_cred_relabel, 3336172955Srwatson .mpo_sysvmsg_cleanup = biba_sysvmsg_cleanup, 3337172955Srwatson .mpo_sysvmsq_cleanup = biba_sysvmsq_cleanup, 3338172955Srwatson .mpo_sysvsem_cleanup = biba_sysvsem_cleanup, 3339172955Srwatson .mpo_sysvshm_cleanup = biba_sysvshm_cleanup, 3340172955Srwatson .mpo_bpfdesc_check_receive = biba_bpfdesc_check_receive, 3341172955Srwatson .mpo_cred_check_relabel = biba_cred_check_relabel, 3342172955Srwatson .mpo_cred_check_visible = biba_cred_check_visible, 3343172955Srwatson .mpo_ifnet_check_relabel = biba_ifnet_check_relabel, 3344172955Srwatson .mpo_ifnet_check_transmit = biba_ifnet_check_transmit, 3345172955Srwatson .mpo_inpcb_check_deliver = biba_inpcb_check_deliver, 3346172955Srwatson .mpo_sysvmsq_check_msgrcv = biba_sysvmsq_check_msgrcv, 3347172955Srwatson .mpo_sysvmsq_check_msgrmid = biba_sysvmsq_check_msgrmid, 3348172955Srwatson .mpo_sysvmsq_check_msqget = biba_sysvmsq_check_msqget, 3349172955Srwatson .mpo_sysvmsq_check_msqsnd = biba_sysvmsq_check_msqsnd, 3350172955Srwatson .mpo_sysvmsq_check_msqrcv = biba_sysvmsq_check_msqrcv, 3351172955Srwatson .mpo_sysvmsq_check_msqctl = biba_sysvmsq_check_msqctl, 3352172955Srwatson .mpo_sysvsem_check_semctl = biba_sysvsem_check_semctl, 3353172955Srwatson .mpo_sysvsem_check_semget = biba_sysvsem_check_semget, 3354172955Srwatson .mpo_sysvsem_check_semop = biba_sysvsem_check_semop, 3355172955Srwatson .mpo_sysvshm_check_shmat = biba_sysvshm_check_shmat, 3356172955Srwatson .mpo_sysvshm_check_shmctl = biba_sysvshm_check_shmctl, 3357172955Srwatson .mpo_sysvshm_check_shmget = biba_sysvshm_check_shmget, 3358172955Srwatson .mpo_kld_check_load = biba_kld_check_load, 3359172955Srwatson .mpo_mount_check_stat = biba_mount_check_stat, 3360172955Srwatson .mpo_pipe_check_ioctl = biba_pipe_check_ioctl, 3361172955Srwatson .mpo_pipe_check_poll = biba_pipe_check_poll, 3362172955Srwatson .mpo_pipe_check_read = biba_pipe_check_read, 3363172955Srwatson .mpo_pipe_check_relabel = biba_pipe_check_relabel, 3364172955Srwatson .mpo_pipe_check_stat = biba_pipe_check_stat, 3365172955Srwatson .mpo_pipe_check_write = biba_pipe_check_write, 3366172955Srwatson .mpo_posixsem_check_destroy = biba_posixsem_check_write, 3367172955Srwatson .mpo_posixsem_check_getvalue = biba_posixsem_check_rdonly, 3368172955Srwatson .mpo_posixsem_check_open = biba_posixsem_check_write, 3369172955Srwatson .mpo_posixsem_check_post = biba_posixsem_check_write, 3370172955Srwatson .mpo_posixsem_check_unlink = biba_posixsem_check_write, 3371172955Srwatson .mpo_posixsem_check_wait = biba_posixsem_check_write, 3372172955Srwatson .mpo_proc_check_debug = biba_proc_check_debug, 3373172955Srwatson .mpo_proc_check_sched = biba_proc_check_sched, 3374172955Srwatson .mpo_proc_check_signal = biba_proc_check_signal, 3375172955Srwatson .mpo_socket_check_deliver = biba_socket_check_deliver, 3376172955Srwatson .mpo_socket_check_relabel = biba_socket_check_relabel, 3377172955Srwatson .mpo_socket_check_visible = biba_socket_check_visible, 3378172955Srwatson .mpo_system_check_acct = biba_system_check_acct, 3379172955Srwatson .mpo_system_check_auditctl = biba_system_check_auditctl, 3380172955Srwatson .mpo_system_check_auditon = biba_system_check_auditon, 3381172955Srwatson .mpo_system_check_swapon = biba_system_check_swapon, 3382172955Srwatson .mpo_system_check_swapoff = biba_system_check_swapoff, 3383172955Srwatson .mpo_system_check_sysctl = biba_system_check_sysctl, 3384172955Srwatson .mpo_vnode_check_access = biba_vnode_check_open, 3385172955Srwatson .mpo_vnode_check_chdir = biba_vnode_check_chdir, 3386172955Srwatson .mpo_vnode_check_chroot = biba_vnode_check_chroot, 3387172955Srwatson .mpo_vnode_check_create = biba_vnode_check_create, 3388172955Srwatson .mpo_vnode_check_deleteacl = biba_vnode_check_deleteacl, 3389172955Srwatson .mpo_vnode_check_deleteextattr = biba_vnode_check_deleteextattr, 3390172955Srwatson .mpo_vnode_check_exec = biba_vnode_check_exec, 3391172955Srwatson .mpo_vnode_check_getacl = biba_vnode_check_getacl, 3392172955Srwatson .mpo_vnode_check_getextattr = biba_vnode_check_getextattr, 3393172955Srwatson .mpo_vnode_check_link = biba_vnode_check_link, 3394172955Srwatson .mpo_vnode_check_listextattr = biba_vnode_check_listextattr, 3395172955Srwatson .mpo_vnode_check_lookup = biba_vnode_check_lookup, 3396172955Srwatson .mpo_vnode_check_mmap = biba_vnode_check_mmap, 3397172955Srwatson .mpo_vnode_check_open = biba_vnode_check_open, 3398172955Srwatson .mpo_vnode_check_poll = biba_vnode_check_poll, 3399172955Srwatson .mpo_vnode_check_read = biba_vnode_check_read, 3400172955Srwatson .mpo_vnode_check_readdir = biba_vnode_check_readdir, 3401172955Srwatson .mpo_vnode_check_readlink = biba_vnode_check_readlink, 3402172955Srwatson .mpo_vnode_check_relabel = biba_vnode_check_relabel, 3403172955Srwatson .mpo_vnode_check_rename_from = biba_vnode_check_rename_from, 3404172955Srwatson .mpo_vnode_check_rename_to = biba_vnode_check_rename_to, 3405172955Srwatson .mpo_vnode_check_revoke = biba_vnode_check_revoke, 3406172955Srwatson .mpo_vnode_check_setacl = biba_vnode_check_setacl, 3407172955Srwatson .mpo_vnode_check_setextattr = biba_vnode_check_setextattr, 3408172955Srwatson .mpo_vnode_check_setflags = biba_vnode_check_setflags, 3409172955Srwatson .mpo_vnode_check_setmode = biba_vnode_check_setmode, 3410172955Srwatson .mpo_vnode_check_setowner = biba_vnode_check_setowner, 3411172955Srwatson .mpo_vnode_check_setutimes = biba_vnode_check_setutimes, 3412172955Srwatson .mpo_vnode_check_stat = biba_vnode_check_stat, 3413172955Srwatson .mpo_vnode_check_unlink = biba_vnode_check_unlink, 3414172955Srwatson .mpo_vnode_check_write = biba_vnode_check_write, 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