35 */ 36 37/* 38 * Developed by the TrustedBSD Project. 39 * Low-watermark floating label mandatory integrity policy. 40 */ 41 42#include <sys/types.h> 43#include <sys/param.h> 44#include <sys/acl.h> 45#include <sys/conf.h> 46#include <sys/extattr.h> 47#include <sys/kernel.h> 48#include <sys/mac.h> 49#include <sys/malloc.h> 50#include <sys/mman.h> 51#include <sys/mount.h> 52#include <sys/proc.h> 53#include <sys/sbuf.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/sx.h> 63#include <sys/pipe.h> 64#include <sys/sysctl.h> 65#include <sys/syslog.h> 66 67#include <fs/devfs/devfs.h> 68 69#include <net/bpfdesc.h> 70#include <net/if.h> 71#include <net/if_types.h> 72#include <net/if_var.h> 73 74#include <netinet/in.h> 75#include <netinet/in_pcb.h> 76#include <netinet/ip_var.h> 77 78#include <vm/vm.h> 79 80#include <sys/mac_policy.h> 81 82#include <security/mac_lomac/mac_lomac.h> 83 84struct mac_lomac_proc { 85 struct mac_lomac mac_lomac; 86 struct mtx mtx; 87}; 88 89SYSCTL_DECL(_security_mac); 90 91SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0, 92 "TrustedBSD mac_lomac policy controls"); 93 94static int mac_lomac_label_size = sizeof(struct mac_lomac); 95SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD, 96 &mac_lomac_label_size, 0, "Size of struct mac_lomac"); 97 98static int mac_lomac_enabled = 1; 99SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW, 100 &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy"); 101TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled); 102 103static int destroyed_not_inited; 104SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 105 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 106 107static int trust_all_interfaces = 0; 108SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 109 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC"); 110TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces); 111 112static char trusted_interfaces[128]; 113SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 114 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC"); 115TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces, 116 sizeof(trusted_interfaces)); 117 118static int ptys_equal = 0; 119SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW, 120 &ptys_equal, 0, "Label pty devices as lomac/equal on create"); 121TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal); 122 123static int revocation_enabled = 1; 124SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW, 125 &revocation_enabled, 0, "Revoke access to objects on relabel"); 126TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled); 127 128static int mac_lomac_slot; 129#define SLOT(l) ((struct mac_lomac *)LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr) 130#define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr = (val)) 131#define PSLOT(l) ((struct mac_lomac_proc *) \ 132 LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr) 133#define PSLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr = (val)) 134 135MALLOC_DEFINE(M_MACLOMAC, "mac_lomac_label", "MAC/LOMAC labels"); 136 137static struct mac_lomac * 138lomac_alloc(int flag) 139{ 140 struct mac_lomac *mac_lomac; 141 142 mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag); 143 144 return (mac_lomac); 145} 146 147static void 148lomac_free(struct mac_lomac *mac_lomac) 149{ 150 151 if (mac_lomac != NULL) 152 free(mac_lomac, M_MACLOMAC); 153 else 154 atomic_add_int(&destroyed_not_inited, 1); 155} 156 157static int 158lomac_atmostflags(struct mac_lomac *mac_lomac, int flags) 159{ 160 161 if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags) 162 return (EINVAL); 163 return (0); 164} 165 166static int 167mac_lomac_dominate_element(struct mac_lomac_element *a, 168 struct mac_lomac_element *b) 169{ 170 171 switch (a->mle_type) { 172 case MAC_LOMAC_TYPE_EQUAL: 173 case MAC_LOMAC_TYPE_HIGH: 174 return (1); 175 176 case MAC_LOMAC_TYPE_LOW: 177 switch (b->mle_type) { 178 case MAC_LOMAC_TYPE_GRADE: 179 case MAC_LOMAC_TYPE_HIGH: 180 return (0); 181 182 case MAC_LOMAC_TYPE_EQUAL: 183 case MAC_LOMAC_TYPE_LOW: 184 return (1); 185 186 default: 187 panic("mac_lomac_dominate_element: b->mle_type invalid"); 188 } 189 190 case MAC_LOMAC_TYPE_GRADE: 191 switch (b->mle_type) { 192 case MAC_LOMAC_TYPE_EQUAL: 193 case MAC_LOMAC_TYPE_LOW: 194 return (1); 195 196 case MAC_LOMAC_TYPE_HIGH: 197 return (0); 198 199 case MAC_LOMAC_TYPE_GRADE: 200 return (a->mle_grade >= b->mle_grade); 201 202 default: 203 panic("mac_lomac_dominate_element: b->mle_type invalid"); 204 } 205 206 default: 207 panic("mac_lomac_dominate_element: a->mle_type invalid"); 208 } 209} 210 211static int 212mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb) 213{ 214 215 return (mac_lomac_dominate_element(&rangeb->ml_rangehigh, 216 &rangea->ml_rangehigh) && 217 mac_lomac_dominate_element(&rangea->ml_rangelow, 218 &rangeb->ml_rangelow)); 219} 220 221static int 222mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range) 223{ 224 225 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 226 ("mac_lomac_single_in_range: a not single")); 227 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 228 ("mac_lomac_single_in_range: b not range")); 229 230 return (mac_lomac_dominate_element(&range->ml_rangehigh, 231 &single->ml_single) && 232 mac_lomac_dominate_element(&single->ml_single, 233 &range->ml_rangelow)); 234} 235 236static int 237mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range) 238{ 239 240 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 241 ("mac_lomac_single_in_range: a not auxsingle")); 242 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 243 ("mac_lomac_single_in_range: b not range")); 244 245 return (mac_lomac_dominate_element(&range->ml_rangehigh, 246 &single->ml_auxsingle) && 247 mac_lomac_dominate_element(&single->ml_auxsingle, 248 &range->ml_rangelow)); 249} 250 251static int 252mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b) 253{ 254 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 255 ("mac_lomac_dominate_single: a not single")); 256 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 257 ("mac_lomac_dominate_single: b not single")); 258 259 return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single)); 260} 261 262static int 263mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b) 264{ 265 KASSERT((~a->ml_flags & 266 (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0, 267 ("mac_lomac_dominate_single: a not subject")); 268 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 269 ("mac_lomac_dominate_single: b not single")); 270 271 return (mac_lomac_dominate_element(&a->ml_rangehigh, 272 &b->ml_single)); 273} 274 275static int 276mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b) 277{ 278 279 if (a->mle_type == MAC_LOMAC_TYPE_EQUAL || 280 b->mle_type == MAC_LOMAC_TYPE_EQUAL) 281 return (1); 282 283 return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade); 284} 285 286static int 287mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b) 288{ 289 290 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 291 ("mac_lomac_equal_single: a not single")); 292 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 293 ("mac_lomac_equal_single: b not single")); 294 295 return (mac_lomac_equal_element(&a->ml_single, &b->ml_single)); 296} 297 298static int 299mac_lomac_contains_equal(struct mac_lomac *mac_lomac) 300{ 301 302 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) 303 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 304 return (1); 305 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) 306 if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL) 307 return (1); 308 309 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 310 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL) 311 return (1); 312 if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 313 return (1); 314 } 315 316 return (0); 317} 318 319static int 320mac_lomac_subject_privileged(struct mac_lomac *mac_lomac) 321{ 322 323 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) == 324 MAC_LOMAC_FLAGS_BOTH, 325 ("mac_lomac_subject_privileged: subject doesn't have both labels")); 326 327 /* If the single is EQUAL, it's ok. */ 328 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 329 return (0); 330 331 /* If either range endpoint is EQUAL, it's ok. */ 332 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL || 333 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 334 return (0); 335 336 /* If the range is low-high, it's ok. */ 337 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW && 338 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH) 339 return (0); 340 341 /* It's not ok. */ 342 return (EPERM); 343} 344 345static int 346mac_lomac_high_single(struct mac_lomac *mac_lomac) 347{ 348 349 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 350 ("mac_lomac_high_single: mac_lomac not single")); 351 352 return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH); 353} 354 355static int 356mac_lomac_valid(struct mac_lomac *mac_lomac) 357{ 358 359 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 360 switch (mac_lomac->ml_single.mle_type) { 361 case MAC_LOMAC_TYPE_GRADE: 362 case MAC_LOMAC_TYPE_EQUAL: 363 case MAC_LOMAC_TYPE_HIGH: 364 case MAC_LOMAC_TYPE_LOW: 365 break; 366 367 default: 368 return (EINVAL); 369 } 370 } else { 371 if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF) 372 return (EINVAL); 373 } 374 375 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { 376 switch (mac_lomac->ml_auxsingle.mle_type) { 377 case MAC_LOMAC_TYPE_GRADE: 378 case MAC_LOMAC_TYPE_EQUAL: 379 case MAC_LOMAC_TYPE_HIGH: 380 case MAC_LOMAC_TYPE_LOW: 381 break; 382 383 default: 384 return (EINVAL); 385 } 386 } else { 387 if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF) 388 return (EINVAL); 389 } 390 391 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 392 switch (mac_lomac->ml_rangelow.mle_type) { 393 case MAC_LOMAC_TYPE_GRADE: 394 case MAC_LOMAC_TYPE_EQUAL: 395 case MAC_LOMAC_TYPE_HIGH: 396 case MAC_LOMAC_TYPE_LOW: 397 break; 398 399 default: 400 return (EINVAL); 401 } 402 403 switch (mac_lomac->ml_rangehigh.mle_type) { 404 case MAC_LOMAC_TYPE_GRADE: 405 case MAC_LOMAC_TYPE_EQUAL: 406 case MAC_LOMAC_TYPE_HIGH: 407 case MAC_LOMAC_TYPE_LOW: 408 break; 409 410 default: 411 return (EINVAL); 412 } 413 if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh, 414 &mac_lomac->ml_rangelow)) 415 return (EINVAL); 416 } else { 417 if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF || 418 mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF) 419 return (EINVAL); 420 } 421 422 return (0); 423} 424 425static void 426mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow, 427 u_short gradelow, u_short typehigh, u_short gradehigh) 428{ 429 430 mac_lomac->ml_rangelow.mle_type = typelow; 431 mac_lomac->ml_rangelow.mle_grade = gradelow; 432 mac_lomac->ml_rangehigh.mle_type = typehigh; 433 mac_lomac->ml_rangehigh.mle_grade = gradehigh; 434 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE; 435} 436 437static void 438mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade) 439{ 440 441 mac_lomac->ml_single.mle_type = type; 442 mac_lomac->ml_single.mle_grade = grade; 443 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 444} 445 446static void 447mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 448{ 449 450 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 451 ("mac_lomac_copy_range: labelfrom not range")); 452 453 labelto->ml_rangelow = labelfrom->ml_rangelow; 454 labelto->ml_rangehigh = labelfrom->ml_rangehigh; 455 labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE; 456} 457 458static void 459mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 460{ 461 462 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 463 ("mac_lomac_copy_single: labelfrom not single")); 464 465 labelto->ml_single = labelfrom->ml_single; 466 labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 467} 468 469static void 470mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 471{ 472 473 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 474 ("mac_lomac_copy_auxsingle: labelfrom not auxsingle")); 475 476 labelto->ml_auxsingle = labelfrom->ml_auxsingle; 477 labelto->ml_flags |= MAC_LOMAC_FLAG_AUX; 478} 479 480static void 481mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest) 482{ 483 484 if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE) 485 mac_lomac_copy_single(source, dest); 486 if (source->ml_flags & MAC_LOMAC_FLAG_AUX) 487 mac_lomac_copy_auxsingle(source, dest); 488 if (source->ml_flags & MAC_LOMAC_FLAG_RANGE) 489 mac_lomac_copy_range(source, dest); 490} 491 492static int mac_lomac_to_string(struct sbuf *sb, 493 struct mac_lomac *mac_lomac); 494 495static int 496maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 497 const char *actionname, const char *objname, struct vnode *vpq) 498{ 499 struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb; 500 char *subjlabeltext, *objlabeltext, *subjtext; 501 struct mac_lomac cached_subjlabel; 502 struct mac_lomac_proc *subj; 503 struct vattr va; 504 struct proc *p; 505 pid_t pgid; 506 507 subj = PSLOT(curthread->td_proc->p_label); 508 509 p = curthread->td_proc; 510 mtx_lock(&subj->mtx); 511 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 512 /* 513 * Check to see if the pending demotion would be more or 514 * less severe than this one, and keep the more severe. 515 * This can only happen for a multi-threaded application. 516 */ 517 if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) { 518 mtx_unlock(&subj->mtx); 519 return (0); 520 } 521 } 522 bzero(&subj->mac_lomac, sizeof(subj->mac_lomac)); 523 /* 524 * Always demote the single label. 525 */ 526 mac_lomac_copy_single(objlabel, &subj->mac_lomac); 527 /* 528 * Start with the original range, then minimize each side of 529 * the range to the point of not dominating the object. The 530 * high side will always be demoted, of course. 531 */ 532 mac_lomac_copy_range(subjlabel, &subj->mac_lomac); 533 if (!mac_lomac_dominate_element(&objlabel->ml_single, 534 &subj->mac_lomac.ml_rangelow)) 535 subj->mac_lomac.ml_rangelow = objlabel->ml_single; 536 subj->mac_lomac.ml_rangehigh = objlabel->ml_single; 537 subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE; 538 mtx_lock_spin(&sched_lock); 539 curthread->td_flags |= TDF_ASTPENDING; 540 curthread->td_proc->p_sflag |= PS_MACPEND; 541 mtx_unlock_spin(&sched_lock); 542 543 /* 544 * Avoid memory allocation while holding a mutex; cache the 545 * label. 546 */ 547 mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel); 548 mtx_unlock(&subj->mtx); 549 550 sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 551 mac_lomac_to_string(&subjlabel_sb, subjlabel); 552 sbuf_finish(&subjlabel_sb); 553 subjlabeltext = sbuf_data(&subjlabel_sb); 554 555 sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND); 556 mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac); 557 sbuf_finish(&subjtext_sb); 558 subjtext = sbuf_data(&subjtext_sb); 559 560 sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 561 mac_lomac_to_string(&objlabel_sb, objlabel); 562 sbuf_finish(&objlabel_sb); 563 objlabeltext = sbuf_data(&objlabel_sb); 564 565 pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ 566 if (vpq != NULL && VOP_GETATTR(vpq, &va, curthread->td_ucred, 567 curthread) == 0) { 568 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 569 " level %s after %s a level-%s %s (inode=%ld, " 570 "mountpount=%s)\n", 571 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 572 p->p_comm, subjtext, actionname, objlabeltext, objname, 573 va.va_fileid, vpq->v_mount->mnt_stat.f_mntonname); 574 } else { 575 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 576 " level %s after %s a level-%s %s\n", 577 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 578 p->p_comm, subjtext, actionname, objlabeltext, objname); 579 } 580 581 sbuf_delete(&subjlabel_sb); 582 sbuf_delete(&subjtext_sb); 583 sbuf_delete(&objlabel_sb); 584 585 return (0); 586} 587 588/* 589 * Relabel "to" to "from" only if "from" is a valid label (contains 590 * at least a single), as for a relabel operation which may or may 591 * not involve a relevant label. 592 */ 593static void 594try_relabel(struct mac_lomac *from, struct mac_lomac *to) 595{ 596 597 if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 598 bzero(to, sizeof(*to)); 599 mac_lomac_copy(from, to); 600 } 601} 602 603/* 604 * Policy module operations. 605 */ 606static void 607mac_lomac_init(struct mac_policy_conf *conf) 608{ 609 610} 611 612/* 613 * Label operations. 614 */ 615static void 616mac_lomac_init_label(struct label *label) 617{ 618 619 SLOT_SET(label, lomac_alloc(M_WAITOK)); 620} 621 622static int 623mac_lomac_init_label_waitcheck(struct label *label, int flag) 624{ 625 626 SLOT_SET(label, lomac_alloc(flag)); 627 if (SLOT(label) == NULL) 628 return (ENOMEM); 629 630 return (0); 631} 632 633static void 634mac_lomac_init_proc_label(struct label *label) 635{ 636 637 PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_MACLOMAC, 638 M_ZERO | M_WAITOK)); 639 mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF); 640} 641 642static void 643mac_lomac_destroy_label(struct label *label) 644{ 645 646 lomac_free(SLOT(label)); 647 SLOT_SET(label, NULL); 648} 649 650static void 651mac_lomac_destroy_proc_label(struct label *label) 652{ 653 654 mtx_destroy(&PSLOT(label)->mtx); 655 FREE(PSLOT(label), M_MACLOMAC); 656 PSLOT_SET(label, NULL); 657} 658 659static int 660mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element) 661{ 662 663 switch (element->mle_type) { 664 case MAC_LOMAC_TYPE_HIGH: 665 return (sbuf_printf(sb, "high")); 666 667 case MAC_LOMAC_TYPE_LOW: 668 return (sbuf_printf(sb, "low")); 669 670 case MAC_LOMAC_TYPE_EQUAL: 671 return (sbuf_printf(sb, "equal")); 672 673 case MAC_LOMAC_TYPE_GRADE: 674 return (sbuf_printf(sb, "%d", element->mle_grade)); 675 676 default: 677 panic("mac_lomac_element_to_string: invalid type (%d)", 678 element->mle_type); 679 } 680} 681 682static int 683mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac) 684{ 685 686 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 687 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single) 688 == -1) 689 return (EINVAL); 690 } 691 692 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { 693 if (sbuf_putc(sb, '[') == -1) 694 return (EINVAL); 695 696 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle) 697 == -1) 698 return (EINVAL); 699 700 if (sbuf_putc(sb, ']') == -1) 701 return (EINVAL); 702 } 703 704 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 705 if (sbuf_putc(sb, '(') == -1) 706 return (EINVAL); 707 708 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow) 709 == -1) 710 return (EINVAL); 711 712 if (sbuf_putc(sb, '-') == -1) 713 return (EINVAL); 714 715 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh) 716 == -1) 717 return (EINVAL); 718 719 if (sbuf_putc(sb, ')') == -1) 720 return (EINVAL); 721 } 722 723 return (0); 724} 725 726static int 727mac_lomac_externalize_label(struct label *label, char *element_name, 728 struct sbuf *sb, int *claimed) 729{ 730 struct mac_lomac *mac_lomac; 731 732 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 733 return (0); 734 735 (*claimed)++; 736 737 mac_lomac = SLOT(label); 738 739 return (mac_lomac_to_string(sb, mac_lomac)); 740} 741 742static int 743mac_lomac_parse_element(struct mac_lomac_element *element, char *string) 744{ 745 746 if (strcmp(string, "high") == 0 || 747 strcmp(string, "hi") == 0) { 748 element->mle_type = MAC_LOMAC_TYPE_HIGH; 749 element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 750 } else if (strcmp(string, "low") == 0 || 751 strcmp(string, "lo") == 0) { 752 element->mle_type = MAC_LOMAC_TYPE_LOW; 753 element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 754 } else if (strcmp(string, "equal") == 0 || 755 strcmp(string, "eq") == 0) { 756 element->mle_type = MAC_LOMAC_TYPE_EQUAL; 757 element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 758 } else { 759 char *p0, *p1; 760 int d; 761 762 p0 = string; 763 d = strtol(p0, &p1, 10); 764 765 if (d < 0 || d > 65535) 766 return (EINVAL); 767 element->mle_type = MAC_LOMAC_TYPE_GRADE; 768 element->mle_grade = d; 769 770 if (p1 == p0 || *p1 != '\0') 771 return (EINVAL); 772 } 773 774 return (0); 775} 776 777/* 778 * Note: destructively consumes the string, make a local copy before 779 * calling if that's a problem. 780 */ 781static int 782mac_lomac_parse(struct mac_lomac *mac_lomac, char *string) 783{ 784 char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle, 785 *auxsingleend; 786 int error; 787 788 /* Do we have a range? */ 789 single = string; 790 range = index(string, '('); 791 if (range == single) 792 single = NULL; 793 auxsingle = index(string, '['); 794 if (auxsingle == single) 795 single = NULL; 796 if (range != NULL && auxsingle != NULL) 797 return (EINVAL); 798 rangelow = rangehigh = NULL; 799 if (range != NULL) { 800 /* Nul terminate the end of the single string. */ 801 *range = '\0'; 802 range++; 803 rangelow = range; 804 rangehigh = index(rangelow, '-'); 805 if (rangehigh == NULL) 806 return (EINVAL); 807 rangehigh++; 808 if (*rangelow == '\0' || *rangehigh == '\0') 809 return (EINVAL); 810 rangeend = index(rangehigh, ')'); 811 if (rangeend == NULL) 812 return (EINVAL); 813 if (*(rangeend + 1) != '\0') 814 return (EINVAL); 815 /* Nul terminate the ends of the ranges. */ 816 *(rangehigh - 1) = '\0'; 817 *rangeend = '\0'; 818 } 819 KASSERT((rangelow != NULL && rangehigh != NULL) || 820 (rangelow == NULL && rangehigh == NULL), 821 ("mac_lomac_internalize_label: range mismatch")); 822 if (auxsingle != NULL) { 823 /* Nul terminate the end of the single string. */ 824 *auxsingle = '\0'; 825 auxsingle++; 826 auxsingleend = index(auxsingle, ']'); 827 if (auxsingleend == NULL) 828 return (EINVAL); 829 if (*(auxsingleend + 1) != '\0') 830 return (EINVAL); 831 /* Nul terminate the end of the auxsingle. */ 832 *auxsingleend = '\0'; 833 } 834 835 bzero(mac_lomac, sizeof(*mac_lomac)); 836 if (single != NULL) { 837 error = mac_lomac_parse_element(&mac_lomac->ml_single, single); 838 if (error) 839 return (error); 840 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 841 } 842 843 if (auxsingle != NULL) { 844 error = mac_lomac_parse_element(&mac_lomac->ml_auxsingle, 845 auxsingle); 846 if (error) 847 return (error); 848 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_AUX; 849 } 850 851 if (rangelow != NULL) { 852 error = mac_lomac_parse_element(&mac_lomac->ml_rangelow, 853 rangelow); 854 if (error) 855 return (error); 856 error = mac_lomac_parse_element(&mac_lomac->ml_rangehigh, 857 rangehigh); 858 if (error) 859 return (error); 860 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE; 861 } 862 863 error = mac_lomac_valid(mac_lomac); 864 if (error) 865 return (error); 866 867 return (0); 868} 869 870static int 871mac_lomac_internalize_label(struct label *label, char *element_name, 872 char *element_data, int *claimed) 873{ 874 struct mac_lomac *mac_lomac, mac_lomac_temp; 875 int error; 876 877 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 878 return (0); 879 880 (*claimed)++; 881 882 error = mac_lomac_parse(&mac_lomac_temp, element_data); 883 if (error) 884 return (error); 885 886 mac_lomac = SLOT(label); 887 *mac_lomac = mac_lomac_temp; 888 889 return (0); 890} 891 892static void 893mac_lomac_copy_label(struct label *src, struct label *dest) 894{ 895 896 *SLOT(dest) = *SLOT(src); 897} 898 899/* 900 * Labeling event operations: file system objects, and things that look 901 * a lot like file system objects. 902 */ 903static void 904mac_lomac_create_devfs_device(struct ucred *cred, struct mount *mp, 905 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label) 906{ 907 struct mac_lomac *mac_lomac; 908 int lomac_type; 909 910 mac_lomac = SLOT(label); 911 if (strcmp(dev->si_name, "null") == 0 || 912 strcmp(dev->si_name, "zero") == 0 || 913 strcmp(dev->si_name, "random") == 0 || 914 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 || 915 strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0) 916 lomac_type = MAC_LOMAC_TYPE_EQUAL; 917 else if (ptys_equal && 918 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 919 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 920 lomac_type = MAC_LOMAC_TYPE_EQUAL; 921 else 922 lomac_type = MAC_LOMAC_TYPE_HIGH; 923 mac_lomac_set_single(mac_lomac, lomac_type, 0); 924} 925 926static void 927mac_lomac_create_devfs_directory(struct mount *mp, char *dirname, 928 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 929{ 930 struct mac_lomac *mac_lomac; 931 932 mac_lomac = SLOT(label); 933 mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0); 934} 935 936static void 937mac_lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 938 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 939 struct label *delabel) 940{ 941 struct mac_lomac *source, *dest; 942 943 source = SLOT(cred->cr_label); 944 dest = SLOT(delabel); 945 946 mac_lomac_copy_single(source, dest); 947} 948 949static void 950mac_lomac_create_mount(struct ucred *cred, struct mount *mp, 951 struct label *mntlabel, struct label *fslabel) 952{ 953 struct mac_lomac *source, *dest; 954 955 source = SLOT(cred->cr_label); 956 dest = SLOT(mntlabel); 957 mac_lomac_copy_single(source, dest); 958 dest = SLOT(fslabel); 959 mac_lomac_copy_single(source, dest); 960} 961 962static void 963mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp, 964 struct label *vnodelabel, struct label *label) 965{ 966 struct mac_lomac *source, *dest; 967 968 source = SLOT(label); 969 dest = SLOT(vnodelabel); 970 971 try_relabel(source, dest); 972} 973 974static void 975mac_lomac_update_devfsdirent(struct mount *mp, 976 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 977 struct vnode *vp, struct label *vnodelabel) 978{ 979 struct mac_lomac *source, *dest; 980 981 source = SLOT(vnodelabel); 982 dest = SLOT(direntlabel); 983 984 mac_lomac_copy(source, dest); 985} 986 987static void 988mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 989 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 990 struct label *vlabel) 991{ 992 struct mac_lomac *source, *dest; 993 994 source = SLOT(delabel); 995 dest = SLOT(vlabel); 996 997 mac_lomac_copy_single(source, dest); 998} 999 1000static int 1001mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 1002 struct vnode *vp, struct label *vlabel) 1003{ 1004 struct mac_lomac temp, *source, *dest; 1005 int buflen, error; 1006 1007 source = SLOT(fslabel); 1008 dest = SLOT(vlabel); 1009 1010 buflen = sizeof(temp); 1011 bzero(&temp, buflen); 1012 1013 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1014 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread); 1015 if (error == ENOATTR || error == EOPNOTSUPP) { 1016 /* Fall back to the fslabel. */ 1017 mac_lomac_copy_single(source, dest); 1018 return (0); 1019 } else if (error) 1020 return (error); 1021 1022 if (buflen != sizeof(temp)) { 1023 if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) { 1024 printf("mac_lomac_associate_vnode_extattr: bad size %d\n", 1025 buflen); 1026 return (EPERM); 1027 } 1028 bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle)); 1029 buflen = sizeof(temp); 1030 (void)vn_extattr_set(vp, IO_NODELOCKED, 1031 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 1032 buflen, (char *)&temp, curthread); 1033 } 1034 if (mac_lomac_valid(&temp) != 0) { 1035 printf("mac_lomac_associate_vnode_extattr: invalid\n"); 1036 return (EPERM); 1037 } 1038 if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) { 1039 printf("mac_lomac_associate_vnode_extattr: not single\n"); 1040 return (EPERM); 1041 } 1042 1043 mac_lomac_copy_single(&temp, dest); 1044 return (0); 1045} 1046 1047static void 1048mac_lomac_associate_vnode_singlelabel(struct mount *mp, 1049 struct label *fslabel, struct vnode *vp, struct label *vlabel) 1050{ 1051 struct mac_lomac *source, *dest; 1052 1053 source = SLOT(fslabel); 1054 dest = SLOT(vlabel); 1055 1056 mac_lomac_copy_single(source, dest); 1057} 1058 1059static int 1060mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1061 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 1062 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 1063{ 1064 struct mac_lomac *source, *dest, *dir, temp; 1065 size_t buflen; 1066 int error; 1067 1068 buflen = sizeof(temp); 1069 bzero(&temp, buflen); 1070 1071 source = SLOT(cred->cr_label); 1072 dest = SLOT(vlabel); 1073 dir = SLOT(dlabel); 1074 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 1075 mac_lomac_copy_auxsingle(dir, &temp); 1076 mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 1077 dir->ml_auxsingle.mle_grade); 1078 } else { 1079 mac_lomac_copy_single(source, &temp); 1080 } 1081 1082 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1083 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1084 if (error == 0) 1085 mac_lomac_copy(&temp, dest); 1086 return (error); 1087} 1088 1089static int 1090mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1091 struct label *vlabel, struct label *intlabel) 1092{ 1093 struct mac_lomac *source, temp; 1094 size_t buflen; 1095 int error; 1096 1097 buflen = sizeof(temp); 1098 bzero(&temp, buflen); 1099 1100 source = SLOT(intlabel); 1101 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1102 return (0); 1103 1104 mac_lomac_copy_single(source, &temp); 1105 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1106 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1107 return (error); 1108} 1109 1110/* 1111 * Labeling event operations: IPC object. 1112 */ 1113static void 1114mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel, 1115 struct inpcb *inp, struct label *inplabel) 1116{ 1117 struct mac_lomac *source, *dest; 1118 1119 source = SLOT(solabel); 1120 dest = SLOT(inplabel); 1121 1122 mac_lomac_copy_single(source, dest); 1123} 1124 1125static void 1126mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1127 struct mbuf *m, struct label *mbuflabel) 1128{ 1129 struct mac_lomac *source, *dest; 1130 1131 source = SLOT(socketlabel); 1132 dest = SLOT(mbuflabel); 1133 1134 mac_lomac_copy_single(source, dest); 1135} 1136 1137static void 1138mac_lomac_create_socket(struct ucred *cred, struct socket *socket, 1139 struct label *socketlabel) 1140{ 1141 struct mac_lomac *source, *dest; 1142 1143 source = SLOT(cred->cr_label); 1144 dest = SLOT(socketlabel); 1145 1146 mac_lomac_copy_single(source, dest); 1147} 1148 1149static void 1150mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp, 1151 struct label *pipelabel) 1152{ 1153 struct mac_lomac *source, *dest; 1154 1155 source = SLOT(cred->cr_label); 1156 dest = SLOT(pipelabel); 1157 1158 mac_lomac_copy_single(source, dest); 1159} 1160 1161static void 1162mac_lomac_create_socket_from_socket(struct socket *oldsocket, 1163 struct label *oldsocketlabel, struct socket *newsocket, 1164 struct label *newsocketlabel) 1165{ 1166 struct mac_lomac *source, *dest; 1167 1168 source = SLOT(oldsocketlabel); 1169 dest = SLOT(newsocketlabel); 1170 1171 mac_lomac_copy_single(source, dest); 1172} 1173 1174static void 1175mac_lomac_relabel_socket(struct ucred *cred, struct socket *socket, 1176 struct label *socketlabel, struct label *newlabel) 1177{ 1178 struct mac_lomac *source, *dest; 1179 1180 source = SLOT(newlabel); 1181 dest = SLOT(socketlabel); 1182 1183 try_relabel(source, dest); 1184} 1185 1186static void 1187mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1188 struct label *pipelabel, struct label *newlabel) 1189{ 1190 struct mac_lomac *source, *dest; 1191 1192 source = SLOT(newlabel); 1193 dest = SLOT(pipelabel); 1194 1195 try_relabel(source, dest); 1196} 1197 1198static void 1199mac_lomac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1200 struct socket *socket, struct label *socketpeerlabel) 1201{ 1202 struct mac_lomac *source, *dest; 1203 1204 source = SLOT(mbuflabel); 1205 dest = SLOT(socketpeerlabel); 1206 1207 mac_lomac_copy_single(source, dest); 1208} 1209 1210/* 1211 * Labeling event operations: network objects. 1212 */ 1213static void 1214mac_lomac_set_socket_peer_from_socket(struct socket *oldsocket, 1215 struct label *oldsocketlabel, struct socket *newsocket, 1216 struct label *newsocketpeerlabel) 1217{ 1218 struct mac_lomac *source, *dest; 1219 1220 source = SLOT(oldsocketlabel); 1221 dest = SLOT(newsocketpeerlabel); 1222 1223 mac_lomac_copy_single(source, dest); 1224} 1225 1226static void 1227mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1228 struct label *bpflabel) 1229{ 1230 struct mac_lomac *source, *dest; 1231 1232 source = SLOT(cred->cr_label); 1233 dest = SLOT(bpflabel); 1234 1235 mac_lomac_copy_single(source, dest); 1236} 1237 1238static void 1239mac_lomac_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1240{ 1241 char tifname[IFNAMSIZ], *p, *q; 1242 char tiflist[sizeof(trusted_interfaces)]; 1243 struct mac_lomac *dest; 1244 int len, grade; 1245 1246 dest = SLOT(ifnetlabel); 1247 1248 if (ifnet->if_type == IFT_LOOP) { 1249 grade = MAC_LOMAC_TYPE_EQUAL; 1250 goto set; 1251 } 1252 1253 if (trust_all_interfaces) { 1254 grade = MAC_LOMAC_TYPE_HIGH; 1255 goto set; 1256 } 1257 1258 grade = MAC_LOMAC_TYPE_LOW; 1259 1260 if (trusted_interfaces[0] == '\0' || 1261 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1262 goto set; 1263 1264 bzero(tiflist, sizeof(tiflist)); 1265 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1266 if(*p != ' ' && *p != '\t') 1267 *q = *p; 1268 1269 for (p = q = tiflist;; p++) { 1270 if (*p == ',' || *p == '\0') { 1271 len = p - q; 1272 if (len < IFNAMSIZ) { 1273 bzero(tifname, sizeof(tifname)); 1274 bcopy(q, tifname, len); 1275 if (strcmp(tifname, ifnet->if_xname) == 0) { 1276 grade = MAC_LOMAC_TYPE_HIGH; 1277 break; 1278 } 1279 } 1280 else { 1281 *p = '\0'; 1282 printf("MAC/LOMAC warning: interface name " 1283 "\"%s\" is too long (must be < %d)\n", 1284 q, IFNAMSIZ); 1285 } 1286 if (*p == '\0') 1287 break; 1288 q = p + 1; 1289 } 1290 } 1291set: 1292 mac_lomac_set_single(dest, grade, 0); 1293 mac_lomac_set_range(dest, grade, 0, grade, 0); 1294} 1295 1296static void 1297mac_lomac_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1298 struct ipq *ipq, struct label *ipqlabel) 1299{ 1300 struct mac_lomac *source, *dest; 1301 1302 source = SLOT(fragmentlabel); 1303 dest = SLOT(ipqlabel); 1304 1305 mac_lomac_copy_single(source, dest); 1306} 1307 1308static void 1309mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1310 struct mbuf *datagram, struct label *datagramlabel) 1311{ 1312 struct mac_lomac *source, *dest; 1313 1314 source = SLOT(ipqlabel); 1315 dest = SLOT(datagramlabel); 1316 1317 /* Just use the head, since we require them all to match. */ 1318 mac_lomac_copy_single(source, dest); 1319} 1320 1321static void 1322mac_lomac_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1323 struct mbuf *fragment, struct label *fragmentlabel) 1324{ 1325 struct mac_lomac *source, *dest; 1326 1327 source = SLOT(datagramlabel); 1328 dest = SLOT(fragmentlabel); 1329 1330 mac_lomac_copy_single(source, dest); 1331} 1332 1333static void 1334mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1335 struct mbuf *m, struct label *mlabel) 1336{ 1337 struct mac_lomac *source, *dest; 1338 1339 source = SLOT(inplabel); 1340 dest = SLOT(mlabel); 1341 1342 mac_lomac_copy_single(source, dest); 1343} 1344 1345static void 1346mac_lomac_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1347 struct mbuf *mbuf, struct label *mbuflabel) 1348{ 1349 struct mac_lomac *dest; 1350 1351 dest = SLOT(mbuflabel); 1352 1353 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1354} 1355 1356static void 1357mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1358 struct mbuf *mbuf, struct label *mbuflabel) 1359{ 1360 struct mac_lomac *source, *dest; 1361 1362 source = SLOT(bpflabel); 1363 dest = SLOT(mbuflabel); 1364 1365 mac_lomac_copy_single(source, dest); 1366} 1367 1368static void 1369mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1370 struct mbuf *m, struct label *mbuflabel) 1371{ 1372 struct mac_lomac *source, *dest; 1373 1374 source = SLOT(ifnetlabel); 1375 dest = SLOT(mbuflabel); 1376 1377 mac_lomac_copy_single(source, dest); 1378} 1379 1380static void 1381mac_lomac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1382 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1383 struct mbuf *newmbuf, struct label *newmbuflabel) 1384{ 1385 struct mac_lomac *source, *dest; 1386 1387 source = SLOT(oldmbuflabel); 1388 dest = SLOT(newmbuflabel); 1389 1390 mac_lomac_copy_single(source, dest); 1391} 1392 1393static void 1394mac_lomac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1395 struct mbuf *newmbuf, struct label *newmbuflabel) 1396{ 1397 struct mac_lomac *source, *dest; 1398 1399 source = SLOT(oldmbuflabel); 1400 dest = SLOT(newmbuflabel); 1401 1402 mac_lomac_copy_single(source, dest); 1403} 1404 1405static int 1406mac_lomac_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1407 struct ipq *ipq, struct label *ipqlabel) 1408{ 1409 struct mac_lomac *a, *b; 1410 1411 a = SLOT(ipqlabel); 1412 b = SLOT(fragmentlabel); 1413 1414 return (mac_lomac_equal_single(a, b)); 1415} 1416 1417static void 1418mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1419 struct label *ifnetlabel, struct label *newlabel) 1420{ 1421 struct mac_lomac *source, *dest; 1422 1423 source = SLOT(newlabel); 1424 dest = SLOT(ifnetlabel); 1425 1426 try_relabel(source, dest); 1427} 1428 1429static void 1430mac_lomac_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1431 struct ipq *ipq, struct label *ipqlabel) 1432{ 1433 1434 /* NOOP: we only accept matching labels, so no need to update */ 1435} 1436 1437static void 1438mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1439 struct inpcb *inp, struct label *inplabel) 1440{ 1441 struct mac_lomac *source, *dest; 1442 1443 source = SLOT(solabel); 1444 dest = SLOT(inplabel); 1445 1446 mac_lomac_copy_single(source, dest); 1447} 1448
| 35 */ 36 37/* 38 * Developed by the TrustedBSD Project. 39 * Low-watermark floating label mandatory integrity policy. 40 */ 41 42#include <sys/types.h> 43#include <sys/param.h> 44#include <sys/acl.h> 45#include <sys/conf.h> 46#include <sys/extattr.h> 47#include <sys/kernel.h> 48#include <sys/mac.h> 49#include <sys/malloc.h> 50#include <sys/mman.h> 51#include <sys/mount.h> 52#include <sys/proc.h> 53#include <sys/sbuf.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/sx.h> 63#include <sys/pipe.h> 64#include <sys/sysctl.h> 65#include <sys/syslog.h> 66 67#include <fs/devfs/devfs.h> 68 69#include <net/bpfdesc.h> 70#include <net/if.h> 71#include <net/if_types.h> 72#include <net/if_var.h> 73 74#include <netinet/in.h> 75#include <netinet/in_pcb.h> 76#include <netinet/ip_var.h> 77 78#include <vm/vm.h> 79 80#include <sys/mac_policy.h> 81 82#include <security/mac_lomac/mac_lomac.h> 83 84struct mac_lomac_proc { 85 struct mac_lomac mac_lomac; 86 struct mtx mtx; 87}; 88 89SYSCTL_DECL(_security_mac); 90 91SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0, 92 "TrustedBSD mac_lomac policy controls"); 93 94static int mac_lomac_label_size = sizeof(struct mac_lomac); 95SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD, 96 &mac_lomac_label_size, 0, "Size of struct mac_lomac"); 97 98static int mac_lomac_enabled = 1; 99SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW, 100 &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy"); 101TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled); 102 103static int destroyed_not_inited; 104SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 105 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 106 107static int trust_all_interfaces = 0; 108SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 109 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC"); 110TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces); 111 112static char trusted_interfaces[128]; 113SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 114 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC"); 115TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces, 116 sizeof(trusted_interfaces)); 117 118static int ptys_equal = 0; 119SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW, 120 &ptys_equal, 0, "Label pty devices as lomac/equal on create"); 121TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal); 122 123static int revocation_enabled = 1; 124SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW, 125 &revocation_enabled, 0, "Revoke access to objects on relabel"); 126TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled); 127 128static int mac_lomac_slot; 129#define SLOT(l) ((struct mac_lomac *)LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr) 130#define SLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr = (val)) 131#define PSLOT(l) ((struct mac_lomac_proc *) \ 132 LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr) 133#define PSLOT_SET(l, val) (LABEL_TO_SLOT((l), mac_lomac_slot).l_ptr = (val)) 134 135MALLOC_DEFINE(M_MACLOMAC, "mac_lomac_label", "MAC/LOMAC labels"); 136 137static struct mac_lomac * 138lomac_alloc(int flag) 139{ 140 struct mac_lomac *mac_lomac; 141 142 mac_lomac = malloc(sizeof(struct mac_lomac), M_MACLOMAC, M_ZERO | flag); 143 144 return (mac_lomac); 145} 146 147static void 148lomac_free(struct mac_lomac *mac_lomac) 149{ 150 151 if (mac_lomac != NULL) 152 free(mac_lomac, M_MACLOMAC); 153 else 154 atomic_add_int(&destroyed_not_inited, 1); 155} 156 157static int 158lomac_atmostflags(struct mac_lomac *mac_lomac, int flags) 159{ 160 161 if ((mac_lomac->ml_flags & flags) != mac_lomac->ml_flags) 162 return (EINVAL); 163 return (0); 164} 165 166static int 167mac_lomac_dominate_element(struct mac_lomac_element *a, 168 struct mac_lomac_element *b) 169{ 170 171 switch (a->mle_type) { 172 case MAC_LOMAC_TYPE_EQUAL: 173 case MAC_LOMAC_TYPE_HIGH: 174 return (1); 175 176 case MAC_LOMAC_TYPE_LOW: 177 switch (b->mle_type) { 178 case MAC_LOMAC_TYPE_GRADE: 179 case MAC_LOMAC_TYPE_HIGH: 180 return (0); 181 182 case MAC_LOMAC_TYPE_EQUAL: 183 case MAC_LOMAC_TYPE_LOW: 184 return (1); 185 186 default: 187 panic("mac_lomac_dominate_element: b->mle_type invalid"); 188 } 189 190 case MAC_LOMAC_TYPE_GRADE: 191 switch (b->mle_type) { 192 case MAC_LOMAC_TYPE_EQUAL: 193 case MAC_LOMAC_TYPE_LOW: 194 return (1); 195 196 case MAC_LOMAC_TYPE_HIGH: 197 return (0); 198 199 case MAC_LOMAC_TYPE_GRADE: 200 return (a->mle_grade >= b->mle_grade); 201 202 default: 203 panic("mac_lomac_dominate_element: b->mle_type invalid"); 204 } 205 206 default: 207 panic("mac_lomac_dominate_element: a->mle_type invalid"); 208 } 209} 210 211static int 212mac_lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb) 213{ 214 215 return (mac_lomac_dominate_element(&rangeb->ml_rangehigh, 216 &rangea->ml_rangehigh) && 217 mac_lomac_dominate_element(&rangea->ml_rangelow, 218 &rangeb->ml_rangelow)); 219} 220 221static int 222mac_lomac_single_in_range(struct mac_lomac *single, struct mac_lomac *range) 223{ 224 225 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 226 ("mac_lomac_single_in_range: a not single")); 227 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 228 ("mac_lomac_single_in_range: b not range")); 229 230 return (mac_lomac_dominate_element(&range->ml_rangehigh, 231 &single->ml_single) && 232 mac_lomac_dominate_element(&single->ml_single, 233 &range->ml_rangelow)); 234} 235 236static int 237mac_lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range) 238{ 239 240 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 241 ("mac_lomac_single_in_range: a not auxsingle")); 242 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 243 ("mac_lomac_single_in_range: b not range")); 244 245 return (mac_lomac_dominate_element(&range->ml_rangehigh, 246 &single->ml_auxsingle) && 247 mac_lomac_dominate_element(&single->ml_auxsingle, 248 &range->ml_rangelow)); 249} 250 251static int 252mac_lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b) 253{ 254 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 255 ("mac_lomac_dominate_single: a not single")); 256 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 257 ("mac_lomac_dominate_single: b not single")); 258 259 return (mac_lomac_dominate_element(&a->ml_single, &b->ml_single)); 260} 261 262static int 263mac_lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b) 264{ 265 KASSERT((~a->ml_flags & 266 (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0, 267 ("mac_lomac_dominate_single: a not subject")); 268 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 269 ("mac_lomac_dominate_single: b not single")); 270 271 return (mac_lomac_dominate_element(&a->ml_rangehigh, 272 &b->ml_single)); 273} 274 275static int 276mac_lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b) 277{ 278 279 if (a->mle_type == MAC_LOMAC_TYPE_EQUAL || 280 b->mle_type == MAC_LOMAC_TYPE_EQUAL) 281 return (1); 282 283 return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade); 284} 285 286static int 287mac_lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b) 288{ 289 290 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 291 ("mac_lomac_equal_single: a not single")); 292 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 293 ("mac_lomac_equal_single: b not single")); 294 295 return (mac_lomac_equal_element(&a->ml_single, &b->ml_single)); 296} 297 298static int 299mac_lomac_contains_equal(struct mac_lomac *mac_lomac) 300{ 301 302 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) 303 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 304 return (1); 305 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) 306 if (mac_lomac->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL) 307 return (1); 308 309 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 310 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL) 311 return (1); 312 if (mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 313 return (1); 314 } 315 316 return (0); 317} 318 319static int 320mac_lomac_subject_privileged(struct mac_lomac *mac_lomac) 321{ 322 323 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAGS_BOTH) == 324 MAC_LOMAC_FLAGS_BOTH, 325 ("mac_lomac_subject_privileged: subject doesn't have both labels")); 326 327 /* If the single is EQUAL, it's ok. */ 328 if (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 329 return (0); 330 331 /* If either range endpoint is EQUAL, it's ok. */ 332 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL || 333 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 334 return (0); 335 336 /* If the range is low-high, it's ok. */ 337 if (mac_lomac->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW && 338 mac_lomac->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH) 339 return (0); 340 341 /* It's not ok. */ 342 return (EPERM); 343} 344 345static int 346mac_lomac_high_single(struct mac_lomac *mac_lomac) 347{ 348 349 KASSERT((mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 350 ("mac_lomac_high_single: mac_lomac not single")); 351 352 return (mac_lomac->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH); 353} 354 355static int 356mac_lomac_valid(struct mac_lomac *mac_lomac) 357{ 358 359 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 360 switch (mac_lomac->ml_single.mle_type) { 361 case MAC_LOMAC_TYPE_GRADE: 362 case MAC_LOMAC_TYPE_EQUAL: 363 case MAC_LOMAC_TYPE_HIGH: 364 case MAC_LOMAC_TYPE_LOW: 365 break; 366 367 default: 368 return (EINVAL); 369 } 370 } else { 371 if (mac_lomac->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF) 372 return (EINVAL); 373 } 374 375 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { 376 switch (mac_lomac->ml_auxsingle.mle_type) { 377 case MAC_LOMAC_TYPE_GRADE: 378 case MAC_LOMAC_TYPE_EQUAL: 379 case MAC_LOMAC_TYPE_HIGH: 380 case MAC_LOMAC_TYPE_LOW: 381 break; 382 383 default: 384 return (EINVAL); 385 } 386 } else { 387 if (mac_lomac->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF) 388 return (EINVAL); 389 } 390 391 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 392 switch (mac_lomac->ml_rangelow.mle_type) { 393 case MAC_LOMAC_TYPE_GRADE: 394 case MAC_LOMAC_TYPE_EQUAL: 395 case MAC_LOMAC_TYPE_HIGH: 396 case MAC_LOMAC_TYPE_LOW: 397 break; 398 399 default: 400 return (EINVAL); 401 } 402 403 switch (mac_lomac->ml_rangehigh.mle_type) { 404 case MAC_LOMAC_TYPE_GRADE: 405 case MAC_LOMAC_TYPE_EQUAL: 406 case MAC_LOMAC_TYPE_HIGH: 407 case MAC_LOMAC_TYPE_LOW: 408 break; 409 410 default: 411 return (EINVAL); 412 } 413 if (!mac_lomac_dominate_element(&mac_lomac->ml_rangehigh, 414 &mac_lomac->ml_rangelow)) 415 return (EINVAL); 416 } else { 417 if (mac_lomac->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF || 418 mac_lomac->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF) 419 return (EINVAL); 420 } 421 422 return (0); 423} 424 425static void 426mac_lomac_set_range(struct mac_lomac *mac_lomac, u_short typelow, 427 u_short gradelow, u_short typehigh, u_short gradehigh) 428{ 429 430 mac_lomac->ml_rangelow.mle_type = typelow; 431 mac_lomac->ml_rangelow.mle_grade = gradelow; 432 mac_lomac->ml_rangehigh.mle_type = typehigh; 433 mac_lomac->ml_rangehigh.mle_grade = gradehigh; 434 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE; 435} 436 437static void 438mac_lomac_set_single(struct mac_lomac *mac_lomac, u_short type, u_short grade) 439{ 440 441 mac_lomac->ml_single.mle_type = type; 442 mac_lomac->ml_single.mle_grade = grade; 443 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 444} 445 446static void 447mac_lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 448{ 449 450 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 451 ("mac_lomac_copy_range: labelfrom not range")); 452 453 labelto->ml_rangelow = labelfrom->ml_rangelow; 454 labelto->ml_rangehigh = labelfrom->ml_rangehigh; 455 labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE; 456} 457 458static void 459mac_lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 460{ 461 462 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 463 ("mac_lomac_copy_single: labelfrom not single")); 464 465 labelto->ml_single = labelfrom->ml_single; 466 labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 467} 468 469static void 470mac_lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 471{ 472 473 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 474 ("mac_lomac_copy_auxsingle: labelfrom not auxsingle")); 475 476 labelto->ml_auxsingle = labelfrom->ml_auxsingle; 477 labelto->ml_flags |= MAC_LOMAC_FLAG_AUX; 478} 479 480static void 481mac_lomac_copy(struct mac_lomac *source, struct mac_lomac *dest) 482{ 483 484 if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE) 485 mac_lomac_copy_single(source, dest); 486 if (source->ml_flags & MAC_LOMAC_FLAG_AUX) 487 mac_lomac_copy_auxsingle(source, dest); 488 if (source->ml_flags & MAC_LOMAC_FLAG_RANGE) 489 mac_lomac_copy_range(source, dest); 490} 491 492static int mac_lomac_to_string(struct sbuf *sb, 493 struct mac_lomac *mac_lomac); 494 495static int 496maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 497 const char *actionname, const char *objname, struct vnode *vpq) 498{ 499 struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb; 500 char *subjlabeltext, *objlabeltext, *subjtext; 501 struct mac_lomac cached_subjlabel; 502 struct mac_lomac_proc *subj; 503 struct vattr va; 504 struct proc *p; 505 pid_t pgid; 506 507 subj = PSLOT(curthread->td_proc->p_label); 508 509 p = curthread->td_proc; 510 mtx_lock(&subj->mtx); 511 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 512 /* 513 * Check to see if the pending demotion would be more or 514 * less severe than this one, and keep the more severe. 515 * This can only happen for a multi-threaded application. 516 */ 517 if (mac_lomac_dominate_single(objlabel, &subj->mac_lomac)) { 518 mtx_unlock(&subj->mtx); 519 return (0); 520 } 521 } 522 bzero(&subj->mac_lomac, sizeof(subj->mac_lomac)); 523 /* 524 * Always demote the single label. 525 */ 526 mac_lomac_copy_single(objlabel, &subj->mac_lomac); 527 /* 528 * Start with the original range, then minimize each side of 529 * the range to the point of not dominating the object. The 530 * high side will always be demoted, of course. 531 */ 532 mac_lomac_copy_range(subjlabel, &subj->mac_lomac); 533 if (!mac_lomac_dominate_element(&objlabel->ml_single, 534 &subj->mac_lomac.ml_rangelow)) 535 subj->mac_lomac.ml_rangelow = objlabel->ml_single; 536 subj->mac_lomac.ml_rangehigh = objlabel->ml_single; 537 subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE; 538 mtx_lock_spin(&sched_lock); 539 curthread->td_flags |= TDF_ASTPENDING; 540 curthread->td_proc->p_sflag |= PS_MACPEND; 541 mtx_unlock_spin(&sched_lock); 542 543 /* 544 * Avoid memory allocation while holding a mutex; cache the 545 * label. 546 */ 547 mac_lomac_copy_single(&subj->mac_lomac, &cached_subjlabel); 548 mtx_unlock(&subj->mtx); 549 550 sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 551 mac_lomac_to_string(&subjlabel_sb, subjlabel); 552 sbuf_finish(&subjlabel_sb); 553 subjlabeltext = sbuf_data(&subjlabel_sb); 554 555 sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND); 556 mac_lomac_to_string(&subjtext_sb, &subj->mac_lomac); 557 sbuf_finish(&subjtext_sb); 558 subjtext = sbuf_data(&subjtext_sb); 559 560 sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 561 mac_lomac_to_string(&objlabel_sb, objlabel); 562 sbuf_finish(&objlabel_sb); 563 objlabeltext = sbuf_data(&objlabel_sb); 564 565 pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ 566 if (vpq != NULL && VOP_GETATTR(vpq, &va, curthread->td_ucred, 567 curthread) == 0) { 568 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 569 " level %s after %s a level-%s %s (inode=%ld, " 570 "mountpount=%s)\n", 571 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 572 p->p_comm, subjtext, actionname, objlabeltext, objname, 573 va.va_fileid, vpq->v_mount->mnt_stat.f_mntonname); 574 } else { 575 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 576 " level %s after %s a level-%s %s\n", 577 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 578 p->p_comm, subjtext, actionname, objlabeltext, objname); 579 } 580 581 sbuf_delete(&subjlabel_sb); 582 sbuf_delete(&subjtext_sb); 583 sbuf_delete(&objlabel_sb); 584 585 return (0); 586} 587 588/* 589 * Relabel "to" to "from" only if "from" is a valid label (contains 590 * at least a single), as for a relabel operation which may or may 591 * not involve a relevant label. 592 */ 593static void 594try_relabel(struct mac_lomac *from, struct mac_lomac *to) 595{ 596 597 if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 598 bzero(to, sizeof(*to)); 599 mac_lomac_copy(from, to); 600 } 601} 602 603/* 604 * Policy module operations. 605 */ 606static void 607mac_lomac_init(struct mac_policy_conf *conf) 608{ 609 610} 611 612/* 613 * Label operations. 614 */ 615static void 616mac_lomac_init_label(struct label *label) 617{ 618 619 SLOT_SET(label, lomac_alloc(M_WAITOK)); 620} 621 622static int 623mac_lomac_init_label_waitcheck(struct label *label, int flag) 624{ 625 626 SLOT_SET(label, lomac_alloc(flag)); 627 if (SLOT(label) == NULL) 628 return (ENOMEM); 629 630 return (0); 631} 632 633static void 634mac_lomac_init_proc_label(struct label *label) 635{ 636 637 PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_MACLOMAC, 638 M_ZERO | M_WAITOK)); 639 mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF); 640} 641 642static void 643mac_lomac_destroy_label(struct label *label) 644{ 645 646 lomac_free(SLOT(label)); 647 SLOT_SET(label, NULL); 648} 649 650static void 651mac_lomac_destroy_proc_label(struct label *label) 652{ 653 654 mtx_destroy(&PSLOT(label)->mtx); 655 FREE(PSLOT(label), M_MACLOMAC); 656 PSLOT_SET(label, NULL); 657} 658 659static int 660mac_lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element) 661{ 662 663 switch (element->mle_type) { 664 case MAC_LOMAC_TYPE_HIGH: 665 return (sbuf_printf(sb, "high")); 666 667 case MAC_LOMAC_TYPE_LOW: 668 return (sbuf_printf(sb, "low")); 669 670 case MAC_LOMAC_TYPE_EQUAL: 671 return (sbuf_printf(sb, "equal")); 672 673 case MAC_LOMAC_TYPE_GRADE: 674 return (sbuf_printf(sb, "%d", element->mle_grade)); 675 676 default: 677 panic("mac_lomac_element_to_string: invalid type (%d)", 678 element->mle_type); 679 } 680} 681 682static int 683mac_lomac_to_string(struct sbuf *sb, struct mac_lomac *mac_lomac) 684{ 685 686 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 687 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_single) 688 == -1) 689 return (EINVAL); 690 } 691 692 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_AUX) { 693 if (sbuf_putc(sb, '[') == -1) 694 return (EINVAL); 695 696 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_auxsingle) 697 == -1) 698 return (EINVAL); 699 700 if (sbuf_putc(sb, ']') == -1) 701 return (EINVAL); 702 } 703 704 if (mac_lomac->ml_flags & MAC_LOMAC_FLAG_RANGE) { 705 if (sbuf_putc(sb, '(') == -1) 706 return (EINVAL); 707 708 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangelow) 709 == -1) 710 return (EINVAL); 711 712 if (sbuf_putc(sb, '-') == -1) 713 return (EINVAL); 714 715 if (mac_lomac_element_to_string(sb, &mac_lomac->ml_rangehigh) 716 == -1) 717 return (EINVAL); 718 719 if (sbuf_putc(sb, ')') == -1) 720 return (EINVAL); 721 } 722 723 return (0); 724} 725 726static int 727mac_lomac_externalize_label(struct label *label, char *element_name, 728 struct sbuf *sb, int *claimed) 729{ 730 struct mac_lomac *mac_lomac; 731 732 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 733 return (0); 734 735 (*claimed)++; 736 737 mac_lomac = SLOT(label); 738 739 return (mac_lomac_to_string(sb, mac_lomac)); 740} 741 742static int 743mac_lomac_parse_element(struct mac_lomac_element *element, char *string) 744{ 745 746 if (strcmp(string, "high") == 0 || 747 strcmp(string, "hi") == 0) { 748 element->mle_type = MAC_LOMAC_TYPE_HIGH; 749 element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 750 } else if (strcmp(string, "low") == 0 || 751 strcmp(string, "lo") == 0) { 752 element->mle_type = MAC_LOMAC_TYPE_LOW; 753 element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 754 } else if (strcmp(string, "equal") == 0 || 755 strcmp(string, "eq") == 0) { 756 element->mle_type = MAC_LOMAC_TYPE_EQUAL; 757 element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 758 } else { 759 char *p0, *p1; 760 int d; 761 762 p0 = string; 763 d = strtol(p0, &p1, 10); 764 765 if (d < 0 || d > 65535) 766 return (EINVAL); 767 element->mle_type = MAC_LOMAC_TYPE_GRADE; 768 element->mle_grade = d; 769 770 if (p1 == p0 || *p1 != '\0') 771 return (EINVAL); 772 } 773 774 return (0); 775} 776 777/* 778 * Note: destructively consumes the string, make a local copy before 779 * calling if that's a problem. 780 */ 781static int 782mac_lomac_parse(struct mac_lomac *mac_lomac, char *string) 783{ 784 char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle, 785 *auxsingleend; 786 int error; 787 788 /* Do we have a range? */ 789 single = string; 790 range = index(string, '('); 791 if (range == single) 792 single = NULL; 793 auxsingle = index(string, '['); 794 if (auxsingle == single) 795 single = NULL; 796 if (range != NULL && auxsingle != NULL) 797 return (EINVAL); 798 rangelow = rangehigh = NULL; 799 if (range != NULL) { 800 /* Nul terminate the end of the single string. */ 801 *range = '\0'; 802 range++; 803 rangelow = range; 804 rangehigh = index(rangelow, '-'); 805 if (rangehigh == NULL) 806 return (EINVAL); 807 rangehigh++; 808 if (*rangelow == '\0' || *rangehigh == '\0') 809 return (EINVAL); 810 rangeend = index(rangehigh, ')'); 811 if (rangeend == NULL) 812 return (EINVAL); 813 if (*(rangeend + 1) != '\0') 814 return (EINVAL); 815 /* Nul terminate the ends of the ranges. */ 816 *(rangehigh - 1) = '\0'; 817 *rangeend = '\0'; 818 } 819 KASSERT((rangelow != NULL && rangehigh != NULL) || 820 (rangelow == NULL && rangehigh == NULL), 821 ("mac_lomac_internalize_label: range mismatch")); 822 if (auxsingle != NULL) { 823 /* Nul terminate the end of the single string. */ 824 *auxsingle = '\0'; 825 auxsingle++; 826 auxsingleend = index(auxsingle, ']'); 827 if (auxsingleend == NULL) 828 return (EINVAL); 829 if (*(auxsingleend + 1) != '\0') 830 return (EINVAL); 831 /* Nul terminate the end of the auxsingle. */ 832 *auxsingleend = '\0'; 833 } 834 835 bzero(mac_lomac, sizeof(*mac_lomac)); 836 if (single != NULL) { 837 error = mac_lomac_parse_element(&mac_lomac->ml_single, single); 838 if (error) 839 return (error); 840 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 841 } 842 843 if (auxsingle != NULL) { 844 error = mac_lomac_parse_element(&mac_lomac->ml_auxsingle, 845 auxsingle); 846 if (error) 847 return (error); 848 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_AUX; 849 } 850 851 if (rangelow != NULL) { 852 error = mac_lomac_parse_element(&mac_lomac->ml_rangelow, 853 rangelow); 854 if (error) 855 return (error); 856 error = mac_lomac_parse_element(&mac_lomac->ml_rangehigh, 857 rangehigh); 858 if (error) 859 return (error); 860 mac_lomac->ml_flags |= MAC_LOMAC_FLAG_RANGE; 861 } 862 863 error = mac_lomac_valid(mac_lomac); 864 if (error) 865 return (error); 866 867 return (0); 868} 869 870static int 871mac_lomac_internalize_label(struct label *label, char *element_name, 872 char *element_data, int *claimed) 873{ 874 struct mac_lomac *mac_lomac, mac_lomac_temp; 875 int error; 876 877 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 878 return (0); 879 880 (*claimed)++; 881 882 error = mac_lomac_parse(&mac_lomac_temp, element_data); 883 if (error) 884 return (error); 885 886 mac_lomac = SLOT(label); 887 *mac_lomac = mac_lomac_temp; 888 889 return (0); 890} 891 892static void 893mac_lomac_copy_label(struct label *src, struct label *dest) 894{ 895 896 *SLOT(dest) = *SLOT(src); 897} 898 899/* 900 * Labeling event operations: file system objects, and things that look 901 * a lot like file system objects. 902 */ 903static void 904mac_lomac_create_devfs_device(struct ucred *cred, struct mount *mp, 905 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label) 906{ 907 struct mac_lomac *mac_lomac; 908 int lomac_type; 909 910 mac_lomac = SLOT(label); 911 if (strcmp(dev->si_name, "null") == 0 || 912 strcmp(dev->si_name, "zero") == 0 || 913 strcmp(dev->si_name, "random") == 0 || 914 strncmp(dev->si_name, "fd/", strlen("fd/")) == 0 || 915 strncmp(dev->si_name, "ttyv", strlen("ttyv")) == 0) 916 lomac_type = MAC_LOMAC_TYPE_EQUAL; 917 else if (ptys_equal && 918 (strncmp(dev->si_name, "ttyp", strlen("ttyp")) == 0 || 919 strncmp(dev->si_name, "ptyp", strlen("ptyp")) == 0)) 920 lomac_type = MAC_LOMAC_TYPE_EQUAL; 921 else 922 lomac_type = MAC_LOMAC_TYPE_HIGH; 923 mac_lomac_set_single(mac_lomac, lomac_type, 0); 924} 925 926static void 927mac_lomac_create_devfs_directory(struct mount *mp, char *dirname, 928 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 929{ 930 struct mac_lomac *mac_lomac; 931 932 mac_lomac = SLOT(label); 933 mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0); 934} 935 936static void 937mac_lomac_create_devfs_symlink(struct ucred *cred, struct mount *mp, 938 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 939 struct label *delabel) 940{ 941 struct mac_lomac *source, *dest; 942 943 source = SLOT(cred->cr_label); 944 dest = SLOT(delabel); 945 946 mac_lomac_copy_single(source, dest); 947} 948 949static void 950mac_lomac_create_mount(struct ucred *cred, struct mount *mp, 951 struct label *mntlabel, struct label *fslabel) 952{ 953 struct mac_lomac *source, *dest; 954 955 source = SLOT(cred->cr_label); 956 dest = SLOT(mntlabel); 957 mac_lomac_copy_single(source, dest); 958 dest = SLOT(fslabel); 959 mac_lomac_copy_single(source, dest); 960} 961 962static void 963mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp, 964 struct label *vnodelabel, struct label *label) 965{ 966 struct mac_lomac *source, *dest; 967 968 source = SLOT(label); 969 dest = SLOT(vnodelabel); 970 971 try_relabel(source, dest); 972} 973 974static void 975mac_lomac_update_devfsdirent(struct mount *mp, 976 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 977 struct vnode *vp, struct label *vnodelabel) 978{ 979 struct mac_lomac *source, *dest; 980 981 source = SLOT(vnodelabel); 982 dest = SLOT(direntlabel); 983 984 mac_lomac_copy(source, dest); 985} 986 987static void 988mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *fslabel, 989 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 990 struct label *vlabel) 991{ 992 struct mac_lomac *source, *dest; 993 994 source = SLOT(delabel); 995 dest = SLOT(vlabel); 996 997 mac_lomac_copy_single(source, dest); 998} 999 1000static int 1001mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *fslabel, 1002 struct vnode *vp, struct label *vlabel) 1003{ 1004 struct mac_lomac temp, *source, *dest; 1005 int buflen, error; 1006 1007 source = SLOT(fslabel); 1008 dest = SLOT(vlabel); 1009 1010 buflen = sizeof(temp); 1011 bzero(&temp, buflen); 1012 1013 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1014 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread); 1015 if (error == ENOATTR || error == EOPNOTSUPP) { 1016 /* Fall back to the fslabel. */ 1017 mac_lomac_copy_single(source, dest); 1018 return (0); 1019 } else if (error) 1020 return (error); 1021 1022 if (buflen != sizeof(temp)) { 1023 if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) { 1024 printf("mac_lomac_associate_vnode_extattr: bad size %d\n", 1025 buflen); 1026 return (EPERM); 1027 } 1028 bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle)); 1029 buflen = sizeof(temp); 1030 (void)vn_extattr_set(vp, IO_NODELOCKED, 1031 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 1032 buflen, (char *)&temp, curthread); 1033 } 1034 if (mac_lomac_valid(&temp) != 0) { 1035 printf("mac_lomac_associate_vnode_extattr: invalid\n"); 1036 return (EPERM); 1037 } 1038 if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) { 1039 printf("mac_lomac_associate_vnode_extattr: not single\n"); 1040 return (EPERM); 1041 } 1042 1043 mac_lomac_copy_single(&temp, dest); 1044 return (0); 1045} 1046 1047static void 1048mac_lomac_associate_vnode_singlelabel(struct mount *mp, 1049 struct label *fslabel, struct vnode *vp, struct label *vlabel) 1050{ 1051 struct mac_lomac *source, *dest; 1052 1053 source = SLOT(fslabel); 1054 dest = SLOT(vlabel); 1055 1056 mac_lomac_copy_single(source, dest); 1057} 1058 1059static int 1060mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1061 struct label *fslabel, struct vnode *dvp, struct label *dlabel, 1062 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 1063{ 1064 struct mac_lomac *source, *dest, *dir, temp; 1065 size_t buflen; 1066 int error; 1067 1068 buflen = sizeof(temp); 1069 bzero(&temp, buflen); 1070 1071 source = SLOT(cred->cr_label); 1072 dest = SLOT(vlabel); 1073 dir = SLOT(dlabel); 1074 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 1075 mac_lomac_copy_auxsingle(dir, &temp); 1076 mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 1077 dir->ml_auxsingle.mle_grade); 1078 } else { 1079 mac_lomac_copy_single(source, &temp); 1080 } 1081 1082 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1083 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1084 if (error == 0) 1085 mac_lomac_copy(&temp, dest); 1086 return (error); 1087} 1088 1089static int 1090mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1091 struct label *vlabel, struct label *intlabel) 1092{ 1093 struct mac_lomac *source, temp; 1094 size_t buflen; 1095 int error; 1096 1097 buflen = sizeof(temp); 1098 bzero(&temp, buflen); 1099 1100 source = SLOT(intlabel); 1101 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1102 return (0); 1103 1104 mac_lomac_copy_single(source, &temp); 1105 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1106 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1107 return (error); 1108} 1109 1110/* 1111 * Labeling event operations: IPC object. 1112 */ 1113static void 1114mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel, 1115 struct inpcb *inp, struct label *inplabel) 1116{ 1117 struct mac_lomac *source, *dest; 1118 1119 source = SLOT(solabel); 1120 dest = SLOT(inplabel); 1121 1122 mac_lomac_copy_single(source, dest); 1123} 1124 1125static void 1126mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1127 struct mbuf *m, struct label *mbuflabel) 1128{ 1129 struct mac_lomac *source, *dest; 1130 1131 source = SLOT(socketlabel); 1132 dest = SLOT(mbuflabel); 1133 1134 mac_lomac_copy_single(source, dest); 1135} 1136 1137static void 1138mac_lomac_create_socket(struct ucred *cred, struct socket *socket, 1139 struct label *socketlabel) 1140{ 1141 struct mac_lomac *source, *dest; 1142 1143 source = SLOT(cred->cr_label); 1144 dest = SLOT(socketlabel); 1145 1146 mac_lomac_copy_single(source, dest); 1147} 1148 1149static void 1150mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp, 1151 struct label *pipelabel) 1152{ 1153 struct mac_lomac *source, *dest; 1154 1155 source = SLOT(cred->cr_label); 1156 dest = SLOT(pipelabel); 1157 1158 mac_lomac_copy_single(source, dest); 1159} 1160 1161static void 1162mac_lomac_create_socket_from_socket(struct socket *oldsocket, 1163 struct label *oldsocketlabel, struct socket *newsocket, 1164 struct label *newsocketlabel) 1165{ 1166 struct mac_lomac *source, *dest; 1167 1168 source = SLOT(oldsocketlabel); 1169 dest = SLOT(newsocketlabel); 1170 1171 mac_lomac_copy_single(source, dest); 1172} 1173 1174static void 1175mac_lomac_relabel_socket(struct ucred *cred, struct socket *socket, 1176 struct label *socketlabel, struct label *newlabel) 1177{ 1178 struct mac_lomac *source, *dest; 1179 1180 source = SLOT(newlabel); 1181 dest = SLOT(socketlabel); 1182 1183 try_relabel(source, dest); 1184} 1185 1186static void 1187mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1188 struct label *pipelabel, struct label *newlabel) 1189{ 1190 struct mac_lomac *source, *dest; 1191 1192 source = SLOT(newlabel); 1193 dest = SLOT(pipelabel); 1194 1195 try_relabel(source, dest); 1196} 1197 1198static void 1199mac_lomac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1200 struct socket *socket, struct label *socketpeerlabel) 1201{ 1202 struct mac_lomac *source, *dest; 1203 1204 source = SLOT(mbuflabel); 1205 dest = SLOT(socketpeerlabel); 1206 1207 mac_lomac_copy_single(source, dest); 1208} 1209 1210/* 1211 * Labeling event operations: network objects. 1212 */ 1213static void 1214mac_lomac_set_socket_peer_from_socket(struct socket *oldsocket, 1215 struct label *oldsocketlabel, struct socket *newsocket, 1216 struct label *newsocketpeerlabel) 1217{ 1218 struct mac_lomac *source, *dest; 1219 1220 source = SLOT(oldsocketlabel); 1221 dest = SLOT(newsocketpeerlabel); 1222 1223 mac_lomac_copy_single(source, dest); 1224} 1225 1226static void 1227mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1228 struct label *bpflabel) 1229{ 1230 struct mac_lomac *source, *dest; 1231 1232 source = SLOT(cred->cr_label); 1233 dest = SLOT(bpflabel); 1234 1235 mac_lomac_copy_single(source, dest); 1236} 1237 1238static void 1239mac_lomac_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1240{ 1241 char tifname[IFNAMSIZ], *p, *q; 1242 char tiflist[sizeof(trusted_interfaces)]; 1243 struct mac_lomac *dest; 1244 int len, grade; 1245 1246 dest = SLOT(ifnetlabel); 1247 1248 if (ifnet->if_type == IFT_LOOP) { 1249 grade = MAC_LOMAC_TYPE_EQUAL; 1250 goto set; 1251 } 1252 1253 if (trust_all_interfaces) { 1254 grade = MAC_LOMAC_TYPE_HIGH; 1255 goto set; 1256 } 1257 1258 grade = MAC_LOMAC_TYPE_LOW; 1259 1260 if (trusted_interfaces[0] == '\0' || 1261 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1262 goto set; 1263 1264 bzero(tiflist, sizeof(tiflist)); 1265 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1266 if(*p != ' ' && *p != '\t') 1267 *q = *p; 1268 1269 for (p = q = tiflist;; p++) { 1270 if (*p == ',' || *p == '\0') { 1271 len = p - q; 1272 if (len < IFNAMSIZ) { 1273 bzero(tifname, sizeof(tifname)); 1274 bcopy(q, tifname, len); 1275 if (strcmp(tifname, ifnet->if_xname) == 0) { 1276 grade = MAC_LOMAC_TYPE_HIGH; 1277 break; 1278 } 1279 } 1280 else { 1281 *p = '\0'; 1282 printf("MAC/LOMAC warning: interface name " 1283 "\"%s\" is too long (must be < %d)\n", 1284 q, IFNAMSIZ); 1285 } 1286 if (*p == '\0') 1287 break; 1288 q = p + 1; 1289 } 1290 } 1291set: 1292 mac_lomac_set_single(dest, grade, 0); 1293 mac_lomac_set_range(dest, grade, 0, grade, 0); 1294} 1295 1296static void 1297mac_lomac_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1298 struct ipq *ipq, struct label *ipqlabel) 1299{ 1300 struct mac_lomac *source, *dest; 1301 1302 source = SLOT(fragmentlabel); 1303 dest = SLOT(ipqlabel); 1304 1305 mac_lomac_copy_single(source, dest); 1306} 1307 1308static void 1309mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1310 struct mbuf *datagram, struct label *datagramlabel) 1311{ 1312 struct mac_lomac *source, *dest; 1313 1314 source = SLOT(ipqlabel); 1315 dest = SLOT(datagramlabel); 1316 1317 /* Just use the head, since we require them all to match. */ 1318 mac_lomac_copy_single(source, dest); 1319} 1320 1321static void 1322mac_lomac_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1323 struct mbuf *fragment, struct label *fragmentlabel) 1324{ 1325 struct mac_lomac *source, *dest; 1326 1327 source = SLOT(datagramlabel); 1328 dest = SLOT(fragmentlabel); 1329 1330 mac_lomac_copy_single(source, dest); 1331} 1332 1333static void 1334mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1335 struct mbuf *m, struct label *mlabel) 1336{ 1337 struct mac_lomac *source, *dest; 1338 1339 source = SLOT(inplabel); 1340 dest = SLOT(mlabel); 1341 1342 mac_lomac_copy_single(source, dest); 1343} 1344 1345static void 1346mac_lomac_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1347 struct mbuf *mbuf, struct label *mbuflabel) 1348{ 1349 struct mac_lomac *dest; 1350 1351 dest = SLOT(mbuflabel); 1352 1353 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1354} 1355 1356static void 1357mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1358 struct mbuf *mbuf, struct label *mbuflabel) 1359{ 1360 struct mac_lomac *source, *dest; 1361 1362 source = SLOT(bpflabel); 1363 dest = SLOT(mbuflabel); 1364 1365 mac_lomac_copy_single(source, dest); 1366} 1367 1368static void 1369mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1370 struct mbuf *m, struct label *mbuflabel) 1371{ 1372 struct mac_lomac *source, *dest; 1373 1374 source = SLOT(ifnetlabel); 1375 dest = SLOT(mbuflabel); 1376 1377 mac_lomac_copy_single(source, dest); 1378} 1379 1380static void 1381mac_lomac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1382 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1383 struct mbuf *newmbuf, struct label *newmbuflabel) 1384{ 1385 struct mac_lomac *source, *dest; 1386 1387 source = SLOT(oldmbuflabel); 1388 dest = SLOT(newmbuflabel); 1389 1390 mac_lomac_copy_single(source, dest); 1391} 1392 1393static void 1394mac_lomac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1395 struct mbuf *newmbuf, struct label *newmbuflabel) 1396{ 1397 struct mac_lomac *source, *dest; 1398 1399 source = SLOT(oldmbuflabel); 1400 dest = SLOT(newmbuflabel); 1401 1402 mac_lomac_copy_single(source, dest); 1403} 1404 1405static int 1406mac_lomac_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1407 struct ipq *ipq, struct label *ipqlabel) 1408{ 1409 struct mac_lomac *a, *b; 1410 1411 a = SLOT(ipqlabel); 1412 b = SLOT(fragmentlabel); 1413 1414 return (mac_lomac_equal_single(a, b)); 1415} 1416 1417static void 1418mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1419 struct label *ifnetlabel, struct label *newlabel) 1420{ 1421 struct mac_lomac *source, *dest; 1422 1423 source = SLOT(newlabel); 1424 dest = SLOT(ifnetlabel); 1425 1426 try_relabel(source, dest); 1427} 1428 1429static void 1430mac_lomac_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1431 struct ipq *ipq, struct label *ipqlabel) 1432{ 1433 1434 /* NOOP: we only accept matching labels, so no need to update */ 1435} 1436 1437static void 1438mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1439 struct inpcb *inp, struct label *inplabel) 1440{ 1441 struct mac_lomac *source, *dest; 1442 1443 source = SLOT(solabel); 1444 dest = SLOT(inplabel); 1445 1446 mac_lomac_copy_single(source, dest); 1447} 1448
|
1449/* 1450 * Labeling event operations: processes. 1451 */ 1452static void 1453mac_lomac_execve_transition(struct ucred *old, struct ucred *new, 1454 struct vnode *vp, struct label *vnodelabel, 1455 struct label *interpvnodelabel, struct image_params *imgp, 1456 struct label *execlabel) 1457{ 1458 struct mac_lomac *source, *dest, *obj, *robj; 1459 1460 source = SLOT(old->cr_label); 1461 dest = SLOT(new->cr_label); 1462 obj = SLOT(vnodelabel); 1463 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1464 1465 mac_lomac_copy(source, dest); 1466 /* 1467 * If there's an auxiliary label on the real object, respect it 1468 * and assume that this level should be assumed immediately if 1469 * a higher level is currently in place. 1470 */ 1471 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1472 !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 1473 && mac_lomac_auxsingle_in_range(robj, dest)) 1474 mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type, 1475 robj->ml_auxsingle.mle_grade); 1476 /* 1477 * Restructuring to use the execve transitioning mechanism 1478 * instead of the normal demotion mechanism here would be 1479 * difficult, so just copy the label over and perform standard 1480 * demotion. This is also non-optimal because it will result 1481 * in the intermediate label "new" being created and immediately 1482 * recycled. 1483 */ 1484 if (mac_lomac_enabled && revocation_enabled && 1485 !mac_lomac_dominate_single(obj, source)) 1486 (void)maybe_demote(source, obj, "executing", "file", vp); 1487} 1488 1489static int 1490mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp, 1491 struct label *vnodelabel, struct label *interpvnodelabel, 1492 struct image_params *imgp, struct label *execlabel) 1493{ 1494 struct mac_lomac *subj, *obj, *robj; 1495 1496 if (!mac_lomac_enabled || !revocation_enabled) 1497 return (0); 1498 1499 subj = SLOT(old->cr_label); 1500 obj = SLOT(vnodelabel); 1501 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1502 1503 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1504 !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 1505 && mac_lomac_auxsingle_in_range(robj, subj)) || 1506 !mac_lomac_dominate_single(obj, subj)); 1507} 1508 1509static void 1510mac_lomac_create_proc0(struct ucred *cred) 1511{ 1512 struct mac_lomac *dest; 1513 1514 dest = SLOT(cred->cr_label); 1515 1516 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1517 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1518 0); 1519} 1520 1521static void 1522mac_lomac_create_proc1(struct ucred *cred) 1523{ 1524 struct mac_lomac *dest; 1525 1526 dest = SLOT(cred->cr_label); 1527 1528 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0); 1529 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1530 0); 1531} 1532 1533static void 1534mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel) 1535{ 1536 struct mac_lomac *source, *dest; 1537 1538 source = SLOT(newlabel); 1539 dest = SLOT(cred->cr_label); 1540 1541 try_relabel(source, dest); 1542} 1543 1544/* 1545 * Access control checks. 1546 */ 1547static int 1548mac_lomac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1549 struct ifnet *ifnet, struct label *ifnetlabel) 1550{ 1551 struct mac_lomac *a, *b; 1552 1553 if (!mac_lomac_enabled) 1554 return (0); 1555 1556 a = SLOT(bpflabel); 1557 b = SLOT(ifnetlabel); 1558 1559 if (mac_lomac_equal_single(a, b)) 1560 return (0); 1561 return (EACCES); 1562} 1563 1564static int 1565mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1566{ 1567 struct mac_lomac *subj, *new; 1568 int error; 1569 1570 subj = SLOT(cred->cr_label); 1571 new = SLOT(newlabel); 1572 1573 /* 1574 * If there is a LOMAC label update for the credential, it may 1575 * be an update of the single, range, or both. 1576 */ 1577 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1578 if (error) 1579 return (error); 1580 1581 /* 1582 * If the LOMAC label is to be changed, authorize as appropriate. 1583 */ 1584 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1585 /* 1586 * Fill in the missing parts from the previous label. 1587 */ 1588 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1589 mac_lomac_copy_single(subj, new); 1590 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1591 mac_lomac_copy_range(subj, new); 1592 1593 /* 1594 * To change the LOMAC range on a credential, the new 1595 * range label must be in the current range. 1596 */ 1597 if (!mac_lomac_range_in_range(new, subj)) 1598 return (EPERM); 1599 1600 /* 1601 * To change the LOMAC single label on a credential, the 1602 * new single label must be in the new range. Implicitly 1603 * from the previous check, the new single is in the old 1604 * range. 1605 */ 1606 if (!mac_lomac_single_in_range(new, new)) 1607 return (EPERM); 1608 1609 /* 1610 * To have EQUAL in any component of the new credential 1611 * LOMAC label, the subject must already have EQUAL in 1612 * their label. 1613 */ 1614 if (mac_lomac_contains_equal(new)) { 1615 error = mac_lomac_subject_privileged(subj); 1616 if (error) 1617 return (error); 1618 } 1619 1620 /* 1621 * XXXMAC: Additional consistency tests regarding the 1622 * single and range of the new label might be performed 1623 * here. 1624 */ 1625 } 1626 1627 return (0); 1628} 1629 1630static int 1631mac_lomac_check_cred_visible(struct ucred *u1, struct ucred *u2) 1632{ 1633 struct mac_lomac *subj, *obj; 1634 1635 if (!mac_lomac_enabled) 1636 return (0); 1637 1638 subj = SLOT(u1->cr_label); 1639 obj = SLOT(u2->cr_label); 1640 1641 /* XXX: range */ 1642 if (!mac_lomac_dominate_single(obj, subj)) 1643 return (ESRCH); 1644 1645 return (0); 1646} 1647 1648static int 1649mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1650 struct label *ifnetlabel, struct label *newlabel) 1651{ 1652 struct mac_lomac *subj, *new; 1653 int error; 1654 1655 subj = SLOT(cred->cr_label); 1656 new = SLOT(newlabel); 1657 1658 /* 1659 * If there is a LOMAC label update for the interface, it may 1660 * be an update of the single, range, or both. 1661 */ 1662 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1663 if (error) 1664 return (error); 1665 1666 /* 1667 * Relabling network interfaces requires LOMAC privilege. 1668 */ 1669 error = mac_lomac_subject_privileged(subj); 1670 if (error) 1671 return (error); 1672 1673 /* 1674 * If the LOMAC label is to be changed, authorize as appropriate. 1675 */ 1676 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1677 /* 1678 * Fill in the missing parts from the previous label. 1679 */ 1680 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1681 mac_lomac_copy_single(subj, new); 1682 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1683 mac_lomac_copy_range(subj, new); 1684 1685 /* 1686 * Rely on the traditional superuser status for the LOMAC 1687 * interface relabel requirements. XXXMAC: This will go 1688 * away. 1689 */ 1690 error = suser_cred(cred, 0); 1691 if (error) 1692 return (EPERM); 1693 1694 /* 1695 * XXXMAC: Additional consistency tests regarding the single 1696 * and the range of the new label might be performed here. 1697 */ 1698 } 1699 1700 return (0); 1701} 1702 1703static int 1704mac_lomac_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1705 struct mbuf *m, struct label *mbuflabel) 1706{ 1707 struct mac_lomac *p, *i; 1708 1709 if (!mac_lomac_enabled) 1710 return (0); 1711 1712 p = SLOT(mbuflabel); 1713 i = SLOT(ifnetlabel); 1714 1715 return (mac_lomac_single_in_range(p, i) ? 0 : EACCES); 1716} 1717 1718static int 1719mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1720 struct mbuf *m, struct label *mlabel) 1721{ 1722 struct mac_lomac *p, *i; 1723 1724 if (!mac_lomac_enabled) 1725 return (0); 1726 1727 p = SLOT(mlabel); 1728 i = SLOT(inplabel); 1729 1730 return (mac_lomac_equal_single(p, i) ? 0 : EACCES); 1731} 1732 1733static int 1734mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp, 1735 struct label *label) 1736{ 1737 struct mac_lomac *subj, *obj; 1738 1739 if (!mac_lomac_enabled) 1740 return (0); 1741 1742 subj = SLOT(cred->cr_label); 1743 obj = SLOT(label); 1744 1745 if (mac_lomac_subject_privileged(subj)) 1746 return (EPERM); 1747 1748 if (!mac_lomac_high_single(obj)) 1749 return (EACCES); 1750 1751 return (0); 1752} 1753 1754static int 1755mac_lomac_check_kld_unload(struct ucred *cred) 1756{ 1757 struct mac_lomac *subj; 1758 1759 if (!mac_lomac_enabled) 1760 return (0); 1761 1762 subj = SLOT(cred->cr_label); 1763 1764 if (mac_lomac_subject_privileged(subj)) 1765 return (EPERM); 1766 1767 return (0); 1768} 1769 1770static int 1771mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1772 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1773{ 1774 1775 if(!mac_lomac_enabled) 1776 return (0); 1777 1778 /* XXX: This will be implemented soon... */ 1779 1780 return (0); 1781} 1782 1783static int 1784mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1785 struct label *pipelabel) 1786{ 1787 struct mac_lomac *subj, *obj; 1788 1789 if (!mac_lomac_enabled) 1790 return (0); 1791 1792 subj = SLOT(cred->cr_label); 1793 obj = SLOT((pipelabel)); 1794 1795 if (!mac_lomac_dominate_single(obj, subj)) 1796 return (maybe_demote(subj, obj, "reading", "pipe", NULL)); 1797 1798 return (0); 1799} 1800 1801static int 1802mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1803 struct label *pipelabel, struct label *newlabel) 1804{ 1805 struct mac_lomac *subj, *obj, *new; 1806 int error; 1807 1808 new = SLOT(newlabel); 1809 subj = SLOT(cred->cr_label); 1810 obj = SLOT(pipelabel); 1811 1812 /* 1813 * If there is a LOMAC label update for a pipe, it must be a 1814 * single update. 1815 */ 1816 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1817 if (error) 1818 return (error); 1819 1820 /* 1821 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must 1822 * authorize the relabel. 1823 */ 1824 if (!mac_lomac_single_in_range(obj, subj)) 1825 return (EPERM); 1826 1827 /* 1828 * If the LOMAC label is to be changed, authorize as appropriate. 1829 */ 1830 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1831 /* 1832 * To change the LOMAC label on a pipe, the new pipe label 1833 * must be in the subject range. 1834 */ 1835 if (!mac_lomac_single_in_range(new, subj)) 1836 return (EPERM); 1837 1838 /* 1839 * To change the LOMAC label on a pipe to be EQUAL, the 1840 * subject must have appropriate privilege. 1841 */ 1842 if (mac_lomac_contains_equal(new)) { 1843 error = mac_lomac_subject_privileged(subj); 1844 if (error) 1845 return (error); 1846 } 1847 } 1848 1849 return (0); 1850} 1851 1852static int 1853mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp, 1854 struct label *pipelabel) 1855{ 1856 struct mac_lomac *subj, *obj; 1857 1858 if (!mac_lomac_enabled) 1859 return (0); 1860 1861 subj = SLOT(cred->cr_label); 1862 obj = SLOT((pipelabel)); 1863 1864 if (!mac_lomac_subject_dominate(subj, obj)) 1865 return (EACCES); 1866 1867 return (0); 1868} 1869 1870static int 1871mac_lomac_check_proc_debug(struct ucred *cred, struct proc *proc) 1872{ 1873 struct mac_lomac *subj, *obj; 1874 1875 if (!mac_lomac_enabled) 1876 return (0); 1877 1878 subj = SLOT(cred->cr_label); 1879 obj = SLOT(proc->p_ucred->cr_label); 1880 1881 /* XXX: range checks */ 1882 if (!mac_lomac_dominate_single(obj, subj)) 1883 return (ESRCH); 1884 if (!mac_lomac_subject_dominate(subj, obj)) 1885 return (EACCES); 1886 1887 return (0); 1888} 1889 1890static int 1891mac_lomac_check_proc_sched(struct ucred *cred, struct proc *proc) 1892{ 1893 struct mac_lomac *subj, *obj; 1894 1895 if (!mac_lomac_enabled) 1896 return (0); 1897 1898 subj = SLOT(cred->cr_label); 1899 obj = SLOT(proc->p_ucred->cr_label); 1900 1901 /* XXX: range checks */ 1902 if (!mac_lomac_dominate_single(obj, subj)) 1903 return (ESRCH); 1904 if (!mac_lomac_subject_dominate(subj, obj)) 1905 return (EACCES); 1906 1907 return (0); 1908} 1909 1910static int 1911mac_lomac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1912{ 1913 struct mac_lomac *subj, *obj; 1914 1915 if (!mac_lomac_enabled) 1916 return (0); 1917 1918 subj = SLOT(cred->cr_label); 1919 obj = SLOT(proc->p_ucred->cr_label); 1920 1921 /* XXX: range checks */ 1922 if (!mac_lomac_dominate_single(obj, subj)) 1923 return (ESRCH); 1924 if (!mac_lomac_subject_dominate(subj, obj)) 1925 return (EACCES); 1926 1927 return (0); 1928} 1929 1930static int 1931mac_lomac_check_socket_deliver(struct socket *so, struct label *socketlabel, 1932 struct mbuf *m, struct label *mbuflabel) 1933{ 1934 struct mac_lomac *p, *s; 1935 1936 if (!mac_lomac_enabled) 1937 return (0); 1938 1939 p = SLOT(mbuflabel); 1940 s = SLOT(socketlabel); 1941 1942 return (mac_lomac_equal_single(p, s) ? 0 : EACCES); 1943} 1944 1945static int 1946mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *socket, 1947 struct label *socketlabel, struct label *newlabel) 1948{ 1949 struct mac_lomac *subj, *obj, *new; 1950 int error; 1951 1952 new = SLOT(newlabel); 1953 subj = SLOT(cred->cr_label); 1954 obj = SLOT(socketlabel); 1955 1956 /* 1957 * If there is a LOMAC label update for the socket, it may be 1958 * an update of single. 1959 */ 1960 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1961 if (error) 1962 return (error); 1963 1964 /* 1965 * To relabel a socket, the old socket single must be in the subject 1966 * range. 1967 */ 1968 if (!mac_lomac_single_in_range(obj, subj)) 1969 return (EPERM); 1970 1971 /* 1972 * If the LOMAC label is to be changed, authorize as appropriate. 1973 */ 1974 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1975 /* 1976 * To relabel a socket, the new socket single must be in 1977 * the subject range. 1978 */ 1979 if (!mac_lomac_single_in_range(new, subj)) 1980 return (EPERM); 1981 1982 /* 1983 * To change the LOMAC label on the socket to contain EQUAL, 1984 * the subject must have appropriate privilege. 1985 */ 1986 if (mac_lomac_contains_equal(new)) { 1987 error = mac_lomac_subject_privileged(subj); 1988 if (error) 1989 return (error); 1990 } 1991 } 1992 1993 return (0); 1994} 1995 1996static int 1997mac_lomac_check_socket_visible(struct ucred *cred, struct socket *socket, 1998 struct label *socketlabel) 1999{ 2000 struct mac_lomac *subj, *obj; 2001 2002 if (!mac_lomac_enabled) 2003 return (0); 2004 2005 subj = SLOT(cred->cr_label); 2006 obj = SLOT(socketlabel); 2007 2008 if (!mac_lomac_dominate_single(obj, subj)) 2009 return (ENOENT); 2010 2011 return (0); 2012} 2013 2014static int 2015mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp, 2016 struct label *label) 2017{ 2018 struct mac_lomac *subj, *obj; 2019 2020 if (!mac_lomac_enabled) 2021 return (0); 2022 2023 subj = SLOT(cred->cr_label); 2024 obj = SLOT(label); 2025 2026 if (mac_lomac_subject_privileged(subj)) 2027 return (EPERM); 2028 2029 if (!mac_lomac_high_single(obj)) 2030 return (EACCES); 2031 2032 return (0); 2033} 2034 2035static int 2036mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2037 void *arg1, int arg2, struct sysctl_req *req) 2038{ 2039 struct mac_lomac *subj; 2040 2041 if (!mac_lomac_enabled) 2042 return (0); 2043 2044 subj = SLOT(cred->cr_label); 2045 2046 /* 2047 * Treat sysctl variables without CTLFLAG_ANYBODY flag as 2048 * lomac/high, but also require privilege to change them. 2049 */ 2050 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2051#ifdef notdef 2052 if (!mac_lomac_subject_dominate_high(subj)) 2053 return (EACCES); 2054#endif 2055 2056 if (mac_lomac_subject_privileged(subj)) 2057 return (EPERM); 2058 } 2059 2060 return (0); 2061} 2062 2063static int 2064mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2065 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2066{ 2067 struct mac_lomac *subj, *obj; 2068 2069 if (!mac_lomac_enabled) 2070 return (0); 2071 2072 subj = SLOT(cred->cr_label); 2073 obj = SLOT(dlabel); 2074 2075 if (!mac_lomac_subject_dominate(subj, obj)) 2076 return (EACCES); 2077 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2078 !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2079 return (EACCES); 2080 2081 return (0); 2082} 2083 2084static int 2085mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2086 struct label *dlabel, struct vnode *vp, struct label *label, 2087 struct componentname *cnp) 2088{ 2089 struct mac_lomac *subj, *obj; 2090 2091 if (!mac_lomac_enabled) 2092 return (0); 2093 2094 subj = SLOT(cred->cr_label); 2095 obj = SLOT(dlabel); 2096 2097 if (!mac_lomac_subject_dominate(subj, obj)) 2098 return (EACCES); 2099 2100 obj = SLOT(label); 2101 2102 if (!mac_lomac_subject_dominate(subj, obj)) 2103 return (EACCES); 2104 2105 return (0); 2106} 2107 2108static int 2109mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2110 struct label *label, acl_type_t type) 2111{ 2112 struct mac_lomac *subj, *obj; 2113 2114 if (!mac_lomac_enabled) 2115 return (0); 2116 2117 subj = SLOT(cred->cr_label); 2118 obj = SLOT(label); 2119 2120 if (!mac_lomac_subject_dominate(subj, obj)) 2121 return (EACCES); 2122 2123 return (0); 2124} 2125 2126static int 2127mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2128 struct label *dlabel, struct vnode *vp, struct label *label, 2129 struct componentname *cnp) 2130{ 2131 struct mac_lomac *subj, *obj; 2132 2133 if (!mac_lomac_enabled) 2134 return (0); 2135 2136 subj = SLOT(cred->cr_label); 2137 obj = SLOT(dlabel); 2138 2139 if (!mac_lomac_subject_dominate(subj, obj)) 2140 return (EACCES); 2141 2142 obj = SLOT(label); 2143 2144 if (!mac_lomac_subject_dominate(subj, obj)) 2145 return (EACCES); 2146 2147 return (0); 2148} 2149 2150static int 2151mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2152 struct label *label, int prot, int flags) 2153{ 2154 struct mac_lomac *subj, *obj; 2155 2156 /* 2157 * Rely on the use of open()-time protections to handle 2158 * non-revocation cases. 2159 */ 2160 if (!mac_lomac_enabled) 2161 return (0); 2162 2163 subj = SLOT(cred->cr_label); 2164 obj = SLOT(label); 2165 2166 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2167 if (!mac_lomac_subject_dominate(subj, obj)) 2168 return (EACCES); 2169 } 2170 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2171 if (!mac_lomac_dominate_single(obj, subj)) 2172 return (maybe_demote(subj, obj, "mapping", "file", vp)); 2173 } 2174 2175 return (0); 2176} 2177 2178static void 2179mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, 2180 struct label *label, /* XXX vm_prot_t */ int *prot) 2181{ 2182 struct mac_lomac *subj, *obj; 2183 2184 /* 2185 * Rely on the use of open()-time protections to handle 2186 * non-revocation cases. 2187 */ 2188 if (!mac_lomac_enabled || !revocation_enabled) 2189 return; 2190 2191 subj = SLOT(cred->cr_label); 2192 obj = SLOT(label); 2193 2194 if (!mac_lomac_subject_dominate(subj, obj)) 2195 *prot &= ~VM_PROT_WRITE; 2196} 2197 2198static int 2199mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp, 2200 struct label *vnodelabel, int acc_mode) 2201{ 2202 struct mac_lomac *subj, *obj; 2203 2204 if (!mac_lomac_enabled) 2205 return (0); 2206 2207 subj = SLOT(cred->cr_label); 2208 obj = SLOT(vnodelabel); 2209 2210 /* XXX privilege override for admin? */ 2211 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2212 if (!mac_lomac_subject_dominate(subj, obj)) 2213 return (EACCES); 2214 } 2215 2216 return (0); 2217} 2218 2219static int 2220mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2221 struct vnode *vp, struct label *label) 2222{ 2223 struct mac_lomac *subj, *obj; 2224 2225 if (!mac_lomac_enabled || !revocation_enabled) 2226 return (0); 2227 2228 subj = SLOT(active_cred->cr_label); 2229 obj = SLOT(label); 2230 2231 if (!mac_lomac_dominate_single(obj, subj)) 2232 return (maybe_demote(subj, obj, "reading", "file", vp)); 2233 2234 return (0); 2235} 2236 2237static int 2238mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2239 struct label *vnodelabel, struct label *newlabel) 2240{ 2241 struct mac_lomac *old, *new, *subj; 2242 int error; 2243 2244 old = SLOT(vnodelabel); 2245 new = SLOT(newlabel); 2246 subj = SLOT(cred->cr_label); 2247 2248 /* 2249 * If there is a LOMAC label update for the vnode, it must be a 2250 * single label, with an optional explicit auxiliary single. 2251 */ 2252 error = lomac_atmostflags(new, 2253 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2254 if (error) 2255 return (error); 2256 2257 /* 2258 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2259 * authorize the relabel. 2260 */ 2261 if (!mac_lomac_single_in_range(old, subj)) 2262 return (EPERM); 2263 2264 /* 2265 * If the LOMAC label is to be changed, authorize as appropriate. 2266 */ 2267 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2268 /* 2269 * To change the LOMAC label on a vnode, the new vnode label 2270 * must be in the subject range. 2271 */ 2272 if (!mac_lomac_single_in_range(new, subj)) 2273 return (EPERM); 2274 2275 /* 2276 * To change the LOMAC label on the vnode to be EQUAL, 2277 * the subject must have appropriate privilege. 2278 */ 2279 if (mac_lomac_contains_equal(new)) { 2280 error = mac_lomac_subject_privileged(subj); 2281 if (error) 2282 return (error); 2283 } 2284 } 2285 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2286 /* 2287 * Fill in the missing parts from the previous label. 2288 */ 2289 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2290 mac_lomac_copy_single(subj, new); 2291 2292 /* 2293 * To change the auxiliary LOMAC label on a vnode, the new 2294 * vnode label must be in the subject range. 2295 */ 2296 if (!mac_lomac_auxsingle_in_range(new, subj)) 2297 return (EPERM); 2298 2299 /* 2300 * To change the auxiliary LOMAC label on the vnode to be 2301 * EQUAL, the subject must have appropriate privilege. 2302 */ 2303 if (mac_lomac_contains_equal(new)) { 2304 error = mac_lomac_subject_privileged(subj); 2305 if (error) 2306 return (error); 2307 } 2308 } 2309 2310 return (0); 2311} 2312 2313static int 2314mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2315 struct label *dlabel, struct vnode *vp, struct label *label, 2316 struct componentname *cnp) 2317{ 2318 struct mac_lomac *subj, *obj; 2319 2320 if (!mac_lomac_enabled) 2321 return (0); 2322 2323 subj = SLOT(cred->cr_label); 2324 obj = SLOT(dlabel); 2325 2326 if (!mac_lomac_subject_dominate(subj, obj)) 2327 return (EACCES); 2328 2329 obj = SLOT(label); 2330 2331 if (!mac_lomac_subject_dominate(subj, obj)) 2332 return (EACCES); 2333 2334 return (0); 2335} 2336 2337static int 2338mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2339 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2340 struct componentname *cnp) 2341{ 2342 struct mac_lomac *subj, *obj; 2343 2344 if (!mac_lomac_enabled) 2345 return (0); 2346 2347 subj = SLOT(cred->cr_label); 2348 obj = SLOT(dlabel); 2349 2350 if (!mac_lomac_subject_dominate(subj, obj)) 2351 return (EACCES); 2352 2353 if (vp != NULL) { 2354 obj = SLOT(label); 2355 2356 if (!mac_lomac_subject_dominate(subj, obj)) 2357 return (EACCES); 2358 } 2359 2360 return (0); 2361} 2362 2363static int 2364mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2365 struct label *label) 2366{ 2367 struct mac_lomac *subj, *obj; 2368 2369 if (!mac_lomac_enabled) 2370 return (0); 2371 2372 subj = SLOT(cred->cr_label); 2373 obj = SLOT(label); 2374 2375 if (!mac_lomac_subject_dominate(subj, obj)) 2376 return (EACCES); 2377 2378 return (0); 2379} 2380 2381static int 2382mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2383 struct label *label, acl_type_t type, struct acl *acl) 2384{ 2385 struct mac_lomac *subj, *obj; 2386 2387 if (!mac_lomac_enabled) 2388 return (0); 2389 2390 subj = SLOT(cred->cr_label); 2391 obj = SLOT(label); 2392 2393 if (!mac_lomac_subject_dominate(subj, obj)) 2394 return (EACCES); 2395 2396 return (0); 2397} 2398 2399static int 2400mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2401 struct label *vnodelabel, int attrnamespace, const char *name, 2402 struct uio *uio) 2403{ 2404 struct mac_lomac *subj, *obj; 2405 2406 if (!mac_lomac_enabled) 2407 return (0); 2408 2409 subj = SLOT(cred->cr_label); 2410 obj = SLOT(vnodelabel); 2411 2412 if (!mac_lomac_subject_dominate(subj, obj)) 2413 return (EACCES); 2414 2415 /* XXX: protect the MAC EA in a special way? */ 2416 2417 return (0); 2418} 2419 2420static int 2421mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2422 struct label *vnodelabel, u_long flags) 2423{ 2424 struct mac_lomac *subj, *obj; 2425 2426 if (!mac_lomac_enabled) 2427 return (0); 2428 2429 subj = SLOT(cred->cr_label); 2430 obj = SLOT(vnodelabel); 2431 2432 if (!mac_lomac_subject_dominate(subj, obj)) 2433 return (EACCES); 2434 2435 return (0); 2436} 2437 2438static int 2439mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2440 struct label *vnodelabel, mode_t mode) 2441{ 2442 struct mac_lomac *subj, *obj; 2443 2444 if (!mac_lomac_enabled) 2445 return (0); 2446 2447 subj = SLOT(cred->cr_label); 2448 obj = SLOT(vnodelabel); 2449 2450 if (!mac_lomac_subject_dominate(subj, obj)) 2451 return (EACCES); 2452 2453 return (0); 2454} 2455 2456static int 2457mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2458 struct label *vnodelabel, uid_t uid, gid_t gid) 2459{ 2460 struct mac_lomac *subj, *obj; 2461 2462 if (!mac_lomac_enabled) 2463 return (0); 2464 2465 subj = SLOT(cred->cr_label); 2466 obj = SLOT(vnodelabel); 2467 2468 if (!mac_lomac_subject_dominate(subj, obj)) 2469 return (EACCES); 2470 2471 return (0); 2472} 2473 2474static int 2475mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2476 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2477{ 2478 struct mac_lomac *subj, *obj; 2479 2480 if (!mac_lomac_enabled) 2481 return (0); 2482 2483 subj = SLOT(cred->cr_label); 2484 obj = SLOT(vnodelabel); 2485 2486 if (!mac_lomac_subject_dominate(subj, obj)) 2487 return (EACCES); 2488 2489 return (0); 2490} 2491 2492static int 2493mac_lomac_check_vnode_write(struct ucred *active_cred, 2494 struct ucred *file_cred, struct vnode *vp, struct label *label) 2495{ 2496 struct mac_lomac *subj, *obj; 2497 2498 if (!mac_lomac_enabled || !revocation_enabled) 2499 return (0); 2500 2501 subj = SLOT(active_cred->cr_label); 2502 obj = SLOT(label); 2503 2504 if (!mac_lomac_subject_dominate(subj, obj)) 2505 return (EACCES); 2506 2507 return (0); 2508} 2509 2510static void 2511mac_lomac_thread_userret(struct thread *td) 2512{ 2513 struct proc *p = td->td_proc; 2514 struct mac_lomac_proc *subj = PSLOT(p->p_label); 2515 struct ucred *newcred, *oldcred; 2516 int dodrop; 2517 2518 mtx_lock(&subj->mtx); 2519 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 2520 dodrop = 0; 2521 mtx_unlock(&subj->mtx); 2522 newcred = crget(); 2523 /* 2524 * Prevent a lock order reversal in 2525 * mac_cred_mmapped_drop_perms; ideally, the other 2526 * user of subj->mtx wouldn't be holding Giant. 2527 */ 2528 mtx_lock(&Giant); 2529 PROC_LOCK(p); 2530 mtx_lock(&subj->mtx); 2531 /* 2532 * Check if we lost the race while allocating the cred. 2533 */ 2534 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2535 crfree(newcred); 2536 goto out; 2537 } 2538 oldcred = p->p_ucred; 2539 crcopy(newcred, oldcred); 2540 crhold(newcred); 2541 mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2542 p->p_ucred = newcred; 2543 crfree(oldcred); 2544 dodrop = 1; 2545 out: 2546 mtx_unlock(&subj->mtx); 2547 PROC_UNLOCK(p); 2548 if (dodrop) 2549 mac_cred_mmapped_drop_perms(curthread, newcred); 2550 mtx_unlock(&Giant); 2551 } else { 2552 mtx_unlock(&subj->mtx); 2553 } 2554} 2555 2556static struct mac_policy_ops mac_lomac_ops = 2557{ 2558 .mpo_init = mac_lomac_init, 2559 .mpo_init_bpfdesc_label = mac_lomac_init_label, 2560 .mpo_init_cred_label = mac_lomac_init_label, 2561 .mpo_init_devfsdirent_label = mac_lomac_init_label, 2562 .mpo_init_ifnet_label = mac_lomac_init_label, 2563 .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck, 2564 .mpo_init_ipq_label = mac_lomac_init_label_waitcheck, 2565 .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck, 2566 .mpo_init_mount_label = mac_lomac_init_label, 2567 .mpo_init_mount_fs_label = mac_lomac_init_label, 2568 .mpo_init_pipe_label = mac_lomac_init_label, 2569 .mpo_init_proc_label = mac_lomac_init_proc_label, 2570 .mpo_init_socket_label = mac_lomac_init_label_waitcheck, 2571 .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck, 2572 .mpo_init_vnode_label = mac_lomac_init_label, 2573 .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label, 2574 .mpo_destroy_cred_label = mac_lomac_destroy_label, 2575 .mpo_destroy_devfsdirent_label = mac_lomac_destroy_label, 2576 .mpo_destroy_ifnet_label = mac_lomac_destroy_label, 2577 .mpo_destroy_inpcb_label = mac_lomac_destroy_label, 2578 .mpo_destroy_ipq_label = mac_lomac_destroy_label, 2579 .mpo_destroy_mbuf_label = mac_lomac_destroy_label, 2580 .mpo_destroy_mount_label = mac_lomac_destroy_label, 2581 .mpo_destroy_mount_fs_label = mac_lomac_destroy_label, 2582 .mpo_destroy_pipe_label = mac_lomac_destroy_label, 2583 .mpo_destroy_proc_label = mac_lomac_destroy_proc_label, 2584 .mpo_destroy_socket_label = mac_lomac_destroy_label, 2585 .mpo_destroy_socket_peer_label = mac_lomac_destroy_label, 2586 .mpo_destroy_vnode_label = mac_lomac_destroy_label, 2587 .mpo_copy_cred_label = mac_lomac_copy_label, 2588 .mpo_copy_ifnet_label = mac_lomac_copy_label, 2589 .mpo_copy_mbuf_label = mac_lomac_copy_label, 2590 .mpo_copy_pipe_label = mac_lomac_copy_label, 2591 .mpo_copy_socket_label = mac_lomac_copy_label, 2592 .mpo_copy_vnode_label = mac_lomac_copy_label, 2593 .mpo_externalize_cred_label = mac_lomac_externalize_label, 2594 .mpo_externalize_ifnet_label = mac_lomac_externalize_label, 2595 .mpo_externalize_pipe_label = mac_lomac_externalize_label, 2596 .mpo_externalize_socket_label = mac_lomac_externalize_label, 2597 .mpo_externalize_socket_peer_label = mac_lomac_externalize_label, 2598 .mpo_externalize_vnode_label = mac_lomac_externalize_label, 2599 .mpo_internalize_cred_label = mac_lomac_internalize_label, 2600 .mpo_internalize_ifnet_label = mac_lomac_internalize_label, 2601 .mpo_internalize_pipe_label = mac_lomac_internalize_label, 2602 .mpo_internalize_socket_label = mac_lomac_internalize_label, 2603 .mpo_internalize_vnode_label = mac_lomac_internalize_label, 2604 .mpo_create_devfs_device = mac_lomac_create_devfs_device, 2605 .mpo_create_devfs_directory = mac_lomac_create_devfs_directory, 2606 .mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink, 2607 .mpo_create_mount = mac_lomac_create_mount, 2608 .mpo_relabel_vnode = mac_lomac_relabel_vnode, 2609 .mpo_update_devfsdirent = mac_lomac_update_devfsdirent, 2610 .mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs, 2611 .mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr, 2612 .mpo_associate_vnode_singlelabel = 2613 mac_lomac_associate_vnode_singlelabel, 2614 .mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr, 2615 .mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr, 2616 .mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket, 2617 .mpo_create_pipe = mac_lomac_create_pipe, 2618 .mpo_create_socket = mac_lomac_create_socket, 2619 .mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket, 2620 .mpo_relabel_pipe = mac_lomac_relabel_pipe, 2621 .mpo_relabel_socket = mac_lomac_relabel_socket, 2622 .mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf, 2623 .mpo_set_socket_peer_from_socket = 2624 mac_lomac_set_socket_peer_from_socket, 2625 .mpo_create_bpfdesc = mac_lomac_create_bpfdesc, 2626 .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq, 2627 .mpo_create_fragment = mac_lomac_create_fragment, 2628 .mpo_create_ifnet = mac_lomac_create_ifnet, 2629 .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket, 2630 .mpo_create_ipq = mac_lomac_create_ipq, 2631 .mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb, 2632 .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer, 2633 .mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc, 2634 .mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet, 2635 .mpo_create_mbuf_multicast_encap = 2636 mac_lomac_create_mbuf_multicast_encap, 2637 .mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer, 2638 .mpo_fragment_match = mac_lomac_fragment_match, 2639 .mpo_relabel_ifnet = mac_lomac_relabel_ifnet, 2640 .mpo_update_ipq = mac_lomac_update_ipq, 2641 .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel, 2642 .mpo_execve_transition = mac_lomac_execve_transition, 2643 .mpo_execve_will_transition = mac_lomac_execve_will_transition, 2644 .mpo_create_proc0 = mac_lomac_create_proc0, 2645 .mpo_create_proc1 = mac_lomac_create_proc1, 2646 .mpo_relabel_cred = mac_lomac_relabel_cred, 2647 .mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive, 2648 .mpo_check_cred_relabel = mac_lomac_check_cred_relabel, 2649 .mpo_check_cred_visible = mac_lomac_check_cred_visible, 2650 .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel, 2651 .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit, 2652 .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver, 2653 .mpo_check_kld_load = mac_lomac_check_kld_load, 2654 .mpo_check_kld_unload = mac_lomac_check_kld_unload, 2655 .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl, 2656 .mpo_check_pipe_read = mac_lomac_check_pipe_read, 2657 .mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel, 2658 .mpo_check_pipe_write = mac_lomac_check_pipe_write, 2659 .mpo_check_proc_debug = mac_lomac_check_proc_debug, 2660 .mpo_check_proc_sched = mac_lomac_check_proc_sched, 2661 .mpo_check_proc_signal = mac_lomac_check_proc_signal, 2662 .mpo_check_socket_deliver = mac_lomac_check_socket_deliver, 2663 .mpo_check_socket_relabel = mac_lomac_check_socket_relabel, 2664 .mpo_check_socket_visible = mac_lomac_check_socket_visible, 2665 .mpo_check_system_swapon = mac_lomac_check_system_swapon, 2666 .mpo_check_system_sysctl = mac_lomac_check_system_sysctl, 2667 .mpo_check_vnode_access = mac_lomac_check_vnode_open, 2668 .mpo_check_vnode_create = mac_lomac_check_vnode_create, 2669 .mpo_check_vnode_delete = mac_lomac_check_vnode_delete, 2670 .mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl, 2671 .mpo_check_vnode_link = mac_lomac_check_vnode_link, 2672 .mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap, 2673 .mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade, 2674 .mpo_check_vnode_open = mac_lomac_check_vnode_open, 2675 .mpo_check_vnode_read = mac_lomac_check_vnode_read, 2676 .mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel, 2677 .mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from, 2678 .mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to, 2679 .mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke, 2680 .mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl, 2681 .mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr, 2682 .mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags, 2683 .mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode, 2684 .mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner, 2685 .mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes, 2686 .mpo_check_vnode_write = mac_lomac_check_vnode_write, 2687 .mpo_thread_userret = mac_lomac_thread_userret,
| 1460/* 1461 * Labeling event operations: processes. 1462 */ 1463static void 1464mac_lomac_execve_transition(struct ucred *old, struct ucred *new, 1465 struct vnode *vp, struct label *vnodelabel, 1466 struct label *interpvnodelabel, struct image_params *imgp, 1467 struct label *execlabel) 1468{ 1469 struct mac_lomac *source, *dest, *obj, *robj; 1470 1471 source = SLOT(old->cr_label); 1472 dest = SLOT(new->cr_label); 1473 obj = SLOT(vnodelabel); 1474 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1475 1476 mac_lomac_copy(source, dest); 1477 /* 1478 * If there's an auxiliary label on the real object, respect it 1479 * and assume that this level should be assumed immediately if 1480 * a higher level is currently in place. 1481 */ 1482 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1483 !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 1484 && mac_lomac_auxsingle_in_range(robj, dest)) 1485 mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type, 1486 robj->ml_auxsingle.mle_grade); 1487 /* 1488 * Restructuring to use the execve transitioning mechanism 1489 * instead of the normal demotion mechanism here would be 1490 * difficult, so just copy the label over and perform standard 1491 * demotion. This is also non-optimal because it will result 1492 * in the intermediate label "new" being created and immediately 1493 * recycled. 1494 */ 1495 if (mac_lomac_enabled && revocation_enabled && 1496 !mac_lomac_dominate_single(obj, source)) 1497 (void)maybe_demote(source, obj, "executing", "file", vp); 1498} 1499 1500static int 1501mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp, 1502 struct label *vnodelabel, struct label *interpvnodelabel, 1503 struct image_params *imgp, struct label *execlabel) 1504{ 1505 struct mac_lomac *subj, *obj, *robj; 1506 1507 if (!mac_lomac_enabled || !revocation_enabled) 1508 return (0); 1509 1510 subj = SLOT(old->cr_label); 1511 obj = SLOT(vnodelabel); 1512 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1513 1514 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1515 !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 1516 && mac_lomac_auxsingle_in_range(robj, subj)) || 1517 !mac_lomac_dominate_single(obj, subj)); 1518} 1519 1520static void 1521mac_lomac_create_proc0(struct ucred *cred) 1522{ 1523 struct mac_lomac *dest; 1524 1525 dest = SLOT(cred->cr_label); 1526 1527 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1528 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1529 0); 1530} 1531 1532static void 1533mac_lomac_create_proc1(struct ucred *cred) 1534{ 1535 struct mac_lomac *dest; 1536 1537 dest = SLOT(cred->cr_label); 1538 1539 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0); 1540 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1541 0); 1542} 1543 1544static void 1545mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel) 1546{ 1547 struct mac_lomac *source, *dest; 1548 1549 source = SLOT(newlabel); 1550 dest = SLOT(cred->cr_label); 1551 1552 try_relabel(source, dest); 1553} 1554 1555/* 1556 * Access control checks. 1557 */ 1558static int 1559mac_lomac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1560 struct ifnet *ifnet, struct label *ifnetlabel) 1561{ 1562 struct mac_lomac *a, *b; 1563 1564 if (!mac_lomac_enabled) 1565 return (0); 1566 1567 a = SLOT(bpflabel); 1568 b = SLOT(ifnetlabel); 1569 1570 if (mac_lomac_equal_single(a, b)) 1571 return (0); 1572 return (EACCES); 1573} 1574 1575static int 1576mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1577{ 1578 struct mac_lomac *subj, *new; 1579 int error; 1580 1581 subj = SLOT(cred->cr_label); 1582 new = SLOT(newlabel); 1583 1584 /* 1585 * If there is a LOMAC label update for the credential, it may 1586 * be an update of the single, range, or both. 1587 */ 1588 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1589 if (error) 1590 return (error); 1591 1592 /* 1593 * If the LOMAC label is to be changed, authorize as appropriate. 1594 */ 1595 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1596 /* 1597 * Fill in the missing parts from the previous label. 1598 */ 1599 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1600 mac_lomac_copy_single(subj, new); 1601 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1602 mac_lomac_copy_range(subj, new); 1603 1604 /* 1605 * To change the LOMAC range on a credential, the new 1606 * range label must be in the current range. 1607 */ 1608 if (!mac_lomac_range_in_range(new, subj)) 1609 return (EPERM); 1610 1611 /* 1612 * To change the LOMAC single label on a credential, the 1613 * new single label must be in the new range. Implicitly 1614 * from the previous check, the new single is in the old 1615 * range. 1616 */ 1617 if (!mac_lomac_single_in_range(new, new)) 1618 return (EPERM); 1619 1620 /* 1621 * To have EQUAL in any component of the new credential 1622 * LOMAC label, the subject must already have EQUAL in 1623 * their label. 1624 */ 1625 if (mac_lomac_contains_equal(new)) { 1626 error = mac_lomac_subject_privileged(subj); 1627 if (error) 1628 return (error); 1629 } 1630 1631 /* 1632 * XXXMAC: Additional consistency tests regarding the 1633 * single and range of the new label might be performed 1634 * here. 1635 */ 1636 } 1637 1638 return (0); 1639} 1640 1641static int 1642mac_lomac_check_cred_visible(struct ucred *u1, struct ucred *u2) 1643{ 1644 struct mac_lomac *subj, *obj; 1645 1646 if (!mac_lomac_enabled) 1647 return (0); 1648 1649 subj = SLOT(u1->cr_label); 1650 obj = SLOT(u2->cr_label); 1651 1652 /* XXX: range */ 1653 if (!mac_lomac_dominate_single(obj, subj)) 1654 return (ESRCH); 1655 1656 return (0); 1657} 1658 1659static int 1660mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1661 struct label *ifnetlabel, struct label *newlabel) 1662{ 1663 struct mac_lomac *subj, *new; 1664 int error; 1665 1666 subj = SLOT(cred->cr_label); 1667 new = SLOT(newlabel); 1668 1669 /* 1670 * If there is a LOMAC label update for the interface, it may 1671 * be an update of the single, range, or both. 1672 */ 1673 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1674 if (error) 1675 return (error); 1676 1677 /* 1678 * Relabling network interfaces requires LOMAC privilege. 1679 */ 1680 error = mac_lomac_subject_privileged(subj); 1681 if (error) 1682 return (error); 1683 1684 /* 1685 * If the LOMAC label is to be changed, authorize as appropriate. 1686 */ 1687 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1688 /* 1689 * Fill in the missing parts from the previous label. 1690 */ 1691 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1692 mac_lomac_copy_single(subj, new); 1693 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1694 mac_lomac_copy_range(subj, new); 1695 1696 /* 1697 * Rely on the traditional superuser status for the LOMAC 1698 * interface relabel requirements. XXXMAC: This will go 1699 * away. 1700 */ 1701 error = suser_cred(cred, 0); 1702 if (error) 1703 return (EPERM); 1704 1705 /* 1706 * XXXMAC: Additional consistency tests regarding the single 1707 * and the range of the new label might be performed here. 1708 */ 1709 } 1710 1711 return (0); 1712} 1713 1714static int 1715mac_lomac_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1716 struct mbuf *m, struct label *mbuflabel) 1717{ 1718 struct mac_lomac *p, *i; 1719 1720 if (!mac_lomac_enabled) 1721 return (0); 1722 1723 p = SLOT(mbuflabel); 1724 i = SLOT(ifnetlabel); 1725 1726 return (mac_lomac_single_in_range(p, i) ? 0 : EACCES); 1727} 1728 1729static int 1730mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1731 struct mbuf *m, struct label *mlabel) 1732{ 1733 struct mac_lomac *p, *i; 1734 1735 if (!mac_lomac_enabled) 1736 return (0); 1737 1738 p = SLOT(mlabel); 1739 i = SLOT(inplabel); 1740 1741 return (mac_lomac_equal_single(p, i) ? 0 : EACCES); 1742} 1743 1744static int 1745mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp, 1746 struct label *label) 1747{ 1748 struct mac_lomac *subj, *obj; 1749 1750 if (!mac_lomac_enabled) 1751 return (0); 1752 1753 subj = SLOT(cred->cr_label); 1754 obj = SLOT(label); 1755 1756 if (mac_lomac_subject_privileged(subj)) 1757 return (EPERM); 1758 1759 if (!mac_lomac_high_single(obj)) 1760 return (EACCES); 1761 1762 return (0); 1763} 1764 1765static int 1766mac_lomac_check_kld_unload(struct ucred *cred) 1767{ 1768 struct mac_lomac *subj; 1769 1770 if (!mac_lomac_enabled) 1771 return (0); 1772 1773 subj = SLOT(cred->cr_label); 1774 1775 if (mac_lomac_subject_privileged(subj)) 1776 return (EPERM); 1777 1778 return (0); 1779} 1780 1781static int 1782mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1783 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1784{ 1785 1786 if(!mac_lomac_enabled) 1787 return (0); 1788 1789 /* XXX: This will be implemented soon... */ 1790 1791 return (0); 1792} 1793 1794static int 1795mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1796 struct label *pipelabel) 1797{ 1798 struct mac_lomac *subj, *obj; 1799 1800 if (!mac_lomac_enabled) 1801 return (0); 1802 1803 subj = SLOT(cred->cr_label); 1804 obj = SLOT((pipelabel)); 1805 1806 if (!mac_lomac_dominate_single(obj, subj)) 1807 return (maybe_demote(subj, obj, "reading", "pipe", NULL)); 1808 1809 return (0); 1810} 1811 1812static int 1813mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1814 struct label *pipelabel, struct label *newlabel) 1815{ 1816 struct mac_lomac *subj, *obj, *new; 1817 int error; 1818 1819 new = SLOT(newlabel); 1820 subj = SLOT(cred->cr_label); 1821 obj = SLOT(pipelabel); 1822 1823 /* 1824 * If there is a LOMAC label update for a pipe, it must be a 1825 * single update. 1826 */ 1827 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1828 if (error) 1829 return (error); 1830 1831 /* 1832 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must 1833 * authorize the relabel. 1834 */ 1835 if (!mac_lomac_single_in_range(obj, subj)) 1836 return (EPERM); 1837 1838 /* 1839 * If the LOMAC label is to be changed, authorize as appropriate. 1840 */ 1841 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1842 /* 1843 * To change the LOMAC label on a pipe, the new pipe label 1844 * must be in the subject range. 1845 */ 1846 if (!mac_lomac_single_in_range(new, subj)) 1847 return (EPERM); 1848 1849 /* 1850 * To change the LOMAC label on a pipe to be EQUAL, the 1851 * subject must have appropriate privilege. 1852 */ 1853 if (mac_lomac_contains_equal(new)) { 1854 error = mac_lomac_subject_privileged(subj); 1855 if (error) 1856 return (error); 1857 } 1858 } 1859 1860 return (0); 1861} 1862 1863static int 1864mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp, 1865 struct label *pipelabel) 1866{ 1867 struct mac_lomac *subj, *obj; 1868 1869 if (!mac_lomac_enabled) 1870 return (0); 1871 1872 subj = SLOT(cred->cr_label); 1873 obj = SLOT((pipelabel)); 1874 1875 if (!mac_lomac_subject_dominate(subj, obj)) 1876 return (EACCES); 1877 1878 return (0); 1879} 1880 1881static int 1882mac_lomac_check_proc_debug(struct ucred *cred, struct proc *proc) 1883{ 1884 struct mac_lomac *subj, *obj; 1885 1886 if (!mac_lomac_enabled) 1887 return (0); 1888 1889 subj = SLOT(cred->cr_label); 1890 obj = SLOT(proc->p_ucred->cr_label); 1891 1892 /* XXX: range checks */ 1893 if (!mac_lomac_dominate_single(obj, subj)) 1894 return (ESRCH); 1895 if (!mac_lomac_subject_dominate(subj, obj)) 1896 return (EACCES); 1897 1898 return (0); 1899} 1900 1901static int 1902mac_lomac_check_proc_sched(struct ucred *cred, struct proc *proc) 1903{ 1904 struct mac_lomac *subj, *obj; 1905 1906 if (!mac_lomac_enabled) 1907 return (0); 1908 1909 subj = SLOT(cred->cr_label); 1910 obj = SLOT(proc->p_ucred->cr_label); 1911 1912 /* XXX: range checks */ 1913 if (!mac_lomac_dominate_single(obj, subj)) 1914 return (ESRCH); 1915 if (!mac_lomac_subject_dominate(subj, obj)) 1916 return (EACCES); 1917 1918 return (0); 1919} 1920 1921static int 1922mac_lomac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1923{ 1924 struct mac_lomac *subj, *obj; 1925 1926 if (!mac_lomac_enabled) 1927 return (0); 1928 1929 subj = SLOT(cred->cr_label); 1930 obj = SLOT(proc->p_ucred->cr_label); 1931 1932 /* XXX: range checks */ 1933 if (!mac_lomac_dominate_single(obj, subj)) 1934 return (ESRCH); 1935 if (!mac_lomac_subject_dominate(subj, obj)) 1936 return (EACCES); 1937 1938 return (0); 1939} 1940 1941static int 1942mac_lomac_check_socket_deliver(struct socket *so, struct label *socketlabel, 1943 struct mbuf *m, struct label *mbuflabel) 1944{ 1945 struct mac_lomac *p, *s; 1946 1947 if (!mac_lomac_enabled) 1948 return (0); 1949 1950 p = SLOT(mbuflabel); 1951 s = SLOT(socketlabel); 1952 1953 return (mac_lomac_equal_single(p, s) ? 0 : EACCES); 1954} 1955 1956static int 1957mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *socket, 1958 struct label *socketlabel, struct label *newlabel) 1959{ 1960 struct mac_lomac *subj, *obj, *new; 1961 int error; 1962 1963 new = SLOT(newlabel); 1964 subj = SLOT(cred->cr_label); 1965 obj = SLOT(socketlabel); 1966 1967 /* 1968 * If there is a LOMAC label update for the socket, it may be 1969 * an update of single. 1970 */ 1971 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1972 if (error) 1973 return (error); 1974 1975 /* 1976 * To relabel a socket, the old socket single must be in the subject 1977 * range. 1978 */ 1979 if (!mac_lomac_single_in_range(obj, subj)) 1980 return (EPERM); 1981 1982 /* 1983 * If the LOMAC label is to be changed, authorize as appropriate. 1984 */ 1985 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1986 /* 1987 * To relabel a socket, the new socket single must be in 1988 * the subject range. 1989 */ 1990 if (!mac_lomac_single_in_range(new, subj)) 1991 return (EPERM); 1992 1993 /* 1994 * To change the LOMAC label on the socket to contain EQUAL, 1995 * the subject must have appropriate privilege. 1996 */ 1997 if (mac_lomac_contains_equal(new)) { 1998 error = mac_lomac_subject_privileged(subj); 1999 if (error) 2000 return (error); 2001 } 2002 } 2003 2004 return (0); 2005} 2006 2007static int 2008mac_lomac_check_socket_visible(struct ucred *cred, struct socket *socket, 2009 struct label *socketlabel) 2010{ 2011 struct mac_lomac *subj, *obj; 2012 2013 if (!mac_lomac_enabled) 2014 return (0); 2015 2016 subj = SLOT(cred->cr_label); 2017 obj = SLOT(socketlabel); 2018 2019 if (!mac_lomac_dominate_single(obj, subj)) 2020 return (ENOENT); 2021 2022 return (0); 2023} 2024 2025static int 2026mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp, 2027 struct label *label) 2028{ 2029 struct mac_lomac *subj, *obj; 2030 2031 if (!mac_lomac_enabled) 2032 return (0); 2033 2034 subj = SLOT(cred->cr_label); 2035 obj = SLOT(label); 2036 2037 if (mac_lomac_subject_privileged(subj)) 2038 return (EPERM); 2039 2040 if (!mac_lomac_high_single(obj)) 2041 return (EACCES); 2042 2043 return (0); 2044} 2045 2046static int 2047mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2048 void *arg1, int arg2, struct sysctl_req *req) 2049{ 2050 struct mac_lomac *subj; 2051 2052 if (!mac_lomac_enabled) 2053 return (0); 2054 2055 subj = SLOT(cred->cr_label); 2056 2057 /* 2058 * Treat sysctl variables without CTLFLAG_ANYBODY flag as 2059 * lomac/high, but also require privilege to change them. 2060 */ 2061 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2062#ifdef notdef 2063 if (!mac_lomac_subject_dominate_high(subj)) 2064 return (EACCES); 2065#endif 2066 2067 if (mac_lomac_subject_privileged(subj)) 2068 return (EPERM); 2069 } 2070 2071 return (0); 2072} 2073 2074static int 2075mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2076 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2077{ 2078 struct mac_lomac *subj, *obj; 2079 2080 if (!mac_lomac_enabled) 2081 return (0); 2082 2083 subj = SLOT(cred->cr_label); 2084 obj = SLOT(dlabel); 2085 2086 if (!mac_lomac_subject_dominate(subj, obj)) 2087 return (EACCES); 2088 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2089 !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2090 return (EACCES); 2091 2092 return (0); 2093} 2094 2095static int 2096mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2097 struct label *dlabel, struct vnode *vp, struct label *label, 2098 struct componentname *cnp) 2099{ 2100 struct mac_lomac *subj, *obj; 2101 2102 if (!mac_lomac_enabled) 2103 return (0); 2104 2105 subj = SLOT(cred->cr_label); 2106 obj = SLOT(dlabel); 2107 2108 if (!mac_lomac_subject_dominate(subj, obj)) 2109 return (EACCES); 2110 2111 obj = SLOT(label); 2112 2113 if (!mac_lomac_subject_dominate(subj, obj)) 2114 return (EACCES); 2115 2116 return (0); 2117} 2118 2119static int 2120mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2121 struct label *label, acl_type_t type) 2122{ 2123 struct mac_lomac *subj, *obj; 2124 2125 if (!mac_lomac_enabled) 2126 return (0); 2127 2128 subj = SLOT(cred->cr_label); 2129 obj = SLOT(label); 2130 2131 if (!mac_lomac_subject_dominate(subj, obj)) 2132 return (EACCES); 2133 2134 return (0); 2135} 2136 2137static int 2138mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2139 struct label *dlabel, struct vnode *vp, struct label *label, 2140 struct componentname *cnp) 2141{ 2142 struct mac_lomac *subj, *obj; 2143 2144 if (!mac_lomac_enabled) 2145 return (0); 2146 2147 subj = SLOT(cred->cr_label); 2148 obj = SLOT(dlabel); 2149 2150 if (!mac_lomac_subject_dominate(subj, obj)) 2151 return (EACCES); 2152 2153 obj = SLOT(label); 2154 2155 if (!mac_lomac_subject_dominate(subj, obj)) 2156 return (EACCES); 2157 2158 return (0); 2159} 2160 2161static int 2162mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2163 struct label *label, int prot, int flags) 2164{ 2165 struct mac_lomac *subj, *obj; 2166 2167 /* 2168 * Rely on the use of open()-time protections to handle 2169 * non-revocation cases. 2170 */ 2171 if (!mac_lomac_enabled) 2172 return (0); 2173 2174 subj = SLOT(cred->cr_label); 2175 obj = SLOT(label); 2176 2177 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2178 if (!mac_lomac_subject_dominate(subj, obj)) 2179 return (EACCES); 2180 } 2181 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2182 if (!mac_lomac_dominate_single(obj, subj)) 2183 return (maybe_demote(subj, obj, "mapping", "file", vp)); 2184 } 2185 2186 return (0); 2187} 2188 2189static void 2190mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, 2191 struct label *label, /* XXX vm_prot_t */ int *prot) 2192{ 2193 struct mac_lomac *subj, *obj; 2194 2195 /* 2196 * Rely on the use of open()-time protections to handle 2197 * non-revocation cases. 2198 */ 2199 if (!mac_lomac_enabled || !revocation_enabled) 2200 return; 2201 2202 subj = SLOT(cred->cr_label); 2203 obj = SLOT(label); 2204 2205 if (!mac_lomac_subject_dominate(subj, obj)) 2206 *prot &= ~VM_PROT_WRITE; 2207} 2208 2209static int 2210mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp, 2211 struct label *vnodelabel, int acc_mode) 2212{ 2213 struct mac_lomac *subj, *obj; 2214 2215 if (!mac_lomac_enabled) 2216 return (0); 2217 2218 subj = SLOT(cred->cr_label); 2219 obj = SLOT(vnodelabel); 2220 2221 /* XXX privilege override for admin? */ 2222 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2223 if (!mac_lomac_subject_dominate(subj, obj)) 2224 return (EACCES); 2225 } 2226 2227 return (0); 2228} 2229 2230static int 2231mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2232 struct vnode *vp, struct label *label) 2233{ 2234 struct mac_lomac *subj, *obj; 2235 2236 if (!mac_lomac_enabled || !revocation_enabled) 2237 return (0); 2238 2239 subj = SLOT(active_cred->cr_label); 2240 obj = SLOT(label); 2241 2242 if (!mac_lomac_dominate_single(obj, subj)) 2243 return (maybe_demote(subj, obj, "reading", "file", vp)); 2244 2245 return (0); 2246} 2247 2248static int 2249mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2250 struct label *vnodelabel, struct label *newlabel) 2251{ 2252 struct mac_lomac *old, *new, *subj; 2253 int error; 2254 2255 old = SLOT(vnodelabel); 2256 new = SLOT(newlabel); 2257 subj = SLOT(cred->cr_label); 2258 2259 /* 2260 * If there is a LOMAC label update for the vnode, it must be a 2261 * single label, with an optional explicit auxiliary single. 2262 */ 2263 error = lomac_atmostflags(new, 2264 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2265 if (error) 2266 return (error); 2267 2268 /* 2269 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2270 * authorize the relabel. 2271 */ 2272 if (!mac_lomac_single_in_range(old, subj)) 2273 return (EPERM); 2274 2275 /* 2276 * If the LOMAC label is to be changed, authorize as appropriate. 2277 */ 2278 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2279 /* 2280 * To change the LOMAC label on a vnode, the new vnode label 2281 * must be in the subject range. 2282 */ 2283 if (!mac_lomac_single_in_range(new, subj)) 2284 return (EPERM); 2285 2286 /* 2287 * To change the LOMAC label on the vnode to be EQUAL, 2288 * the subject must have appropriate privilege. 2289 */ 2290 if (mac_lomac_contains_equal(new)) { 2291 error = mac_lomac_subject_privileged(subj); 2292 if (error) 2293 return (error); 2294 } 2295 } 2296 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2297 /* 2298 * Fill in the missing parts from the previous label. 2299 */ 2300 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2301 mac_lomac_copy_single(subj, new); 2302 2303 /* 2304 * To change the auxiliary LOMAC label on a vnode, the new 2305 * vnode label must be in the subject range. 2306 */ 2307 if (!mac_lomac_auxsingle_in_range(new, subj)) 2308 return (EPERM); 2309 2310 /* 2311 * To change the auxiliary LOMAC label on the vnode to be 2312 * EQUAL, the subject must have appropriate privilege. 2313 */ 2314 if (mac_lomac_contains_equal(new)) { 2315 error = mac_lomac_subject_privileged(subj); 2316 if (error) 2317 return (error); 2318 } 2319 } 2320 2321 return (0); 2322} 2323 2324static int 2325mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2326 struct label *dlabel, struct vnode *vp, struct label *label, 2327 struct componentname *cnp) 2328{ 2329 struct mac_lomac *subj, *obj; 2330 2331 if (!mac_lomac_enabled) 2332 return (0); 2333 2334 subj = SLOT(cred->cr_label); 2335 obj = SLOT(dlabel); 2336 2337 if (!mac_lomac_subject_dominate(subj, obj)) 2338 return (EACCES); 2339 2340 obj = SLOT(label); 2341 2342 if (!mac_lomac_subject_dominate(subj, obj)) 2343 return (EACCES); 2344 2345 return (0); 2346} 2347 2348static int 2349mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2350 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2351 struct componentname *cnp) 2352{ 2353 struct mac_lomac *subj, *obj; 2354 2355 if (!mac_lomac_enabled) 2356 return (0); 2357 2358 subj = SLOT(cred->cr_label); 2359 obj = SLOT(dlabel); 2360 2361 if (!mac_lomac_subject_dominate(subj, obj)) 2362 return (EACCES); 2363 2364 if (vp != NULL) { 2365 obj = SLOT(label); 2366 2367 if (!mac_lomac_subject_dominate(subj, obj)) 2368 return (EACCES); 2369 } 2370 2371 return (0); 2372} 2373 2374static int 2375mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2376 struct label *label) 2377{ 2378 struct mac_lomac *subj, *obj; 2379 2380 if (!mac_lomac_enabled) 2381 return (0); 2382 2383 subj = SLOT(cred->cr_label); 2384 obj = SLOT(label); 2385 2386 if (!mac_lomac_subject_dominate(subj, obj)) 2387 return (EACCES); 2388 2389 return (0); 2390} 2391 2392static int 2393mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2394 struct label *label, acl_type_t type, struct acl *acl) 2395{ 2396 struct mac_lomac *subj, *obj; 2397 2398 if (!mac_lomac_enabled) 2399 return (0); 2400 2401 subj = SLOT(cred->cr_label); 2402 obj = SLOT(label); 2403 2404 if (!mac_lomac_subject_dominate(subj, obj)) 2405 return (EACCES); 2406 2407 return (0); 2408} 2409 2410static int 2411mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2412 struct label *vnodelabel, int attrnamespace, const char *name, 2413 struct uio *uio) 2414{ 2415 struct mac_lomac *subj, *obj; 2416 2417 if (!mac_lomac_enabled) 2418 return (0); 2419 2420 subj = SLOT(cred->cr_label); 2421 obj = SLOT(vnodelabel); 2422 2423 if (!mac_lomac_subject_dominate(subj, obj)) 2424 return (EACCES); 2425 2426 /* XXX: protect the MAC EA in a special way? */ 2427 2428 return (0); 2429} 2430 2431static int 2432mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2433 struct label *vnodelabel, u_long flags) 2434{ 2435 struct mac_lomac *subj, *obj; 2436 2437 if (!mac_lomac_enabled) 2438 return (0); 2439 2440 subj = SLOT(cred->cr_label); 2441 obj = SLOT(vnodelabel); 2442 2443 if (!mac_lomac_subject_dominate(subj, obj)) 2444 return (EACCES); 2445 2446 return (0); 2447} 2448 2449static int 2450mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2451 struct label *vnodelabel, mode_t mode) 2452{ 2453 struct mac_lomac *subj, *obj; 2454 2455 if (!mac_lomac_enabled) 2456 return (0); 2457 2458 subj = SLOT(cred->cr_label); 2459 obj = SLOT(vnodelabel); 2460 2461 if (!mac_lomac_subject_dominate(subj, obj)) 2462 return (EACCES); 2463 2464 return (0); 2465} 2466 2467static int 2468mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2469 struct label *vnodelabel, uid_t uid, gid_t gid) 2470{ 2471 struct mac_lomac *subj, *obj; 2472 2473 if (!mac_lomac_enabled) 2474 return (0); 2475 2476 subj = SLOT(cred->cr_label); 2477 obj = SLOT(vnodelabel); 2478 2479 if (!mac_lomac_subject_dominate(subj, obj)) 2480 return (EACCES); 2481 2482 return (0); 2483} 2484 2485static int 2486mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2487 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2488{ 2489 struct mac_lomac *subj, *obj; 2490 2491 if (!mac_lomac_enabled) 2492 return (0); 2493 2494 subj = SLOT(cred->cr_label); 2495 obj = SLOT(vnodelabel); 2496 2497 if (!mac_lomac_subject_dominate(subj, obj)) 2498 return (EACCES); 2499 2500 return (0); 2501} 2502 2503static int 2504mac_lomac_check_vnode_write(struct ucred *active_cred, 2505 struct ucred *file_cred, struct vnode *vp, struct label *label) 2506{ 2507 struct mac_lomac *subj, *obj; 2508 2509 if (!mac_lomac_enabled || !revocation_enabled) 2510 return (0); 2511 2512 subj = SLOT(active_cred->cr_label); 2513 obj = SLOT(label); 2514 2515 if (!mac_lomac_subject_dominate(subj, obj)) 2516 return (EACCES); 2517 2518 return (0); 2519} 2520 2521static void 2522mac_lomac_thread_userret(struct thread *td) 2523{ 2524 struct proc *p = td->td_proc; 2525 struct mac_lomac_proc *subj = PSLOT(p->p_label); 2526 struct ucred *newcred, *oldcred; 2527 int dodrop; 2528 2529 mtx_lock(&subj->mtx); 2530 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 2531 dodrop = 0; 2532 mtx_unlock(&subj->mtx); 2533 newcred = crget(); 2534 /* 2535 * Prevent a lock order reversal in 2536 * mac_cred_mmapped_drop_perms; ideally, the other 2537 * user of subj->mtx wouldn't be holding Giant. 2538 */ 2539 mtx_lock(&Giant); 2540 PROC_LOCK(p); 2541 mtx_lock(&subj->mtx); 2542 /* 2543 * Check if we lost the race while allocating the cred. 2544 */ 2545 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2546 crfree(newcred); 2547 goto out; 2548 } 2549 oldcred = p->p_ucred; 2550 crcopy(newcred, oldcred); 2551 crhold(newcred); 2552 mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2553 p->p_ucred = newcred; 2554 crfree(oldcred); 2555 dodrop = 1; 2556 out: 2557 mtx_unlock(&subj->mtx); 2558 PROC_UNLOCK(p); 2559 if (dodrop) 2560 mac_cred_mmapped_drop_perms(curthread, newcred); 2561 mtx_unlock(&Giant); 2562 } else { 2563 mtx_unlock(&subj->mtx); 2564 } 2565} 2566 2567static struct mac_policy_ops mac_lomac_ops = 2568{ 2569 .mpo_init = mac_lomac_init, 2570 .mpo_init_bpfdesc_label = mac_lomac_init_label, 2571 .mpo_init_cred_label = mac_lomac_init_label, 2572 .mpo_init_devfsdirent_label = mac_lomac_init_label, 2573 .mpo_init_ifnet_label = mac_lomac_init_label, 2574 .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck, 2575 .mpo_init_ipq_label = mac_lomac_init_label_waitcheck, 2576 .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck, 2577 .mpo_init_mount_label = mac_lomac_init_label, 2578 .mpo_init_mount_fs_label = mac_lomac_init_label, 2579 .mpo_init_pipe_label = mac_lomac_init_label, 2580 .mpo_init_proc_label = mac_lomac_init_proc_label, 2581 .mpo_init_socket_label = mac_lomac_init_label_waitcheck, 2582 .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck, 2583 .mpo_init_vnode_label = mac_lomac_init_label, 2584 .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label, 2585 .mpo_destroy_cred_label = mac_lomac_destroy_label, 2586 .mpo_destroy_devfsdirent_label = mac_lomac_destroy_label, 2587 .mpo_destroy_ifnet_label = mac_lomac_destroy_label, 2588 .mpo_destroy_inpcb_label = mac_lomac_destroy_label, 2589 .mpo_destroy_ipq_label = mac_lomac_destroy_label, 2590 .mpo_destroy_mbuf_label = mac_lomac_destroy_label, 2591 .mpo_destroy_mount_label = mac_lomac_destroy_label, 2592 .mpo_destroy_mount_fs_label = mac_lomac_destroy_label, 2593 .mpo_destroy_pipe_label = mac_lomac_destroy_label, 2594 .mpo_destroy_proc_label = mac_lomac_destroy_proc_label, 2595 .mpo_destroy_socket_label = mac_lomac_destroy_label, 2596 .mpo_destroy_socket_peer_label = mac_lomac_destroy_label, 2597 .mpo_destroy_vnode_label = mac_lomac_destroy_label, 2598 .mpo_copy_cred_label = mac_lomac_copy_label, 2599 .mpo_copy_ifnet_label = mac_lomac_copy_label, 2600 .mpo_copy_mbuf_label = mac_lomac_copy_label, 2601 .mpo_copy_pipe_label = mac_lomac_copy_label, 2602 .mpo_copy_socket_label = mac_lomac_copy_label, 2603 .mpo_copy_vnode_label = mac_lomac_copy_label, 2604 .mpo_externalize_cred_label = mac_lomac_externalize_label, 2605 .mpo_externalize_ifnet_label = mac_lomac_externalize_label, 2606 .mpo_externalize_pipe_label = mac_lomac_externalize_label, 2607 .mpo_externalize_socket_label = mac_lomac_externalize_label, 2608 .mpo_externalize_socket_peer_label = mac_lomac_externalize_label, 2609 .mpo_externalize_vnode_label = mac_lomac_externalize_label, 2610 .mpo_internalize_cred_label = mac_lomac_internalize_label, 2611 .mpo_internalize_ifnet_label = mac_lomac_internalize_label, 2612 .mpo_internalize_pipe_label = mac_lomac_internalize_label, 2613 .mpo_internalize_socket_label = mac_lomac_internalize_label, 2614 .mpo_internalize_vnode_label = mac_lomac_internalize_label, 2615 .mpo_create_devfs_device = mac_lomac_create_devfs_device, 2616 .mpo_create_devfs_directory = mac_lomac_create_devfs_directory, 2617 .mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink, 2618 .mpo_create_mount = mac_lomac_create_mount, 2619 .mpo_relabel_vnode = mac_lomac_relabel_vnode, 2620 .mpo_update_devfsdirent = mac_lomac_update_devfsdirent, 2621 .mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs, 2622 .mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr, 2623 .mpo_associate_vnode_singlelabel = 2624 mac_lomac_associate_vnode_singlelabel, 2625 .mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr, 2626 .mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr, 2627 .mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket, 2628 .mpo_create_pipe = mac_lomac_create_pipe, 2629 .mpo_create_socket = mac_lomac_create_socket, 2630 .mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket, 2631 .mpo_relabel_pipe = mac_lomac_relabel_pipe, 2632 .mpo_relabel_socket = mac_lomac_relabel_socket, 2633 .mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf, 2634 .mpo_set_socket_peer_from_socket = 2635 mac_lomac_set_socket_peer_from_socket, 2636 .mpo_create_bpfdesc = mac_lomac_create_bpfdesc, 2637 .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq, 2638 .mpo_create_fragment = mac_lomac_create_fragment, 2639 .mpo_create_ifnet = mac_lomac_create_ifnet, 2640 .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket, 2641 .mpo_create_ipq = mac_lomac_create_ipq, 2642 .mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb, 2643 .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer, 2644 .mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc, 2645 .mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet, 2646 .mpo_create_mbuf_multicast_encap = 2647 mac_lomac_create_mbuf_multicast_encap, 2648 .mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer, 2649 .mpo_fragment_match = mac_lomac_fragment_match, 2650 .mpo_relabel_ifnet = mac_lomac_relabel_ifnet, 2651 .mpo_update_ipq = mac_lomac_update_ipq, 2652 .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel, 2653 .mpo_execve_transition = mac_lomac_execve_transition, 2654 .mpo_execve_will_transition = mac_lomac_execve_will_transition, 2655 .mpo_create_proc0 = mac_lomac_create_proc0, 2656 .mpo_create_proc1 = mac_lomac_create_proc1, 2657 .mpo_relabel_cred = mac_lomac_relabel_cred, 2658 .mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive, 2659 .mpo_check_cred_relabel = mac_lomac_check_cred_relabel, 2660 .mpo_check_cred_visible = mac_lomac_check_cred_visible, 2661 .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel, 2662 .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit, 2663 .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver, 2664 .mpo_check_kld_load = mac_lomac_check_kld_load, 2665 .mpo_check_kld_unload = mac_lomac_check_kld_unload, 2666 .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl, 2667 .mpo_check_pipe_read = mac_lomac_check_pipe_read, 2668 .mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel, 2669 .mpo_check_pipe_write = mac_lomac_check_pipe_write, 2670 .mpo_check_proc_debug = mac_lomac_check_proc_debug, 2671 .mpo_check_proc_sched = mac_lomac_check_proc_sched, 2672 .mpo_check_proc_signal = mac_lomac_check_proc_signal, 2673 .mpo_check_socket_deliver = mac_lomac_check_socket_deliver, 2674 .mpo_check_socket_relabel = mac_lomac_check_socket_relabel, 2675 .mpo_check_socket_visible = mac_lomac_check_socket_visible, 2676 .mpo_check_system_swapon = mac_lomac_check_system_swapon, 2677 .mpo_check_system_sysctl = mac_lomac_check_system_sysctl, 2678 .mpo_check_vnode_access = mac_lomac_check_vnode_open, 2679 .mpo_check_vnode_create = mac_lomac_check_vnode_create, 2680 .mpo_check_vnode_delete = mac_lomac_check_vnode_delete, 2681 .mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl, 2682 .mpo_check_vnode_link = mac_lomac_check_vnode_link, 2683 .mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap, 2684 .mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade, 2685 .mpo_check_vnode_open = mac_lomac_check_vnode_open, 2686 .mpo_check_vnode_read = mac_lomac_check_vnode_read, 2687 .mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel, 2688 .mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from, 2689 .mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to, 2690 .mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke, 2691 .mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl, 2692 .mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr, 2693 .mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags, 2694 .mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode, 2695 .mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner, 2696 .mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes, 2697 .mpo_check_vnode_write = mac_lomac_check_vnode_write, 2698 .mpo_thread_userret = mac_lomac_thread_userret,
|