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