mac_biba.c revision 105656
1129906Sbmilekic/*- 2141991Sbmilekic * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3254515Sandre * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 4129906Sbmilekic * All rights reserved. 5129906Sbmilekic * 6129906Sbmilekic * This software was developed by Robert Watson for the TrustedBSD Project. 7129906Sbmilekic * 8129906Sbmilekic * This software was developed for the FreeBSD Project in part by NAI Labs, 9129906Sbmilekic * the Security Research Division of Network Associates, Inc. under 10129906Sbmilekic * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 11129906Sbmilekic * CHATS research program. 12129906Sbmilekic * 13129906Sbmilekic * Redistribution and use in source and binary forms, with or without 14129906Sbmilekic * modification, are permitted provided that the following conditions 15129906Sbmilekic * are met: 16129906Sbmilekic * 1. Redistributions of source code must retain the above copyright 17129906Sbmilekic * notice, this list of conditions and the following disclaimer. 18129906Sbmilekic * 2. Redistributions in binary form must reproduce the above copyright 19129906Sbmilekic * notice, this list of conditions and the following disclaimer in the 20129906Sbmilekic * documentation and/or other materials provided with the distribution. 21129906Sbmilekic * 3. The names of the authors may not be used to endorse or promote 22129906Sbmilekic * products derived from this software without specific prior written 23129906Sbmilekic * permission. 24129906Sbmilekic * 25129906Sbmilekic * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 26129906Sbmilekic * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27129906Sbmilekic * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28129906Sbmilekic * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 29129906Sbmilekic * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30129906Sbmilekic * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31129906Sbmilekic * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32129906Sbmilekic * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33129906Sbmilekic * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34129906Sbmilekic * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35129906Sbmilekic * SUCH DAMAGE. 36129906Sbmilekic * 37129906Sbmilekic * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 105656 2002-10-21 20:55:39Z rwatson $ 38129906Sbmilekic */ 39129906Sbmilekic 40129906Sbmilekic/* 41129906Sbmilekic * Developed by the TrustedBSD Project. 42129906Sbmilekic * Biba fixed label mandatory integrity policy. 43129906Sbmilekic */ 44163606Srwatson 45163606Srwatson#include <sys/types.h> 46129906Sbmilekic#include <sys/param.h> 47194454Salc#include <sys/acl.h> 48194454Salc#include <sys/conf.h> 49129906Sbmilekic#include <sys/kernel.h> 50254515Sandre#include <sys/mac.h> 51129906Sbmilekic#include <sys/malloc.h> 52147537Ssilby#include <sys/mount.h> 53147537Ssilby#include <sys/proc.h> 54129906Sbmilekic#include <sys/systm.h> 55129906Sbmilekic#include <sys/sysproto.h> 56129906Sbmilekic#include <sys/sysent.h> 57129906Sbmilekic#include <sys/vnode.h> 58129906Sbmilekic#include <sys/file.h> 59129906Sbmilekic#include <sys/socket.h> 60129906Sbmilekic#include <sys/socketvar.h> 61129906Sbmilekic#include <sys/pipe.h> 62129906Sbmilekic#include <sys/sysctl.h> 63129906Sbmilekic 64129906Sbmilekic#include <fs/devfs/devfs.h> 65129906Sbmilekic 66129906Sbmilekic#include <net/bpfdesc.h> 67129906Sbmilekic#include <net/if.h> 68129906Sbmilekic#include <net/if_types.h> 69129906Sbmilekic#include <net/if_var.h> 70129906Sbmilekic 71129906Sbmilekic#include <netinet/in.h> 72129906Sbmilekic#include <netinet/ip_var.h> 73129906Sbmilekic 74129906Sbmilekic#include <vm/vm.h> 75129906Sbmilekic 76129906Sbmilekic#include <sys/mac_policy.h> 77129906Sbmilekic 78129906Sbmilekic#include <security/mac_biba/mac_biba.h> 79129906Sbmilekic 80254515SandreSYSCTL_DECL(_security_mac); 81129906Sbmilekic 82129906SbmilekicSYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 83129906Sbmilekic "TrustedBSD mac_biba policy controls"); 84151976Sandre 85151976Sandrestatic int mac_biba_enabled = 0; 86156023SglebiusSYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 87151976Sandre &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 88156023SglebiusTUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 89151976Sandre 90156023Sglebiusstatic int destroyed_not_inited; 91151976SandreSYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 92151976Sandre &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 93156023Sglebius 94151976Sandrestatic int trust_all_interfaces = 0; 95151976SandreSYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 96151976Sandre &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 97151976SandreTUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 98129906Sbmilekic 99129906Sbmilekicstatic char trusted_interfaces[128]; 100254515SandreSYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 101151976Sandre trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 102155780SandreTUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 103151976Sandre sizeof(trusted_interfaces)); 104151976Sandre 105129906Sbmilekicstatic int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 106129906SbmilekicSYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 107254515Sandre &max_compartments, 0, "Maximum supported compartments"); 108254515Sandre 109254515Sandrestatic int ptys_equal = 0; 110254515SandreSYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 111254515Sandre &ptys_equal, 0, "Label pty devices as biba/equal on create"); 112185893SbzTUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 113254515Sandre 114185893Sbzstatic int revocation_enabled = 0; 115129906SbmilekicSYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 116129906Sbmilekic &revocation_enabled, 0, "Revoke access to objects on relabel"); 117129906SbmilekicTUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 118254515Sandre 119129906Sbmilekicstatic int mac_biba_slot; 120254515Sandre#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 121254515Sandre 122254515SandreMALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels"); 123254515Sandre 124254515Sandrestatic __inline int 125254515Sandrebiba_bit_set_empty(u_char *set) { 126254515Sandre int i; 127254515Sandre 128254515Sandre for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 129254515Sandre if (set[i] != 0) 130254515Sandre return (0); 131254515Sandre return (1); 132241468Snp} 133184778Skmacy 134254515Sandrestatic struct mac_biba * 135241468Snpbiba_alloc(int flag) 136241468Snp{ 137241468Snp struct mac_biba *mac_biba; 138254515Sandre 139241468Snp mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag); 140241468Snp 141241468Snp return (mac_biba); 142254515Sandre} 143241468Snp 144241468Snpstatic void 145241468Snpbiba_free(struct mac_biba *mac_biba) 146254515Sandre{ 147254515Sandre 148254515Sandre if (mac_biba != NULL) 149254515Sandre free(mac_biba, M_MACBIBA); 150254515Sandre else 151254515Sandre atomic_add_int(&destroyed_not_inited, 1); 152254515Sandre} 153254515Sandre 154254515Sandrestatic int 155254515Sandrebiba_atmostflags(struct mac_biba *mac_biba, int flags) 156129906Sbmilekic{ 157254515Sandre 158129906Sbmilekic if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 159157927Sps return (EINVAL); 160157927Sps return (0); 161157927Sps} 162157927Sps 163157927Spsstatic int 164157927Spsmac_biba_dominate_element(struct mac_biba_element *a, 165254515Sandre struct mac_biba_element *b) 166258183Sjhb{ 167254515Sandre int bit; 168254515Sandre 169157927Sps switch(a->mbe_type) { 170254515Sandre case MAC_BIBA_TYPE_EQUAL: 171157927Sps case MAC_BIBA_TYPE_HIGH: 172157927Sps return (1); 173157927Sps 174157927Sps case MAC_BIBA_TYPE_LOW: 175157927Sps switch (b->mbe_type) { 176157927Sps case MAC_BIBA_TYPE_GRADE: 177157927Sps case MAC_BIBA_TYPE_HIGH: 178157927Sps return (0); 179129906Sbmilekic 180174292Srrs case MAC_BIBA_TYPE_EQUAL: 181174292Srrs case MAC_BIBA_TYPE_LOW: 182174292Srrs return (1); 183174292Srrs 184174292Srrs default: 185174292Srrs panic("mac_biba_dominate_element: b->mbe_type invalid"); 186174292Srrs } 187254515Sandre 188258183Sjhb case MAC_BIBA_TYPE_GRADE: 189254515Sandre switch (b->mbe_type) { 190254515Sandre case MAC_BIBA_TYPE_EQUAL: 191174292Srrs case MAC_BIBA_TYPE_LOW: 192254515Sandre return (1); 193174292Srrs 194174292Srrs case MAC_BIBA_TYPE_HIGH: 195174292Srrs return (0); 196174292Srrs 197174292Srrs case MAC_BIBA_TYPE_GRADE: 198174292Srrs for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 199174292Srrs if (!MAC_BIBA_BIT_TEST(bit, 200254515Sandre a->mbe_compartments) && 201174292Srrs MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 202174292Srrs return (0); 203174292Srrs return (a->mbe_grade >= b->mbe_grade); 204174292Srrs 205174292Srrs default: 206174292Srrs panic("mac_biba_dominate_element: b->mbe_type invalid"); 207174292Srrs } 208254515Sandre 209258183Sjhb default: 210254515Sandre panic("mac_biba_dominate_element: a->mbe_type invalid"); 211254515Sandre } 212174292Srrs 213254515Sandre return (0); 214174292Srrs} 215174292Srrs 216174292Srrsstatic int 217174292Srrsmac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 218174292Srrs{ 219174292Srrs 220174292Srrs return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 221254515Sandre &rangea->mb_rangehigh) && 222174292Srrs mac_biba_dominate_element(&rangea->mb_rangelow, 223174292Srrs &rangeb->mb_rangelow)); 224174292Srrs} 225174292Srrs 226174292Srrsstatic int 227174292Srrsmac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range) 228174292Srrs{ 229254515Sandre 230258183Sjhb KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 231254515Sandre ("mac_biba_single_in_range: a not single")); 232254515Sandre KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 233174292Srrs ("mac_biba_single_in_range: b not range")); 234254515Sandre 235174292Srrs return (mac_biba_dominate_element(&range->mb_rangehigh, 236174292Srrs &single->mb_single) && 237174292Srrs mac_biba_dominate_element(&single->mb_single, 238174292Srrs &range->mb_rangelow)); 239174292Srrs 240174292Srrs return (1); 241174292Srrs} 242151976Sandre 243174292Srrsstatic int 244254515Sandremac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b) 245254515Sandre{ 246254515Sandre KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 247254515Sandre ("mac_biba_dominate_single: a not single")); 248174292Srrs KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 249254515Sandre ("mac_biba_dominate_single: b not single")); 250254515Sandre 251258183Sjhb return (mac_biba_dominate_element(&a->mb_single, &b->mb_single)); 252254515Sandre} 253254515Sandre 254254515Sandrestatic int 255254515Sandremac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 256254515Sandre{ 257254515Sandre 258254515Sandre if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 259254515Sandre b->mbe_type == MAC_BIBA_TYPE_EQUAL) 260254515Sandre return (1); 261254515Sandre 262254515Sandre return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 263254515Sandre} 264174292Srrs 265129906Sbmilekicstatic int 266129906Sbmilekicmac_biba_equal_single(struct mac_biba *a, struct mac_biba *b) 267129906Sbmilekic{ 268129906Sbmilekic 269129906Sbmilekic KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 270129906Sbmilekic ("mac_biba_equal_single: a not single")); 271129906Sbmilekic KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 272129906Sbmilekic ("mac_biba_equal_single: b not single")); 273129906Sbmilekic 274155780Sandre return (mac_biba_equal_element(&a->mb_single, &b->mb_single)); 275151976Sandre} 276151976Sandre 277151976Sandrestatic int 278129906Sbmilekicmac_biba_contains_equal(struct mac_biba *mac_biba) 279129906Sbmilekic{ 280129906Sbmilekic 281129906Sbmilekic if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) 282132987Sgreen if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 283132987Sgreen return (1); 284132987Sgreen 285129906Sbmilekic if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 286151976Sandre if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 287151976Sandre return (1); 288151976Sandre if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 289151976Sandre return (1); 290129906Sbmilekic } 291129906Sbmilekic 292209390Sed return (0); 293129906Sbmilekic} 294135510Sbrian 295135510Sbrianstatic int 296135510Sbrianmac_biba_subject_equal_ok(struct mac_biba *mac_biba) 297129906Sbmilekic{ 298129906Sbmilekic 299129906Sbmilekic KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 300129906Sbmilekic MAC_BIBA_FLAGS_BOTH, 301129906Sbmilekic ("mac_biba_subject_equal_ok: subject doesn't have both labels")); 302129906Sbmilekic 303129906Sbmilekic /* If the single is EQUAL, it's ok. */ 304129906Sbmilekic if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 305129906Sbmilekic return (0); 306129906Sbmilekic 307151976Sandre /* If either range endpoint is EQUAL, it's ok. */ 308151976Sandre if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 309147537Ssilby mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 310151976Sandre return (0); 311147537Ssilby 312151976Sandre /* If the range is low-high, it's ok. */ 313147537Ssilby if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 314151976Sandre mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 315254515Sandre return (0); 316254515Sandre 317151976Sandre /* It's not ok. */ 318148095Srwatson return (EPERM); 319151976Sandre} 320147537Ssilby 321151976Sandrestatic int 322147537Ssilbymac_biba_valid(struct mac_biba *mac_biba) 323151976Sandre{ 324147537Ssilby 325151976Sandre if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 326129906Sbmilekic switch (mac_biba->mb_single.mbe_type) { 327254515Sandre case MAC_BIBA_TYPE_GRADE: 328151976Sandre break; 329148095Srwatson 330151976Sandre case MAC_BIBA_TYPE_EQUAL: 331129906Sbmilekic case MAC_BIBA_TYPE_HIGH: 332156023Sglebius case MAC_BIBA_TYPE_LOW: 333155780Sandre if (mac_biba->mb_single.mbe_grade != 0 || 334153232Sandre !MAC_BIBA_BIT_SET_EMPTY( 335153232Sandre mac_biba->mb_single.mbe_compartments)) 336153232Sandre return (EINVAL); 337153232Sandre break; 338153232Sandre 339153232Sandre default: 340153232Sandre return (EINVAL); 341155780Sandre } 342254515Sandre } else { 343153232Sandre if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 344151976Sandre return (EINVAL); 345151976Sandre } 346151976Sandre 347151976Sandre if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 348151976Sandre switch (mac_biba->mb_rangelow.mbe_type) { 349151976Sandre case MAC_BIBA_TYPE_GRADE: 350151976Sandre break; 351151976Sandre 352254515Sandre case MAC_BIBA_TYPE_EQUAL: 353151976Sandre case MAC_BIBA_TYPE_HIGH: 354254515Sandre case MAC_BIBA_TYPE_LOW: 355129906Sbmilekic if (mac_biba->mb_rangelow.mbe_grade != 0 || 356151976Sandre !MAC_BIBA_BIT_SET_EMPTY( 357151976Sandre mac_biba->mb_rangelow.mbe_compartments)) 358151976Sandre return (EINVAL); 359151976Sandre break; 360151976Sandre 361151976Sandre default: 362151976Sandre return (EINVAL); 363151976Sandre } 364254515Sandre 365151976Sandre switch (mac_biba->mb_rangehigh.mbe_type) { 366254515Sandre case MAC_BIBA_TYPE_GRADE: 367151976Sandre break; 368151976Sandre 369151976Sandre case MAC_BIBA_TYPE_EQUAL: 370151976Sandre case MAC_BIBA_TYPE_HIGH: 371151976Sandre case MAC_BIBA_TYPE_LOW: 372151976Sandre if (mac_biba->mb_rangehigh.mbe_grade != 0 || 373151976Sandre !MAC_BIBA_BIT_SET_EMPTY( 374151976Sandre mac_biba->mb_rangehigh.mbe_compartments)) 375129906Sbmilekic return (EINVAL); 376129906Sbmilekic break; 377129906Sbmilekic 378129906Sbmilekic default: 379129906Sbmilekic return (EINVAL); 380129906Sbmilekic } 381129906Sbmilekic if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 382129906Sbmilekic &mac_biba->mb_rangelow)) 383129906Sbmilekic return (EINVAL); 384129906Sbmilekic } else { 385129906Sbmilekic if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 386129906Sbmilekic mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 387129906Sbmilekic return (EINVAL); 388129906Sbmilekic } 389129906Sbmilekic 390129906Sbmilekic return (0); 391129906Sbmilekic} 392129906Sbmilekic 393129906Sbmilekicstatic void 394129906Sbmilekicmac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 395129906Sbmilekic u_short gradelow, u_char *compartmentslow, u_short typehigh, 396129906Sbmilekic u_short gradehigh, u_char *compartmentshigh) 397129906Sbmilekic{ 398129906Sbmilekic 399129906Sbmilekic mac_biba->mb_rangelow.mbe_type = typelow; 400129906Sbmilekic mac_biba->mb_rangelow.mbe_grade = gradelow; 401129906Sbmilekic if (compartmentslow != NULL) 402254515Sandre memcpy(mac_biba->mb_rangelow.mbe_compartments, 403129906Sbmilekic compartmentslow, 404129906Sbmilekic sizeof(mac_biba->mb_rangelow.mbe_compartments)); 405174247Salc mac_biba->mb_rangehigh.mbe_type = typehigh; 406174247Salc mac_biba->mb_rangehigh.mbe_grade = gradehigh; 407174247Salc if (compartmentshigh != NULL) 408174247Salc memcpy(mac_biba->mb_rangehigh.mbe_compartments, 409174247Salc compartmentshigh, 410174247Salc sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 411209390Sed mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 412174247Salc} 413174247Salc 414177921Salcstatic void 415177921Salcmac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 416194454Salc u_char *compartments) 417195649Salc{ 418174247Salc 419174247Salc mac_biba->mb_single.mbe_type = type; 420174247Salc mac_biba->mb_single.mbe_grade = grade; 421129906Sbmilekic if (compartments != NULL) 422129906Sbmilekic memcpy(mac_biba->mb_single.mbe_compartments, compartments, 423129906Sbmilekic sizeof(mac_biba->mb_single.mbe_compartments)); 424129906Sbmilekic mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 425151976Sandre} 426129906Sbmilekic 427132987Sgreenstatic void 428132987Sgreenmac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 429129906Sbmilekic{ 430129906Sbmilekic 431129906Sbmilekic KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 432132987Sgreen ("mac_biba_copy_range: labelfrom not range")); 433132987Sgreen 434132987Sgreen labelto->mb_rangelow = labelfrom->mb_rangelow; 435129906Sbmilekic labelto->mb_rangehigh = labelfrom->mb_rangehigh; 436129906Sbmilekic labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 437129906Sbmilekic} 438147537Ssilby 439147537Ssilbystatic void 440147537Ssilbymac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 441129906Sbmilekic{ 442129906Sbmilekic 443129906Sbmilekic KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 444129906Sbmilekic ("mac_biba_copy_single: labelfrom not single")); 445129906Sbmilekic 446151976Sandre labelto->mb_single = labelfrom->mb_single; 447151976Sandre labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 448156059Sglebius} 449151976Sandre 450151976Sandrestatic void 451151976Sandremac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 452151976Sandre{ 453129906Sbmilekic 454129906Sbmilekic if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 455151976Sandre mac_biba_copy_single(source, dest); 456129947Sbmilekic if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 457151976Sandre mac_biba_copy_range(source, dest); 458129906Sbmilekic} 459129906Sbmilekic 460129906Sbmilekic/* 461184778Skmacy * Policy module operations. 462151976Sandre */ 463129906Sbmilekicstatic void 464151976Sandremac_biba_destroy(struct mac_policy_conf *conf) 465162377Sandre{ 466162377Sandre 467186683Srwatson} 468129906Sbmilekic 469129906Sbmilekicstatic void 470129906Sbmilekicmac_biba_init(struct mac_policy_conf *conf) 471172930Srwatson{ 472132987Sgreen 473132987Sgreen} 474129906Sbmilekic 475129947Sbmilekic/* 476129906Sbmilekic * Label operations. 477132987Sgreen */ 478129906Sbmilekicstatic void 479129906Sbmilekicmac_biba_init_label(struct label *label) 480129906Sbmilekic{ 481151976Sandre 482129906Sbmilekic SLOT(label) = biba_alloc(M_WAITOK); 483129906Sbmilekic} 484129906Sbmilekic 485129906Sbmilekicstatic int 486129906Sbmilekicmac_biba_init_label_waitcheck(struct label *label, int flag) 487254515Sandre{ 488129906Sbmilekic 489129906Sbmilekic SLOT(label) = biba_alloc(flag); 490172462Skmacy if (SLOT(label) == NULL) 491173029Sobrien return (ENOMEM); 492172462Skmacy 493129906Sbmilekic return (0); 494151976Sandre} 495173029Sobrien 496147537Ssilbystatic void 497147537Ssilbymac_biba_destroy_label(struct label *label) 498147537Ssilby{ 499129906Sbmilekic 500129906Sbmilekic biba_free(SLOT(label)); 501151976Sandre SLOT(label) = NULL; 502151976Sandre} 503151976Sandre 504129906Sbmilekicstatic int 505129906Sbmilekicmac_biba_externalize(struct label *label, struct mac *extmac) 506129906Sbmilekic{ 507129906Sbmilekic struct mac_biba *mac_biba; 508129906Sbmilekic 509129906Sbmilekic mac_biba = SLOT(label); 510129906Sbmilekic 511129906Sbmilekic if (mac_biba == NULL) { 512151976Sandre printf("mac_biba_externalize: NULL pointer\n"); 513151976Sandre return (0); 514151976Sandre } 515151976Sandre 516151976Sandre extmac->m_biba = *mac_biba; 517175872Sphk 518175872Sphk return (0); 519151976Sandre} 520152130Sglebius 521151976Sandrestatic int 522147537Ssilbymac_biba_internalize(struct label *label, struct mac *extmac) 523147537Ssilby{ 524147537Ssilby struct mac_biba *mac_biba; 525166213Smohans int error; 526173029Sobrien 527173029Sobrien mac_biba = SLOT(label); 528173029Sobrien 529173029Sobrien error = mac_biba_valid(mac_biba); 530173029Sobrien if (error) 531173029Sobrien return (error); 532166213Smohans 533173029Sobrien *mac_biba = extmac->m_biba; 534173029Sobrien 535129906Sbmilekic return (0); 536129906Sbmilekic} 537129906Sbmilekic 538155780Sandre/* 539129906Sbmilekic * Labeling event operations: file system objects, and things that look 540129906Sbmilekic * a lot like file system objects. 541151976Sandre */ 542151976Sandrestatic void 543151976Sandremac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 544129906Sbmilekic struct label *label) 545132987Sgreen{ 546132987Sgreen struct mac_biba *mac_biba; 547129906Sbmilekic int biba_type; 548129906Sbmilekic 549151976Sandre mac_biba = SLOT(label); 550168374Skmacy if (strcmp(dev->si_name, "null") == 0 || 551168374Skmacy strcmp(dev->si_name, "zero") == 0 || 552173029Sobrien strcmp(dev->si_name, "random") == 0 || 553147537Ssilby strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 554147537Ssilby biba_type = MAC_BIBA_TYPE_EQUAL; 555147537Ssilby else if (ptys_equal && 556168374Skmacy (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 557168374Skmacy strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 558168374Skmacy biba_type = MAC_BIBA_TYPE_EQUAL; 559168374Skmacy else 560168374Skmacy biba_type = MAC_BIBA_TYPE_HIGH; 561168374Skmacy mac_biba_set_single(mac_biba, biba_type, 0, NULL); 562168374Skmacy} 563168374Skmacy 564168374Skmacystatic void 565168374Skmacymac_biba_create_devfs_directory(char *dirname, int dirnamelen, 566168374Skmacy struct devfs_dirent *devfs_dirent, struct label *label) 567168374Skmacy{ 568168374Skmacy struct mac_biba *mac_biba; 569168374Skmacy 570168374Skmacy mac_biba = SLOT(label); 571168374Skmacy mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 572168374Skmacy} 573168374Skmacy 574168374Skmacystatic void 575168374Skmacymac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 576168374Skmacy struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) 577168374Skmacy{ 578168374Skmacy struct mac_biba *source, *dest; 579168374Skmacy 580129906Sbmilekic source = SLOT(&cred->cr_label); 581168374Skmacy dest = SLOT(delabel); 582173029Sobrien 583151976Sandre mac_biba_copy_single(source, dest); 584151976Sandre} 585151976Sandre 586151976Sandrestatic void 587151976Sandremac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 588175872Sphk struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 589175872Sphk{ 590151976Sandre struct mac_biba *source, *dest; 591151976Sandre 592168374Skmacy source = SLOT(direntlabel); 593151976Sandre dest = SLOT(vnodelabel); 594168374Skmacy mac_biba_copy_single(source, dest); 595132987Sgreen} 596129906Sbmilekic 597129906Sbmilekicstatic void 598151976Sandremac_biba_create_vnode(struct ucred *cred, struct vnode *parent, 599151976Sandre struct label *parentlabel, struct vnode *child, struct label *childlabel) 600151976Sandre{ 601129906Sbmilekic struct mac_biba *source, *dest; 602129906Sbmilekic 603129906Sbmilekic source = SLOT(&cred->cr_label); 604168374Skmacy dest = SLOT(childlabel); 605168374Skmacy 606151976Sandre mac_biba_copy_single(source, dest); 607168374Skmacy} 608168374Skmacy 609152035Sandrestatic void 610168374Skmacymac_biba_create_mount(struct ucred *cred, struct mount *mp, 611168374Skmacy struct label *mntlabel, struct label *fslabel) 612147537Ssilby{ 613147537Ssilby struct mac_biba *source, *dest; 614129906Sbmilekic 615129906Sbmilekic source = SLOT(&cred->cr_label); 616129906Sbmilekic dest = SLOT(mntlabel); 617129906Sbmilekic mac_biba_copy_single(source, dest); 618151976Sandre dest = SLOT(fslabel); 619129906Sbmilekic mac_biba_copy_single(source, dest); 620132987Sgreen} 621151976Sandre 622129906Sbmilekicstatic void 623129906Sbmilekicmac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 624129906Sbmilekic struct label *mntlabel, struct label *fslabel) 625151976Sandre{ 626156428Sandre struct mac_biba *mac_biba; 627156428Sandre 628132987Sgreen /* Always mount root as high integrity. */ 629152101Sandre mac_biba = SLOT(fslabel); 630147537Ssilby mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 631147537Ssilby mac_biba = SLOT(mntlabel); 632147537Ssilby mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 633132987Sgreen} 634129906Sbmilekic 635129906Sbmilekicstatic void 636129906Sbmilekicmac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 637129906Sbmilekic struct label *vnodelabel, struct label *label) 638129906Sbmilekic{ 639129906Sbmilekic struct mac_biba *source, *dest; 640129906Sbmilekic 641151976Sandre source = SLOT(label); 642129906Sbmilekic dest = SLOT(vnodelabel); 643129906Sbmilekic 644129906Sbmilekic mac_biba_copy(source, dest); 645129906Sbmilekic} 646147537Ssilby 647147537Ssilbystatic void 648147537Ssilbymac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent, 649129906Sbmilekic struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 650147652Ssilby{ 651147652Ssilby struct mac_biba *source, *dest; 652147652Ssilby 653129906Sbmilekic source = SLOT(vnodelabel); 654129906Sbmilekic dest = SLOT(direntlabel); 655129906Sbmilekic 656129906Sbmilekic mac_biba_copy(source, dest); 657129906Sbmilekic} 658132987Sgreen 659132987Sgreenstatic void 660129906Sbmilekicmac_biba_update_procfsvnode(struct vnode *vp, struct label *vnodelabel, 661129906Sbmilekic struct ucred *cred) 662129906Sbmilekic{ 663132987Sgreen struct mac_biba *source, *dest; 664132987Sgreen 665132987Sgreen source = SLOT(&cred->cr_label); 666132987Sgreen dest = SLOT(vnodelabel); 667129906Sbmilekic 668129906Sbmilekic /* 669129906Sbmilekic * Only copy the single, not the range, since vnodes only have 670129906Sbmilekic * a single. 671129906Sbmilekic */ 672129906Sbmilekic mac_biba_copy_single(source, dest); 673129906Sbmilekic} 674147537Ssilby 675147537Ssilbystatic int 676147537Ssilbymac_biba_update_vnode_from_externalized(struct vnode *vp, 677129906Sbmilekic struct label *vnodelabel, struct mac *extmac) 678129947Sbmilekic{ 679129906Sbmilekic struct mac_biba *source, *dest; 680151976Sandre int error; 681151976Sandre 682151976Sandre source = &extmac->m_biba; 683173029Sobrien dest = SLOT(vnodelabel); 684129906Sbmilekic 685129906Sbmilekic error = mac_biba_valid(source); 686151976Sandre if (error) 687151976Sandre return (error); 688129906Sbmilekic 689151976Sandre if ((source->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) 690162377Sandre return (EINVAL); 691162377Sandre 692186683Srwatson mac_biba_copy_single(source, dest); 693129906Sbmilekic 694129906Sbmilekic return (0); 695129906Sbmilekic} 696172930Srwatson 697132987Sgreenstatic void 698132987Sgreenmac_biba_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel, 699129906Sbmilekic struct mount *mp, struct label *fslabel) 700129906Sbmilekic{ 701151976Sandre struct mac_biba *source, *dest; 702151976Sandre 703132987Sgreen source = SLOT(fslabel); 704129906Sbmilekic dest = SLOT(vnodelabel); 705129906Sbmilekic 706194515Skmacy mac_biba_copy_single(source, dest); 707194515Skmacy} 708194515Skmacy 709194515Skmacy/* 710194515Skmacy * Labeling event operations: IPC object. 711194515Skmacy */ 712194515Skmacystatic void 713194515Skmacymac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 714194515Skmacy struct mbuf *m, struct label *mbuflabel) 715194515Skmacy{ 716194515Skmacy struct mac_biba *source, *dest; 717194515Skmacy 718194515Skmacy source = SLOT(socketlabel); 719194515Skmacy dest = SLOT(mbuflabel); 720194515Skmacy 721194515Skmacy mac_biba_copy_single(source, dest); 722194515Skmacy} 723194515Skmacy 724194515Skmacystatic void 725194515Skmacymac_biba_create_socket(struct ucred *cred, struct socket *socket, 726194515Skmacy struct label *socketlabel) 727194515Skmacy{ 728194515Skmacy struct mac_biba *source, *dest; 729194515Skmacy 730194515Skmacy source = SLOT(&cred->cr_label); 731194515Skmacy dest = SLOT(socketlabel); 732129906Sbmilekic 733129906Sbmilekic mac_biba_copy_single(source, dest); 734129906Sbmilekic} 735129906Sbmilekic 736129906Sbmilekicstatic void 737129906Sbmilekicmac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 738129906Sbmilekic struct label *pipelabel) 739129906Sbmilekic{ 740129906Sbmilekic struct mac_biba *source, *dest; 741129906Sbmilekic 742129906Sbmilekic source = SLOT(&cred->cr_label); 743129906Sbmilekic dest = SLOT(pipelabel); 744129906Sbmilekic 745129906Sbmilekic mac_biba_copy_single(source, dest); 746129906Sbmilekic} 747129906Sbmilekic 748129906Sbmilekicstatic void 749129906Sbmilekicmac_biba_create_socket_from_socket(struct socket *oldsocket, 750129906Sbmilekic struct label *oldsocketlabel, struct socket *newsocket, 751129906Sbmilekic struct label *newsocketlabel) 752129906Sbmilekic{ 753 struct mac_biba *source, *dest; 754 755 source = SLOT(oldsocketlabel); 756 dest = SLOT(newsocketlabel); 757 758 mac_biba_copy_single(source, dest); 759} 760 761static void 762mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 763 struct label *socketlabel, struct label *newlabel) 764{ 765 struct mac_biba *source, *dest; 766 767 source = SLOT(newlabel); 768 dest = SLOT(socketlabel); 769 770 mac_biba_copy(source, dest); 771} 772 773static void 774mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 775 struct label *pipelabel, struct label *newlabel) 776{ 777 struct mac_biba *source, *dest; 778 779 source = SLOT(newlabel); 780 dest = SLOT(pipelabel); 781 782 mac_biba_copy(source, dest); 783} 784 785static void 786mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 787 struct socket *socket, struct label *socketpeerlabel) 788{ 789 struct mac_biba *source, *dest; 790 791 source = SLOT(mbuflabel); 792 dest = SLOT(socketpeerlabel); 793 794 mac_biba_copy_single(source, dest); 795} 796 797/* 798 * Labeling event operations: network objects. 799 */ 800static void 801mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 802 struct label *oldsocketlabel, struct socket *newsocket, 803 struct label *newsocketpeerlabel) 804{ 805 struct mac_biba *source, *dest; 806 807 source = SLOT(oldsocketlabel); 808 dest = SLOT(newsocketpeerlabel); 809 810 mac_biba_copy_single(source, dest); 811} 812 813static void 814mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 815 struct label *bpflabel) 816{ 817 struct mac_biba *source, *dest; 818 819 source = SLOT(&cred->cr_label); 820 dest = SLOT(bpflabel); 821 822 mac_biba_copy_single(source, dest); 823} 824 825static void 826mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 827{ 828 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 829 char tiflist[sizeof(trusted_interfaces)]; 830 struct mac_biba *dest; 831 int len, grade; 832 833 dest = SLOT(ifnetlabel); 834 835 if (ifnet->if_type == IFT_LOOP) { 836 grade = MAC_BIBA_TYPE_EQUAL; 837 goto set; 838 } 839 840 if (trust_all_interfaces) { 841 grade = MAC_BIBA_TYPE_HIGH; 842 goto set; 843 } 844 845 grade = MAC_BIBA_TYPE_LOW; 846 847 if (trusted_interfaces[0] == '\0' || 848 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 849 goto set; 850 851 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 852 if(*p != ' ' && *p != '\t') 853 *q = *p; 854 855 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 856 857 for (p = q = tiflist;; p++) { 858 if (*p == ',' || *p == '\0') { 859 len = p - q; 860 if (len < IFNAMSIZ) { 861 bzero(tifname, sizeof(tifname)); 862 bcopy(q, tifname, len); 863 if (strcmp(tifname, ifname) == 0) { 864 grade = MAC_BIBA_TYPE_HIGH; 865 break; 866 } 867 } 868 if (*p == '\0') 869 break; 870 q = p + 1; 871 } 872 } 873set: 874 mac_biba_set_single(dest, grade, 0, NULL); 875 mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL); 876} 877 878static void 879mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 880 struct ipq *ipq, struct label *ipqlabel) 881{ 882 struct mac_biba *source, *dest; 883 884 source = SLOT(fragmentlabel); 885 dest = SLOT(ipqlabel); 886 887 mac_biba_copy_single(source, dest); 888} 889 890static void 891mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 892 struct mbuf *datagram, struct label *datagramlabel) 893{ 894 struct mac_biba *source, *dest; 895 896 source = SLOT(ipqlabel); 897 dest = SLOT(datagramlabel); 898 899 /* Just use the head, since we require them all to match. */ 900 mac_biba_copy_single(source, dest); 901} 902 903static void 904mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 905 struct mbuf *fragment, struct label *fragmentlabel) 906{ 907 struct mac_biba *source, *dest; 908 909 source = SLOT(datagramlabel); 910 dest = SLOT(fragmentlabel); 911 912 mac_biba_copy_single(source, dest); 913} 914 915static void 916mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 917 struct label *oldmbuflabel, struct mbuf *newmbuf, 918 struct label *newmbuflabel) 919{ 920 struct mac_biba *source, *dest; 921 922 source = SLOT(oldmbuflabel); 923 dest = SLOT(newmbuflabel); 924 925 /* 926 * Because the source mbuf may not yet have been "created", 927 * just initialiezd, we do a conditional copy. Since we don't 928 * allow mbufs to have ranges, do a KASSERT to make sure that 929 * doesn't happen. 930 */ 931 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 932 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 933 mac_biba_copy(source, dest); 934} 935 936static void 937mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 938 struct mbuf *mbuf, struct label *mbuflabel) 939{ 940 struct mac_biba *dest; 941 942 dest = SLOT(mbuflabel); 943 944 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 945} 946 947static void 948mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 949 struct mbuf *mbuf, struct label *mbuflabel) 950{ 951 struct mac_biba *source, *dest; 952 953 source = SLOT(bpflabel); 954 dest = SLOT(mbuflabel); 955 956 mac_biba_copy_single(source, dest); 957} 958 959static void 960mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 961 struct mbuf *m, struct label *mbuflabel) 962{ 963 struct mac_biba *source, *dest; 964 965 source = SLOT(ifnetlabel); 966 dest = SLOT(mbuflabel); 967 968 mac_biba_copy_single(source, dest); 969} 970 971static void 972mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 973 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 974 struct mbuf *newmbuf, struct label *newmbuflabel) 975{ 976 struct mac_biba *source, *dest; 977 978 source = SLOT(oldmbuflabel); 979 dest = SLOT(newmbuflabel); 980 981 mac_biba_copy_single(source, dest); 982} 983 984static void 985mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 986 struct mbuf *newmbuf, struct label *newmbuflabel) 987{ 988 struct mac_biba *source, *dest; 989 990 source = SLOT(oldmbuflabel); 991 dest = SLOT(newmbuflabel); 992 993 mac_biba_copy_single(source, dest); 994} 995 996static int 997mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 998 struct ipq *ipq, struct label *ipqlabel) 999{ 1000 struct mac_biba *a, *b; 1001 1002 a = SLOT(ipqlabel); 1003 b = SLOT(fragmentlabel); 1004 1005 return (mac_biba_equal_single(a, b)); 1006} 1007 1008static void 1009mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1010 struct label *ifnetlabel, struct label *newlabel) 1011{ 1012 struct mac_biba *source, *dest; 1013 1014 source = SLOT(newlabel); 1015 dest = SLOT(ifnetlabel); 1016 1017 mac_biba_copy(source, dest); 1018} 1019 1020static void 1021mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1022 struct ipq *ipq, struct label *ipqlabel) 1023{ 1024 1025 /* NOOP: we only accept matching labels, so no need to update */ 1026} 1027 1028/* 1029 * Labeling event operations: processes. 1030 */ 1031static void 1032mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1033{ 1034 struct mac_biba *source, *dest; 1035 1036 source = SLOT(&cred_parent->cr_label); 1037 dest = SLOT(&cred_child->cr_label); 1038 1039 mac_biba_copy_single(source, dest); 1040 mac_biba_copy_range(source, dest); 1041} 1042 1043static void 1044mac_biba_execve_transition(struct ucred *old, struct ucred *new, 1045 struct vnode *vp, struct mac *vnodelabel) 1046{ 1047 struct mac_biba *source, *dest; 1048 1049 source = SLOT(&old->cr_label); 1050 dest = SLOT(&new->cr_label); 1051 1052 mac_biba_copy_single(source, dest); 1053 mac_biba_copy_range(source, dest); 1054} 1055 1056static int 1057mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp, 1058 struct mac *vnodelabel) 1059{ 1060 1061 return (0); 1062} 1063 1064static void 1065mac_biba_create_proc0(struct ucred *cred) 1066{ 1067 struct mac_biba *dest; 1068 1069 dest = SLOT(&cred->cr_label); 1070 1071 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1072 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1073 MAC_BIBA_TYPE_HIGH, 0, NULL); 1074} 1075 1076static void 1077mac_biba_create_proc1(struct ucred *cred) 1078{ 1079 struct mac_biba *dest; 1080 1081 dest = SLOT(&cred->cr_label); 1082 1083 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1084 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1085 MAC_BIBA_TYPE_HIGH, 0, NULL); 1086} 1087 1088static void 1089mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1090{ 1091 struct mac_biba *source, *dest; 1092 1093 source = SLOT(newlabel); 1094 dest = SLOT(&cred->cr_label); 1095 1096 mac_biba_copy(source, dest); 1097} 1098 1099/* 1100 * Access control checks. 1101 */ 1102static int 1103mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1104 struct ifnet *ifnet, struct label *ifnetlabel) 1105{ 1106 struct mac_biba *a, *b; 1107 1108 if (!mac_biba_enabled) 1109 return (0); 1110 1111 a = SLOT(bpflabel); 1112 b = SLOT(ifnetlabel); 1113 1114 if (mac_biba_equal_single(a, b)) 1115 return (0); 1116 return (EACCES); 1117} 1118 1119static int 1120mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1121{ 1122 struct mac_biba *subj, *new; 1123 int error; 1124 1125 subj = SLOT(&cred->cr_label); 1126 new = SLOT(newlabel); 1127 1128 /* 1129 * If there is a Biba label update for the credential, it may 1130 * be an update of the single, range, or both. 1131 */ 1132 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1133 if (error) 1134 return (error); 1135 1136 /* 1137 * If the Biba label is to be changed, authorize as appropriate. 1138 */ 1139 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1140 /* 1141 * To change the Biba single label on a credential, the 1142 * new single label must be in the current range. 1143 */ 1144 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1145 !mac_biba_single_in_range(new, subj)) 1146 return (EPERM); 1147 1148 /* 1149 * To change the Biba range on a credential, the new 1150 * range label must be in the current range. 1151 */ 1152 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1153 !mac_biba_range_in_range(new, subj)) 1154 return (EPERM); 1155 1156 /* 1157 * To have EQUAL in any component of the new credential 1158 * Biba label, the subject must already have EQUAL in 1159 * their label. 1160 */ 1161 if (mac_biba_contains_equal(new)) { 1162 error = mac_biba_subject_equal_ok(subj); 1163 if (error) 1164 return (error); 1165 } 1166 1167 /* 1168 * XXXMAC: Additional consistency tests regarding the 1169 * single and range of the new label might be performed 1170 * here. 1171 */ 1172 } 1173 1174 return (0); 1175} 1176 1177static int 1178mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1179{ 1180 struct mac_biba *subj, *obj; 1181 1182 if (!mac_biba_enabled) 1183 return (0); 1184 1185 subj = SLOT(&u1->cr_label); 1186 obj = SLOT(&u2->cr_label); 1187 1188 /* XXX: range */ 1189 if (!mac_biba_dominate_single(obj, subj)) 1190 return (ESRCH); 1191 1192 return (0); 1193} 1194 1195static int 1196mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1197 struct label *ifnetlabel, struct label *newlabel) 1198{ 1199 struct mac_biba *subj, *new; 1200 int error; 1201 1202 subj = SLOT(&cred->cr_label); 1203 new = SLOT(newlabel); 1204 1205 /* 1206 * If there is a Biba label update for the interface, it may 1207 * be an update of the single, range, or both. 1208 */ 1209 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1210 if (error) 1211 return (error); 1212 1213 /* 1214 * If the Biba label is to be changed, authorize as appropriate. 1215 */ 1216 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1217 /* 1218 * Rely on the traditional superuser status for the Biba 1219 * interface relabel requirements. XXXMAC: This will go 1220 * away. 1221 */ 1222 error = suser_cred(cred, 0); 1223 if (error) 1224 return (EPERM); 1225 1226 /* 1227 * XXXMAC: Additional consistency tests regarding the single 1228 * and the range of the new label might be performed here. 1229 */ 1230 } 1231 1232 return (0); 1233} 1234 1235static int 1236mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1237 struct mbuf *m, struct label *mbuflabel) 1238{ 1239 struct mac_biba *p, *i; 1240 1241 if (!mac_biba_enabled) 1242 return (0); 1243 1244 p = SLOT(mbuflabel); 1245 i = SLOT(ifnetlabel); 1246 1247 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1248} 1249 1250static int 1251mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1252 struct label *mntlabel) 1253{ 1254 struct mac_biba *subj, *obj; 1255 1256 if (!mac_biba_enabled) 1257 return (0); 1258 1259 subj = SLOT(&cred->cr_label); 1260 obj = SLOT(mntlabel); 1261 1262 if (!mac_biba_dominate_single(obj, subj)) 1263 return (EACCES); 1264 1265 return (0); 1266} 1267 1268static int 1269mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1270 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1271{ 1272 1273 if(!mac_biba_enabled) 1274 return (0); 1275 1276 /* XXX: This will be implemented soon... */ 1277 1278 return (0); 1279} 1280 1281static int 1282mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1283 struct label *pipelabel) 1284{ 1285 struct mac_biba *subj, *obj; 1286 1287 if (!mac_biba_enabled) 1288 return (0); 1289 1290 subj = SLOT(&cred->cr_label); 1291 obj = SLOT((pipelabel)); 1292 1293 if (!mac_biba_dominate_single(obj, subj)) 1294 return (EACCES); 1295 1296 return (0); 1297} 1298 1299static int 1300mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1301 struct label *pipelabel) 1302{ 1303 struct mac_biba *subj, *obj; 1304 1305 if (!mac_biba_enabled) 1306 return (0); 1307 1308 subj = SLOT(&cred->cr_label); 1309 obj = SLOT((pipelabel)); 1310 1311 if (!mac_biba_dominate_single(obj, subj)) 1312 return (EACCES); 1313 1314 return (0); 1315} 1316 1317static int 1318mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1319 struct label *pipelabel, struct label *newlabel) 1320{ 1321 struct mac_biba *subj, *obj, *new; 1322 int error; 1323 1324 new = SLOT(newlabel); 1325 subj = SLOT(&cred->cr_label); 1326 obj = SLOT(pipelabel); 1327 1328 /* 1329 * If there is a Biba label update for a pipe, it must be a 1330 * single update. 1331 */ 1332 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1333 if (error) 1334 return (error); 1335 1336 /* 1337 * To perform a relabel of a pipe (Biba label or not), Biba must 1338 * authorize the relabel. 1339 */ 1340 if (!mac_biba_single_in_range(obj, subj)) 1341 return (EPERM); 1342 1343 /* 1344 * If the Biba label is to be changed, authorize as appropriate. 1345 */ 1346 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1347 /* 1348 * To change the Biba label on a pipe, the new pipe label 1349 * must be in the subject range. 1350 */ 1351 if (!mac_biba_single_in_range(new, subj)) 1352 return (EPERM); 1353 1354 /* 1355 * To change the Biba label on a pipe to be EQUAL, the 1356 * subject must have appropriate privilege. 1357 */ 1358 if (mac_biba_contains_equal(new)) { 1359 error = mac_biba_subject_equal_ok(subj); 1360 if (error) 1361 return (error); 1362 } 1363 } 1364 1365 return (0); 1366} 1367 1368static int 1369mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1370 struct label *pipelabel) 1371{ 1372 struct mac_biba *subj, *obj; 1373 1374 if (!mac_biba_enabled) 1375 return (0); 1376 1377 subj = SLOT(&cred->cr_label); 1378 obj = SLOT((pipelabel)); 1379 1380 if (!mac_biba_dominate_single(obj, subj)) 1381 return (EACCES); 1382 1383 return (0); 1384} 1385 1386static int 1387mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1388 struct label *pipelabel) 1389{ 1390 struct mac_biba *subj, *obj; 1391 1392 if (!mac_biba_enabled) 1393 return (0); 1394 1395 subj = SLOT(&cred->cr_label); 1396 obj = SLOT((pipelabel)); 1397 1398 if (!mac_biba_dominate_single(subj, obj)) 1399 return (EACCES); 1400 1401 return (0); 1402} 1403 1404static int 1405mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1406{ 1407 struct mac_biba *subj, *obj; 1408 1409 if (!mac_biba_enabled) 1410 return (0); 1411 1412 subj = SLOT(&cred->cr_label); 1413 obj = SLOT(&proc->p_ucred->cr_label); 1414 1415 /* XXX: range checks */ 1416 if (!mac_biba_dominate_single(obj, subj)) 1417 return (ESRCH); 1418 if (!mac_biba_dominate_single(subj, obj)) 1419 return (EACCES); 1420 1421 return (0); 1422} 1423 1424static int 1425mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1426{ 1427 struct mac_biba *subj, *obj; 1428 1429 if (!mac_biba_enabled) 1430 return (0); 1431 1432 subj = SLOT(&cred->cr_label); 1433 obj = SLOT(&proc->p_ucred->cr_label); 1434 1435 /* XXX: range checks */ 1436 if (!mac_biba_dominate_single(obj, subj)) 1437 return (ESRCH); 1438 if (!mac_biba_dominate_single(subj, obj)) 1439 return (EACCES); 1440 1441 return (0); 1442} 1443 1444static int 1445mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1446{ 1447 struct mac_biba *subj, *obj; 1448 1449 if (!mac_biba_enabled) 1450 return (0); 1451 1452 subj = SLOT(&cred->cr_label); 1453 obj = SLOT(&proc->p_ucred->cr_label); 1454 1455 /* XXX: range checks */ 1456 if (!mac_biba_dominate_single(obj, subj)) 1457 return (ESRCH); 1458 if (!mac_biba_dominate_single(subj, obj)) 1459 return (EACCES); 1460 1461 return (0); 1462} 1463 1464static int 1465mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1466 struct mbuf *m, struct label *mbuflabel) 1467{ 1468 struct mac_biba *p, *s; 1469 1470 if (!mac_biba_enabled) 1471 return (0); 1472 1473 p = SLOT(mbuflabel); 1474 s = SLOT(socketlabel); 1475 1476 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1477} 1478 1479static int 1480mac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket, 1481 struct label *socketlabel, struct label *newlabel) 1482{ 1483 struct mac_biba *subj, *obj, *new; 1484 int error; 1485 1486 new = SLOT(newlabel); 1487 subj = SLOT(&cred->cr_label); 1488 obj = SLOT(socketlabel); 1489 1490 /* 1491 * If there is a Biba label update for the socket, it may be 1492 * an update of single. 1493 */ 1494 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1495 if (error) 1496 return (error); 1497 1498 /* 1499 * To relabel a socket, the old socket single must be in the subject 1500 * range. 1501 */ 1502 if (!mac_biba_single_in_range(obj, subj)) 1503 return (EPERM); 1504 1505 /* 1506 * If the Biba label is to be changed, authorize as appropriate. 1507 */ 1508 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1509 /* 1510 * To relabel a socket, the new socket single must be in 1511 * the subject range. 1512 */ 1513 if (!mac_biba_single_in_range(new, subj)) 1514 return (EPERM); 1515 1516 /* 1517 * To change the Biba label on the socket to contain EQUAL, 1518 * the subject must have appropriate privilege. 1519 */ 1520 if (mac_biba_contains_equal(new)) { 1521 error = mac_biba_subject_equal_ok(subj); 1522 if (error) 1523 return (error); 1524 } 1525 } 1526 1527 return (0); 1528} 1529 1530static int 1531mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1532 struct label *socketlabel) 1533{ 1534 struct mac_biba *subj, *obj; 1535 1536 subj = SLOT(&cred->cr_label); 1537 obj = SLOT(socketlabel); 1538 1539 if (!mac_biba_dominate_single(obj, subj)) 1540 return (ENOENT); 1541 1542 return (0); 1543} 1544 1545static int 1546mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1547 struct label *dlabel) 1548{ 1549 struct mac_biba *subj, *obj; 1550 1551 if (!mac_biba_enabled) 1552 return (0); 1553 1554 subj = SLOT(&cred->cr_label); 1555 obj = SLOT(dlabel); 1556 1557 if (!mac_biba_dominate_single(obj, subj)) 1558 return (EACCES); 1559 1560 return (0); 1561} 1562 1563static int 1564mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1565 struct label *dlabel) 1566{ 1567 struct mac_biba *subj, *obj; 1568 1569 if (!mac_biba_enabled) 1570 return (0); 1571 1572 subj = SLOT(&cred->cr_label); 1573 obj = SLOT(dlabel); 1574 1575 if (!mac_biba_dominate_single(obj, subj)) 1576 return (EACCES); 1577 1578 return (0); 1579} 1580 1581static int 1582mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1583 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1584{ 1585 struct mac_biba *subj, *obj; 1586 1587 if (!mac_biba_enabled) 1588 return (0); 1589 1590 subj = SLOT(&cred->cr_label); 1591 obj = SLOT(dlabel); 1592 1593 if (!mac_biba_dominate_single(subj, obj)) 1594 return (EACCES); 1595 1596 return (0); 1597} 1598 1599static int 1600mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1601 struct label *dlabel, struct vnode *vp, struct label *label, 1602 struct componentname *cnp) 1603{ 1604 struct mac_biba *subj, *obj; 1605 1606 if (!mac_biba_enabled) 1607 return (0); 1608 1609 subj = SLOT(&cred->cr_label); 1610 obj = SLOT(dlabel); 1611 1612 if (!mac_biba_dominate_single(subj, obj)) 1613 return (EACCES); 1614 1615 obj = SLOT(label); 1616 1617 if (!mac_biba_dominate_single(subj, obj)) 1618 return (EACCES); 1619 1620 return (0); 1621} 1622 1623static int 1624mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1625 struct label *label, acl_type_t type) 1626{ 1627 struct mac_biba *subj, *obj; 1628 1629 if (!mac_biba_enabled) 1630 return (0); 1631 1632 subj = SLOT(&cred->cr_label); 1633 obj = SLOT(label); 1634 1635 if (!mac_biba_dominate_single(subj, obj)) 1636 return (EACCES); 1637 1638 return (0); 1639} 1640 1641static int 1642mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1643 struct label *label) 1644{ 1645 struct mac_biba *subj, *obj; 1646 1647 if (!mac_biba_enabled) 1648 return (0); 1649 1650 subj = SLOT(&cred->cr_label); 1651 obj = SLOT(label); 1652 1653 if (!mac_biba_dominate_single(obj, subj)) 1654 return (EACCES); 1655 1656 return (0); 1657} 1658 1659static int 1660mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 1661 struct label *label, acl_type_t type) 1662{ 1663 struct mac_biba *subj, *obj; 1664 1665 if (!mac_biba_enabled) 1666 return (0); 1667 1668 subj = SLOT(&cred->cr_label); 1669 obj = SLOT(label); 1670 1671 if (!mac_biba_dominate_single(obj, subj)) 1672 return (EACCES); 1673 1674 return (0); 1675} 1676 1677static int 1678mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1679 struct label *label, int attrnamespace, const char *name, struct uio *uio) 1680{ 1681 struct mac_biba *subj, *obj; 1682 1683 if (!mac_biba_enabled) 1684 return (0); 1685 1686 subj = SLOT(&cred->cr_label); 1687 obj = SLOT(label); 1688 1689 if (!mac_biba_dominate_single(obj, subj)) 1690 return (EACCES); 1691 1692 return (0); 1693} 1694 1695static int 1696mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1697 struct label *dlabel, struct vnode *vp, struct label *label, 1698 struct componentname *cnp) 1699{ 1700 struct mac_biba *subj, *obj; 1701 1702 if (!mac_biba_enabled) 1703 return (0); 1704 1705 subj = SLOT(&cred->cr_label); 1706 obj = SLOT(dlabel); 1707 1708 if (!mac_biba_dominate_single(subj, obj)) 1709 return (EACCES); 1710 1711 obj = SLOT(label); 1712 1713 if (!mac_biba_dominate_single(subj, obj)) 1714 return (EACCES); 1715 1716 return (0); 1717} 1718 1719static int 1720mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1721 struct label *dlabel, struct componentname *cnp) 1722{ 1723 struct mac_biba *subj, *obj; 1724 1725 if (!mac_biba_enabled) 1726 return (0); 1727 1728 subj = SLOT(&cred->cr_label); 1729 obj = SLOT(dlabel); 1730 1731 if (!mac_biba_dominate_single(obj, subj)) 1732 return (EACCES); 1733 1734 return (0); 1735} 1736 1737static int 1738mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 1739 struct label *label, int prot) 1740{ 1741 struct mac_biba *subj, *obj; 1742 1743 /* 1744 * Rely on the use of open()-time protections to handle 1745 * non-revocation cases. 1746 */ 1747 if (!mac_biba_enabled || !revocation_enabled) 1748 return (0); 1749 1750 subj = SLOT(&cred->cr_label); 1751 obj = SLOT(label); 1752 1753 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 1754 if (!mac_biba_dominate_single(obj, subj)) 1755 return (EACCES); 1756 } 1757 if (prot & VM_PROT_WRITE) { 1758 if (!mac_biba_dominate_single(subj, obj)) 1759 return (EACCES); 1760 } 1761 1762 return (0); 1763} 1764 1765static int 1766mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 1767 struct label *vnodelabel, mode_t acc_mode) 1768{ 1769 struct mac_biba *subj, *obj; 1770 1771 if (!mac_biba_enabled) 1772 return (0); 1773 1774 subj = SLOT(&cred->cr_label); 1775 obj = SLOT(vnodelabel); 1776 1777 /* XXX privilege override for admin? */ 1778 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 1779 if (!mac_biba_dominate_single(obj, subj)) 1780 return (EACCES); 1781 } 1782 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 1783 if (!mac_biba_dominate_single(subj, obj)) 1784 return (EACCES); 1785 } 1786 1787 return (0); 1788} 1789 1790static int 1791mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1792 struct vnode *vp, struct label *label) 1793{ 1794 struct mac_biba *subj, *obj; 1795 1796 if (!mac_biba_enabled || !revocation_enabled) 1797 return (0); 1798 1799 subj = SLOT(&active_cred->cr_label); 1800 obj = SLOT(label); 1801 1802 if (!mac_biba_dominate_single(obj, subj)) 1803 return (EACCES); 1804 1805 return (0); 1806} 1807 1808static int 1809mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1810 struct vnode *vp, struct label *label) 1811{ 1812 struct mac_biba *subj, *obj; 1813 1814 if (!mac_biba_enabled || !revocation_enabled) 1815 return (0); 1816 1817 subj = SLOT(&active_cred->cr_label); 1818 obj = SLOT(label); 1819 1820 if (!mac_biba_dominate_single(obj, subj)) 1821 return (EACCES); 1822 1823 return (0); 1824} 1825 1826static int 1827mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 1828 struct label *dlabel) 1829{ 1830 struct mac_biba *subj, *obj; 1831 1832 if (!mac_biba_enabled) 1833 return (0); 1834 1835 subj = SLOT(&cred->cr_label); 1836 obj = SLOT(dlabel); 1837 1838 if (!mac_biba_dominate_single(obj, subj)) 1839 return (EACCES); 1840 1841 return (0); 1842} 1843 1844static int 1845mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 1846 struct label *label) 1847{ 1848 struct mac_biba *subj, *obj; 1849 1850 if (!mac_biba_enabled) 1851 return (0); 1852 1853 subj = SLOT(&cred->cr_label); 1854 obj = SLOT(label); 1855 1856 if (!mac_biba_dominate_single(obj, subj)) 1857 return (EACCES); 1858 1859 return (0); 1860} 1861 1862static int 1863mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1864 struct label *vnodelabel, struct label *newlabel) 1865{ 1866 struct mac_biba *old, *new, *subj; 1867 int error; 1868 1869 old = SLOT(vnodelabel); 1870 new = SLOT(newlabel); 1871 subj = SLOT(&cred->cr_label); 1872 1873 /* 1874 * If there is a Biba label update for the vnode, it must be a 1875 * single label. 1876 */ 1877 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1878 if (error) 1879 return (error); 1880 1881 /* 1882 * To perform a relabel of the vnode (Biba label or not), Biba must 1883 * authorize the relabel. 1884 */ 1885 if (!mac_biba_single_in_range(old, subj)) 1886 return (EPERM); 1887 1888 /* 1889 * If the Biba label is to be changed, authorize as appropriate. 1890 */ 1891 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1892 /* 1893 * To change the Biba label on a vnode, the new vnode label 1894 * must be in the subject range. 1895 */ 1896 if (!mac_biba_single_in_range(new, subj)) 1897 return (EPERM); 1898 1899 /* 1900 * To change the Biba label on the vnode to be EQUAL, 1901 * the subject must have appropriate privilege. 1902 */ 1903 if (mac_biba_contains_equal(new)) { 1904 error = mac_biba_subject_equal_ok(subj); 1905 if (error) 1906 return (error); 1907 } 1908 } 1909 1910 return (0); 1911} 1912 1913static int 1914mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1915 struct label *dlabel, struct vnode *vp, struct label *label, 1916 struct componentname *cnp) 1917{ 1918 struct mac_biba *subj, *obj; 1919 1920 if (!mac_biba_enabled) 1921 return (0); 1922 1923 subj = SLOT(&cred->cr_label); 1924 obj = SLOT(dlabel); 1925 1926 if (!mac_biba_dominate_single(subj, obj)) 1927 return (EACCES); 1928 1929 obj = SLOT(label); 1930 1931 if (!mac_biba_dominate_single(subj, obj)) 1932 return (EACCES); 1933 1934 return (0); 1935} 1936 1937static int 1938mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1939 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 1940 struct componentname *cnp) 1941{ 1942 struct mac_biba *subj, *obj; 1943 1944 if (!mac_biba_enabled) 1945 return (0); 1946 1947 subj = SLOT(&cred->cr_label); 1948 obj = SLOT(dlabel); 1949 1950 if (!mac_biba_dominate_single(subj, obj)) 1951 return (EACCES); 1952 1953 if (vp != NULL) { 1954 obj = SLOT(label); 1955 1956 if (!mac_biba_dominate_single(subj, obj)) 1957 return (EACCES); 1958 } 1959 1960 return (0); 1961} 1962 1963static int 1964mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 1965 struct label *label) 1966{ 1967 struct mac_biba *subj, *obj; 1968 1969 if (!mac_biba_enabled) 1970 return (0); 1971 1972 subj = SLOT(&cred->cr_label); 1973 obj = SLOT(label); 1974 1975 if (!mac_biba_dominate_single(subj, obj)) 1976 return (EACCES); 1977 1978 return (0); 1979} 1980 1981static int 1982mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 1983 struct label *label, acl_type_t type, struct acl *acl) 1984{ 1985 struct mac_biba *subj, *obj; 1986 1987 if (!mac_biba_enabled) 1988 return (0); 1989 1990 subj = SLOT(&cred->cr_label); 1991 obj = SLOT(label); 1992 1993 if (!mac_biba_dominate_single(subj, obj)) 1994 return (EACCES); 1995 1996 return (0); 1997} 1998 1999static int 2000mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2001 struct label *vnodelabel, int attrnamespace, const char *name, 2002 struct uio *uio) 2003{ 2004 struct mac_biba *subj, *obj; 2005 2006 if (!mac_biba_enabled) 2007 return (0); 2008 2009 subj = SLOT(&cred->cr_label); 2010 obj = SLOT(vnodelabel); 2011 2012 if (!mac_biba_dominate_single(subj, obj)) 2013 return (EACCES); 2014 2015 /* XXX: protect the MAC EA in a special way? */ 2016 2017 return (0); 2018} 2019 2020static int 2021mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2022 struct label *vnodelabel, u_long flags) 2023{ 2024 struct mac_biba *subj, *obj; 2025 2026 if (!mac_biba_enabled) 2027 return (0); 2028 2029 subj = SLOT(&cred->cr_label); 2030 obj = SLOT(vnodelabel); 2031 2032 if (!mac_biba_dominate_single(subj, obj)) 2033 return (EACCES); 2034 2035 return (0); 2036} 2037 2038static int 2039mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2040 struct label *vnodelabel, mode_t mode) 2041{ 2042 struct mac_biba *subj, *obj; 2043 2044 if (!mac_biba_enabled) 2045 return (0); 2046 2047 subj = SLOT(&cred->cr_label); 2048 obj = SLOT(vnodelabel); 2049 2050 if (!mac_biba_dominate_single(subj, obj)) 2051 return (EACCES); 2052 2053 return (0); 2054} 2055 2056static int 2057mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2058 struct label *vnodelabel, uid_t uid, gid_t gid) 2059{ 2060 struct mac_biba *subj, *obj; 2061 2062 if (!mac_biba_enabled) 2063 return (0); 2064 2065 subj = SLOT(&cred->cr_label); 2066 obj = SLOT(vnodelabel); 2067 2068 if (!mac_biba_dominate_single(subj, obj)) 2069 return (EACCES); 2070 2071 return (0); 2072} 2073 2074static int 2075mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2076 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2077{ 2078 struct mac_biba *subj, *obj; 2079 2080 if (!mac_biba_enabled) 2081 return (0); 2082 2083 subj = SLOT(&cred->cr_label); 2084 obj = SLOT(vnodelabel); 2085 2086 if (!mac_biba_dominate_single(subj, obj)) 2087 return (EACCES); 2088 2089 return (0); 2090} 2091 2092static int 2093mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2094 struct vnode *vp, struct label *vnodelabel) 2095{ 2096 struct mac_biba *subj, *obj; 2097 2098 if (!mac_biba_enabled) 2099 return (0); 2100 2101 subj = SLOT(&active_cred->cr_label); 2102 obj = SLOT(vnodelabel); 2103 2104 if (!mac_biba_dominate_single(obj, subj)) 2105 return (EACCES); 2106 2107 return (0); 2108} 2109 2110static int 2111mac_biba_check_vnode_write(struct ucred *active_cred, 2112 struct ucred *file_cred, struct vnode *vp, struct label *label) 2113{ 2114 struct mac_biba *subj, *obj; 2115 2116 if (!mac_biba_enabled || !revocation_enabled) 2117 return (0); 2118 2119 subj = SLOT(&active_cred->cr_label); 2120 obj = SLOT(label); 2121 2122 if (!mac_biba_dominate_single(subj, obj)) 2123 return (EACCES); 2124 2125 return (0); 2126} 2127 2128static struct mac_policy_op_entry mac_biba_ops[] = 2129{ 2130 { MAC_DESTROY, 2131 (macop_t)mac_biba_destroy }, 2132 { MAC_INIT, 2133 (macop_t)mac_biba_init }, 2134 { MAC_INIT_BPFDESC_LABEL, 2135 (macop_t)mac_biba_init_label }, 2136 { MAC_INIT_CRED_LABEL, 2137 (macop_t)mac_biba_init_label }, 2138 { MAC_INIT_DEVFSDIRENT_LABEL, 2139 (macop_t)mac_biba_init_label }, 2140 { MAC_INIT_IFNET_LABEL, 2141 (macop_t)mac_biba_init_label }, 2142 { MAC_INIT_IPQ_LABEL, 2143 (macop_t)mac_biba_init_label }, 2144 { MAC_INIT_MBUF_LABEL, 2145 (macop_t)mac_biba_init_label_waitcheck }, 2146 { MAC_INIT_MOUNT_LABEL, 2147 (macop_t)mac_biba_init_label }, 2148 { MAC_INIT_MOUNT_FS_LABEL, 2149 (macop_t)mac_biba_init_label }, 2150 { MAC_INIT_PIPE_LABEL, 2151 (macop_t)mac_biba_init_label }, 2152 { MAC_INIT_SOCKET_LABEL, 2153 (macop_t)mac_biba_init_label_waitcheck }, 2154 { MAC_INIT_SOCKET_PEER_LABEL, 2155 (macop_t)mac_biba_init_label_waitcheck }, 2156 { MAC_INIT_TEMP_LABEL, 2157 (macop_t)mac_biba_init_label }, 2158 { MAC_INIT_VNODE_LABEL, 2159 (macop_t)mac_biba_init_label }, 2160 { MAC_DESTROY_BPFDESC_LABEL, 2161 (macop_t)mac_biba_destroy_label }, 2162 { MAC_DESTROY_CRED_LABEL, 2163 (macop_t)mac_biba_destroy_label }, 2164 { MAC_DESTROY_DEVFSDIRENT_LABEL, 2165 (macop_t)mac_biba_destroy_label }, 2166 { MAC_DESTROY_IFNET_LABEL, 2167 (macop_t)mac_biba_destroy_label }, 2168 { MAC_DESTROY_IPQ_LABEL, 2169 (macop_t)mac_biba_destroy_label }, 2170 { MAC_DESTROY_MBUF_LABEL, 2171 (macop_t)mac_biba_destroy_label }, 2172 { MAC_DESTROY_MOUNT_LABEL, 2173 (macop_t)mac_biba_destroy_label }, 2174 { MAC_DESTROY_MOUNT_FS_LABEL, 2175 (macop_t)mac_biba_destroy_label }, 2176 { MAC_DESTROY_PIPE_LABEL, 2177 (macop_t)mac_biba_destroy_label }, 2178 { MAC_DESTROY_SOCKET_LABEL, 2179 (macop_t)mac_biba_destroy_label }, 2180 { MAC_DESTROY_SOCKET_PEER_LABEL, 2181 (macop_t)mac_biba_destroy_label }, 2182 { MAC_DESTROY_TEMP_LABEL, 2183 (macop_t)mac_biba_destroy_label }, 2184 { MAC_DESTROY_VNODE_LABEL, 2185 (macop_t)mac_biba_destroy_label }, 2186 { MAC_EXTERNALIZE, 2187 (macop_t)mac_biba_externalize }, 2188 { MAC_INTERNALIZE, 2189 (macop_t)mac_biba_internalize }, 2190 { MAC_CREATE_DEVFS_DEVICE, 2191 (macop_t)mac_biba_create_devfs_device }, 2192 { MAC_CREATE_DEVFS_DIRECTORY, 2193 (macop_t)mac_biba_create_devfs_directory }, 2194 { MAC_CREATE_DEVFS_SYMLINK, 2195 (macop_t)mac_biba_create_devfs_symlink }, 2196 { MAC_CREATE_DEVFS_VNODE, 2197 (macop_t)mac_biba_create_devfs_vnode }, 2198 { MAC_CREATE_VNODE, 2199 (macop_t)mac_biba_create_vnode }, 2200 { MAC_CREATE_MOUNT, 2201 (macop_t)mac_biba_create_mount }, 2202 { MAC_CREATE_ROOT_MOUNT, 2203 (macop_t)mac_biba_create_root_mount }, 2204 { MAC_RELABEL_VNODE, 2205 (macop_t)mac_biba_relabel_vnode }, 2206 { MAC_UPDATE_DEVFSDIRENT, 2207 (macop_t)mac_biba_update_devfsdirent }, 2208 { MAC_UPDATE_PROCFSVNODE, 2209 (macop_t)mac_biba_update_procfsvnode }, 2210 { MAC_UPDATE_VNODE_FROM_EXTERNALIZED, 2211 (macop_t)mac_biba_update_vnode_from_externalized }, 2212 { MAC_UPDATE_VNODE_FROM_MOUNT, 2213 (macop_t)mac_biba_update_vnode_from_mount }, 2214 { MAC_CREATE_MBUF_FROM_SOCKET, 2215 (macop_t)mac_biba_create_mbuf_from_socket }, 2216 { MAC_CREATE_PIPE, 2217 (macop_t)mac_biba_create_pipe }, 2218 { MAC_CREATE_SOCKET, 2219 (macop_t)mac_biba_create_socket }, 2220 { MAC_CREATE_SOCKET_FROM_SOCKET, 2221 (macop_t)mac_biba_create_socket_from_socket }, 2222 { MAC_RELABEL_PIPE, 2223 (macop_t)mac_biba_relabel_pipe }, 2224 { MAC_RELABEL_SOCKET, 2225 (macop_t)mac_biba_relabel_socket }, 2226 { MAC_SET_SOCKET_PEER_FROM_MBUF, 2227 (macop_t)mac_biba_set_socket_peer_from_mbuf }, 2228 { MAC_SET_SOCKET_PEER_FROM_SOCKET, 2229 (macop_t)mac_biba_set_socket_peer_from_socket }, 2230 { MAC_CREATE_BPFDESC, 2231 (macop_t)mac_biba_create_bpfdesc }, 2232 { MAC_CREATE_DATAGRAM_FROM_IPQ, 2233 (macop_t)mac_biba_create_datagram_from_ipq }, 2234 { MAC_CREATE_FRAGMENT, 2235 (macop_t)mac_biba_create_fragment }, 2236 { MAC_CREATE_IFNET, 2237 (macop_t)mac_biba_create_ifnet }, 2238 { MAC_CREATE_IPQ, 2239 (macop_t)mac_biba_create_ipq }, 2240 { MAC_CREATE_MBUF_FROM_MBUF, 2241 (macop_t)mac_biba_create_mbuf_from_mbuf }, 2242 { MAC_CREATE_MBUF_LINKLAYER, 2243 (macop_t)mac_biba_create_mbuf_linklayer }, 2244 { MAC_CREATE_MBUF_FROM_BPFDESC, 2245 (macop_t)mac_biba_create_mbuf_from_bpfdesc }, 2246 { MAC_CREATE_MBUF_FROM_IFNET, 2247 (macop_t)mac_biba_create_mbuf_from_ifnet }, 2248 { MAC_CREATE_MBUF_MULTICAST_ENCAP, 2249 (macop_t)mac_biba_create_mbuf_multicast_encap }, 2250 { MAC_CREATE_MBUF_NETLAYER, 2251 (macop_t)mac_biba_create_mbuf_netlayer }, 2252 { MAC_FRAGMENT_MATCH, 2253 (macop_t)mac_biba_fragment_match }, 2254 { MAC_RELABEL_IFNET, 2255 (macop_t)mac_biba_relabel_ifnet }, 2256 { MAC_UPDATE_IPQ, 2257 (macop_t)mac_biba_update_ipq }, 2258 { MAC_CREATE_CRED, 2259 (macop_t)mac_biba_create_cred }, 2260 { MAC_EXECVE_TRANSITION, 2261 (macop_t)mac_biba_execve_transition }, 2262 { MAC_EXECVE_WILL_TRANSITION, 2263 (macop_t)mac_biba_execve_will_transition }, 2264 { MAC_CREATE_PROC0, 2265 (macop_t)mac_biba_create_proc0 }, 2266 { MAC_CREATE_PROC1, 2267 (macop_t)mac_biba_create_proc1 }, 2268 { MAC_RELABEL_CRED, 2269 (macop_t)mac_biba_relabel_cred }, 2270 { MAC_CHECK_BPFDESC_RECEIVE, 2271 (macop_t)mac_biba_check_bpfdesc_receive }, 2272 { MAC_CHECK_CRED_RELABEL, 2273 (macop_t)mac_biba_check_cred_relabel }, 2274 { MAC_CHECK_CRED_VISIBLE, 2275 (macop_t)mac_biba_check_cred_visible }, 2276 { MAC_CHECK_IFNET_RELABEL, 2277 (macop_t)mac_biba_check_ifnet_relabel }, 2278 { MAC_CHECK_IFNET_TRANSMIT, 2279 (macop_t)mac_biba_check_ifnet_transmit }, 2280 { MAC_CHECK_MOUNT_STAT, 2281 (macop_t)mac_biba_check_mount_stat }, 2282 { MAC_CHECK_PIPE_IOCTL, 2283 (macop_t)mac_biba_check_pipe_ioctl }, 2284 { MAC_CHECK_PIPE_POLL, 2285 (macop_t)mac_biba_check_pipe_poll }, 2286 { MAC_CHECK_PIPE_READ, 2287 (macop_t)mac_biba_check_pipe_read }, 2288 { MAC_CHECK_PIPE_RELABEL, 2289 (macop_t)mac_biba_check_pipe_relabel }, 2290 { MAC_CHECK_PIPE_STAT, 2291 (macop_t)mac_biba_check_pipe_stat }, 2292 { MAC_CHECK_PIPE_WRITE, 2293 (macop_t)mac_biba_check_pipe_write }, 2294 { MAC_CHECK_PROC_DEBUG, 2295 (macop_t)mac_biba_check_proc_debug }, 2296 { MAC_CHECK_PROC_SCHED, 2297 (macop_t)mac_biba_check_proc_sched }, 2298 { MAC_CHECK_PROC_SIGNAL, 2299 (macop_t)mac_biba_check_proc_signal }, 2300 { MAC_CHECK_SOCKET_DELIVER, 2301 (macop_t)mac_biba_check_socket_deliver }, 2302 { MAC_CHECK_SOCKET_RELABEL, 2303 (macop_t)mac_biba_check_socket_relabel }, 2304 { MAC_CHECK_SOCKET_VISIBLE, 2305 (macop_t)mac_biba_check_socket_visible }, 2306 { MAC_CHECK_VNODE_ACCESS, 2307 (macop_t)mac_biba_check_vnode_open }, 2308 { MAC_CHECK_VNODE_CHDIR, 2309 (macop_t)mac_biba_check_vnode_chdir }, 2310 { MAC_CHECK_VNODE_CHROOT, 2311 (macop_t)mac_biba_check_vnode_chroot }, 2312 { MAC_CHECK_VNODE_CREATE, 2313 (macop_t)mac_biba_check_vnode_create }, 2314 { MAC_CHECK_VNODE_DELETE, 2315 (macop_t)mac_biba_check_vnode_delete }, 2316 { MAC_CHECK_VNODE_DELETEACL, 2317 (macop_t)mac_biba_check_vnode_deleteacl }, 2318 { MAC_CHECK_VNODE_EXEC, 2319 (macop_t)mac_biba_check_vnode_exec }, 2320 { MAC_CHECK_VNODE_GETACL, 2321 (macop_t)mac_biba_check_vnode_getacl }, 2322 { MAC_CHECK_VNODE_GETEXTATTR, 2323 (macop_t)mac_biba_check_vnode_getextattr }, 2324 { MAC_CHECK_VNODE_LINK, 2325 (macop_t)mac_biba_check_vnode_link }, 2326 { MAC_CHECK_VNODE_LOOKUP, 2327 (macop_t)mac_biba_check_vnode_lookup }, 2328 { MAC_CHECK_VNODE_MMAP, 2329 (macop_t)mac_biba_check_vnode_mmap }, 2330 { MAC_CHECK_VNODE_MPROTECT, 2331 (macop_t)mac_biba_check_vnode_mmap }, 2332 { MAC_CHECK_VNODE_OPEN, 2333 (macop_t)mac_biba_check_vnode_open }, 2334 { MAC_CHECK_VNODE_POLL, 2335 (macop_t)mac_biba_check_vnode_poll }, 2336 { MAC_CHECK_VNODE_READ, 2337 (macop_t)mac_biba_check_vnode_read }, 2338 { MAC_CHECK_VNODE_READDIR, 2339 (macop_t)mac_biba_check_vnode_readdir }, 2340 { MAC_CHECK_VNODE_READLINK, 2341 (macop_t)mac_biba_check_vnode_readlink }, 2342 { MAC_CHECK_VNODE_RELABEL, 2343 (macop_t)mac_biba_check_vnode_relabel }, 2344 { MAC_CHECK_VNODE_RENAME_FROM, 2345 (macop_t)mac_biba_check_vnode_rename_from }, 2346 { MAC_CHECK_VNODE_RENAME_TO, 2347 (macop_t)mac_biba_check_vnode_rename_to }, 2348 { MAC_CHECK_VNODE_REVOKE, 2349 (macop_t)mac_biba_check_vnode_revoke }, 2350 { MAC_CHECK_VNODE_SETACL, 2351 (macop_t)mac_biba_check_vnode_setacl }, 2352 { MAC_CHECK_VNODE_SETEXTATTR, 2353 (macop_t)mac_biba_check_vnode_setextattr }, 2354 { MAC_CHECK_VNODE_SETFLAGS, 2355 (macop_t)mac_biba_check_vnode_setflags }, 2356 { MAC_CHECK_VNODE_SETMODE, 2357 (macop_t)mac_biba_check_vnode_setmode }, 2358 { MAC_CHECK_VNODE_SETOWNER, 2359 (macop_t)mac_biba_check_vnode_setowner }, 2360 { MAC_CHECK_VNODE_SETUTIMES, 2361 (macop_t)mac_biba_check_vnode_setutimes }, 2362 { MAC_CHECK_VNODE_STAT, 2363 (macop_t)mac_biba_check_vnode_stat }, 2364 { MAC_CHECK_VNODE_WRITE, 2365 (macop_t)mac_biba_check_vnode_write }, 2366 { MAC_OP_LAST, NULL } 2367}; 2368 2369MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2370 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot); 2371