mac_biba.c revision 106091
1/*- 2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3 * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 4 * All rights reserved. 5 * 6 * This software was developed by Robert Watson for the TrustedBSD Project. 7 * 8 * This software was developed for the FreeBSD Project in part by NAI Labs, 9 * the Security Research Division of Network Associates, Inc. under 10 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 11 * CHATS research program. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. The names of the authors may not be used to endorse or promote 22 * products derived from this software without specific prior written 23 * permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * $FreeBSD: head/sys/security/mac_biba/mac_biba.c 106091 2002-10-28 19:18:29Z rwatson $ 38 */ 39 40/* 41 * Developed by the TrustedBSD Project. 42 * Biba fixed label mandatory integrity policy. 43 */ 44 45#include <sys/types.h> 46#include <sys/param.h> 47#include <sys/acl.h> 48#include <sys/conf.h> 49#include <sys/extattr.h> 50#include <sys/kernel.h> 51#include <sys/mac.h> 52#include <sys/malloc.h> 53#include <sys/mount.h> 54#include <sys/proc.h> 55#include <sys/systm.h> 56#include <sys/sysproto.h> 57#include <sys/sysent.h> 58#include <sys/systm.h> 59#include <sys/vnode.h> 60#include <sys/file.h> 61#include <sys/socket.h> 62#include <sys/socketvar.h> 63#include <sys/pipe.h> 64#include <sys/sysctl.h> 65 66#include <fs/devfs/devfs.h> 67 68#include <net/bpfdesc.h> 69#include <net/if.h> 70#include <net/if_types.h> 71#include <net/if_var.h> 72 73#include <netinet/in.h> 74#include <netinet/ip_var.h> 75 76#include <vm/vm.h> 77 78#include <sys/mac_policy.h> 79 80#include <security/mac_biba/mac_biba.h> 81 82SYSCTL_DECL(_security_mac); 83 84SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0, 85 "TrustedBSD mac_biba policy controls"); 86 87static int mac_biba_label_size = sizeof(struct mac_biba); 88SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD, 89 &mac_biba_label_size, 0, "Size of struct mac_biba"); 90 91static int mac_biba_enabled = 0; 92SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW, 93 &mac_biba_enabled, 0, "Enforce MAC/Biba policy"); 94TUNABLE_INT("security.mac.biba.enabled", &mac_biba_enabled); 95 96static int destroyed_not_inited; 97SYSCTL_INT(_security_mac_biba, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 98 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 99 100static int trust_all_interfaces = 0; 101SYSCTL_INT(_security_mac_biba, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 102 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/Biba"); 103TUNABLE_INT("security.mac.biba.trust_all_interfaces", &trust_all_interfaces); 104 105static char trusted_interfaces[128]; 106SYSCTL_STRING(_security_mac_biba, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 107 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/Biba"); 108TUNABLE_STR("security.mac.biba.trusted_interfaces", trusted_interfaces, 109 sizeof(trusted_interfaces)); 110 111static int max_compartments = MAC_BIBA_MAX_COMPARTMENTS; 112SYSCTL_INT(_security_mac_biba, OID_AUTO, max_compartments, CTLFLAG_RD, 113 &max_compartments, 0, "Maximum supported compartments"); 114 115static int ptys_equal = 0; 116SYSCTL_INT(_security_mac_biba, OID_AUTO, ptys_equal, CTLFLAG_RW, 117 &ptys_equal, 0, "Label pty devices as biba/equal on create"); 118TUNABLE_INT("security.mac.biba.ptys_equal", &ptys_equal); 119 120static int revocation_enabled = 0; 121SYSCTL_INT(_security_mac_biba, OID_AUTO, revocation_enabled, CTLFLAG_RW, 122 &revocation_enabled, 0, "Revoke access to objects on relabel"); 123TUNABLE_INT("security.mac.biba.revocation_enabled", &revocation_enabled); 124 125static int mac_biba_slot; 126#define SLOT(l) ((struct mac_biba *)LABEL_TO_SLOT((l), mac_biba_slot).l_ptr) 127 128MALLOC_DEFINE(M_MACBIBA, "biba label", "MAC/Biba labels"); 129 130static __inline int 131biba_bit_set_empty(u_char *set) { 132 int i; 133 134 for (i = 0; i < MAC_BIBA_MAX_COMPARTMENTS >> 3; i++) 135 if (set[i] != 0) 136 return (0); 137 return (1); 138} 139 140static struct mac_biba * 141biba_alloc(int flag) 142{ 143 struct mac_biba *mac_biba; 144 145 mac_biba = malloc(sizeof(struct mac_biba), M_MACBIBA, M_ZERO | flag); 146 147 return (mac_biba); 148} 149 150static void 151biba_free(struct mac_biba *mac_biba) 152{ 153 154 if (mac_biba != NULL) 155 free(mac_biba, M_MACBIBA); 156 else 157 atomic_add_int(&destroyed_not_inited, 1); 158} 159 160static int 161biba_atmostflags(struct mac_biba *mac_biba, int flags) 162{ 163 164 if ((mac_biba->mb_flags & flags) != mac_biba->mb_flags) 165 return (EINVAL); 166 return (0); 167} 168 169static int 170mac_biba_dominate_element(struct mac_biba_element *a, 171 struct mac_biba_element *b) 172{ 173 int bit; 174 175 switch (a->mbe_type) { 176 case MAC_BIBA_TYPE_EQUAL: 177 case MAC_BIBA_TYPE_HIGH: 178 return (1); 179 180 case MAC_BIBA_TYPE_LOW: 181 switch (b->mbe_type) { 182 case MAC_BIBA_TYPE_GRADE: 183 case MAC_BIBA_TYPE_HIGH: 184 return (0); 185 186 case MAC_BIBA_TYPE_EQUAL: 187 case MAC_BIBA_TYPE_LOW: 188 return (1); 189 190 default: 191 panic("mac_biba_dominate_element: b->mbe_type invalid"); 192 } 193 194 case MAC_BIBA_TYPE_GRADE: 195 switch (b->mbe_type) { 196 case MAC_BIBA_TYPE_EQUAL: 197 case MAC_BIBA_TYPE_LOW: 198 return (1); 199 200 case MAC_BIBA_TYPE_HIGH: 201 return (0); 202 203 case MAC_BIBA_TYPE_GRADE: 204 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) 205 if (!MAC_BIBA_BIT_TEST(bit, 206 a->mbe_compartments) && 207 MAC_BIBA_BIT_TEST(bit, b->mbe_compartments)) 208 return (0); 209 return (a->mbe_grade >= b->mbe_grade); 210 211 default: 212 panic("mac_biba_dominate_element: b->mbe_type invalid"); 213 } 214 215 default: 216 panic("mac_biba_dominate_element: a->mbe_type invalid"); 217 } 218 219 return (0); 220} 221 222static int 223mac_biba_subject_dominate_high(struct mac_biba *mac_biba) 224{ 225 struct mac_biba_element *element; 226 227 KASSERT((mac_biba->mb_single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 228 ("mac_biba_single_in_range: mac_biba not single")); 229 element = &mac_biba->mb_single; 230 231 return (element->mbe_type == MAC_BIBA_TYPE_EQUAL || 232 element->mbe_type == MAC_BIBA_TYPE_HIGH); 233} 234 235static int 236mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb) 237{ 238 239 return (mac_biba_dominate_element(&rangeb->mb_rangehigh, 240 &rangea->mb_rangehigh) && 241 mac_biba_dominate_element(&rangea->mb_rangelow, 242 &rangeb->mb_rangelow)); 243} 244 245static int 246mac_biba_single_in_range(struct mac_biba *single, struct mac_biba *range) 247{ 248 249 KASSERT((single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 250 ("mac_biba_single_in_range: a not single")); 251 KASSERT((range->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 252 ("mac_biba_single_in_range: b not range")); 253 254 return (mac_biba_dominate_element(&range->mb_rangehigh, 255 &single->mb_single) && 256 mac_biba_dominate_element(&single->mb_single, 257 &range->mb_rangelow)); 258 259 return (1); 260} 261 262static int 263mac_biba_dominate_single(struct mac_biba *a, struct mac_biba *b) 264{ 265 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 266 ("mac_biba_dominate_single: a not single")); 267 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 268 ("mac_biba_dominate_single: b not single")); 269 270 return (mac_biba_dominate_element(&a->mb_single, &b->mb_single)); 271} 272 273static int 274mac_biba_equal_element(struct mac_biba_element *a, struct mac_biba_element *b) 275{ 276 277 if (a->mbe_type == MAC_BIBA_TYPE_EQUAL || 278 b->mbe_type == MAC_BIBA_TYPE_EQUAL) 279 return (1); 280 281 return (a->mbe_type == b->mbe_type && a->mbe_grade == b->mbe_grade); 282} 283 284static int 285mac_biba_equal_single(struct mac_biba *a, struct mac_biba *b) 286{ 287 288 KASSERT((a->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 289 ("mac_biba_equal_single: a not single")); 290 KASSERT((b->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 291 ("mac_biba_equal_single: b not single")); 292 293 return (mac_biba_equal_element(&a->mb_single, &b->mb_single)); 294} 295 296static int 297mac_biba_contains_equal(struct mac_biba *mac_biba) 298{ 299 300 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) 301 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 302 return (1); 303 304 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 305 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL) 306 return (1); 307 if (mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 308 return (1); 309 } 310 311 return (0); 312} 313 314static int 315mac_biba_subject_privileged(struct mac_biba *mac_biba) 316{ 317 318 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAGS_BOTH) == 319 MAC_BIBA_FLAGS_BOTH, 320 ("mac_biba_subject_privileged: subject doesn't have both labels")); 321 322 /* If the single is EQUAL, it's ok. */ 323 if (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_EQUAL) 324 return (0); 325 326 /* If either range endpoint is EQUAL, it's ok. */ 327 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_EQUAL || 328 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_EQUAL) 329 return (0); 330 331 /* If the range is low-high, it's ok. */ 332 if (mac_biba->mb_rangelow.mbe_type == MAC_BIBA_TYPE_LOW && 333 mac_biba->mb_rangehigh.mbe_type == MAC_BIBA_TYPE_HIGH) 334 return (0); 335 336 /* It's not ok. */ 337 return (EPERM); 338} 339 340static int 341mac_biba_high_single(struct mac_biba *mac_biba) 342{ 343 344 KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 345 ("mac_biba_equal_single: mac_biba not single")); 346 347 return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH); 348} 349 350static int 351mac_biba_valid(struct mac_biba *mac_biba) 352{ 353 354 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 355 switch (mac_biba->mb_single.mbe_type) { 356 case MAC_BIBA_TYPE_GRADE: 357 break; 358 359 case MAC_BIBA_TYPE_EQUAL: 360 case MAC_BIBA_TYPE_HIGH: 361 case MAC_BIBA_TYPE_LOW: 362 if (mac_biba->mb_single.mbe_grade != 0 || 363 !MAC_BIBA_BIT_SET_EMPTY( 364 mac_biba->mb_single.mbe_compartments)) 365 return (EINVAL); 366 break; 367 368 default: 369 return (EINVAL); 370 } 371 } else { 372 if (mac_biba->mb_single.mbe_type != MAC_BIBA_TYPE_UNDEF) 373 return (EINVAL); 374 } 375 376 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 377 switch (mac_biba->mb_rangelow.mbe_type) { 378 case MAC_BIBA_TYPE_GRADE: 379 break; 380 381 case MAC_BIBA_TYPE_EQUAL: 382 case MAC_BIBA_TYPE_HIGH: 383 case MAC_BIBA_TYPE_LOW: 384 if (mac_biba->mb_rangelow.mbe_grade != 0 || 385 !MAC_BIBA_BIT_SET_EMPTY( 386 mac_biba->mb_rangelow.mbe_compartments)) 387 return (EINVAL); 388 break; 389 390 default: 391 return (EINVAL); 392 } 393 394 switch (mac_biba->mb_rangehigh.mbe_type) { 395 case MAC_BIBA_TYPE_GRADE: 396 break; 397 398 case MAC_BIBA_TYPE_EQUAL: 399 case MAC_BIBA_TYPE_HIGH: 400 case MAC_BIBA_TYPE_LOW: 401 if (mac_biba->mb_rangehigh.mbe_grade != 0 || 402 !MAC_BIBA_BIT_SET_EMPTY( 403 mac_biba->mb_rangehigh.mbe_compartments)) 404 return (EINVAL); 405 break; 406 407 default: 408 return (EINVAL); 409 } 410 if (!mac_biba_dominate_element(&mac_biba->mb_rangehigh, 411 &mac_biba->mb_rangelow)) 412 return (EINVAL); 413 } else { 414 if (mac_biba->mb_rangelow.mbe_type != MAC_BIBA_TYPE_UNDEF || 415 mac_biba->mb_rangehigh.mbe_type != MAC_BIBA_TYPE_UNDEF) 416 return (EINVAL); 417 } 418 419 return (0); 420} 421 422static void 423mac_biba_set_range(struct mac_biba *mac_biba, u_short typelow, 424 u_short gradelow, u_char *compartmentslow, u_short typehigh, 425 u_short gradehigh, u_char *compartmentshigh) 426{ 427 428 mac_biba->mb_rangelow.mbe_type = typelow; 429 mac_biba->mb_rangelow.mbe_grade = gradelow; 430 if (compartmentslow != NULL) 431 memcpy(mac_biba->mb_rangelow.mbe_compartments, 432 compartmentslow, 433 sizeof(mac_biba->mb_rangelow.mbe_compartments)); 434 mac_biba->mb_rangehigh.mbe_type = typehigh; 435 mac_biba->mb_rangehigh.mbe_grade = gradehigh; 436 if (compartmentshigh != NULL) 437 memcpy(mac_biba->mb_rangehigh.mbe_compartments, 438 compartmentshigh, 439 sizeof(mac_biba->mb_rangehigh.mbe_compartments)); 440 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 441} 442 443static void 444mac_biba_set_single(struct mac_biba *mac_biba, u_short type, u_short grade, 445 u_char *compartments) 446{ 447 448 mac_biba->mb_single.mbe_type = type; 449 mac_biba->mb_single.mbe_grade = grade; 450 if (compartments != NULL) 451 memcpy(mac_biba->mb_single.mbe_compartments, compartments, 452 sizeof(mac_biba->mb_single.mbe_compartments)); 453 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 454} 455 456static void 457mac_biba_copy_range(struct mac_biba *labelfrom, struct mac_biba *labelto) 458{ 459 460 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_RANGE) != 0, 461 ("mac_biba_copy_range: labelfrom not range")); 462 463 labelto->mb_rangelow = labelfrom->mb_rangelow; 464 labelto->mb_rangehigh = labelfrom->mb_rangehigh; 465 labelto->mb_flags |= MAC_BIBA_FLAG_RANGE; 466} 467 468static void 469mac_biba_copy_single(struct mac_biba *labelfrom, struct mac_biba *labelto) 470{ 471 472 KASSERT((labelfrom->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0, 473 ("mac_biba_copy_single: labelfrom not single")); 474 475 labelto->mb_single = labelfrom->mb_single; 476 labelto->mb_flags |= MAC_BIBA_FLAG_SINGLE; 477} 478 479static void 480mac_biba_copy(struct mac_biba *source, struct mac_biba *dest) 481{ 482 483 if (source->mb_flags & MAC_BIBA_FLAG_SINGLE) 484 mac_biba_copy_single(source, dest); 485 if (source->mb_flags & MAC_BIBA_FLAG_RANGE) 486 mac_biba_copy_range(source, dest); 487} 488 489/* 490 * Policy module operations. 491 */ 492static void 493mac_biba_destroy(struct mac_policy_conf *conf) 494{ 495 496} 497 498static void 499mac_biba_init(struct mac_policy_conf *conf) 500{ 501 502} 503 504/* 505 * Label operations. 506 */ 507static void 508mac_biba_init_label(struct label *label) 509{ 510 511 SLOT(label) = biba_alloc(M_WAITOK); 512} 513 514static int 515mac_biba_init_label_waitcheck(struct label *label, int flag) 516{ 517 518 SLOT(label) = biba_alloc(flag); 519 if (SLOT(label) == NULL) 520 return (ENOMEM); 521 522 return (0); 523} 524 525static void 526mac_biba_destroy_label(struct label *label) 527{ 528 529 biba_free(SLOT(label)); 530 SLOT(label) = NULL; 531} 532 533/* 534 * mac_biba_element_to_string() is basically an snprintf wrapper with 535 * the same properties as snprintf(). It returns the length it would 536 * have added to the string in the event the string is too short. 537 */ 538static size_t 539mac_biba_element_to_string(char *string, size_t size, 540 struct mac_biba_element *element) 541{ 542 int pos, bit = 1; 543 544 switch (element->mbe_type) { 545 case MAC_BIBA_TYPE_HIGH: 546 return (snprintf(string, size, "high")); 547 548 case MAC_BIBA_TYPE_LOW: 549 return (snprintf(string, size, "low")); 550 551 case MAC_BIBA_TYPE_EQUAL: 552 return (snprintf(string, size, "equal")); 553 554 case MAC_BIBA_TYPE_GRADE: 555 pos = snprintf(string, size, "%d:", element->mbe_grade); 556 for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) { 557 if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments)) 558 pos += snprintf(string + pos, size - pos, 559 "%d+", bit); 560 } 561 if (string[pos - 1] == '+' || string[pos - 1] == ':') 562 string[--pos] = NULL; 563 return (pos); 564 565 default: 566 panic("mac_biba_element_to_string: invalid type (%d)", 567 element->mbe_type); 568 } 569} 570 571static int 572mac_biba_to_string(char *string, size_t size, size_t *caller_len, 573 struct mac_biba *mac_biba) 574{ 575 size_t left, len; 576 char *curptr; 577 578 bzero(string, size); 579 curptr = string; 580 left = size; 581 582 if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) { 583 len = mac_biba_element_to_string(curptr, left, 584 &mac_biba->mb_single); 585 if (len >= left) 586 return (EINVAL); 587 left -= len; 588 curptr += len; 589 } 590 591 if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) { 592 len = snprintf(curptr, left, "("); 593 if (len >= left) 594 return (EINVAL); 595 left -= len; 596 curptr += len; 597 598 len = mac_biba_element_to_string(curptr, left, 599 &mac_biba->mb_rangelow); 600 if (len >= left) 601 return (EINVAL); 602 left -= len; 603 curptr += len; 604 605 len = snprintf(curptr, left, "-"); 606 if (len >= left) 607 return (EINVAL); 608 left -= len; 609 curptr += len; 610 611 len = mac_biba_element_to_string(curptr, left, 612 &mac_biba->mb_rangehigh); 613 if (len >= left) 614 return (EINVAL); 615 left -= len; 616 curptr += len; 617 618 len = snprintf(curptr, left, ")"); 619 if (len >= left) 620 return (EINVAL); 621 left -= len; 622 curptr += len; 623 } 624 625 *caller_len = strlen(string); 626 return (0); 627} 628 629static int 630mac_biba_externalize_label(struct label *label, char *element_name, 631 char *element_data, size_t size, size_t *len, int *claimed) 632{ 633 struct mac_biba *mac_biba; 634 int error; 635 636 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 637 return (0); 638 639 (*claimed)++; 640 641 mac_biba = SLOT(label); 642 error = mac_biba_to_string(element_data, size, len, mac_biba); 643 if (error) 644 return (error); 645 646 *len = strlen(element_data); 647 return (0); 648} 649 650static int 651mac_biba_parse_element(struct mac_biba_element *element, char *string) 652{ 653 654 if (strcmp(string, "high") == 0 || 655 strcmp(string, "hi") == 0) { 656 element->mbe_type = MAC_BIBA_TYPE_HIGH; 657 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 658 } else if (strcmp(string, "low") == 0 || 659 strcmp(string, "lo") == 0) { 660 element->mbe_type = MAC_BIBA_TYPE_LOW; 661 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 662 } else if (strcmp(string, "equal") == 0 || 663 strcmp(string, "eq") == 0) { 664 element->mbe_type = MAC_BIBA_TYPE_EQUAL; 665 element->mbe_grade = MAC_BIBA_TYPE_UNDEF; 666 } else { 667 char *p0, *p1; 668 int d; 669 670 p0 = string; 671 d = strtol(p0, &p1, 10); 672 673 if (d < 0 || d > 65535) 674 return (EINVAL); 675 element->mbe_type = MAC_BIBA_TYPE_GRADE; 676 element->mbe_grade = d; 677 678 if (*p1 != ':') { 679 if (p1 == p0 || *p1 != '\0') 680 return (EINVAL); 681 else 682 return (0); 683 } 684 else 685 if (*(p1 + 1) == '\0') 686 return (0); 687 688 while ((p0 = ++p1)) { 689 d = strtol(p0, &p1, 10); 690 if (d < 1 || d > MAC_BIBA_MAX_COMPARTMENTS) 691 return (EINVAL); 692 693 MAC_BIBA_BIT_SET(d, element->mbe_compartments); 694 695 if (*p1 == '\0') 696 break; 697 if (p1 == p0 || *p1 != '+') 698 return (EINVAL); 699 } 700 } 701 702 return (0); 703} 704 705/* 706 * Note: destructively consumes the string, make a local copy before 707 * calling if that's a problem. 708 */ 709static int 710mac_biba_parse(struct mac_biba *mac_biba, char *string) 711{ 712 char *range, *rangeend, *rangehigh, *rangelow, *single; 713 int error; 714 715 /* Do we have a range? */ 716 single = string; 717 range = index(string, '('); 718 if (range == single) 719 single = NULL; 720 rangelow = rangehigh = NULL; 721 if (range != NULL) { 722 /* Nul terminate the end of the single string. */ 723 *range = '\0'; 724 range++; 725 rangelow = range; 726 rangehigh = index(rangelow, '-'); 727 if (rangehigh == NULL) 728 return (EINVAL); 729 rangehigh++; 730 if (*rangelow == '\0' || *rangehigh == '\0') 731 return (EINVAL); 732 rangeend = index(rangehigh, ')'); 733 if (rangeend == NULL) 734 return (EINVAL); 735 if (*(rangeend + 1) != '\0') 736 return (EINVAL); 737 /* Nul terminate the ends of the ranges. */ 738 *(rangehigh - 1) = '\0'; 739 *rangeend = '\0'; 740 } 741 KASSERT((rangelow != NULL && rangehigh != NULL) || 742 (rangelow == NULL && rangehigh == NULL), 743 ("mac_biba_internalize_label: range mismatch")); 744 745 bzero(mac_biba, sizeof(*mac_biba)); 746 if (single != NULL) { 747 error = mac_biba_parse_element(&mac_biba->mb_single, single); 748 if (error) 749 return (error); 750 mac_biba->mb_flags |= MAC_BIBA_FLAG_SINGLE; 751 } 752 753 if (rangelow != NULL) { 754 error = mac_biba_parse_element(&mac_biba->mb_rangelow, 755 rangelow); 756 if (error) 757 return (error); 758 error = mac_biba_parse_element(&mac_biba->mb_rangehigh, 759 rangehigh); 760 if (error) 761 return (error); 762 mac_biba->mb_flags |= MAC_BIBA_FLAG_RANGE; 763 } 764 765 error = mac_biba_valid(mac_biba); 766 if (error) 767 return (error); 768 769 return (0); 770} 771 772static int 773mac_biba_internalize_label(struct label *label, char *element_name, 774 char *element_data, int *claimed) 775{ 776 struct mac_biba *mac_biba, mac_biba_temp; 777 int error; 778 779 if (strcmp(MAC_BIBA_LABEL_NAME, element_name) != 0) 780 return (0); 781 782 (*claimed)++; 783 784 error = mac_biba_parse(&mac_biba_temp, element_data); 785 if (error) 786 return (error); 787 788 mac_biba = SLOT(label); 789 *mac_biba = mac_biba_temp; 790 791 return (0); 792} 793 794static void 795mac_biba_copy_label(struct label *src, struct label *dest) 796{ 797 798 *SLOT(dest) = *SLOT(src); 799} 800 801/* 802 * Labeling event operations: file system objects, and things that look 803 * a lot like file system objects. 804 */ 805static void 806mac_biba_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent, 807 struct label *label) 808{ 809 struct mac_biba *mac_biba; 810 int biba_type; 811 812 mac_biba = SLOT(label); 813 if (strcmp(dev->si_name, "null") == 0 || 814 strcmp(dev->si_name, "zero") == 0 || 815 strcmp(dev->si_name, "random") == 0 || 816 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0) 817 biba_type = MAC_BIBA_TYPE_EQUAL; 818 else if (ptys_equal && 819 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 820 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 821 biba_type = MAC_BIBA_TYPE_EQUAL; 822 else 823 biba_type = MAC_BIBA_TYPE_HIGH; 824 mac_biba_set_single(mac_biba, biba_type, 0, NULL); 825} 826 827static void 828mac_biba_create_devfs_directory(char *dirname, int dirnamelen, 829 struct devfs_dirent *devfs_dirent, struct label *label) 830{ 831 struct mac_biba *mac_biba; 832 833 mac_biba = SLOT(label); 834 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 835} 836 837static void 838mac_biba_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 839 struct label *ddlabel, struct devfs_dirent *de, struct label *delabel) 840{ 841 struct mac_biba *source, *dest; 842 843 source = SLOT(&cred->cr_label); 844 dest = SLOT(delabel); 845 846 mac_biba_copy_single(source, dest); 847} 848 849static void 850mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent, 851 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 852{ 853 struct mac_biba *source, *dest; 854 855 source = SLOT(direntlabel); 856 dest = SLOT(vnodelabel); 857 mac_biba_copy_single(source, dest); 858} 859 860static void 861mac_biba_create_mount(struct ucred *cred, struct mount *mp, 862 struct label *mntlabel, struct label *fslabel) 863{ 864 struct mac_biba *source, *dest; 865 866 source = SLOT(&cred->cr_label); 867 dest = SLOT(mntlabel); 868 mac_biba_copy_single(source, dest); 869 dest = SLOT(fslabel); 870 mac_biba_copy_single(source, dest); 871} 872 873static void 874mac_biba_create_root_mount(struct ucred *cred, struct mount *mp, 875 struct label *mntlabel, struct label *fslabel) 876{ 877 struct mac_biba *mac_biba; 878 879 /* Always mount root as high integrity. */ 880 mac_biba = SLOT(fslabel); 881 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 882 mac_biba = SLOT(mntlabel); 883 mac_biba_set_single(mac_biba, MAC_BIBA_TYPE_HIGH, 0, NULL); 884} 885 886static void 887mac_biba_relabel_vnode(struct ucred *cred, struct vnode *vp, 888 struct label *vnodelabel, struct label *label) 889{ 890 struct mac_biba *source, *dest; 891 892 source = SLOT(label); 893 dest = SLOT(vnodelabel); 894 895 mac_biba_copy(source, dest); 896} 897 898static void 899mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent, 900 struct label *direntlabel, struct vnode *vp, struct label *vnodelabel) 901{ 902 struct mac_biba *source, *dest; 903 904 source = SLOT(vnodelabel); 905 dest = SLOT(direntlabel); 906 907 mac_biba_copy(source, dest); 908} 909 910static void 911mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 912 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 913 struct label *vlabel) 914{ 915 struct mac_biba *source, *dest; 916 917 source = SLOT(delabel); 918 dest = SLOT(vlabel); 919 920 mac_biba_copy_single(source, dest); 921} 922 923static int 924mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 925 struct vnode *vp, struct label *vlabel) 926{ 927 struct mac_biba temp, *source, *dest; 928 size_t buflen; 929 int error; 930 931 source = SLOT(fslabel); 932 dest = SLOT(vlabel); 933 934 buflen = sizeof(temp); 935 bzero(&temp, buflen); 936 937 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 938 MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread); 939 if (error == ENOATTR || error == EOPNOTSUPP) { 940 /* Fall back to the fslabel. */ 941 mac_biba_copy_single(source, dest); 942 return (0); 943 } else if (error) 944 return (error); 945 946 if (buflen != sizeof(temp)) { 947 printf("mac_biba_associate_vnode_extattr: bad size %d\n", 948 buflen); 949 return (EPERM); 950 } 951 if (mac_biba_valid(&temp) != 0) { 952 printf("mac_biba_associate_vnode_extattr: invalid\n"); 953 return (EPERM); 954 } 955 if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) { 956 printf("mac_biba_associate_vnode_extattr: not single\n"); 957 return (EPERM); 958 } 959 960 mac_biba_copy_single(&temp, dest); 961 return (0); 962} 963 964static void 965mac_biba_associate_vnode_singlelabel(struct mount *mp, 966 struct label *fslabel, struct vnode *vp, struct label *vlabel) 967{ 968 struct mac_biba *source, *dest; 969 970 source = SLOT(fslabel); 971 dest = SLOT(vlabel); 972 973 mac_biba_copy_single(source, dest); 974} 975 976static int 977mac_biba_create_vnode_extattr(struct ucred *cred, struct mount *mp, 978 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 979 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 980{ 981 struct mac_biba *source, *dest, temp; 982 size_t buflen; 983 int error; 984 985 buflen = sizeof(temp); 986 bzero(&temp, buflen); 987 988 source = SLOT(&cred->cr_label); 989 dest = SLOT(vlabel); 990 mac_biba_copy_single(source, &temp); 991 992 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 993 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 994 if (error == 0) 995 mac_biba_copy_single(source, dest); 996 return (error); 997} 998 999static int 1000mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1001 struct label *vlabel, struct label *intlabel) 1002{ 1003 struct mac_biba *source, temp; 1004 size_t buflen; 1005 int error; 1006 1007 buflen = sizeof(temp); 1008 bzero(&temp, buflen); 1009 1010 source = SLOT(intlabel); 1011 if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0) 1012 return (0); 1013 1014 mac_biba_copy_single(source, &temp); 1015 1016 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE, 1017 MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread); 1018 return (error); 1019} 1020 1021/* 1022 * Labeling event operations: IPC object. 1023 */ 1024static void 1025mac_biba_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1026 struct mbuf *m, struct label *mbuflabel) 1027{ 1028 struct mac_biba *source, *dest; 1029 1030 source = SLOT(socketlabel); 1031 dest = SLOT(mbuflabel); 1032 1033 mac_biba_copy_single(source, dest); 1034} 1035 1036static void 1037mac_biba_create_socket(struct ucred *cred, struct socket *socket, 1038 struct label *socketlabel) 1039{ 1040 struct mac_biba *source, *dest; 1041 1042 source = SLOT(&cred->cr_label); 1043 dest = SLOT(socketlabel); 1044 1045 mac_biba_copy_single(source, dest); 1046} 1047 1048static void 1049mac_biba_create_pipe(struct ucred *cred, struct pipe *pipe, 1050 struct label *pipelabel) 1051{ 1052 struct mac_biba *source, *dest; 1053 1054 source = SLOT(&cred->cr_label); 1055 dest = SLOT(pipelabel); 1056 1057 mac_biba_copy_single(source, dest); 1058} 1059 1060static void 1061mac_biba_create_socket_from_socket(struct socket *oldsocket, 1062 struct label *oldsocketlabel, struct socket *newsocket, 1063 struct label *newsocketlabel) 1064{ 1065 struct mac_biba *source, *dest; 1066 1067 source = SLOT(oldsocketlabel); 1068 dest = SLOT(newsocketlabel); 1069 1070 mac_biba_copy_single(source, dest); 1071} 1072 1073static void 1074mac_biba_relabel_socket(struct ucred *cred, struct socket *socket, 1075 struct label *socketlabel, struct label *newlabel) 1076{ 1077 struct mac_biba *source, *dest; 1078 1079 source = SLOT(newlabel); 1080 dest = SLOT(socketlabel); 1081 1082 mac_biba_copy(source, dest); 1083} 1084 1085static void 1086mac_biba_relabel_pipe(struct ucred *cred, struct pipe *pipe, 1087 struct label *pipelabel, struct label *newlabel) 1088{ 1089 struct mac_biba *source, *dest; 1090 1091 source = SLOT(newlabel); 1092 dest = SLOT(pipelabel); 1093 1094 mac_biba_copy(source, dest); 1095} 1096 1097static void 1098mac_biba_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1099 struct socket *socket, struct label *socketpeerlabel) 1100{ 1101 struct mac_biba *source, *dest; 1102 1103 source = SLOT(mbuflabel); 1104 dest = SLOT(socketpeerlabel); 1105 1106 mac_biba_copy_single(source, dest); 1107} 1108 1109/* 1110 * Labeling event operations: network objects. 1111 */ 1112static void 1113mac_biba_set_socket_peer_from_socket(struct socket *oldsocket, 1114 struct label *oldsocketlabel, struct socket *newsocket, 1115 struct label *newsocketpeerlabel) 1116{ 1117 struct mac_biba *source, *dest; 1118 1119 source = SLOT(oldsocketlabel); 1120 dest = SLOT(newsocketpeerlabel); 1121 1122 mac_biba_copy_single(source, dest); 1123} 1124 1125static void 1126mac_biba_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1127 struct label *bpflabel) 1128{ 1129 struct mac_biba *source, *dest; 1130 1131 source = SLOT(&cred->cr_label); 1132 dest = SLOT(bpflabel); 1133 1134 mac_biba_copy_single(source, dest); 1135} 1136 1137static void 1138mac_biba_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1139{ 1140 char tifname[IFNAMSIZ], ifname[IFNAMSIZ], *p, *q; 1141 char tiflist[sizeof(trusted_interfaces)]; 1142 struct mac_biba *dest; 1143 int len, grade; 1144 1145 dest = SLOT(ifnetlabel); 1146 1147 if (ifnet->if_type == IFT_LOOP) { 1148 grade = MAC_BIBA_TYPE_EQUAL; 1149 goto set; 1150 } 1151 1152 if (trust_all_interfaces) { 1153 grade = MAC_BIBA_TYPE_HIGH; 1154 goto set; 1155 } 1156 1157 grade = MAC_BIBA_TYPE_LOW; 1158 1159 if (trusted_interfaces[0] == '\0' || 1160 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1161 goto set; 1162 1163 bzero(tiflist, sizeof(tiflist)); 1164 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1165 if(*p != ' ' && *p != '\t') 1166 *q = *p; 1167 1168 snprintf(ifname, IFNAMSIZ, "%s%d", ifnet->if_name, ifnet->if_unit); 1169 1170 for (p = q = tiflist;; p++) { 1171 if (*p == ',' || *p == '\0') { 1172 len = p - q; 1173 if (len < IFNAMSIZ) { 1174 bzero(tifname, sizeof(tifname)); 1175 bcopy(q, tifname, len); 1176 if (strcmp(tifname, ifname) == 0) { 1177 grade = MAC_BIBA_TYPE_HIGH; 1178 break; 1179 } 1180 } else { 1181 *p = '\0'; 1182 printf("mac_biba warning: interface name " 1183 "\"%s\" is too long (must be < %d)\n", 1184 q, IFNAMSIZ); 1185 } 1186 if (*p == '\0') 1187 break; 1188 q = p + 1; 1189 } 1190 } 1191set: 1192 mac_biba_set_single(dest, grade, 0, NULL); 1193 mac_biba_set_range(dest, grade, 0, NULL, grade, 0, NULL); 1194} 1195 1196static void 1197mac_biba_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1198 struct ipq *ipq, struct label *ipqlabel) 1199{ 1200 struct mac_biba *source, *dest; 1201 1202 source = SLOT(fragmentlabel); 1203 dest = SLOT(ipqlabel); 1204 1205 mac_biba_copy_single(source, dest); 1206} 1207 1208static void 1209mac_biba_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1210 struct mbuf *datagram, struct label *datagramlabel) 1211{ 1212 struct mac_biba *source, *dest; 1213 1214 source = SLOT(ipqlabel); 1215 dest = SLOT(datagramlabel); 1216 1217 /* Just use the head, since we require them all to match. */ 1218 mac_biba_copy_single(source, dest); 1219} 1220 1221static void 1222mac_biba_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1223 struct mbuf *fragment, struct label *fragmentlabel) 1224{ 1225 struct mac_biba *source, *dest; 1226 1227 source = SLOT(datagramlabel); 1228 dest = SLOT(fragmentlabel); 1229 1230 mac_biba_copy_single(source, dest); 1231} 1232 1233static void 1234mac_biba_create_mbuf_from_mbuf(struct mbuf *oldmbuf, 1235 struct label *oldmbuflabel, struct mbuf *newmbuf, 1236 struct label *newmbuflabel) 1237{ 1238 struct mac_biba *source, *dest; 1239 1240 source = SLOT(oldmbuflabel); 1241 dest = SLOT(newmbuflabel); 1242 1243 /* 1244 * Because the source mbuf may not yet have been "created", 1245 * just initialized, we do a conditional copy. Since we don't 1246 * allow mbufs to have ranges, do a KASSERT to make sure that 1247 * doesn't happen. 1248 */ 1249 KASSERT((source->mb_flags & MAC_BIBA_FLAG_RANGE) == 0, 1250 ("mac_biba_create_mbuf_from_mbuf: source mbuf has range")); 1251 mac_biba_copy(source, dest); 1252} 1253 1254static void 1255mac_biba_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1256 struct mbuf *mbuf, struct label *mbuflabel) 1257{ 1258 struct mac_biba *dest; 1259 1260 dest = SLOT(mbuflabel); 1261 1262 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1263} 1264 1265static void 1266mac_biba_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1267 struct mbuf *mbuf, struct label *mbuflabel) 1268{ 1269 struct mac_biba *source, *dest; 1270 1271 source = SLOT(bpflabel); 1272 dest = SLOT(mbuflabel); 1273 1274 mac_biba_copy_single(source, dest); 1275} 1276 1277static void 1278mac_biba_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1279 struct mbuf *m, struct label *mbuflabel) 1280{ 1281 struct mac_biba *source, *dest; 1282 1283 source = SLOT(ifnetlabel); 1284 dest = SLOT(mbuflabel); 1285 1286 mac_biba_copy_single(source, dest); 1287} 1288 1289static void 1290mac_biba_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1291 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1292 struct mbuf *newmbuf, struct label *newmbuflabel) 1293{ 1294 struct mac_biba *source, *dest; 1295 1296 source = SLOT(oldmbuflabel); 1297 dest = SLOT(newmbuflabel); 1298 1299 mac_biba_copy_single(source, dest); 1300} 1301 1302static void 1303mac_biba_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1304 struct mbuf *newmbuf, struct label *newmbuflabel) 1305{ 1306 struct mac_biba *source, *dest; 1307 1308 source = SLOT(oldmbuflabel); 1309 dest = SLOT(newmbuflabel); 1310 1311 mac_biba_copy_single(source, dest); 1312} 1313 1314static int 1315mac_biba_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1316 struct ipq *ipq, struct label *ipqlabel) 1317{ 1318 struct mac_biba *a, *b; 1319 1320 a = SLOT(ipqlabel); 1321 b = SLOT(fragmentlabel); 1322 1323 return (mac_biba_equal_single(a, b)); 1324} 1325 1326static void 1327mac_biba_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1328 struct label *ifnetlabel, struct label *newlabel) 1329{ 1330 struct mac_biba *source, *dest; 1331 1332 source = SLOT(newlabel); 1333 dest = SLOT(ifnetlabel); 1334 1335 mac_biba_copy(source, dest); 1336} 1337 1338static void 1339mac_biba_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1340 struct ipq *ipq, struct label *ipqlabel) 1341{ 1342 1343 /* NOOP: we only accept matching labels, so no need to update */ 1344} 1345 1346/* 1347 * Labeling event operations: processes. 1348 */ 1349static void 1350mac_biba_create_cred(struct ucred *cred_parent, struct ucred *cred_child) 1351{ 1352 struct mac_biba *source, *dest; 1353 1354 source = SLOT(&cred_parent->cr_label); 1355 dest = SLOT(&cred_child->cr_label); 1356 1357 mac_biba_copy_single(source, dest); 1358 mac_biba_copy_range(source, dest); 1359} 1360 1361static void 1362mac_biba_execve_transition(struct ucred *old, struct ucred *new, 1363 struct vnode *vp, struct mac *vnodelabel) 1364{ 1365 struct mac_biba *source, *dest; 1366 1367 source = SLOT(&old->cr_label); 1368 dest = SLOT(&new->cr_label); 1369 1370 mac_biba_copy_single(source, dest); 1371 mac_biba_copy_range(source, dest); 1372} 1373 1374static int 1375mac_biba_execve_will_transition(struct ucred *old, struct vnode *vp, 1376 struct mac *vnodelabel) 1377{ 1378 1379 return (0); 1380} 1381 1382static void 1383mac_biba_create_proc0(struct ucred *cred) 1384{ 1385 struct mac_biba *dest; 1386 1387 dest = SLOT(&cred->cr_label); 1388 1389 mac_biba_set_single(dest, MAC_BIBA_TYPE_EQUAL, 0, NULL); 1390 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1391 MAC_BIBA_TYPE_HIGH, 0, NULL); 1392} 1393 1394static void 1395mac_biba_create_proc1(struct ucred *cred) 1396{ 1397 struct mac_biba *dest; 1398 1399 dest = SLOT(&cred->cr_label); 1400 1401 mac_biba_set_single(dest, MAC_BIBA_TYPE_HIGH, 0, NULL); 1402 mac_biba_set_range(dest, MAC_BIBA_TYPE_LOW, 0, NULL, 1403 MAC_BIBA_TYPE_HIGH, 0, NULL); 1404} 1405 1406static void 1407mac_biba_relabel_cred(struct ucred *cred, struct label *newlabel) 1408{ 1409 struct mac_biba *source, *dest; 1410 1411 source = SLOT(newlabel); 1412 dest = SLOT(&cred->cr_label); 1413 1414 mac_biba_copy(source, dest); 1415} 1416 1417/* 1418 * Access control checks. 1419 */ 1420static int 1421mac_biba_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1422 struct ifnet *ifnet, struct label *ifnetlabel) 1423{ 1424 struct mac_biba *a, *b; 1425 1426 if (!mac_biba_enabled) 1427 return (0); 1428 1429 a = SLOT(bpflabel); 1430 b = SLOT(ifnetlabel); 1431 1432 if (mac_biba_equal_single(a, b)) 1433 return (0); 1434 return (EACCES); 1435} 1436 1437static int 1438mac_biba_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1439{ 1440 struct mac_biba *subj, *new; 1441 int error; 1442 1443 subj = SLOT(&cred->cr_label); 1444 new = SLOT(newlabel); 1445 1446 /* 1447 * If there is a Biba label update for the credential, it may 1448 * be an update of the single, range, or both. 1449 */ 1450 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1451 if (error) 1452 return (error); 1453 1454 /* 1455 * If the Biba label is to be changed, authorize as appropriate. 1456 */ 1457 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1458 /* 1459 * To change the Biba single label on a credential, the 1460 * new single label must be in the current range. 1461 */ 1462 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE && 1463 !mac_biba_single_in_range(new, subj)) 1464 return (EPERM); 1465 1466 /* 1467 * To change the Biba range on a credential, the new 1468 * range label must be in the current range. 1469 */ 1470 if (new->mb_flags & MAC_BIBA_FLAG_RANGE && 1471 !mac_biba_range_in_range(new, subj)) 1472 return (EPERM); 1473 1474 /* 1475 * To have EQUAL in any component of the new credential 1476 * Biba label, the subject must already have EQUAL in 1477 * their label. 1478 */ 1479 if (mac_biba_contains_equal(new)) { 1480 error = mac_biba_subject_privileged(subj); 1481 if (error) 1482 return (error); 1483 } 1484 1485 /* 1486 * XXXMAC: Additional consistency tests regarding the 1487 * single and range of the new label might be performed 1488 * here. 1489 */ 1490 } 1491 1492 return (0); 1493} 1494 1495static int 1496mac_biba_check_cred_visible(struct ucred *u1, struct ucred *u2) 1497{ 1498 struct mac_biba *subj, *obj; 1499 1500 if (!mac_biba_enabled) 1501 return (0); 1502 1503 subj = SLOT(&u1->cr_label); 1504 obj = SLOT(&u2->cr_label); 1505 1506 /* XXX: range */ 1507 if (!mac_biba_dominate_single(obj, subj)) 1508 return (ESRCH); 1509 1510 return (0); 1511} 1512 1513static int 1514mac_biba_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1515 struct label *ifnetlabel, struct label *newlabel) 1516{ 1517 struct mac_biba *subj, *new; 1518 int error; 1519 1520 subj = SLOT(&cred->cr_label); 1521 new = SLOT(newlabel); 1522 1523 /* 1524 * If there is a Biba label update for the interface, it may 1525 * be an update of the single, range, or both. 1526 */ 1527 error = biba_atmostflags(new, MAC_BIBA_FLAGS_BOTH); 1528 if (error) 1529 return (error); 1530 1531 /* 1532 * If the Biba label is to be changed, authorize as appropriate. 1533 */ 1534 if (new->mb_flags & MAC_BIBA_FLAGS_BOTH) { 1535 /* 1536 * Rely on the traditional superuser status for the Biba 1537 * interface relabel requirements. XXXMAC: This will go 1538 * away. 1539 */ 1540 error = suser_cred(cred, 0); 1541 if (error) 1542 return (EPERM); 1543 1544 /* 1545 * XXXMAC: Additional consistency tests regarding the single 1546 * and the range of the new label might be performed here. 1547 */ 1548 } 1549 1550 return (0); 1551} 1552 1553static int 1554mac_biba_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1555 struct mbuf *m, struct label *mbuflabel) 1556{ 1557 struct mac_biba *p, *i; 1558 1559 if (!mac_biba_enabled) 1560 return (0); 1561 1562 p = SLOT(mbuflabel); 1563 i = SLOT(ifnetlabel); 1564 1565 return (mac_biba_single_in_range(p, i) ? 0 : EACCES); 1566} 1567 1568static int 1569mac_biba_check_mount_stat(struct ucred *cred, struct mount *mp, 1570 struct label *mntlabel) 1571{ 1572 struct mac_biba *subj, *obj; 1573 1574 if (!mac_biba_enabled) 1575 return (0); 1576 1577 subj = SLOT(&cred->cr_label); 1578 obj = SLOT(mntlabel); 1579 1580 if (!mac_biba_dominate_single(obj, subj)) 1581 return (EACCES); 1582 1583 return (0); 1584} 1585 1586static int 1587mac_biba_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, 1588 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1589{ 1590 1591 if(!mac_biba_enabled) 1592 return (0); 1593 1594 /* XXX: This will be implemented soon... */ 1595 1596 return (0); 1597} 1598 1599static int 1600mac_biba_check_pipe_poll(struct ucred *cred, struct pipe *pipe, 1601 struct label *pipelabel) 1602{ 1603 struct mac_biba *subj, *obj; 1604 1605 if (!mac_biba_enabled) 1606 return (0); 1607 1608 subj = SLOT(&cred->cr_label); 1609 obj = SLOT((pipelabel)); 1610 1611 if (!mac_biba_dominate_single(obj, subj)) 1612 return (EACCES); 1613 1614 return (0); 1615} 1616 1617static int 1618mac_biba_check_pipe_read(struct ucred *cred, struct pipe *pipe, 1619 struct label *pipelabel) 1620{ 1621 struct mac_biba *subj, *obj; 1622 1623 if (!mac_biba_enabled) 1624 return (0); 1625 1626 subj = SLOT(&cred->cr_label); 1627 obj = SLOT((pipelabel)); 1628 1629 if (!mac_biba_dominate_single(obj, subj)) 1630 return (EACCES); 1631 1632 return (0); 1633} 1634 1635static int 1636mac_biba_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 1637 struct label *pipelabel, struct label *newlabel) 1638{ 1639 struct mac_biba *subj, *obj, *new; 1640 int error; 1641 1642 new = SLOT(newlabel); 1643 subj = SLOT(&cred->cr_label); 1644 obj = SLOT(pipelabel); 1645 1646 /* 1647 * If there is a Biba label update for a pipe, it must be a 1648 * single update. 1649 */ 1650 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1651 if (error) 1652 return (error); 1653 1654 /* 1655 * To perform a relabel of a pipe (Biba label or not), Biba must 1656 * authorize the relabel. 1657 */ 1658 if (!mac_biba_single_in_range(obj, subj)) 1659 return (EPERM); 1660 1661 /* 1662 * If the Biba label is to be changed, authorize as appropriate. 1663 */ 1664 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1665 /* 1666 * To change the Biba label on a pipe, the new pipe label 1667 * must be in the subject range. 1668 */ 1669 if (!mac_biba_single_in_range(new, subj)) 1670 return (EPERM); 1671 1672 /* 1673 * To change the Biba label on a pipe to be EQUAL, the 1674 * subject must have appropriate privilege. 1675 */ 1676 if (mac_biba_contains_equal(new)) { 1677 error = mac_biba_subject_privileged(subj); 1678 if (error) 1679 return (error); 1680 } 1681 } 1682 1683 return (0); 1684} 1685 1686static int 1687mac_biba_check_pipe_stat(struct ucred *cred, struct pipe *pipe, 1688 struct label *pipelabel) 1689{ 1690 struct mac_biba *subj, *obj; 1691 1692 if (!mac_biba_enabled) 1693 return (0); 1694 1695 subj = SLOT(&cred->cr_label); 1696 obj = SLOT((pipelabel)); 1697 1698 if (!mac_biba_dominate_single(obj, subj)) 1699 return (EACCES); 1700 1701 return (0); 1702} 1703 1704static int 1705mac_biba_check_pipe_write(struct ucred *cred, struct pipe *pipe, 1706 struct label *pipelabel) 1707{ 1708 struct mac_biba *subj, *obj; 1709 1710 if (!mac_biba_enabled) 1711 return (0); 1712 1713 subj = SLOT(&cred->cr_label); 1714 obj = SLOT((pipelabel)); 1715 1716 if (!mac_biba_dominate_single(subj, obj)) 1717 return (EACCES); 1718 1719 return (0); 1720} 1721 1722static int 1723mac_biba_check_proc_debug(struct ucred *cred, struct proc *proc) 1724{ 1725 struct mac_biba *subj, *obj; 1726 1727 if (!mac_biba_enabled) 1728 return (0); 1729 1730 subj = SLOT(&cred->cr_label); 1731 obj = SLOT(&proc->p_ucred->cr_label); 1732 1733 /* XXX: range checks */ 1734 if (!mac_biba_dominate_single(obj, subj)) 1735 return (ESRCH); 1736 if (!mac_biba_dominate_single(subj, obj)) 1737 return (EACCES); 1738 1739 return (0); 1740} 1741 1742static int 1743mac_biba_check_proc_sched(struct ucred *cred, struct proc *proc) 1744{ 1745 struct mac_biba *subj, *obj; 1746 1747 if (!mac_biba_enabled) 1748 return (0); 1749 1750 subj = SLOT(&cred->cr_label); 1751 obj = SLOT(&proc->p_ucred->cr_label); 1752 1753 /* XXX: range checks */ 1754 if (!mac_biba_dominate_single(obj, subj)) 1755 return (ESRCH); 1756 if (!mac_biba_dominate_single(subj, obj)) 1757 return (EACCES); 1758 1759 return (0); 1760} 1761 1762static int 1763mac_biba_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1764{ 1765 struct mac_biba *subj, *obj; 1766 1767 if (!mac_biba_enabled) 1768 return (0); 1769 1770 subj = SLOT(&cred->cr_label); 1771 obj = SLOT(&proc->p_ucred->cr_label); 1772 1773 /* XXX: range checks */ 1774 if (!mac_biba_dominate_single(obj, subj)) 1775 return (ESRCH); 1776 if (!mac_biba_dominate_single(subj, obj)) 1777 return (EACCES); 1778 1779 return (0); 1780} 1781 1782static int 1783mac_biba_check_socket_deliver(struct socket *so, struct label *socketlabel, 1784 struct mbuf *m, struct label *mbuflabel) 1785{ 1786 struct mac_biba *p, *s; 1787 1788 if (!mac_biba_enabled) 1789 return (0); 1790 1791 p = SLOT(mbuflabel); 1792 s = SLOT(socketlabel); 1793 1794 return (mac_biba_equal_single(p, s) ? 0 : EACCES); 1795} 1796 1797static int 1798mac_biba_check_socket_relabel(struct ucred *cred, struct socket *socket, 1799 struct label *socketlabel, struct label *newlabel) 1800{ 1801 struct mac_biba *subj, *obj, *new; 1802 int error; 1803 1804 new = SLOT(newlabel); 1805 subj = SLOT(&cred->cr_label); 1806 obj = SLOT(socketlabel); 1807 1808 /* 1809 * If there is a Biba label update for the socket, it may be 1810 * an update of single. 1811 */ 1812 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 1813 if (error) 1814 return (error); 1815 1816 /* 1817 * To relabel a socket, the old socket single must be in the subject 1818 * range. 1819 */ 1820 if (!mac_biba_single_in_range(obj, subj)) 1821 return (EPERM); 1822 1823 /* 1824 * If the Biba label is to be changed, authorize as appropriate. 1825 */ 1826 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 1827 /* 1828 * To relabel a socket, the new socket single must be in 1829 * the subject range. 1830 */ 1831 if (!mac_biba_single_in_range(new, subj)) 1832 return (EPERM); 1833 1834 /* 1835 * To change the Biba label on the socket to contain EQUAL, 1836 * the subject must have appropriate privilege. 1837 */ 1838 if (mac_biba_contains_equal(new)) { 1839 error = mac_biba_subject_privileged(subj); 1840 if (error) 1841 return (error); 1842 } 1843 } 1844 1845 return (0); 1846} 1847 1848static int 1849mac_biba_check_socket_visible(struct ucred *cred, struct socket *socket, 1850 struct label *socketlabel) 1851{ 1852 struct mac_biba *subj, *obj; 1853 1854 if (!mac_biba_enabled) 1855 return (0); 1856 1857 subj = SLOT(&cred->cr_label); 1858 obj = SLOT(socketlabel); 1859 1860 if (!mac_biba_dominate_single(obj, subj)) 1861 return (ENOENT); 1862 1863 return (0); 1864} 1865 1866static int 1867mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1868 struct label *dlabel) 1869{ 1870 struct mac_biba *subj, *obj; 1871 1872 if (!mac_biba_enabled) 1873 return (0); 1874 1875 subj = SLOT(&cred->cr_label); 1876 obj = SLOT(dlabel); 1877 1878 if (!mac_biba_dominate_single(obj, subj)) 1879 return (EACCES); 1880 1881 return (0); 1882} 1883 1884static int 1885mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1886 struct label *dlabel) 1887{ 1888 struct mac_biba *subj, *obj; 1889 1890 if (!mac_biba_enabled) 1891 return (0); 1892 1893 subj = SLOT(&cred->cr_label); 1894 obj = SLOT(dlabel); 1895 1896 if (!mac_biba_dominate_single(obj, subj)) 1897 return (EACCES); 1898 1899 return (0); 1900} 1901 1902static int 1903mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1904 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1905{ 1906 struct mac_biba *subj, *obj; 1907 1908 if (!mac_biba_enabled) 1909 return (0); 1910 1911 subj = SLOT(&cred->cr_label); 1912 obj = SLOT(dlabel); 1913 1914 if (!mac_biba_dominate_single(subj, obj)) 1915 return (EACCES); 1916 1917 return (0); 1918} 1919 1920static int 1921mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1922 struct label *dlabel, struct vnode *vp, struct label *label, 1923 struct componentname *cnp) 1924{ 1925 struct mac_biba *subj, *obj; 1926 1927 if (!mac_biba_enabled) 1928 return (0); 1929 1930 subj = SLOT(&cred->cr_label); 1931 obj = SLOT(dlabel); 1932 1933 if (!mac_biba_dominate_single(subj, obj)) 1934 return (EACCES); 1935 1936 obj = SLOT(label); 1937 1938 if (!mac_biba_dominate_single(subj, obj)) 1939 return (EACCES); 1940 1941 return (0); 1942} 1943 1944static int 1945mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1946 struct label *label, acl_type_t type) 1947{ 1948 struct mac_biba *subj, *obj; 1949 1950 if (!mac_biba_enabled) 1951 return (0); 1952 1953 subj = SLOT(&cred->cr_label); 1954 obj = SLOT(label); 1955 1956 if (!mac_biba_dominate_single(subj, obj)) 1957 return (EACCES); 1958 1959 return (0); 1960} 1961 1962static int 1963mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1964 struct label *label) 1965{ 1966 struct mac_biba *subj, *obj; 1967 1968 if (!mac_biba_enabled) 1969 return (0); 1970 1971 subj = SLOT(&cred->cr_label); 1972 obj = SLOT(label); 1973 1974 if (!mac_biba_dominate_single(obj, subj)) 1975 return (EACCES); 1976 1977 return (0); 1978} 1979 1980static int 1981mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 1982 struct label *label, acl_type_t type) 1983{ 1984 struct mac_biba *subj, *obj; 1985 1986 if (!mac_biba_enabled) 1987 return (0); 1988 1989 subj = SLOT(&cred->cr_label); 1990 obj = SLOT(label); 1991 1992 if (!mac_biba_dominate_single(obj, subj)) 1993 return (EACCES); 1994 1995 return (0); 1996} 1997 1998static int 1999mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 2000 struct label *label, int attrnamespace, const char *name, struct uio *uio) 2001{ 2002 struct mac_biba *subj, *obj; 2003 2004 if (!mac_biba_enabled) 2005 return (0); 2006 2007 subj = SLOT(&cred->cr_label); 2008 obj = SLOT(label); 2009 2010 if (!mac_biba_dominate_single(obj, subj)) 2011 return (EACCES); 2012 2013 return (0); 2014} 2015 2016static int 2017mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2018 struct label *dlabel, struct vnode *vp, struct label *label, 2019 struct componentname *cnp) 2020{ 2021 struct mac_biba *subj, *obj; 2022 2023 if (!mac_biba_enabled) 2024 return (0); 2025 2026 subj = SLOT(&cred->cr_label); 2027 obj = SLOT(dlabel); 2028 2029 if (!mac_biba_dominate_single(subj, obj)) 2030 return (EACCES); 2031 2032 obj = SLOT(label); 2033 2034 if (!mac_biba_dominate_single(subj, obj)) 2035 return (EACCES); 2036 2037 return (0); 2038} 2039 2040static int 2041mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 2042 struct label *dlabel, struct componentname *cnp) 2043{ 2044 struct mac_biba *subj, *obj; 2045 2046 if (!mac_biba_enabled) 2047 return (0); 2048 2049 subj = SLOT(&cred->cr_label); 2050 obj = SLOT(dlabel); 2051 2052 if (!mac_biba_dominate_single(obj, subj)) 2053 return (EACCES); 2054 2055 return (0); 2056} 2057 2058static int 2059mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2060 struct label *label, int prot) 2061{ 2062 struct mac_biba *subj, *obj; 2063 2064 /* 2065 * Rely on the use of open()-time protections to handle 2066 * non-revocation cases. 2067 */ 2068 if (!mac_biba_enabled || !revocation_enabled) 2069 return (0); 2070 2071 subj = SLOT(&cred->cr_label); 2072 obj = SLOT(label); 2073 2074 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2075 if (!mac_biba_dominate_single(obj, subj)) 2076 return (EACCES); 2077 } 2078 if (prot & VM_PROT_WRITE) { 2079 if (!mac_biba_dominate_single(subj, obj)) 2080 return (EACCES); 2081 } 2082 2083 return (0); 2084} 2085 2086static int 2087mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2088 struct label *vnodelabel, mode_t acc_mode) 2089{ 2090 struct mac_biba *subj, *obj; 2091 2092 if (!mac_biba_enabled) 2093 return (0); 2094 2095 subj = SLOT(&cred->cr_label); 2096 obj = SLOT(vnodelabel); 2097 2098 /* XXX privilege override for admin? */ 2099 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2100 if (!mac_biba_dominate_single(obj, subj)) 2101 return (EACCES); 2102 } 2103 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2104 if (!mac_biba_dominate_single(subj, obj)) 2105 return (EACCES); 2106 } 2107 2108 return (0); 2109} 2110 2111static int 2112mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2113 struct vnode *vp, struct label *label) 2114{ 2115 struct mac_biba *subj, *obj; 2116 2117 if (!mac_biba_enabled || !revocation_enabled) 2118 return (0); 2119 2120 subj = SLOT(&active_cred->cr_label); 2121 obj = SLOT(label); 2122 2123 if (!mac_biba_dominate_single(obj, subj)) 2124 return (EACCES); 2125 2126 return (0); 2127} 2128 2129static int 2130mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2131 struct vnode *vp, struct label *label) 2132{ 2133 struct mac_biba *subj, *obj; 2134 2135 if (!mac_biba_enabled || !revocation_enabled) 2136 return (0); 2137 2138 subj = SLOT(&active_cred->cr_label); 2139 obj = SLOT(label); 2140 2141 if (!mac_biba_dominate_single(obj, subj)) 2142 return (EACCES); 2143 2144 return (0); 2145} 2146 2147static int 2148mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2149 struct label *dlabel) 2150{ 2151 struct mac_biba *subj, *obj; 2152 2153 if (!mac_biba_enabled) 2154 return (0); 2155 2156 subj = SLOT(&cred->cr_label); 2157 obj = SLOT(dlabel); 2158 2159 if (!mac_biba_dominate_single(obj, subj)) 2160 return (EACCES); 2161 2162 return (0); 2163} 2164 2165static int 2166mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2167 struct label *label) 2168{ 2169 struct mac_biba *subj, *obj; 2170 2171 if (!mac_biba_enabled) 2172 return (0); 2173 2174 subj = SLOT(&cred->cr_label); 2175 obj = SLOT(label); 2176 2177 if (!mac_biba_dominate_single(obj, subj)) 2178 return (EACCES); 2179 2180 return (0); 2181} 2182 2183static int 2184mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2185 struct label *vnodelabel, struct label *newlabel) 2186{ 2187 struct mac_biba *old, *new, *subj; 2188 int error; 2189 2190 old = SLOT(vnodelabel); 2191 new = SLOT(newlabel); 2192 subj = SLOT(&cred->cr_label); 2193 2194 /* 2195 * If there is a Biba label update for the vnode, it must be a 2196 * single label. 2197 */ 2198 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2199 if (error) 2200 return (error); 2201 2202 /* 2203 * To perform a relabel of the vnode (Biba label or not), Biba must 2204 * authorize the relabel. 2205 */ 2206 if (!mac_biba_single_in_range(old, subj)) 2207 return (EPERM); 2208 2209 /* 2210 * If the Biba label is to be changed, authorize as appropriate. 2211 */ 2212 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2213 /* 2214 * To change the Biba label on a vnode, the new vnode label 2215 * must be in the subject range. 2216 */ 2217 if (!mac_biba_single_in_range(new, subj)) 2218 return (EPERM); 2219 2220 /* 2221 * To change the Biba label on the vnode to be EQUAL, 2222 * the subject must have appropriate privilege. 2223 */ 2224 if (mac_biba_contains_equal(new)) { 2225 error = mac_biba_subject_privileged(subj); 2226 if (error) 2227 return (error); 2228 } 2229 } 2230 2231 return (0); 2232} 2233 2234static int 2235mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2236 struct label *dlabel, struct vnode *vp, struct label *label, 2237 struct componentname *cnp) 2238{ 2239 struct mac_biba *subj, *obj; 2240 2241 if (!mac_biba_enabled) 2242 return (0); 2243 2244 subj = SLOT(&cred->cr_label); 2245 obj = SLOT(dlabel); 2246 2247 if (!mac_biba_dominate_single(subj, obj)) 2248 return (EACCES); 2249 2250 obj = SLOT(label); 2251 2252 if (!mac_biba_dominate_single(subj, obj)) 2253 return (EACCES); 2254 2255 return (0); 2256} 2257 2258static int 2259mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2260 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2261 struct componentname *cnp) 2262{ 2263 struct mac_biba *subj, *obj; 2264 2265 if (!mac_biba_enabled) 2266 return (0); 2267 2268 subj = SLOT(&cred->cr_label); 2269 obj = SLOT(dlabel); 2270 2271 if (!mac_biba_dominate_single(subj, obj)) 2272 return (EACCES); 2273 2274 if (vp != NULL) { 2275 obj = SLOT(label); 2276 2277 if (!mac_biba_dominate_single(subj, obj)) 2278 return (EACCES); 2279 } 2280 2281 return (0); 2282} 2283 2284static int 2285mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2286 struct label *label) 2287{ 2288 struct mac_biba *subj, *obj; 2289 2290 if (!mac_biba_enabled) 2291 return (0); 2292 2293 subj = SLOT(&cred->cr_label); 2294 obj = SLOT(label); 2295 2296 if (!mac_biba_dominate_single(subj, obj)) 2297 return (EACCES); 2298 2299 return (0); 2300} 2301 2302static int 2303mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2304 struct label *label, acl_type_t type, struct acl *acl) 2305{ 2306 struct mac_biba *subj, *obj; 2307 2308 if (!mac_biba_enabled) 2309 return (0); 2310 2311 subj = SLOT(&cred->cr_label); 2312 obj = SLOT(label); 2313 2314 if (!mac_biba_dominate_single(subj, obj)) 2315 return (EACCES); 2316 2317 return (0); 2318} 2319 2320static int 2321mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2322 struct label *vnodelabel, int attrnamespace, const char *name, 2323 struct uio *uio) 2324{ 2325 struct mac_biba *subj, *obj; 2326 2327 if (!mac_biba_enabled) 2328 return (0); 2329 2330 subj = SLOT(&cred->cr_label); 2331 obj = SLOT(vnodelabel); 2332 2333 if (!mac_biba_dominate_single(subj, obj)) 2334 return (EACCES); 2335 2336 /* XXX: protect the MAC EA in a special way? */ 2337 2338 return (0); 2339} 2340 2341static int 2342mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2343 struct label *vnodelabel, u_long flags) 2344{ 2345 struct mac_biba *subj, *obj; 2346 2347 if (!mac_biba_enabled) 2348 return (0); 2349 2350 subj = SLOT(&cred->cr_label); 2351 obj = SLOT(vnodelabel); 2352 2353 if (!mac_biba_dominate_single(subj, obj)) 2354 return (EACCES); 2355 2356 return (0); 2357} 2358 2359static int 2360mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2361 struct label *vnodelabel, mode_t mode) 2362{ 2363 struct mac_biba *subj, *obj; 2364 2365 if (!mac_biba_enabled) 2366 return (0); 2367 2368 subj = SLOT(&cred->cr_label); 2369 obj = SLOT(vnodelabel); 2370 2371 if (!mac_biba_dominate_single(subj, obj)) 2372 return (EACCES); 2373 2374 return (0); 2375} 2376 2377static int 2378mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2379 struct label *vnodelabel, uid_t uid, gid_t gid) 2380{ 2381 struct mac_biba *subj, *obj; 2382 2383 if (!mac_biba_enabled) 2384 return (0); 2385 2386 subj = SLOT(&cred->cr_label); 2387 obj = SLOT(vnodelabel); 2388 2389 if (!mac_biba_dominate_single(subj, obj)) 2390 return (EACCES); 2391 2392 return (0); 2393} 2394 2395static int 2396mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2397 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2398{ 2399 struct mac_biba *subj, *obj; 2400 2401 if (!mac_biba_enabled) 2402 return (0); 2403 2404 subj = SLOT(&cred->cr_label); 2405 obj = SLOT(vnodelabel); 2406 2407 if (!mac_biba_dominate_single(subj, obj)) 2408 return (EACCES); 2409 2410 return (0); 2411} 2412 2413static int 2414mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2415 struct vnode *vp, struct label *vnodelabel) 2416{ 2417 struct mac_biba *subj, *obj; 2418 2419 if (!mac_biba_enabled) 2420 return (0); 2421 2422 subj = SLOT(&active_cred->cr_label); 2423 obj = SLOT(vnodelabel); 2424 2425 if (!mac_biba_dominate_single(obj, subj)) 2426 return (EACCES); 2427 2428 return (0); 2429} 2430 2431static int 2432mac_biba_check_vnode_write(struct ucred *active_cred, 2433 struct ucred *file_cred, struct vnode *vp, struct label *label) 2434{ 2435 struct mac_biba *subj, *obj; 2436 2437 if (!mac_biba_enabled || !revocation_enabled) 2438 return (0); 2439 2440 subj = SLOT(&active_cred->cr_label); 2441 obj = SLOT(label); 2442 2443 if (!mac_biba_dominate_single(subj, obj)) 2444 return (EACCES); 2445 2446 return (0); 2447} 2448 2449static struct mac_policy_op_entry mac_biba_ops[] = 2450{ 2451 { MAC_DESTROY, 2452 (macop_t)mac_biba_destroy }, 2453 { MAC_INIT, 2454 (macop_t)mac_biba_init }, 2455 { MAC_INIT_BPFDESC_LABEL, 2456 (macop_t)mac_biba_init_label }, 2457 { MAC_INIT_CRED_LABEL, 2458 (macop_t)mac_biba_init_label }, 2459 { MAC_INIT_DEVFSDIRENT_LABEL, 2460 (macop_t)mac_biba_init_label }, 2461 { MAC_INIT_IFNET_LABEL, 2462 (macop_t)mac_biba_init_label }, 2463 { MAC_INIT_IPQ_LABEL, 2464 (macop_t)mac_biba_init_label }, 2465 { MAC_INIT_MBUF_LABEL, 2466 (macop_t)mac_biba_init_label_waitcheck }, 2467 { MAC_INIT_MOUNT_LABEL, 2468 (macop_t)mac_biba_init_label }, 2469 { MAC_INIT_MOUNT_FS_LABEL, 2470 (macop_t)mac_biba_init_label }, 2471 { MAC_INIT_PIPE_LABEL, 2472 (macop_t)mac_biba_init_label }, 2473 { MAC_INIT_SOCKET_LABEL, 2474 (macop_t)mac_biba_init_label_waitcheck }, 2475 { MAC_INIT_SOCKET_PEER_LABEL, 2476 (macop_t)mac_biba_init_label_waitcheck }, 2477 { MAC_INIT_VNODE_LABEL, 2478 (macop_t)mac_biba_init_label }, 2479 { MAC_DESTROY_BPFDESC_LABEL, 2480 (macop_t)mac_biba_destroy_label }, 2481 { MAC_DESTROY_CRED_LABEL, 2482 (macop_t)mac_biba_destroy_label }, 2483 { MAC_DESTROY_DEVFSDIRENT_LABEL, 2484 (macop_t)mac_biba_destroy_label }, 2485 { MAC_DESTROY_IFNET_LABEL, 2486 (macop_t)mac_biba_destroy_label }, 2487 { MAC_DESTROY_IPQ_LABEL, 2488 (macop_t)mac_biba_destroy_label }, 2489 { MAC_DESTROY_MBUF_LABEL, 2490 (macop_t)mac_biba_destroy_label }, 2491 { MAC_DESTROY_MOUNT_LABEL, 2492 (macop_t)mac_biba_destroy_label }, 2493 { MAC_DESTROY_MOUNT_FS_LABEL, 2494 (macop_t)mac_biba_destroy_label }, 2495 { MAC_DESTROY_PIPE_LABEL, 2496 (macop_t)mac_biba_destroy_label }, 2497 { MAC_DESTROY_SOCKET_LABEL, 2498 (macop_t)mac_biba_destroy_label }, 2499 { MAC_DESTROY_SOCKET_PEER_LABEL, 2500 (macop_t)mac_biba_destroy_label }, 2501 { MAC_DESTROY_VNODE_LABEL, 2502 (macop_t)mac_biba_destroy_label }, 2503 { MAC_COPY_PIPE_LABEL, 2504 (macop_t)mac_biba_copy_label }, 2505 { MAC_COPY_VNODE_LABEL, 2506 (macop_t)mac_biba_copy_label }, 2507 { MAC_EXTERNALIZE_CRED_LABEL, 2508 (macop_t)mac_biba_externalize_label }, 2509 { MAC_EXTERNALIZE_IFNET_LABEL, 2510 (macop_t)mac_biba_externalize_label }, 2511 { MAC_EXTERNALIZE_PIPE_LABEL, 2512 (macop_t)mac_biba_externalize_label }, 2513 { MAC_EXTERNALIZE_SOCKET_LABEL, 2514 (macop_t)mac_biba_externalize_label }, 2515 { MAC_EXTERNALIZE_SOCKET_PEER_LABEL, 2516 (macop_t)mac_biba_externalize_label }, 2517 { MAC_EXTERNALIZE_VNODE_LABEL, 2518 (macop_t)mac_biba_externalize_label }, 2519 { MAC_INTERNALIZE_CRED_LABEL, 2520 (macop_t)mac_biba_internalize_label }, 2521 { MAC_INTERNALIZE_IFNET_LABEL, 2522 (macop_t)mac_biba_internalize_label }, 2523 { MAC_INTERNALIZE_PIPE_LABEL, 2524 (macop_t)mac_biba_internalize_label }, 2525 { MAC_INTERNALIZE_SOCKET_LABEL, 2526 (macop_t)mac_biba_internalize_label }, 2527 { MAC_INTERNALIZE_VNODE_LABEL, 2528 (macop_t)mac_biba_internalize_label }, 2529 { MAC_CREATE_DEVFS_DEVICE, 2530 (macop_t)mac_biba_create_devfs_device }, 2531 { MAC_CREATE_DEVFS_DIRECTORY, 2532 (macop_t)mac_biba_create_devfs_directory }, 2533 { MAC_CREATE_DEVFS_SYMLINK, 2534 (macop_t)mac_biba_create_devfs_symlink }, 2535 { MAC_CREATE_DEVFS_VNODE, 2536 (macop_t)mac_biba_create_devfs_vnode }, 2537 { MAC_CREATE_MOUNT, 2538 (macop_t)mac_biba_create_mount }, 2539 { MAC_CREATE_ROOT_MOUNT, 2540 (macop_t)mac_biba_create_root_mount }, 2541 { MAC_RELABEL_VNODE, 2542 (macop_t)mac_biba_relabel_vnode }, 2543 { MAC_UPDATE_DEVFSDIRENT, 2544 (macop_t)mac_biba_update_devfsdirent }, 2545 { MAC_ASSOCIATE_VNODE_DEVFS, 2546 (macop_t)mac_biba_associate_vnode_devfs }, 2547 { MAC_ASSOCIATE_VNODE_EXTATTR, 2548 (macop_t)mac_biba_associate_vnode_extattr }, 2549 { MAC_ASSOCIATE_VNODE_SINGLELABEL, 2550 (macop_t)mac_biba_associate_vnode_singlelabel }, 2551 { MAC_CREATE_VNODE_EXTATTR, 2552 (macop_t)mac_biba_create_vnode_extattr }, 2553 { MAC_SETLABEL_VNODE_EXTATTR, 2554 (macop_t)mac_biba_setlabel_vnode_extattr }, 2555 { MAC_CREATE_MBUF_FROM_SOCKET, 2556 (macop_t)mac_biba_create_mbuf_from_socket }, 2557 { MAC_CREATE_PIPE, 2558 (macop_t)mac_biba_create_pipe }, 2559 { MAC_CREATE_SOCKET, 2560 (macop_t)mac_biba_create_socket }, 2561 { MAC_CREATE_SOCKET_FROM_SOCKET, 2562 (macop_t)mac_biba_create_socket_from_socket }, 2563 { MAC_RELABEL_PIPE, 2564 (macop_t)mac_biba_relabel_pipe }, 2565 { MAC_RELABEL_SOCKET, 2566 (macop_t)mac_biba_relabel_socket }, 2567 { MAC_SET_SOCKET_PEER_FROM_MBUF, 2568 (macop_t)mac_biba_set_socket_peer_from_mbuf }, 2569 { MAC_SET_SOCKET_PEER_FROM_SOCKET, 2570 (macop_t)mac_biba_set_socket_peer_from_socket }, 2571 { MAC_CREATE_BPFDESC, 2572 (macop_t)mac_biba_create_bpfdesc }, 2573 { MAC_CREATE_DATAGRAM_FROM_IPQ, 2574 (macop_t)mac_biba_create_datagram_from_ipq }, 2575 { MAC_CREATE_FRAGMENT, 2576 (macop_t)mac_biba_create_fragment }, 2577 { MAC_CREATE_IFNET, 2578 (macop_t)mac_biba_create_ifnet }, 2579 { MAC_CREATE_IPQ, 2580 (macop_t)mac_biba_create_ipq }, 2581 { MAC_CREATE_MBUF_FROM_MBUF, 2582 (macop_t)mac_biba_create_mbuf_from_mbuf }, 2583 { MAC_CREATE_MBUF_LINKLAYER, 2584 (macop_t)mac_biba_create_mbuf_linklayer }, 2585 { MAC_CREATE_MBUF_FROM_BPFDESC, 2586 (macop_t)mac_biba_create_mbuf_from_bpfdesc }, 2587 { MAC_CREATE_MBUF_FROM_IFNET, 2588 (macop_t)mac_biba_create_mbuf_from_ifnet }, 2589 { MAC_CREATE_MBUF_MULTICAST_ENCAP, 2590 (macop_t)mac_biba_create_mbuf_multicast_encap }, 2591 { MAC_CREATE_MBUF_NETLAYER, 2592 (macop_t)mac_biba_create_mbuf_netlayer }, 2593 { MAC_FRAGMENT_MATCH, 2594 (macop_t)mac_biba_fragment_match }, 2595 { MAC_RELABEL_IFNET, 2596 (macop_t)mac_biba_relabel_ifnet }, 2597 { MAC_UPDATE_IPQ, 2598 (macop_t)mac_biba_update_ipq }, 2599 { MAC_CREATE_CRED, 2600 (macop_t)mac_biba_create_cred }, 2601 { MAC_EXECVE_TRANSITION, 2602 (macop_t)mac_biba_execve_transition }, 2603 { MAC_EXECVE_WILL_TRANSITION, 2604 (macop_t)mac_biba_execve_will_transition }, 2605 { MAC_CREATE_PROC0, 2606 (macop_t)mac_biba_create_proc0 }, 2607 { MAC_CREATE_PROC1, 2608 (macop_t)mac_biba_create_proc1 }, 2609 { MAC_RELABEL_CRED, 2610 (macop_t)mac_biba_relabel_cred }, 2611 { MAC_CHECK_BPFDESC_RECEIVE, 2612 (macop_t)mac_biba_check_bpfdesc_receive }, 2613 { MAC_CHECK_CRED_RELABEL, 2614 (macop_t)mac_biba_check_cred_relabel }, 2615 { MAC_CHECK_CRED_VISIBLE, 2616 (macop_t)mac_biba_check_cred_visible }, 2617 { MAC_CHECK_IFNET_RELABEL, 2618 (macop_t)mac_biba_check_ifnet_relabel }, 2619 { MAC_CHECK_IFNET_TRANSMIT, 2620 (macop_t)mac_biba_check_ifnet_transmit }, 2621 { MAC_CHECK_MOUNT_STAT, 2622 (macop_t)mac_biba_check_mount_stat }, 2623 { MAC_CHECK_PIPE_IOCTL, 2624 (macop_t)mac_biba_check_pipe_ioctl }, 2625 { MAC_CHECK_PIPE_POLL, 2626 (macop_t)mac_biba_check_pipe_poll }, 2627 { MAC_CHECK_PIPE_READ, 2628 (macop_t)mac_biba_check_pipe_read }, 2629 { MAC_CHECK_PIPE_RELABEL, 2630 (macop_t)mac_biba_check_pipe_relabel }, 2631 { MAC_CHECK_PIPE_STAT, 2632 (macop_t)mac_biba_check_pipe_stat }, 2633 { MAC_CHECK_PIPE_WRITE, 2634 (macop_t)mac_biba_check_pipe_write }, 2635 { MAC_CHECK_PROC_DEBUG, 2636 (macop_t)mac_biba_check_proc_debug }, 2637 { MAC_CHECK_PROC_SCHED, 2638 (macop_t)mac_biba_check_proc_sched }, 2639 { MAC_CHECK_PROC_SIGNAL, 2640 (macop_t)mac_biba_check_proc_signal }, 2641 { MAC_CHECK_SOCKET_DELIVER, 2642 (macop_t)mac_biba_check_socket_deliver }, 2643 { MAC_CHECK_SOCKET_RELABEL, 2644 (macop_t)mac_biba_check_socket_relabel }, 2645 { MAC_CHECK_SOCKET_VISIBLE, 2646 (macop_t)mac_biba_check_socket_visible }, 2647 { MAC_CHECK_VNODE_ACCESS, 2648 (macop_t)mac_biba_check_vnode_open }, 2649 { MAC_CHECK_VNODE_CHDIR, 2650 (macop_t)mac_biba_check_vnode_chdir }, 2651 { MAC_CHECK_VNODE_CHROOT, 2652 (macop_t)mac_biba_check_vnode_chroot }, 2653 { MAC_CHECK_VNODE_CREATE, 2654 (macop_t)mac_biba_check_vnode_create }, 2655 { MAC_CHECK_VNODE_DELETE, 2656 (macop_t)mac_biba_check_vnode_delete }, 2657 { MAC_CHECK_VNODE_DELETEACL, 2658 (macop_t)mac_biba_check_vnode_deleteacl }, 2659 { MAC_CHECK_VNODE_EXEC, 2660 (macop_t)mac_biba_check_vnode_exec }, 2661 { MAC_CHECK_VNODE_GETACL, 2662 (macop_t)mac_biba_check_vnode_getacl }, 2663 { MAC_CHECK_VNODE_GETEXTATTR, 2664 (macop_t)mac_biba_check_vnode_getextattr }, 2665 { MAC_CHECK_VNODE_LINK, 2666 (macop_t)mac_biba_check_vnode_link }, 2667 { MAC_CHECK_VNODE_LOOKUP, 2668 (macop_t)mac_biba_check_vnode_lookup }, 2669 { MAC_CHECK_VNODE_MMAP, 2670 (macop_t)mac_biba_check_vnode_mmap }, 2671 { MAC_CHECK_VNODE_MPROTECT, 2672 (macop_t)mac_biba_check_vnode_mmap }, 2673 { MAC_CHECK_VNODE_OPEN, 2674 (macop_t)mac_biba_check_vnode_open }, 2675 { MAC_CHECK_VNODE_POLL, 2676 (macop_t)mac_biba_check_vnode_poll }, 2677 { MAC_CHECK_VNODE_READ, 2678 (macop_t)mac_biba_check_vnode_read }, 2679 { MAC_CHECK_VNODE_READDIR, 2680 (macop_t)mac_biba_check_vnode_readdir }, 2681 { MAC_CHECK_VNODE_READLINK, 2682 (macop_t)mac_biba_check_vnode_readlink }, 2683 { MAC_CHECK_VNODE_RELABEL, 2684 (macop_t)mac_biba_check_vnode_relabel }, 2685 { MAC_CHECK_VNODE_RENAME_FROM, 2686 (macop_t)mac_biba_check_vnode_rename_from }, 2687 { MAC_CHECK_VNODE_RENAME_TO, 2688 (macop_t)mac_biba_check_vnode_rename_to }, 2689 { MAC_CHECK_VNODE_REVOKE, 2690 (macop_t)mac_biba_check_vnode_revoke }, 2691 { MAC_CHECK_VNODE_SETACL, 2692 (macop_t)mac_biba_check_vnode_setacl }, 2693 { MAC_CHECK_VNODE_SETEXTATTR, 2694 (macop_t)mac_biba_check_vnode_setextattr }, 2695 { MAC_CHECK_VNODE_SETFLAGS, 2696 (macop_t)mac_biba_check_vnode_setflags }, 2697 { MAC_CHECK_VNODE_SETMODE, 2698 (macop_t)mac_biba_check_vnode_setmode }, 2699 { MAC_CHECK_VNODE_SETOWNER, 2700 (macop_t)mac_biba_check_vnode_setowner }, 2701 { MAC_CHECK_VNODE_SETUTIMES, 2702 (macop_t)mac_biba_check_vnode_setutimes }, 2703 { MAC_CHECK_VNODE_STAT, 2704 (macop_t)mac_biba_check_vnode_stat }, 2705 { MAC_CHECK_VNODE_WRITE, 2706 (macop_t)mac_biba_check_vnode_write }, 2707 { MAC_OP_LAST, NULL } 2708}; 2709 2710MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2711 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot); 2712