mac_biba.c revision 105696
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 105696 2002-10-22 14:31:34Z 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 subj = SLOT(&cred->cr_label); 1789 obj = SLOT(socketlabel); 1790 1791 if (!mac_biba_dominate_single(obj, subj)) 1792 return (ENOENT); 1793 1794 return (0); 1795} 1796 1797static int 1798mac_biba_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 1799 struct label *dlabel) 1800{ 1801 struct mac_biba *subj, *obj; 1802 1803 if (!mac_biba_enabled) 1804 return (0); 1805 1806 subj = SLOT(&cred->cr_label); 1807 obj = SLOT(dlabel); 1808 1809 if (!mac_biba_dominate_single(obj, subj)) 1810 return (EACCES); 1811 1812 return (0); 1813} 1814 1815static int 1816mac_biba_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 1817 struct label *dlabel) 1818{ 1819 struct mac_biba *subj, *obj; 1820 1821 if (!mac_biba_enabled) 1822 return (0); 1823 1824 subj = SLOT(&cred->cr_label); 1825 obj = SLOT(dlabel); 1826 1827 if (!mac_biba_dominate_single(obj, subj)) 1828 return (EACCES); 1829 1830 return (0); 1831} 1832 1833static int 1834mac_biba_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1835 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 1836{ 1837 struct mac_biba *subj, *obj; 1838 1839 if (!mac_biba_enabled) 1840 return (0); 1841 1842 subj = SLOT(&cred->cr_label); 1843 obj = SLOT(dlabel); 1844 1845 if (!mac_biba_dominate_single(subj, obj)) 1846 return (EACCES); 1847 1848 return (0); 1849} 1850 1851static int 1852mac_biba_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 1853 struct label *dlabel, struct vnode *vp, struct label *label, 1854 struct componentname *cnp) 1855{ 1856 struct mac_biba *subj, *obj; 1857 1858 if (!mac_biba_enabled) 1859 return (0); 1860 1861 subj = SLOT(&cred->cr_label); 1862 obj = SLOT(dlabel); 1863 1864 if (!mac_biba_dominate_single(subj, obj)) 1865 return (EACCES); 1866 1867 obj = SLOT(label); 1868 1869 if (!mac_biba_dominate_single(subj, obj)) 1870 return (EACCES); 1871 1872 return (0); 1873} 1874 1875static int 1876mac_biba_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1877 struct label *label, acl_type_t type) 1878{ 1879 struct mac_biba *subj, *obj; 1880 1881 if (!mac_biba_enabled) 1882 return (0); 1883 1884 subj = SLOT(&cred->cr_label); 1885 obj = SLOT(label); 1886 1887 if (!mac_biba_dominate_single(subj, obj)) 1888 return (EACCES); 1889 1890 return (0); 1891} 1892 1893static int 1894mac_biba_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1895 struct label *label) 1896{ 1897 struct mac_biba *subj, *obj; 1898 1899 if (!mac_biba_enabled) 1900 return (0); 1901 1902 subj = SLOT(&cred->cr_label); 1903 obj = SLOT(label); 1904 1905 if (!mac_biba_dominate_single(obj, subj)) 1906 return (EACCES); 1907 1908 return (0); 1909} 1910 1911static int 1912mac_biba_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 1913 struct label *label, acl_type_t type) 1914{ 1915 struct mac_biba *subj, *obj; 1916 1917 if (!mac_biba_enabled) 1918 return (0); 1919 1920 subj = SLOT(&cred->cr_label); 1921 obj = SLOT(label); 1922 1923 if (!mac_biba_dominate_single(obj, subj)) 1924 return (EACCES); 1925 1926 return (0); 1927} 1928 1929static int 1930mac_biba_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1931 struct label *label, int attrnamespace, const char *name, struct uio *uio) 1932{ 1933 struct mac_biba *subj, *obj; 1934 1935 if (!mac_biba_enabled) 1936 return (0); 1937 1938 subj = SLOT(&cred->cr_label); 1939 obj = SLOT(label); 1940 1941 if (!mac_biba_dominate_single(obj, subj)) 1942 return (EACCES); 1943 1944 return (0); 1945} 1946 1947static int 1948mac_biba_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1949 struct label *dlabel, struct vnode *vp, struct label *label, 1950 struct componentname *cnp) 1951{ 1952 struct mac_biba *subj, *obj; 1953 1954 if (!mac_biba_enabled) 1955 return (0); 1956 1957 subj = SLOT(&cred->cr_label); 1958 obj = SLOT(dlabel); 1959 1960 if (!mac_biba_dominate_single(subj, obj)) 1961 return (EACCES); 1962 1963 obj = SLOT(label); 1964 1965 if (!mac_biba_dominate_single(subj, obj)) 1966 return (EACCES); 1967 1968 return (0); 1969} 1970 1971static int 1972mac_biba_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1973 struct label *dlabel, struct componentname *cnp) 1974{ 1975 struct mac_biba *subj, *obj; 1976 1977 if (!mac_biba_enabled) 1978 return (0); 1979 1980 subj = SLOT(&cred->cr_label); 1981 obj = SLOT(dlabel); 1982 1983 if (!mac_biba_dominate_single(obj, subj)) 1984 return (EACCES); 1985 1986 return (0); 1987} 1988 1989static int 1990mac_biba_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 1991 struct label *label, int prot) 1992{ 1993 struct mac_biba *subj, *obj; 1994 1995 /* 1996 * Rely on the use of open()-time protections to handle 1997 * non-revocation cases. 1998 */ 1999 if (!mac_biba_enabled || !revocation_enabled) 2000 return (0); 2001 2002 subj = SLOT(&cred->cr_label); 2003 obj = SLOT(label); 2004 2005 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2006 if (!mac_biba_dominate_single(obj, subj)) 2007 return (EACCES); 2008 } 2009 if (prot & VM_PROT_WRITE) { 2010 if (!mac_biba_dominate_single(subj, obj)) 2011 return (EACCES); 2012 } 2013 2014 return (0); 2015} 2016 2017static int 2018mac_biba_check_vnode_open(struct ucred *cred, struct vnode *vp, 2019 struct label *vnodelabel, mode_t acc_mode) 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(vnodelabel); 2028 2029 /* XXX privilege override for admin? */ 2030 if (acc_mode & (VREAD | VEXEC | VSTAT)) { 2031 if (!mac_biba_dominate_single(obj, subj)) 2032 return (EACCES); 2033 } 2034 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2035 if (!mac_biba_dominate_single(subj, obj)) 2036 return (EACCES); 2037 } 2038 2039 return (0); 2040} 2041 2042static int 2043mac_biba_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 2044 struct vnode *vp, struct label *label) 2045{ 2046 struct mac_biba *subj, *obj; 2047 2048 if (!mac_biba_enabled || !revocation_enabled) 2049 return (0); 2050 2051 subj = SLOT(&active_cred->cr_label); 2052 obj = SLOT(label); 2053 2054 if (!mac_biba_dominate_single(obj, subj)) 2055 return (EACCES); 2056 2057 return (0); 2058} 2059 2060static int 2061mac_biba_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2062 struct vnode *vp, struct label *label) 2063{ 2064 struct mac_biba *subj, *obj; 2065 2066 if (!mac_biba_enabled || !revocation_enabled) 2067 return (0); 2068 2069 subj = SLOT(&active_cred->cr_label); 2070 obj = SLOT(label); 2071 2072 if (!mac_biba_dominate_single(obj, subj)) 2073 return (EACCES); 2074 2075 return (0); 2076} 2077 2078static int 2079mac_biba_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 2080 struct label *dlabel) 2081{ 2082 struct mac_biba *subj, *obj; 2083 2084 if (!mac_biba_enabled) 2085 return (0); 2086 2087 subj = SLOT(&cred->cr_label); 2088 obj = SLOT(dlabel); 2089 2090 if (!mac_biba_dominate_single(obj, subj)) 2091 return (EACCES); 2092 2093 return (0); 2094} 2095 2096static int 2097mac_biba_check_vnode_readlink(struct ucred *cred, struct vnode *vp, 2098 struct label *label) 2099{ 2100 struct mac_biba *subj, *obj; 2101 2102 if (!mac_biba_enabled) 2103 return (0); 2104 2105 subj = SLOT(&cred->cr_label); 2106 obj = SLOT(label); 2107 2108 if (!mac_biba_dominate_single(obj, subj)) 2109 return (EACCES); 2110 2111 return (0); 2112} 2113 2114static int 2115mac_biba_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2116 struct label *vnodelabel, struct label *newlabel) 2117{ 2118 struct mac_biba *old, *new, *subj; 2119 int error; 2120 2121 old = SLOT(vnodelabel); 2122 new = SLOT(newlabel); 2123 subj = SLOT(&cred->cr_label); 2124 2125 /* 2126 * If there is a Biba label update for the vnode, it must be a 2127 * single label. 2128 */ 2129 error = biba_atmostflags(new, MAC_BIBA_FLAG_SINGLE); 2130 if (error) 2131 return (error); 2132 2133 /* 2134 * To perform a relabel of the vnode (Biba label or not), Biba must 2135 * authorize the relabel. 2136 */ 2137 if (!mac_biba_single_in_range(old, subj)) 2138 return (EPERM); 2139 2140 /* 2141 * If the Biba label is to be changed, authorize as appropriate. 2142 */ 2143 if (new->mb_flags & MAC_BIBA_FLAG_SINGLE) { 2144 /* 2145 * To change the Biba label on a vnode, the new vnode label 2146 * must be in the subject range. 2147 */ 2148 if (!mac_biba_single_in_range(new, subj)) 2149 return (EPERM); 2150 2151 /* 2152 * To change the Biba label on the vnode to be EQUAL, 2153 * the subject must have appropriate privilege. 2154 */ 2155 if (mac_biba_contains_equal(new)) { 2156 error = mac_biba_subject_equal_ok(subj); 2157 if (error) 2158 return (error); 2159 } 2160 } 2161 2162 return (0); 2163} 2164 2165static int 2166mac_biba_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2167 struct label *dlabel, struct vnode *vp, struct label *label, 2168 struct componentname *cnp) 2169{ 2170 struct mac_biba *subj, *obj; 2171 2172 if (!mac_biba_enabled) 2173 return (0); 2174 2175 subj = SLOT(&cred->cr_label); 2176 obj = SLOT(dlabel); 2177 2178 if (!mac_biba_dominate_single(subj, obj)) 2179 return (EACCES); 2180 2181 obj = SLOT(label); 2182 2183 if (!mac_biba_dominate_single(subj, obj)) 2184 return (EACCES); 2185 2186 return (0); 2187} 2188 2189static int 2190mac_biba_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2191 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2192 struct componentname *cnp) 2193{ 2194 struct mac_biba *subj, *obj; 2195 2196 if (!mac_biba_enabled) 2197 return (0); 2198 2199 subj = SLOT(&cred->cr_label); 2200 obj = SLOT(dlabel); 2201 2202 if (!mac_biba_dominate_single(subj, obj)) 2203 return (EACCES); 2204 2205 if (vp != NULL) { 2206 obj = SLOT(label); 2207 2208 if (!mac_biba_dominate_single(subj, obj)) 2209 return (EACCES); 2210 } 2211 2212 return (0); 2213} 2214 2215static int 2216mac_biba_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2217 struct label *label) 2218{ 2219 struct mac_biba *subj, *obj; 2220 2221 if (!mac_biba_enabled) 2222 return (0); 2223 2224 subj = SLOT(&cred->cr_label); 2225 obj = SLOT(label); 2226 2227 if (!mac_biba_dominate_single(subj, obj)) 2228 return (EACCES); 2229 2230 return (0); 2231} 2232 2233static int 2234mac_biba_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2235 struct label *label, acl_type_t type, struct acl *acl) 2236{ 2237 struct mac_biba *subj, *obj; 2238 2239 if (!mac_biba_enabled) 2240 return (0); 2241 2242 subj = SLOT(&cred->cr_label); 2243 obj = SLOT(label); 2244 2245 if (!mac_biba_dominate_single(subj, obj)) 2246 return (EACCES); 2247 2248 return (0); 2249} 2250 2251static int 2252mac_biba_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2253 struct label *vnodelabel, int attrnamespace, const char *name, 2254 struct uio *uio) 2255{ 2256 struct mac_biba *subj, *obj; 2257 2258 if (!mac_biba_enabled) 2259 return (0); 2260 2261 subj = SLOT(&cred->cr_label); 2262 obj = SLOT(vnodelabel); 2263 2264 if (!mac_biba_dominate_single(subj, obj)) 2265 return (EACCES); 2266 2267 /* XXX: protect the MAC EA in a special way? */ 2268 2269 return (0); 2270} 2271 2272static int 2273mac_biba_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2274 struct label *vnodelabel, u_long flags) 2275{ 2276 struct mac_biba *subj, *obj; 2277 2278 if (!mac_biba_enabled) 2279 return (0); 2280 2281 subj = SLOT(&cred->cr_label); 2282 obj = SLOT(vnodelabel); 2283 2284 if (!mac_biba_dominate_single(subj, obj)) 2285 return (EACCES); 2286 2287 return (0); 2288} 2289 2290static int 2291mac_biba_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2292 struct label *vnodelabel, mode_t mode) 2293{ 2294 struct mac_biba *subj, *obj; 2295 2296 if (!mac_biba_enabled) 2297 return (0); 2298 2299 subj = SLOT(&cred->cr_label); 2300 obj = SLOT(vnodelabel); 2301 2302 if (!mac_biba_dominate_single(subj, obj)) 2303 return (EACCES); 2304 2305 return (0); 2306} 2307 2308static int 2309mac_biba_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2310 struct label *vnodelabel, uid_t uid, gid_t gid) 2311{ 2312 struct mac_biba *subj, *obj; 2313 2314 if (!mac_biba_enabled) 2315 return (0); 2316 2317 subj = SLOT(&cred->cr_label); 2318 obj = SLOT(vnodelabel); 2319 2320 if (!mac_biba_dominate_single(subj, obj)) 2321 return (EACCES); 2322 2323 return (0); 2324} 2325 2326static int 2327mac_biba_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2328 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2329{ 2330 struct mac_biba *subj, *obj; 2331 2332 if (!mac_biba_enabled) 2333 return (0); 2334 2335 subj = SLOT(&cred->cr_label); 2336 obj = SLOT(vnodelabel); 2337 2338 if (!mac_biba_dominate_single(subj, obj)) 2339 return (EACCES); 2340 2341 return (0); 2342} 2343 2344static int 2345mac_biba_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 2346 struct vnode *vp, struct label *vnodelabel) 2347{ 2348 struct mac_biba *subj, *obj; 2349 2350 if (!mac_biba_enabled) 2351 return (0); 2352 2353 subj = SLOT(&active_cred->cr_label); 2354 obj = SLOT(vnodelabel); 2355 2356 if (!mac_biba_dominate_single(obj, subj)) 2357 return (EACCES); 2358 2359 return (0); 2360} 2361 2362static int 2363mac_biba_check_vnode_write(struct ucred *active_cred, 2364 struct ucred *file_cred, struct vnode *vp, struct label *label) 2365{ 2366 struct mac_biba *subj, *obj; 2367 2368 if (!mac_biba_enabled || !revocation_enabled) 2369 return (0); 2370 2371 subj = SLOT(&active_cred->cr_label); 2372 obj = SLOT(label); 2373 2374 if (!mac_biba_dominate_single(subj, obj)) 2375 return (EACCES); 2376 2377 return (0); 2378} 2379 2380static struct mac_policy_op_entry mac_biba_ops[] = 2381{ 2382 { MAC_DESTROY, 2383 (macop_t)mac_biba_destroy }, 2384 { MAC_INIT, 2385 (macop_t)mac_biba_init }, 2386 { MAC_INIT_BPFDESC_LABEL, 2387 (macop_t)mac_biba_init_label }, 2388 { MAC_INIT_CRED_LABEL, 2389 (macop_t)mac_biba_init_label }, 2390 { MAC_INIT_DEVFSDIRENT_LABEL, 2391 (macop_t)mac_biba_init_label }, 2392 { MAC_INIT_IFNET_LABEL, 2393 (macop_t)mac_biba_init_label }, 2394 { MAC_INIT_IPQ_LABEL, 2395 (macop_t)mac_biba_init_label }, 2396 { MAC_INIT_MBUF_LABEL, 2397 (macop_t)mac_biba_init_label_waitcheck }, 2398 { MAC_INIT_MOUNT_LABEL, 2399 (macop_t)mac_biba_init_label }, 2400 { MAC_INIT_MOUNT_FS_LABEL, 2401 (macop_t)mac_biba_init_label }, 2402 { MAC_INIT_PIPE_LABEL, 2403 (macop_t)mac_biba_init_label }, 2404 { MAC_INIT_SOCKET_LABEL, 2405 (macop_t)mac_biba_init_label_waitcheck }, 2406 { MAC_INIT_SOCKET_PEER_LABEL, 2407 (macop_t)mac_biba_init_label_waitcheck }, 2408 { MAC_INIT_VNODE_LABEL, 2409 (macop_t)mac_biba_init_label }, 2410 { MAC_DESTROY_BPFDESC_LABEL, 2411 (macop_t)mac_biba_destroy_label }, 2412 { MAC_DESTROY_CRED_LABEL, 2413 (macop_t)mac_biba_destroy_label }, 2414 { MAC_DESTROY_DEVFSDIRENT_LABEL, 2415 (macop_t)mac_biba_destroy_label }, 2416 { MAC_DESTROY_IFNET_LABEL, 2417 (macop_t)mac_biba_destroy_label }, 2418 { MAC_DESTROY_IPQ_LABEL, 2419 (macop_t)mac_biba_destroy_label }, 2420 { MAC_DESTROY_MBUF_LABEL, 2421 (macop_t)mac_biba_destroy_label }, 2422 { MAC_DESTROY_MOUNT_LABEL, 2423 (macop_t)mac_biba_destroy_label }, 2424 { MAC_DESTROY_MOUNT_FS_LABEL, 2425 (macop_t)mac_biba_destroy_label }, 2426 { MAC_DESTROY_PIPE_LABEL, 2427 (macop_t)mac_biba_destroy_label }, 2428 { MAC_DESTROY_SOCKET_LABEL, 2429 (macop_t)mac_biba_destroy_label }, 2430 { MAC_DESTROY_SOCKET_PEER_LABEL, 2431 (macop_t)mac_biba_destroy_label }, 2432 { MAC_DESTROY_VNODE_LABEL, 2433 (macop_t)mac_biba_destroy_label }, 2434 { MAC_COPY_PIPE_LABEL, 2435 (macop_t)mac_biba_copy_label }, 2436 { MAC_COPY_VNODE_LABEL, 2437 (macop_t)mac_biba_copy_label }, 2438 { MAC_EXTERNALIZE_CRED_LABEL, 2439 (macop_t)mac_biba_externalize_label }, 2440 { MAC_EXTERNALIZE_IFNET_LABEL, 2441 (macop_t)mac_biba_externalize_label }, 2442 { MAC_EXTERNALIZE_PIPE_LABEL, 2443 (macop_t)mac_biba_externalize_label }, 2444 { MAC_EXTERNALIZE_SOCKET_LABEL, 2445 (macop_t)mac_biba_externalize_label }, 2446 { MAC_EXTERNALIZE_SOCKET_PEER_LABEL, 2447 (macop_t)mac_biba_externalize_label }, 2448 { MAC_EXTERNALIZE_VNODE_LABEL, 2449 (macop_t)mac_biba_externalize_label }, 2450 { MAC_EXTERNALIZE_VNODE_OLDMAC, 2451 (macop_t)mac_biba_externalize_vnode_oldmac }, 2452 { MAC_INTERNALIZE_CRED_LABEL, 2453 (macop_t)mac_biba_internalize_label }, 2454 { MAC_INTERNALIZE_IFNET_LABEL, 2455 (macop_t)mac_biba_internalize_label }, 2456 { MAC_INTERNALIZE_PIPE_LABEL, 2457 (macop_t)mac_biba_internalize_label }, 2458 { MAC_INTERNALIZE_SOCKET_LABEL, 2459 (macop_t)mac_biba_internalize_label }, 2460 { MAC_INTERNALIZE_VNODE_LABEL, 2461 (macop_t)mac_biba_internalize_label }, 2462 { MAC_CREATE_DEVFS_DEVICE, 2463 (macop_t)mac_biba_create_devfs_device }, 2464 { MAC_CREATE_DEVFS_DIRECTORY, 2465 (macop_t)mac_biba_create_devfs_directory }, 2466 { MAC_CREATE_DEVFS_SYMLINK, 2467 (macop_t)mac_biba_create_devfs_symlink }, 2468 { MAC_CREATE_DEVFS_VNODE, 2469 (macop_t)mac_biba_create_devfs_vnode }, 2470 { MAC_CREATE_VNODE, 2471 (macop_t)mac_biba_create_vnode }, 2472 { MAC_CREATE_MOUNT, 2473 (macop_t)mac_biba_create_mount }, 2474 { MAC_CREATE_ROOT_MOUNT, 2475 (macop_t)mac_biba_create_root_mount }, 2476 { MAC_RELABEL_VNODE, 2477 (macop_t)mac_biba_relabel_vnode }, 2478 { MAC_UPDATE_DEVFSDIRENT, 2479 (macop_t)mac_biba_update_devfsdirent }, 2480 { MAC_UPDATE_PROCFSVNODE, 2481 (macop_t)mac_biba_update_procfsvnode }, 2482 { MAC_UPDATE_VNODE_FROM_EXTERNALIZED, 2483 (macop_t)mac_biba_update_vnode_from_externalized }, 2484 { MAC_UPDATE_VNODE_FROM_MOUNT, 2485 (macop_t)mac_biba_update_vnode_from_mount }, 2486 { MAC_CREATE_MBUF_FROM_SOCKET, 2487 (macop_t)mac_biba_create_mbuf_from_socket }, 2488 { MAC_CREATE_PIPE, 2489 (macop_t)mac_biba_create_pipe }, 2490 { MAC_CREATE_SOCKET, 2491 (macop_t)mac_biba_create_socket }, 2492 { MAC_CREATE_SOCKET_FROM_SOCKET, 2493 (macop_t)mac_biba_create_socket_from_socket }, 2494 { MAC_RELABEL_PIPE, 2495 (macop_t)mac_biba_relabel_pipe }, 2496 { MAC_RELABEL_SOCKET, 2497 (macop_t)mac_biba_relabel_socket }, 2498 { MAC_SET_SOCKET_PEER_FROM_MBUF, 2499 (macop_t)mac_biba_set_socket_peer_from_mbuf }, 2500 { MAC_SET_SOCKET_PEER_FROM_SOCKET, 2501 (macop_t)mac_biba_set_socket_peer_from_socket }, 2502 { MAC_CREATE_BPFDESC, 2503 (macop_t)mac_biba_create_bpfdesc }, 2504 { MAC_CREATE_DATAGRAM_FROM_IPQ, 2505 (macop_t)mac_biba_create_datagram_from_ipq }, 2506 { MAC_CREATE_FRAGMENT, 2507 (macop_t)mac_biba_create_fragment }, 2508 { MAC_CREATE_IFNET, 2509 (macop_t)mac_biba_create_ifnet }, 2510 { MAC_CREATE_IPQ, 2511 (macop_t)mac_biba_create_ipq }, 2512 { MAC_CREATE_MBUF_FROM_MBUF, 2513 (macop_t)mac_biba_create_mbuf_from_mbuf }, 2514 { MAC_CREATE_MBUF_LINKLAYER, 2515 (macop_t)mac_biba_create_mbuf_linklayer }, 2516 { MAC_CREATE_MBUF_FROM_BPFDESC, 2517 (macop_t)mac_biba_create_mbuf_from_bpfdesc }, 2518 { MAC_CREATE_MBUF_FROM_IFNET, 2519 (macop_t)mac_biba_create_mbuf_from_ifnet }, 2520 { MAC_CREATE_MBUF_MULTICAST_ENCAP, 2521 (macop_t)mac_biba_create_mbuf_multicast_encap }, 2522 { MAC_CREATE_MBUF_NETLAYER, 2523 (macop_t)mac_biba_create_mbuf_netlayer }, 2524 { MAC_FRAGMENT_MATCH, 2525 (macop_t)mac_biba_fragment_match }, 2526 { MAC_RELABEL_IFNET, 2527 (macop_t)mac_biba_relabel_ifnet }, 2528 { MAC_UPDATE_IPQ, 2529 (macop_t)mac_biba_update_ipq }, 2530 { MAC_CREATE_CRED, 2531 (macop_t)mac_biba_create_cred }, 2532 { MAC_EXECVE_TRANSITION, 2533 (macop_t)mac_biba_execve_transition }, 2534 { MAC_EXECVE_WILL_TRANSITION, 2535 (macop_t)mac_biba_execve_will_transition }, 2536 { MAC_CREATE_PROC0, 2537 (macop_t)mac_biba_create_proc0 }, 2538 { MAC_CREATE_PROC1, 2539 (macop_t)mac_biba_create_proc1 }, 2540 { MAC_RELABEL_CRED, 2541 (macop_t)mac_biba_relabel_cred }, 2542 { MAC_CHECK_BPFDESC_RECEIVE, 2543 (macop_t)mac_biba_check_bpfdesc_receive }, 2544 { MAC_CHECK_CRED_RELABEL, 2545 (macop_t)mac_biba_check_cred_relabel }, 2546 { MAC_CHECK_CRED_VISIBLE, 2547 (macop_t)mac_biba_check_cred_visible }, 2548 { MAC_CHECK_IFNET_RELABEL, 2549 (macop_t)mac_biba_check_ifnet_relabel }, 2550 { MAC_CHECK_IFNET_TRANSMIT, 2551 (macop_t)mac_biba_check_ifnet_transmit }, 2552 { MAC_CHECK_MOUNT_STAT, 2553 (macop_t)mac_biba_check_mount_stat }, 2554 { MAC_CHECK_PIPE_IOCTL, 2555 (macop_t)mac_biba_check_pipe_ioctl }, 2556 { MAC_CHECK_PIPE_POLL, 2557 (macop_t)mac_biba_check_pipe_poll }, 2558 { MAC_CHECK_PIPE_READ, 2559 (macop_t)mac_biba_check_pipe_read }, 2560 { MAC_CHECK_PIPE_RELABEL, 2561 (macop_t)mac_biba_check_pipe_relabel }, 2562 { MAC_CHECK_PIPE_STAT, 2563 (macop_t)mac_biba_check_pipe_stat }, 2564 { MAC_CHECK_PIPE_WRITE, 2565 (macop_t)mac_biba_check_pipe_write }, 2566 { MAC_CHECK_PROC_DEBUG, 2567 (macop_t)mac_biba_check_proc_debug }, 2568 { MAC_CHECK_PROC_SCHED, 2569 (macop_t)mac_biba_check_proc_sched }, 2570 { MAC_CHECK_PROC_SIGNAL, 2571 (macop_t)mac_biba_check_proc_signal }, 2572 { MAC_CHECK_SOCKET_DELIVER, 2573 (macop_t)mac_biba_check_socket_deliver }, 2574 { MAC_CHECK_SOCKET_RELABEL, 2575 (macop_t)mac_biba_check_socket_relabel }, 2576 { MAC_CHECK_SOCKET_VISIBLE, 2577 (macop_t)mac_biba_check_socket_visible }, 2578 { MAC_CHECK_VNODE_ACCESS, 2579 (macop_t)mac_biba_check_vnode_open }, 2580 { MAC_CHECK_VNODE_CHDIR, 2581 (macop_t)mac_biba_check_vnode_chdir }, 2582 { MAC_CHECK_VNODE_CHROOT, 2583 (macop_t)mac_biba_check_vnode_chroot }, 2584 { MAC_CHECK_VNODE_CREATE, 2585 (macop_t)mac_biba_check_vnode_create }, 2586 { MAC_CHECK_VNODE_DELETE, 2587 (macop_t)mac_biba_check_vnode_delete }, 2588 { MAC_CHECK_VNODE_DELETEACL, 2589 (macop_t)mac_biba_check_vnode_deleteacl }, 2590 { MAC_CHECK_VNODE_EXEC, 2591 (macop_t)mac_biba_check_vnode_exec }, 2592 { MAC_CHECK_VNODE_GETACL, 2593 (macop_t)mac_biba_check_vnode_getacl }, 2594 { MAC_CHECK_VNODE_GETEXTATTR, 2595 (macop_t)mac_biba_check_vnode_getextattr }, 2596 { MAC_CHECK_VNODE_LINK, 2597 (macop_t)mac_biba_check_vnode_link }, 2598 { MAC_CHECK_VNODE_LOOKUP, 2599 (macop_t)mac_biba_check_vnode_lookup }, 2600 { MAC_CHECK_VNODE_MMAP, 2601 (macop_t)mac_biba_check_vnode_mmap }, 2602 { MAC_CHECK_VNODE_MPROTECT, 2603 (macop_t)mac_biba_check_vnode_mmap }, 2604 { MAC_CHECK_VNODE_OPEN, 2605 (macop_t)mac_biba_check_vnode_open }, 2606 { MAC_CHECK_VNODE_POLL, 2607 (macop_t)mac_biba_check_vnode_poll }, 2608 { MAC_CHECK_VNODE_READ, 2609 (macop_t)mac_biba_check_vnode_read }, 2610 { MAC_CHECK_VNODE_READDIR, 2611 (macop_t)mac_biba_check_vnode_readdir }, 2612 { MAC_CHECK_VNODE_READLINK, 2613 (macop_t)mac_biba_check_vnode_readlink }, 2614 { MAC_CHECK_VNODE_RELABEL, 2615 (macop_t)mac_biba_check_vnode_relabel }, 2616 { MAC_CHECK_VNODE_RENAME_FROM, 2617 (macop_t)mac_biba_check_vnode_rename_from }, 2618 { MAC_CHECK_VNODE_RENAME_TO, 2619 (macop_t)mac_biba_check_vnode_rename_to }, 2620 { MAC_CHECK_VNODE_REVOKE, 2621 (macop_t)mac_biba_check_vnode_revoke }, 2622 { MAC_CHECK_VNODE_SETACL, 2623 (macop_t)mac_biba_check_vnode_setacl }, 2624 { MAC_CHECK_VNODE_SETEXTATTR, 2625 (macop_t)mac_biba_check_vnode_setextattr }, 2626 { MAC_CHECK_VNODE_SETFLAGS, 2627 (macop_t)mac_biba_check_vnode_setflags }, 2628 { MAC_CHECK_VNODE_SETMODE, 2629 (macop_t)mac_biba_check_vnode_setmode }, 2630 { MAC_CHECK_VNODE_SETOWNER, 2631 (macop_t)mac_biba_check_vnode_setowner }, 2632 { MAC_CHECK_VNODE_SETUTIMES, 2633 (macop_t)mac_biba_check_vnode_setutimes }, 2634 { MAC_CHECK_VNODE_STAT, 2635 (macop_t)mac_biba_check_vnode_stat }, 2636 { MAC_CHECK_VNODE_WRITE, 2637 (macop_t)mac_biba_check_vnode_write }, 2638 { MAC_OP_LAST, NULL } 2639}; 2640 2641MAC_POLICY_SET(mac_biba_ops, trustedbsd_mac_biba, "TrustedBSD MAC/Biba", 2642 MPC_LOADTIME_FLAG_NOTLATE, &mac_biba_slot); 2643