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