1 /*- 2 * Copyright (c) 1999-2002, 2007-2009 Robert N. M. Watson 3 * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 4 * Copyright (c) 2006 SPARTA, Inc. 5 * All rights reserved. 6 * 7 * This software was developed by Robert Watson for the TrustedBSD Project. 8 * 9 * This software was developed for the FreeBSD Project in part by NAI Labs, 10 * the Security Research Division of Network Associates, Inc. under 11 * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 12 * CHATS research program. 13 * 14 * This software was enhanced by SPARTA ISSO under SPAWAR contract 15 * N66001-04-C-6019 ("SEFOS"). 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * $FreeBSD$ 39 */ 40 41 /* 42 * Developed by the TrustedBSD Project. 43 * 44 * Low-watermark floating label mandatory integrity policy. 45 */ 46 47 #include <sys/types.h> 48 #include <sys/param.h> 49 #include <sys/acl.h> 50 #include <sys/conf.h> 51 #include <sys/extattr.h> 52 #include <sys/kernel.h> 53 #include <sys/malloc.h> 54 #include <sys/mman.h> 55 #include <sys/mount.h> 56 #include <sys/priv.h> 57 #include <sys/proc.h> 58 #include <sys/sbuf.h> 59 #include <sys/systm.h> 60 #include <sys/sysproto.h> 61 #include <sys/sysent.h> 62 #include <sys/systm.h> 63 #include <sys/vnode.h> 64 #include <sys/file.h> 65 #include <sys/socket.h> 66 #include <sys/socketvar.h> 67 #include <sys/sx.h> 68 #include <sys/pipe.h> 69 #include <sys/sysctl.h> 70 #include <sys/syslog.h> 71 72 #include <fs/devfs/devfs.h> 73 74 #include <net/bpfdesc.h> 75 #include <net/if.h> 76 #include <net/if_types.h> 77 #include <net/if_var.h> 78 79 #include <netinet/in.h> 80 #include <netinet/in_pcb.h> 81 #include <netinet/ip_var.h> 82 83 #include <vm/vm.h> 84 85 #include <security/mac/mac_policy.h> 86 #include <security/mac/mac_framework.h> 87 #include <security/mac_lomac/mac_lomac.h> 88 89 struct mac_lomac_proc { 90 struct mac_lomac mac_lomac; 91 struct mtx mtx; 92 }; 93 94 SYSCTL_DECL(_security_mac); 95 96 static SYSCTL_NODE(_security_mac, OID_AUTO, lomac, 97 CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 98 "TrustedBSD mac_lomac policy controls"); 99 100 static int lomac_label_size = sizeof(struct mac_lomac); 101 SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD, 102 &lomac_label_size, 0, "Size of struct mac_lomac"); 103 104 static int lomac_enabled = 1; 105 SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RWTUN, 106 &lomac_enabled, 0, "Enforce MAC/LOMAC policy"); 107 108 static int destroyed_not_inited; 109 SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 110 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 111 112 static int trust_all_interfaces = 0; 113 SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RDTUN, 114 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC"); 115 116 static char trusted_interfaces[128]; 117 SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RDTUN, 118 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC"); 119 120 static int ptys_equal = 0; 121 SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RWTUN, 122 &ptys_equal, 0, "Label pty devices as lomac/equal on create"); 123 124 static int revocation_enabled = 1; 125 SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RWTUN, 126 &revocation_enabled, 0, "Revoke access to objects on relabel"); 127 128 static int lomac_slot; 129 #define SLOT(l) ((struct mac_lomac *)mac_label_get((l), lomac_slot)) 130 #define SLOT_SET(l, val) mac_label_set((l), lomac_slot, (uintptr_t)(val)) 131 #define PSLOT(l) ((struct mac_lomac_proc *) \ 132 mac_label_get((l), lomac_slot)) 133 #define PSLOT_SET(l, val) mac_label_set((l), lomac_slot, (uintptr_t)(val)) 134 135 static MALLOC_DEFINE(M_LOMAC, "mac_lomac_label", "MAC/LOMAC labels"); 136 137 static struct mac_lomac * 138 lomac_alloc(int flag) 139 { 140 struct mac_lomac *ml; 141 142 ml = malloc(sizeof(*ml), M_LOMAC, M_ZERO | flag); 143 144 return (ml); 145 } 146 147 static void 148 lomac_free(struct mac_lomac *ml) 149 { 150 151 if (ml != NULL) 152 free(ml, M_LOMAC); 153 else 154 atomic_add_int(&destroyed_not_inited, 1); 155 } 156 157 static int 158 lomac_atmostflags(struct mac_lomac *ml, int flags) 159 { 160 161 if ((ml->ml_flags & flags) != ml->ml_flags) 162 return (EINVAL); 163 return (0); 164 } 165 166 static int 167 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("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("lomac_dominate_element: b->mle_type invalid"); 204 } 205 206 default: 207 panic("lomac_dominate_element: a->mle_type invalid"); 208 } 209 } 210 211 static int 212 lomac_range_in_range(struct mac_lomac *rangea, struct mac_lomac *rangeb) 213 { 214 215 return (lomac_dominate_element(&rangeb->ml_rangehigh, 216 &rangea->ml_rangehigh) && 217 lomac_dominate_element(&rangea->ml_rangelow, 218 &rangeb->ml_rangelow)); 219 } 220 221 static int 222 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 ("lomac_single_in_range: a not single")); 227 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 228 ("lomac_single_in_range: b not range")); 229 230 return (lomac_dominate_element(&range->ml_rangehigh, 231 &single->ml_single) && lomac_dominate_element(&single->ml_single, 232 &range->ml_rangelow)); 233 } 234 235 static int 236 lomac_auxsingle_in_range(struct mac_lomac *single, struct mac_lomac *range) 237 { 238 239 KASSERT((single->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 240 ("lomac_single_in_range: a not auxsingle")); 241 KASSERT((range->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 242 ("lomac_single_in_range: b not range")); 243 244 return (lomac_dominate_element(&range->ml_rangehigh, 245 &single->ml_auxsingle) && 246 lomac_dominate_element(&single->ml_auxsingle, 247 &range->ml_rangelow)); 248 } 249 250 static int 251 lomac_dominate_single(struct mac_lomac *a, struct mac_lomac *b) 252 { 253 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 254 ("lomac_dominate_single: a not single")); 255 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 256 ("lomac_dominate_single: b not single")); 257 258 return (lomac_dominate_element(&a->ml_single, &b->ml_single)); 259 } 260 261 static int 262 lomac_subject_dominate(struct mac_lomac *a, struct mac_lomac *b) 263 { 264 KASSERT((~a->ml_flags & 265 (MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_RANGE)) == 0, 266 ("lomac_dominate_single: a not subject")); 267 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 268 ("lomac_dominate_single: b not single")); 269 270 return (lomac_dominate_element(&a->ml_rangehigh, &b->ml_single)); 271 } 272 273 static int 274 lomac_equal_element(struct mac_lomac_element *a, struct mac_lomac_element *b) 275 { 276 277 if (a->mle_type == MAC_LOMAC_TYPE_EQUAL || 278 b->mle_type == MAC_LOMAC_TYPE_EQUAL) 279 return (1); 280 281 return (a->mle_type == b->mle_type && a->mle_grade == b->mle_grade); 282 } 283 284 static int 285 lomac_equal_single(struct mac_lomac *a, struct mac_lomac *b) 286 { 287 288 KASSERT((a->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 289 ("lomac_equal_single: a not single")); 290 KASSERT((b->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 291 ("lomac_equal_single: b not single")); 292 293 return (lomac_equal_element(&a->ml_single, &b->ml_single)); 294 } 295 296 static int 297 lomac_contains_equal(struct mac_lomac *ml) 298 { 299 300 if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) 301 if (ml->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 302 return (1); 303 if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) 304 if (ml->ml_auxsingle.mle_type == MAC_LOMAC_TYPE_EQUAL) 305 return (1); 306 307 if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) { 308 if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL) 309 return (1); 310 if (ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 311 return (1); 312 } 313 314 return (0); 315 } 316 317 static int 318 lomac_subject_privileged(struct mac_lomac *ml) 319 { 320 321 KASSERT((ml->ml_flags & MAC_LOMAC_FLAGS_BOTH) == 322 MAC_LOMAC_FLAGS_BOTH, 323 ("lomac_subject_privileged: subject doesn't have both labels")); 324 325 /* If the single is EQUAL, it's ok. */ 326 if (ml->ml_single.mle_type == MAC_LOMAC_TYPE_EQUAL) 327 return (0); 328 329 /* If either range endpoint is EQUAL, it's ok. */ 330 if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_EQUAL || 331 ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_EQUAL) 332 return (0); 333 334 /* If the range is low-high, it's ok. */ 335 if (ml->ml_rangelow.mle_type == MAC_LOMAC_TYPE_LOW && 336 ml->ml_rangehigh.mle_type == MAC_LOMAC_TYPE_HIGH) 337 return (0); 338 339 /* It's not ok. */ 340 return (EPERM); 341 } 342 343 static int 344 lomac_high_single(struct mac_lomac *ml) 345 { 346 347 KASSERT((ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 348 ("lomac_high_single: mac_lomac not single")); 349 350 return (ml->ml_single.mle_type == MAC_LOMAC_TYPE_HIGH); 351 } 352 353 static int 354 lomac_valid(struct mac_lomac *ml) 355 { 356 357 if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 358 switch (ml->ml_single.mle_type) { 359 case MAC_LOMAC_TYPE_GRADE: 360 case MAC_LOMAC_TYPE_EQUAL: 361 case MAC_LOMAC_TYPE_HIGH: 362 case MAC_LOMAC_TYPE_LOW: 363 break; 364 365 default: 366 return (EINVAL); 367 } 368 } else { 369 if (ml->ml_single.mle_type != MAC_LOMAC_TYPE_UNDEF) 370 return (EINVAL); 371 } 372 373 if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) { 374 switch (ml->ml_auxsingle.mle_type) { 375 case MAC_LOMAC_TYPE_GRADE: 376 case MAC_LOMAC_TYPE_EQUAL: 377 case MAC_LOMAC_TYPE_HIGH: 378 case MAC_LOMAC_TYPE_LOW: 379 break; 380 381 default: 382 return (EINVAL); 383 } 384 } else { 385 if (ml->ml_auxsingle.mle_type != MAC_LOMAC_TYPE_UNDEF) 386 return (EINVAL); 387 } 388 389 if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) { 390 switch (ml->ml_rangelow.mle_type) { 391 case MAC_LOMAC_TYPE_GRADE: 392 case MAC_LOMAC_TYPE_EQUAL: 393 case MAC_LOMAC_TYPE_HIGH: 394 case MAC_LOMAC_TYPE_LOW: 395 break; 396 397 default: 398 return (EINVAL); 399 } 400 401 switch (ml->ml_rangehigh.mle_type) { 402 case MAC_LOMAC_TYPE_GRADE: 403 case MAC_LOMAC_TYPE_EQUAL: 404 case MAC_LOMAC_TYPE_HIGH: 405 case MAC_LOMAC_TYPE_LOW: 406 break; 407 408 default: 409 return (EINVAL); 410 } 411 if (!lomac_dominate_element(&ml->ml_rangehigh, 412 &ml->ml_rangelow)) 413 return (EINVAL); 414 } else { 415 if (ml->ml_rangelow.mle_type != MAC_LOMAC_TYPE_UNDEF || 416 ml->ml_rangehigh.mle_type != MAC_LOMAC_TYPE_UNDEF) 417 return (EINVAL); 418 } 419 420 return (0); 421 } 422 423 static void 424 lomac_set_range(struct mac_lomac *ml, u_short typelow, u_short gradelow, 425 u_short typehigh, u_short gradehigh) 426 { 427 428 ml->ml_rangelow.mle_type = typelow; 429 ml->ml_rangelow.mle_grade = gradelow; 430 ml->ml_rangehigh.mle_type = typehigh; 431 ml->ml_rangehigh.mle_grade = gradehigh; 432 ml->ml_flags |= MAC_LOMAC_FLAG_RANGE; 433 } 434 435 static void 436 lomac_set_single(struct mac_lomac *ml, u_short type, u_short grade) 437 { 438 439 ml->ml_single.mle_type = type; 440 ml->ml_single.mle_grade = grade; 441 ml->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 442 } 443 444 static void 445 lomac_copy_range(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 446 { 447 448 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_RANGE) != 0, 449 ("lomac_copy_range: labelfrom not range")); 450 451 labelto->ml_rangelow = labelfrom->ml_rangelow; 452 labelto->ml_rangehigh = labelfrom->ml_rangehigh; 453 labelto->ml_flags |= MAC_LOMAC_FLAG_RANGE; 454 } 455 456 static void 457 lomac_copy_single(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 458 { 459 460 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_SINGLE) != 0, 461 ("lomac_copy_single: labelfrom not single")); 462 463 labelto->ml_single = labelfrom->ml_single; 464 labelto->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 465 } 466 467 static void 468 lomac_copy_auxsingle(struct mac_lomac *labelfrom, struct mac_lomac *labelto) 469 { 470 471 KASSERT((labelfrom->ml_flags & MAC_LOMAC_FLAG_AUX) != 0, 472 ("lomac_copy_auxsingle: labelfrom not auxsingle")); 473 474 labelto->ml_auxsingle = labelfrom->ml_auxsingle; 475 labelto->ml_flags |= MAC_LOMAC_FLAG_AUX; 476 } 477 478 static void 479 lomac_copy(struct mac_lomac *source, struct mac_lomac *dest) 480 { 481 482 if (source->ml_flags & MAC_LOMAC_FLAG_SINGLE) 483 lomac_copy_single(source, dest); 484 if (source->ml_flags & MAC_LOMAC_FLAG_AUX) 485 lomac_copy_auxsingle(source, dest); 486 if (source->ml_flags & MAC_LOMAC_FLAG_RANGE) 487 lomac_copy_range(source, dest); 488 } 489 490 static int lomac_to_string(struct sbuf *sb, struct mac_lomac *ml); 491 492 static int 493 maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 494 const char *actionname, const char *objname, struct vnode *vp) 495 { 496 struct sbuf subjlabel_sb, subjtext_sb, objlabel_sb; 497 char *subjlabeltext, *objlabeltext, *subjtext; 498 struct mac_lomac cached_subjlabel; 499 struct mac_lomac_proc *subj; 500 struct vattr va; 501 struct proc *p; 502 pid_t pgid; 503 504 subj = PSLOT(curthread->td_proc->p_label); 505 506 p = curthread->td_proc; 507 mtx_lock(&subj->mtx); 508 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 509 /* 510 * Check to see if the pending demotion would be more or less 511 * severe than this one, and keep the more severe. This can 512 * only happen for a multi-threaded application. 513 */ 514 if (lomac_dominate_single(objlabel, &subj->mac_lomac)) { 515 mtx_unlock(&subj->mtx); 516 return (0); 517 } 518 } 519 bzero(&subj->mac_lomac, sizeof(subj->mac_lomac)); 520 /* 521 * Always demote the single label. 522 */ 523 lomac_copy_single(objlabel, &subj->mac_lomac); 524 /* 525 * Start with the original range, then minimize each side of the 526 * range to the point of not dominating the object. The high side 527 * will always be demoted, of course. 528 */ 529 lomac_copy_range(subjlabel, &subj->mac_lomac); 530 if (!lomac_dominate_element(&objlabel->ml_single, 531 &subj->mac_lomac.ml_rangelow)) 532 subj->mac_lomac.ml_rangelow = objlabel->ml_single; 533 subj->mac_lomac.ml_rangehigh = objlabel->ml_single; 534 subj->mac_lomac.ml_flags |= MAC_LOMAC_FLAG_UPDATE; 535 ast_sched(curthread, TDA_MAC); 536 537 /* 538 * Avoid memory allocation while holding a mutex; cache the label. 539 */ 540 lomac_copy_single(&subj->mac_lomac, &cached_subjlabel); 541 mtx_unlock(&subj->mtx); 542 543 sbuf_new(&subjlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 544 lomac_to_string(&subjlabel_sb, subjlabel); 545 sbuf_finish(&subjlabel_sb); 546 subjlabeltext = sbuf_data(&subjlabel_sb); 547 548 sbuf_new(&subjtext_sb, NULL, 0, SBUF_AUTOEXTEND); 549 lomac_to_string(&subjtext_sb, &subj->mac_lomac); 550 sbuf_finish(&subjtext_sb); 551 subjtext = sbuf_data(&subjtext_sb); 552 553 sbuf_new(&objlabel_sb, NULL, 0, SBUF_AUTOEXTEND); 554 lomac_to_string(&objlabel_sb, objlabel); 555 sbuf_finish(&objlabel_sb); 556 objlabeltext = sbuf_data(&objlabel_sb); 557 558 pgid = p->p_pgrp->pg_id; /* XXX could be stale? */ 559 if (vp != NULL && VOP_GETATTR(vp, &va, curthread->td_ucred) == 0) { 560 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 561 " level %s after %s a level-%s %s (inode=%ju, " 562 "mountpount=%s)\n", 563 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 564 p->p_comm, subjtext, actionname, objlabeltext, objname, 565 (uintmax_t)va.va_fileid, vp->v_mount->mnt_stat.f_mntonname); 566 } else { 567 log(LOG_INFO, "LOMAC: level-%s subject p%dg%du%d:%s demoted to" 568 " level %s after %s a level-%s %s\n", 569 subjlabeltext, p->p_pid, pgid, curthread->td_ucred->cr_uid, 570 p->p_comm, subjtext, actionname, objlabeltext, objname); 571 } 572 573 sbuf_delete(&subjlabel_sb); 574 sbuf_delete(&subjtext_sb); 575 sbuf_delete(&objlabel_sb); 576 577 return (0); 578 } 579 580 /* 581 * Relabel "to" to "from" only if "from" is a valid label (contains at least 582 * a single), as for a relabel operation which may or may not involve a 583 * relevant label. 584 */ 585 static void 586 try_relabel(struct mac_lomac *from, struct mac_lomac *to) 587 { 588 589 if (from->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 590 bzero(to, sizeof(*to)); 591 lomac_copy(from, to); 592 } 593 } 594 595 static void 596 ast_mac(struct thread *td, int tda __unused) 597 { 598 mac_thread_userret(td); 599 } 600 601 /* 602 * Policy module operations. 603 */ 604 static void 605 lomac_init(struct mac_policy_conf *conf __unused) 606 { 607 ast_register(TDA_MAC, ASTR_ASTF_REQUIRED, 0, ast_mac); 608 } 609 610 static void 611 lomac_fini(struct mac_policy_conf *conf __unused) 612 { 613 ast_deregister(TDA_MAC); 614 } 615 616 /* 617 * Label operations. 618 */ 619 static void 620 lomac_init_label(struct label *label) 621 { 622 623 SLOT_SET(label, lomac_alloc(M_WAITOK)); 624 } 625 626 static int 627 lomac_init_label_waitcheck(struct label *label, int flag) 628 { 629 630 SLOT_SET(label, lomac_alloc(flag)); 631 if (SLOT(label) == NULL) 632 return (ENOMEM); 633 634 return (0); 635 } 636 637 static void 638 lomac_destroy_label(struct label *label) 639 { 640 641 lomac_free(SLOT(label)); 642 SLOT_SET(label, NULL); 643 } 644 645 static int 646 lomac_element_to_string(struct sbuf *sb, struct mac_lomac_element *element) 647 { 648 649 switch (element->mle_type) { 650 case MAC_LOMAC_TYPE_HIGH: 651 return (sbuf_printf(sb, "high")); 652 653 case MAC_LOMAC_TYPE_LOW: 654 return (sbuf_printf(sb, "low")); 655 656 case MAC_LOMAC_TYPE_EQUAL: 657 return (sbuf_printf(sb, "equal")); 658 659 case MAC_LOMAC_TYPE_GRADE: 660 return (sbuf_printf(sb, "%d", element->mle_grade)); 661 662 default: 663 panic("lomac_element_to_string: invalid type (%d)", 664 element->mle_type); 665 } 666 } 667 668 static int 669 lomac_to_string(struct sbuf *sb, struct mac_lomac *ml) 670 { 671 672 if (ml->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 673 if (lomac_element_to_string(sb, &ml->ml_single) == -1) 674 return (EINVAL); 675 } 676 677 if (ml->ml_flags & MAC_LOMAC_FLAG_AUX) { 678 if (sbuf_putc(sb, '[') == -1) 679 return (EINVAL); 680 681 if (lomac_element_to_string(sb, &ml->ml_auxsingle) == -1) 682 return (EINVAL); 683 684 if (sbuf_putc(sb, ']') == -1) 685 return (EINVAL); 686 } 687 688 if (ml->ml_flags & MAC_LOMAC_FLAG_RANGE) { 689 if (sbuf_putc(sb, '(') == -1) 690 return (EINVAL); 691 692 if (lomac_element_to_string(sb, &ml->ml_rangelow) == -1) 693 return (EINVAL); 694 695 if (sbuf_putc(sb, '-') == -1) 696 return (EINVAL); 697 698 if (lomac_element_to_string(sb, &ml->ml_rangehigh) == -1) 699 return (EINVAL); 700 701 if (sbuf_putc(sb, ')') == -1) 702 return (EINVAL); 703 } 704 705 return (0); 706 } 707 708 static int 709 lomac_externalize_label(struct label *label, char *element_name, 710 struct sbuf *sb, int *claimed) 711 { 712 struct mac_lomac *ml; 713 714 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 715 return (0); 716 717 (*claimed)++; 718 719 ml = SLOT(label); 720 721 return (lomac_to_string(sb, ml)); 722 } 723 724 static int 725 lomac_parse_element(struct mac_lomac_element *element, char *string) 726 { 727 728 if (strcmp(string, "high") == 0 || strcmp(string, "hi") == 0) { 729 element->mle_type = MAC_LOMAC_TYPE_HIGH; 730 element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 731 } else if (strcmp(string, "low") == 0 || strcmp(string, "lo") == 0) { 732 element->mle_type = MAC_LOMAC_TYPE_LOW; 733 element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 734 } else if (strcmp(string, "equal") == 0 || 735 strcmp(string, "eq") == 0) { 736 element->mle_type = MAC_LOMAC_TYPE_EQUAL; 737 element->mle_grade = MAC_LOMAC_TYPE_UNDEF; 738 } else { 739 char *p0, *p1; 740 int d; 741 742 p0 = string; 743 d = strtol(p0, &p1, 10); 744 745 if (d < 0 || d > 65535) 746 return (EINVAL); 747 element->mle_type = MAC_LOMAC_TYPE_GRADE; 748 element->mle_grade = d; 749 750 if (p1 == p0 || *p1 != '\0') 751 return (EINVAL); 752 } 753 754 return (0); 755 } 756 757 /* 758 * Note: destructively consumes the string, make a local copy before calling 759 * if that's a problem. 760 */ 761 static int 762 lomac_parse(struct mac_lomac *ml, char *string) 763 { 764 char *range, *rangeend, *rangehigh, *rangelow, *single, *auxsingle, 765 *auxsingleend; 766 int error; 767 768 /* Do we have a range? */ 769 single = string; 770 range = strchr(string, '('); 771 if (range == single) 772 single = NULL; 773 auxsingle = strchr(string, '['); 774 if (auxsingle == single) 775 single = NULL; 776 if (range != NULL && auxsingle != NULL) 777 return (EINVAL); 778 rangelow = rangehigh = NULL; 779 if (range != NULL) { 780 /* Nul terminate the end of the single string. */ 781 *range = '\0'; 782 range++; 783 rangelow = range; 784 rangehigh = strchr(rangelow, '-'); 785 if (rangehigh == NULL) 786 return (EINVAL); 787 rangehigh++; 788 if (*rangelow == '\0' || *rangehigh == '\0') 789 return (EINVAL); 790 rangeend = strchr(rangehigh, ')'); 791 if (rangeend == NULL) 792 return (EINVAL); 793 if (*(rangeend + 1) != '\0') 794 return (EINVAL); 795 /* Nul terminate the ends of the ranges. */ 796 *(rangehigh - 1) = '\0'; 797 *rangeend = '\0'; 798 } 799 KASSERT((rangelow != NULL && rangehigh != NULL) || 800 (rangelow == NULL && rangehigh == NULL), 801 ("lomac_internalize_label: range mismatch")); 802 if (auxsingle != NULL) { 803 /* Nul terminate the end of the single string. */ 804 *auxsingle = '\0'; 805 auxsingle++; 806 auxsingleend = strchr(auxsingle, ']'); 807 if (auxsingleend == NULL) 808 return (EINVAL); 809 if (*(auxsingleend + 1) != '\0') 810 return (EINVAL); 811 /* Nul terminate the end of the auxsingle. */ 812 *auxsingleend = '\0'; 813 } 814 815 bzero(ml, sizeof(*ml)); 816 if (single != NULL) { 817 error = lomac_parse_element(&ml->ml_single, single); 818 if (error) 819 return (error); 820 ml->ml_flags |= MAC_LOMAC_FLAG_SINGLE; 821 } 822 823 if (auxsingle != NULL) { 824 error = lomac_parse_element(&ml->ml_auxsingle, auxsingle); 825 if (error) 826 return (error); 827 ml->ml_flags |= MAC_LOMAC_FLAG_AUX; 828 } 829 830 if (rangelow != NULL) { 831 error = lomac_parse_element(&ml->ml_rangelow, rangelow); 832 if (error) 833 return (error); 834 error = lomac_parse_element(&ml->ml_rangehigh, rangehigh); 835 if (error) 836 return (error); 837 ml->ml_flags |= MAC_LOMAC_FLAG_RANGE; 838 } 839 840 error = lomac_valid(ml); 841 if (error) 842 return (error); 843 844 return (0); 845 } 846 847 static int 848 lomac_internalize_label(struct label *label, char *element_name, 849 char *element_data, int *claimed) 850 { 851 struct mac_lomac *ml, ml_temp; 852 int error; 853 854 if (strcmp(MAC_LOMAC_LABEL_NAME, element_name) != 0) 855 return (0); 856 857 (*claimed)++; 858 859 error = lomac_parse(&ml_temp, element_data); 860 if (error) 861 return (error); 862 863 ml = SLOT(label); 864 *ml = ml_temp; 865 866 return (0); 867 } 868 869 static void 870 lomac_copy_label(struct label *src, struct label *dest) 871 { 872 873 *SLOT(dest) = *SLOT(src); 874 } 875 876 /* 877 * Object-specific entry point implementations are sorted alphabetically by 878 * object type name and then by operation. 879 */ 880 static int 881 lomac_bpfdesc_check_receive(struct bpf_d *d, struct label *dlabel, 882 struct ifnet *ifp, struct label *ifplabel) 883 { 884 struct mac_lomac *a, *b; 885 886 if (!lomac_enabled) 887 return (0); 888 889 a = SLOT(dlabel); 890 b = SLOT(ifplabel); 891 892 if (lomac_equal_single(a, b)) 893 return (0); 894 return (EACCES); 895 } 896 897 static void 898 lomac_bpfdesc_create(struct ucred *cred, struct bpf_d *d, 899 struct label *dlabel) 900 { 901 struct mac_lomac *source, *dest; 902 903 source = SLOT(cred->cr_label); 904 dest = SLOT(dlabel); 905 906 lomac_copy_single(source, dest); 907 } 908 909 static void 910 lomac_bpfdesc_create_mbuf(struct bpf_d *d, struct label *dlabel, 911 struct mbuf *m, struct label *mlabel) 912 { 913 struct mac_lomac *source, *dest; 914 915 source = SLOT(dlabel); 916 dest = SLOT(mlabel); 917 918 lomac_copy_single(source, dest); 919 } 920 921 static int 922 lomac_cred_check_relabel(struct ucred *cred, struct label *newlabel) 923 { 924 struct mac_lomac *subj, *new; 925 int error; 926 927 subj = SLOT(cred->cr_label); 928 new = SLOT(newlabel); 929 930 /* 931 * If there is a LOMAC label update for the credential, it may be an 932 * update of the single, range, or both. 933 */ 934 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 935 if (error) 936 return (error); 937 938 /* 939 * If the LOMAC label is to be changed, authorize as appropriate. 940 */ 941 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 942 /* 943 * Fill in the missing parts from the previous label. 944 */ 945 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 946 lomac_copy_single(subj, new); 947 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 948 lomac_copy_range(subj, new); 949 950 /* 951 * To change the LOMAC range on a credential, the new range 952 * label must be in the current range. 953 */ 954 if (!lomac_range_in_range(new, subj)) 955 return (EPERM); 956 957 /* 958 * To change the LOMAC single label on a credential, the new 959 * single label must be in the new range. Implicitly from 960 * the previous check, the new single is in the old range. 961 */ 962 if (!lomac_single_in_range(new, new)) 963 return (EPERM); 964 965 /* 966 * To have EQUAL in any component of the new credential LOMAC 967 * label, the subject must already have EQUAL in their label. 968 */ 969 if (lomac_contains_equal(new)) { 970 error = lomac_subject_privileged(subj); 971 if (error) 972 return (error); 973 } 974 975 /* 976 * XXXMAC: Additional consistency tests regarding the single 977 * and range of the new label might be performed here. 978 */ 979 } 980 981 return (0); 982 } 983 984 static int 985 lomac_cred_check_visible(struct ucred *cr1, struct ucred *cr2) 986 { 987 struct mac_lomac *subj, *obj; 988 989 if (!lomac_enabled) 990 return (0); 991 992 subj = SLOT(cr1->cr_label); 993 obj = SLOT(cr2->cr_label); 994 995 /* XXX: range */ 996 if (!lomac_dominate_single(obj, subj)) 997 return (ESRCH); 998 999 return (0); 1000 } 1001 1002 static void 1003 lomac_cred_create_init(struct ucred *cred) 1004 { 1005 struct mac_lomac *dest; 1006 1007 dest = SLOT(cred->cr_label); 1008 1009 lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0); 1010 lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 0); 1011 } 1012 1013 static void 1014 lomac_cred_create_swapper(struct ucred *cred) 1015 { 1016 struct mac_lomac *dest; 1017 1018 dest = SLOT(cred->cr_label); 1019 1020 lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1021 lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 0); 1022 } 1023 1024 static void 1025 lomac_cred_relabel(struct ucred *cred, struct label *newlabel) 1026 { 1027 struct mac_lomac *source, *dest; 1028 1029 source = SLOT(newlabel); 1030 dest = SLOT(cred->cr_label); 1031 1032 try_relabel(source, dest); 1033 } 1034 1035 static void 1036 lomac_devfs_create_device(struct ucred *cred, struct mount *mp, 1037 struct cdev *dev, struct devfs_dirent *de, struct label *delabel) 1038 { 1039 struct mac_lomac *ml; 1040 const char *dn; 1041 int lomac_type; 1042 1043 ml = SLOT(delabel); 1044 dn = devtoname(dev); 1045 if (strcmp(dn, "null") == 0 || 1046 strcmp(dn, "zero") == 0 || 1047 strcmp(dn, "random") == 0 || 1048 strncmp(dn, "fd/", strlen("fd/")) == 0 || 1049 strncmp(dn, "ttyv", strlen("ttyv")) == 0) 1050 lomac_type = MAC_LOMAC_TYPE_EQUAL; 1051 else if (ptys_equal && 1052 (strncmp(dn, "ttyp", strlen("ttyp")) == 0 || 1053 strncmp(dn, "pts/", strlen("pts/")) == 0 || 1054 strncmp(dn, "ptyp", strlen("ptyp")) == 0)) 1055 lomac_type = MAC_LOMAC_TYPE_EQUAL; 1056 else 1057 lomac_type = MAC_LOMAC_TYPE_HIGH; 1058 lomac_set_single(ml, lomac_type, 0); 1059 } 1060 1061 static void 1062 lomac_devfs_create_directory(struct mount *mp, char *dirname, int dirnamelen, 1063 struct devfs_dirent *de, struct label *delabel) 1064 { 1065 struct mac_lomac *ml; 1066 1067 ml = SLOT(delabel); 1068 lomac_set_single(ml, MAC_LOMAC_TYPE_HIGH, 0); 1069 } 1070 1071 static void 1072 lomac_devfs_create_symlink(struct ucred *cred, struct mount *mp, 1073 struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de, 1074 struct label *delabel) 1075 { 1076 struct mac_lomac *source, *dest; 1077 1078 source = SLOT(cred->cr_label); 1079 dest = SLOT(delabel); 1080 1081 lomac_copy_single(source, dest); 1082 } 1083 1084 static void 1085 lomac_devfs_update(struct mount *mp, struct devfs_dirent *de, 1086 struct label *delabel, struct vnode *vp, struct label *vplabel) 1087 { 1088 struct mac_lomac *source, *dest; 1089 1090 source = SLOT(vplabel); 1091 dest = SLOT(delabel); 1092 1093 lomac_copy(source, dest); 1094 } 1095 1096 static void 1097 lomac_devfs_vnode_associate(struct mount *mp, struct label *mplabel, 1098 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 1099 struct label *vplabel) 1100 { 1101 struct mac_lomac *source, *dest; 1102 1103 source = SLOT(delabel); 1104 dest = SLOT(vplabel); 1105 1106 lomac_copy_single(source, dest); 1107 } 1108 1109 static int 1110 lomac_ifnet_check_relabel(struct ucred *cred, struct ifnet *ifp, 1111 struct label *ifplabel, struct label *newlabel) 1112 { 1113 struct mac_lomac *subj, *new; 1114 int error; 1115 1116 subj = SLOT(cred->cr_label); 1117 new = SLOT(newlabel); 1118 1119 /* 1120 * If there is a LOMAC label update for the interface, it may be an 1121 * update of the single, range, or both. 1122 */ 1123 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1124 if (error) 1125 return (error); 1126 1127 /* 1128 * Relabling network interfaces requires LOMAC privilege. 1129 */ 1130 error = lomac_subject_privileged(subj); 1131 if (error) 1132 return (error); 1133 1134 /* 1135 * If the LOMAC label is to be changed, authorize as appropriate. 1136 */ 1137 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1138 /* 1139 * Fill in the missing parts from the previous label. 1140 */ 1141 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1142 lomac_copy_single(subj, new); 1143 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1144 lomac_copy_range(subj, new); 1145 1146 /* 1147 * Rely on the traditional superuser status for the LOMAC 1148 * interface relabel requirements. XXXMAC: This will go 1149 * away. 1150 * 1151 * XXXRW: This is also redundant to a higher layer check. 1152 */ 1153 error = priv_check_cred(cred, PRIV_NET_SETIFMAC); 1154 if (error) 1155 return (EPERM); 1156 1157 /* 1158 * XXXMAC: Additional consistency tests regarding the single 1159 * and the range of the new label might be performed here. 1160 */ 1161 } 1162 1163 return (0); 1164 } 1165 1166 static int 1167 lomac_ifnet_check_transmit(struct ifnet *ifp, struct label *ifplabel, 1168 struct mbuf *m, struct label *mlabel) 1169 { 1170 struct mac_lomac *p, *i; 1171 1172 if (!lomac_enabled) 1173 return (0); 1174 1175 p = SLOT(mlabel); 1176 i = SLOT(ifplabel); 1177 1178 return (lomac_single_in_range(p, i) ? 0 : EACCES); 1179 } 1180 1181 static void 1182 lomac_ifnet_create(struct ifnet *ifp, struct label *ifplabel) 1183 { 1184 char tifname[IFNAMSIZ], *p, *q; 1185 char tiflist[sizeof(trusted_interfaces)]; 1186 struct mac_lomac *dest; 1187 int len, grade; 1188 1189 dest = SLOT(ifplabel); 1190 1191 if (ifp->if_type == IFT_LOOP) { 1192 grade = MAC_LOMAC_TYPE_EQUAL; 1193 goto set; 1194 } 1195 1196 if (trust_all_interfaces) { 1197 grade = MAC_LOMAC_TYPE_HIGH; 1198 goto set; 1199 } 1200 1201 grade = MAC_LOMAC_TYPE_LOW; 1202 1203 if (trusted_interfaces[0] == '\0' || 1204 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1205 goto set; 1206 1207 bzero(tiflist, sizeof(tiflist)); 1208 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1209 if(*p != ' ' && *p != '\t') 1210 *q = *p; 1211 1212 for (p = q = tiflist;; p++) { 1213 if (*p == ',' || *p == '\0') { 1214 len = p - q; 1215 if (len < IFNAMSIZ) { 1216 bzero(tifname, sizeof(tifname)); 1217 bcopy(q, tifname, len); 1218 if (strcmp(tifname, ifp->if_xname) == 0) { 1219 grade = MAC_LOMAC_TYPE_HIGH; 1220 break; 1221 } 1222 } 1223 else { 1224 *p = '\0'; 1225 printf("MAC/LOMAC warning: interface name " 1226 "\"%s\" is too long (must be < %d)\n", 1227 q, IFNAMSIZ); 1228 } 1229 if (*p == '\0') 1230 break; 1231 q = p + 1; 1232 } 1233 } 1234 set: 1235 lomac_set_single(dest, grade, 0); 1236 lomac_set_range(dest, grade, 0, grade, 0); 1237 } 1238 1239 static void 1240 lomac_ifnet_create_mbuf(struct ifnet *ifp, struct label *ifplabel, 1241 struct mbuf *m, struct label *mlabel) 1242 { 1243 struct mac_lomac *source, *dest; 1244 1245 source = SLOT(ifplabel); 1246 dest = SLOT(mlabel); 1247 1248 lomac_copy_single(source, dest); 1249 } 1250 1251 static void 1252 lomac_ifnet_relabel(struct ucred *cred, struct ifnet *ifp, 1253 struct label *ifplabel, struct label *newlabel) 1254 { 1255 struct mac_lomac *source, *dest; 1256 1257 source = SLOT(newlabel); 1258 dest = SLOT(ifplabel); 1259 1260 try_relabel(source, dest); 1261 } 1262 1263 static int 1264 lomac_inpcb_check_deliver(struct inpcb *inp, struct label *inplabel, 1265 struct mbuf *m, struct label *mlabel) 1266 { 1267 struct mac_lomac *p, *i; 1268 1269 if (!lomac_enabled) 1270 return (0); 1271 1272 p = SLOT(mlabel); 1273 i = SLOT(inplabel); 1274 1275 return (lomac_equal_single(p, i) ? 0 : EACCES); 1276 } 1277 1278 static int 1279 lomac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp, 1280 struct label *inplabel) 1281 { 1282 struct mac_lomac *subj, *obj; 1283 1284 if (!lomac_enabled) 1285 return (0); 1286 1287 subj = SLOT(cred->cr_label); 1288 obj = SLOT(inplabel); 1289 1290 if (!lomac_dominate_single(obj, subj)) 1291 return (ENOENT); 1292 1293 return (0); 1294 } 1295 1296 static void 1297 lomac_inpcb_create(struct socket *so, struct label *solabel, 1298 struct inpcb *inp, struct label *inplabel) 1299 { 1300 struct mac_lomac *source, *dest; 1301 1302 source = SLOT(solabel); 1303 dest = SLOT(inplabel); 1304 1305 lomac_copy_single(source, dest); 1306 } 1307 1308 static void 1309 lomac_inpcb_create_mbuf(struct inpcb *inp, struct label *inplabel, 1310 struct mbuf *m, struct label *mlabel) 1311 { 1312 struct mac_lomac *source, *dest; 1313 1314 source = SLOT(inplabel); 1315 dest = SLOT(mlabel); 1316 1317 lomac_copy_single(source, dest); 1318 } 1319 1320 static void 1321 lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1322 struct inpcb *inp, struct label *inplabel) 1323 { 1324 struct mac_lomac *source, *dest; 1325 1326 SOCK_LOCK_ASSERT(so); 1327 1328 source = SLOT(solabel); 1329 dest = SLOT(inplabel); 1330 1331 lomac_copy_single(source, dest); 1332 } 1333 1334 static void 1335 lomac_ip6q_create(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1336 struct label *q6label) 1337 { 1338 struct mac_lomac *source, *dest; 1339 1340 source = SLOT(mlabel); 1341 dest = SLOT(q6label); 1342 1343 lomac_copy_single(source, dest); 1344 } 1345 1346 static int 1347 lomac_ip6q_match(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1348 struct label *q6label) 1349 { 1350 struct mac_lomac *a, *b; 1351 1352 a = SLOT(q6label); 1353 b = SLOT(mlabel); 1354 1355 return (lomac_equal_single(a, b)); 1356 } 1357 1358 static void 1359 lomac_ip6q_reassemble(struct ip6q *q6, struct label *q6label, struct mbuf *m, 1360 struct label *mlabel) 1361 { 1362 struct mac_lomac *source, *dest; 1363 1364 source = SLOT(q6label); 1365 dest = SLOT(mlabel); 1366 1367 /* Just use the head, since we require them all to match. */ 1368 lomac_copy_single(source, dest); 1369 } 1370 1371 static void 1372 lomac_ip6q_update(struct mbuf *m, struct label *mlabel, struct ip6q *q6, 1373 struct label *q6label) 1374 { 1375 1376 /* NOOP: we only accept matching labels, so no need to update */ 1377 } 1378 1379 static void 1380 lomac_ipq_create(struct mbuf *m, struct label *mlabel, struct ipq *q, 1381 struct label *qlabel) 1382 { 1383 struct mac_lomac *source, *dest; 1384 1385 source = SLOT(mlabel); 1386 dest = SLOT(qlabel); 1387 1388 lomac_copy_single(source, dest); 1389 } 1390 1391 static int 1392 lomac_ipq_match(struct mbuf *m, struct label *mlabel, struct ipq *q, 1393 struct label *qlabel) 1394 { 1395 struct mac_lomac *a, *b; 1396 1397 a = SLOT(qlabel); 1398 b = SLOT(mlabel); 1399 1400 return (lomac_equal_single(a, b)); 1401 } 1402 1403 static void 1404 lomac_ipq_reassemble(struct ipq *q, struct label *qlabel, struct mbuf *m, 1405 struct label *mlabel) 1406 { 1407 struct mac_lomac *source, *dest; 1408 1409 source = SLOT(qlabel); 1410 dest = SLOT(mlabel); 1411 1412 /* Just use the head, since we require them all to match. */ 1413 lomac_copy_single(source, dest); 1414 } 1415 1416 static void 1417 lomac_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q, 1418 struct label *qlabel) 1419 { 1420 1421 /* NOOP: we only accept matching labels, so no need to update */ 1422 } 1423 1424 static int 1425 lomac_kld_check_load(struct ucred *cred, struct vnode *vp, 1426 struct label *vplabel) 1427 { 1428 struct mac_lomac *subj, *obj; 1429 1430 if (!lomac_enabled) 1431 return (0); 1432 1433 subj = SLOT(cred->cr_label); 1434 obj = SLOT(vplabel); 1435 1436 if (lomac_subject_privileged(subj)) 1437 return (EPERM); 1438 1439 if (!lomac_high_single(obj)) 1440 return (EACCES); 1441 1442 return (0); 1443 } 1444 1445 static void 1446 lomac_mount_create(struct ucred *cred, struct mount *mp, 1447 struct label *mplabel) 1448 { 1449 struct mac_lomac *source, *dest; 1450 1451 source = SLOT(cred->cr_label); 1452 dest = SLOT(mplabel); 1453 lomac_copy_single(source, dest); 1454 } 1455 1456 static void 1457 lomac_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel, 1458 struct mbuf *m, struct label *mlabel) 1459 { 1460 struct mac_lomac *dest; 1461 1462 dest = SLOT(mlabel); 1463 1464 lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1465 } 1466 1467 static void 1468 lomac_netinet_firewall_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1469 struct mbuf *msend, struct label *msendlabel) 1470 { 1471 struct mac_lomac *source, *dest; 1472 1473 source = SLOT(mrecvlabel); 1474 dest = SLOT(msendlabel); 1475 1476 lomac_copy_single(source, dest); 1477 } 1478 1479 static void 1480 lomac_netinet_firewall_send(struct mbuf *m, struct label *mlabel) 1481 { 1482 struct mac_lomac *dest; 1483 1484 dest = SLOT(mlabel); 1485 1486 /* XXX: where is the label for the firewall really coming from? */ 1487 lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1488 } 1489 1490 static void 1491 lomac_netinet_fragment(struct mbuf *m, struct label *mlabel, 1492 struct mbuf *frag, struct label *fraglabel) 1493 { 1494 struct mac_lomac *source, *dest; 1495 1496 source = SLOT(mlabel); 1497 dest = SLOT(fraglabel); 1498 1499 lomac_copy_single(source, dest); 1500 } 1501 1502 static void 1503 lomac_netinet_icmp_reply(struct mbuf *mrecv, struct label *mrecvlabel, 1504 struct mbuf *msend, struct label *msendlabel) 1505 { 1506 struct mac_lomac *source, *dest; 1507 1508 source = SLOT(mrecvlabel); 1509 dest = SLOT(msendlabel); 1510 1511 lomac_copy_single(source, dest); 1512 } 1513 1514 static void 1515 lomac_netinet_igmp_send(struct ifnet *ifp, struct label *ifplabel, 1516 struct mbuf *m, struct label *mlabel) 1517 { 1518 struct mac_lomac *dest; 1519 1520 dest = SLOT(mlabel); 1521 1522 lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1523 } 1524 1525 static void 1526 lomac_netinet6_nd6_send(struct ifnet *ifp, struct label *ifplabel, 1527 struct mbuf *m, struct label *mlabel) 1528 { 1529 struct mac_lomac *dest; 1530 1531 dest = SLOT(mlabel); 1532 1533 lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1534 } 1535 1536 static int 1537 lomac_pipe_check_ioctl(struct ucred *cred, struct pipepair *pp, 1538 struct label *pplabel, unsigned long cmd, void /* caddr_t */ *data) 1539 { 1540 1541 if (!lomac_enabled) 1542 return (0); 1543 1544 /* XXX: This will be implemented soon... */ 1545 1546 return (0); 1547 } 1548 1549 static int 1550 lomac_pipe_check_read(struct ucred *cred, struct pipepair *pp, 1551 struct label *pplabel) 1552 { 1553 struct mac_lomac *subj, *obj; 1554 1555 if (!lomac_enabled) 1556 return (0); 1557 1558 subj = SLOT(cred->cr_label); 1559 obj = SLOT(pplabel); 1560 1561 if (!lomac_dominate_single(obj, subj)) 1562 return (maybe_demote(subj, obj, "reading", "pipe", NULL)); 1563 1564 return (0); 1565 } 1566 1567 static int 1568 lomac_pipe_check_relabel(struct ucred *cred, struct pipepair *pp, 1569 struct label *pplabel, struct label *newlabel) 1570 { 1571 struct mac_lomac *subj, *obj, *new; 1572 int error; 1573 1574 new = SLOT(newlabel); 1575 subj = SLOT(cred->cr_label); 1576 obj = SLOT(pplabel); 1577 1578 /* 1579 * If there is a LOMAC label update for a pipe, it must be a single 1580 * update. 1581 */ 1582 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1583 if (error) 1584 return (error); 1585 1586 /* 1587 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must 1588 * authorize the relabel. 1589 */ 1590 if (!lomac_single_in_range(obj, subj)) 1591 return (EPERM); 1592 1593 /* 1594 * If the LOMAC label is to be changed, authorize as appropriate. 1595 */ 1596 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1597 /* 1598 * To change the LOMAC label on a pipe, the new pipe label 1599 * must be in the subject range. 1600 */ 1601 if (!lomac_single_in_range(new, subj)) 1602 return (EPERM); 1603 1604 /* 1605 * To change the LOMAC label on a pipe to be EQUAL, the 1606 * subject must have appropriate privilege. 1607 */ 1608 if (lomac_contains_equal(new)) { 1609 error = lomac_subject_privileged(subj); 1610 if (error) 1611 return (error); 1612 } 1613 } 1614 1615 return (0); 1616 } 1617 1618 static int 1619 lomac_pipe_check_write(struct ucred *cred, struct pipepair *pp, 1620 struct label *pplabel) 1621 { 1622 struct mac_lomac *subj, *obj; 1623 1624 if (!lomac_enabled) 1625 return (0); 1626 1627 subj = SLOT(cred->cr_label); 1628 obj = SLOT(pplabel); 1629 1630 if (!lomac_subject_dominate(subj, obj)) 1631 return (EACCES); 1632 1633 return (0); 1634 } 1635 1636 static void 1637 lomac_pipe_create(struct ucred *cred, struct pipepair *pp, 1638 struct label *pplabel) 1639 { 1640 struct mac_lomac *source, *dest; 1641 1642 source = SLOT(cred->cr_label); 1643 dest = SLOT(pplabel); 1644 1645 lomac_copy_single(source, dest); 1646 } 1647 1648 static void 1649 lomac_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1650 struct label *pplabel, struct label *newlabel) 1651 { 1652 struct mac_lomac *source, *dest; 1653 1654 source = SLOT(newlabel); 1655 dest = SLOT(pplabel); 1656 1657 try_relabel(source, dest); 1658 } 1659 1660 /* 1661 * Some system privileges are allowed regardless of integrity grade; others 1662 * are allowed only when running with privilege with respect to the LOMAC 1663 * policy as they might otherwise allow bypassing of the integrity policy. 1664 */ 1665 static int 1666 lomac_priv_check(struct ucred *cred, int priv) 1667 { 1668 struct mac_lomac *subj; 1669 int error; 1670 1671 if (!lomac_enabled) 1672 return (0); 1673 1674 /* 1675 * Exempt only specific privileges from the LOMAC integrity policy. 1676 */ 1677 switch (priv) { 1678 case PRIV_KTRACE: 1679 case PRIV_MSGBUF: 1680 1681 /* 1682 * Allow processes to manipulate basic process audit properties, and 1683 * to submit audit records. 1684 */ 1685 case PRIV_AUDIT_GETAUDIT: 1686 case PRIV_AUDIT_SETAUDIT: 1687 case PRIV_AUDIT_SUBMIT: 1688 1689 /* 1690 * Allow processes to manipulate their regular UNIX credentials. 1691 */ 1692 case PRIV_CRED_SETUID: 1693 case PRIV_CRED_SETEUID: 1694 case PRIV_CRED_SETGID: 1695 case PRIV_CRED_SETEGID: 1696 case PRIV_CRED_SETGROUPS: 1697 case PRIV_CRED_SETREUID: 1698 case PRIV_CRED_SETREGID: 1699 case PRIV_CRED_SETRESUID: 1700 case PRIV_CRED_SETRESGID: 1701 1702 /* 1703 * Allow processes to perform system monitoring. 1704 */ 1705 case PRIV_SEEOTHERGIDS: 1706 case PRIV_SEEOTHERUIDS: 1707 break; 1708 1709 /* 1710 * Allow access to general process debugging facilities. We 1711 * separately control debugging based on MAC label. 1712 */ 1713 case PRIV_DEBUG_DIFFCRED: 1714 case PRIV_DEBUG_SUGID: 1715 case PRIV_DEBUG_UNPRIV: 1716 1717 /* 1718 * Allow manipulating jails. 1719 */ 1720 case PRIV_JAIL_ATTACH: 1721 1722 /* 1723 * Allow privilege with respect to the Partition policy, but not the 1724 * Privs policy. 1725 */ 1726 case PRIV_MAC_PARTITION: 1727 1728 /* 1729 * Allow privilege with respect to process resource limits and login 1730 * context. 1731 */ 1732 case PRIV_PROC_LIMIT: 1733 case PRIV_PROC_SETLOGIN: 1734 case PRIV_PROC_SETRLIMIT: 1735 1736 /* 1737 * Allow System V and POSIX IPC privileges. 1738 */ 1739 case PRIV_IPC_READ: 1740 case PRIV_IPC_WRITE: 1741 case PRIV_IPC_ADMIN: 1742 case PRIV_IPC_MSGSIZE: 1743 case PRIV_MQ_ADMIN: 1744 1745 /* 1746 * Allow certain scheduler manipulations -- possibly this should be 1747 * controlled by more fine-grained policy, as potentially low 1748 * integrity processes can deny CPU to higher integrity ones. 1749 */ 1750 case PRIV_SCHED_DIFFCRED: 1751 case PRIV_SCHED_SETPRIORITY: 1752 case PRIV_SCHED_RTPRIO: 1753 case PRIV_SCHED_SETPOLICY: 1754 case PRIV_SCHED_SET: 1755 case PRIV_SCHED_SETPARAM: 1756 case PRIV_SCHED_IDPRIO: 1757 1758 /* 1759 * More IPC privileges. 1760 */ 1761 case PRIV_SEM_WRITE: 1762 1763 /* 1764 * Allow signaling privileges subject to integrity policy. 1765 */ 1766 case PRIV_SIGNAL_DIFFCRED: 1767 case PRIV_SIGNAL_SUGID: 1768 1769 /* 1770 * Allow access to only limited sysctls from lower integrity levels; 1771 * piggy-back on the Jail definition. 1772 */ 1773 case PRIV_SYSCTL_WRITEJAIL: 1774 1775 /* 1776 * Allow TTY-based privileges, subject to general device access using 1777 * labels on TTY device nodes, but not console privilege. 1778 */ 1779 case PRIV_TTY_DRAINWAIT: 1780 case PRIV_TTY_DTRWAIT: 1781 case PRIV_TTY_EXCLUSIVE: 1782 case PRIV_TTY_STI: 1783 case PRIV_TTY_SETA: 1784 1785 /* 1786 * Grant most VFS privileges, as almost all are in practice bounded 1787 * by more specific checks using labels. 1788 */ 1789 case PRIV_VFS_READ: 1790 case PRIV_VFS_WRITE: 1791 case PRIV_VFS_ADMIN: 1792 case PRIV_VFS_EXEC: 1793 case PRIV_VFS_LOOKUP: 1794 case PRIV_VFS_CHFLAGS_DEV: 1795 case PRIV_VFS_CHOWN: 1796 case PRIV_VFS_CHROOT: 1797 case PRIV_VFS_RETAINSUGID: 1798 case PRIV_VFS_EXCEEDQUOTA: 1799 case PRIV_VFS_FCHROOT: 1800 case PRIV_VFS_FHOPEN: 1801 case PRIV_VFS_FHSTATFS: 1802 case PRIV_VFS_GENERATION: 1803 case PRIV_VFS_GETFH: 1804 case PRIV_VFS_GETQUOTA: 1805 case PRIV_VFS_LINK: 1806 case PRIV_VFS_MOUNT: 1807 case PRIV_VFS_MOUNT_OWNER: 1808 case PRIV_VFS_MOUNT_PERM: 1809 case PRIV_VFS_MOUNT_SUIDDIR: 1810 case PRIV_VFS_MOUNT_NONUSER: 1811 case PRIV_VFS_SETGID: 1812 case PRIV_VFS_STICKYFILE: 1813 case PRIV_VFS_SYSFLAGS: 1814 case PRIV_VFS_UNMOUNT: 1815 1816 /* 1817 * Allow VM privileges; it would be nice if these were subject to 1818 * resource limits. 1819 */ 1820 case PRIV_VM_MADV_PROTECT: 1821 case PRIV_VM_MLOCK: 1822 case PRIV_VM_MUNLOCK: 1823 case PRIV_VM_SWAP_NOQUOTA: 1824 case PRIV_VM_SWAP_NORLIMIT: 1825 1826 /* 1827 * Allow some but not all network privileges. In general, dont allow 1828 * reconfiguring the network stack, just normal use. 1829 */ 1830 case PRIV_NETINET_RESERVEDPORT: 1831 case PRIV_NETINET_RAW: 1832 case PRIV_NETINET_REUSEPORT: 1833 break; 1834 1835 /* 1836 * All remaining system privileges are allow only if the process 1837 * holds privilege with respect to the LOMAC policy. 1838 */ 1839 default: 1840 subj = SLOT(cred->cr_label); 1841 error = lomac_subject_privileged(subj); 1842 if (error) 1843 return (error); 1844 } 1845 return (0); 1846 } 1847 1848 static int 1849 lomac_proc_check_debug(struct ucred *cred, struct proc *p) 1850 { 1851 struct mac_lomac *subj, *obj; 1852 1853 if (!lomac_enabled) 1854 return (0); 1855 1856 subj = SLOT(cred->cr_label); 1857 obj = SLOT(p->p_ucred->cr_label); 1858 1859 /* XXX: range checks */ 1860 if (!lomac_dominate_single(obj, subj)) 1861 return (ESRCH); 1862 if (!lomac_subject_dominate(subj, obj)) 1863 return (EACCES); 1864 1865 return (0); 1866 } 1867 1868 static int 1869 lomac_proc_check_sched(struct ucred *cred, struct proc *p) 1870 { 1871 struct mac_lomac *subj, *obj; 1872 1873 if (!lomac_enabled) 1874 return (0); 1875 1876 subj = SLOT(cred->cr_label); 1877 obj = SLOT(p->p_ucred->cr_label); 1878 1879 /* XXX: range checks */ 1880 if (!lomac_dominate_single(obj, subj)) 1881 return (ESRCH); 1882 if (!lomac_subject_dominate(subj, obj)) 1883 return (EACCES); 1884 1885 return (0); 1886 } 1887 1888 static int 1889 lomac_proc_check_signal(struct ucred *cred, struct proc *p, int signum) 1890 { 1891 struct mac_lomac *subj, *obj; 1892 1893 if (!lomac_enabled) 1894 return (0); 1895 1896 subj = SLOT(cred->cr_label); 1897 obj = SLOT(p->p_ucred->cr_label); 1898 1899 /* XXX: range checks */ 1900 if (!lomac_dominate_single(obj, subj)) 1901 return (ESRCH); 1902 if (!lomac_subject_dominate(subj, obj)) 1903 return (EACCES); 1904 1905 return (0); 1906 } 1907 1908 static void 1909 lomac_proc_destroy_label(struct label *label) 1910 { 1911 1912 mtx_destroy(&PSLOT(label)->mtx); 1913 free(PSLOT(label), M_LOMAC); 1914 PSLOT_SET(label, NULL); 1915 } 1916 1917 static void 1918 lomac_proc_init_label(struct label *label) 1919 { 1920 1921 PSLOT_SET(label, malloc(sizeof(struct mac_lomac_proc), M_LOMAC, 1922 M_ZERO | M_WAITOK)); 1923 mtx_init(&PSLOT(label)->mtx, "MAC/Lomac proc lock", NULL, MTX_DEF); 1924 } 1925 1926 static int 1927 lomac_socket_check_deliver(struct socket *so, struct label *solabel, 1928 struct mbuf *m, struct label *mlabel) 1929 { 1930 struct mac_lomac *p, *s; 1931 int error; 1932 1933 if (!lomac_enabled) 1934 return (0); 1935 1936 p = SLOT(mlabel); 1937 s = SLOT(solabel); 1938 1939 SOCK_LOCK(so); 1940 error = lomac_equal_single(p, s) ? 0 : EACCES; 1941 SOCK_UNLOCK(so); 1942 return (error); 1943 } 1944 1945 static int 1946 lomac_socket_check_relabel(struct ucred *cred, struct socket *so, 1947 struct label *solabel, struct label *newlabel) 1948 { 1949 struct mac_lomac *subj, *obj, *new; 1950 int error; 1951 1952 SOCK_LOCK_ASSERT(so); 1953 1954 new = SLOT(newlabel); 1955 subj = SLOT(cred->cr_label); 1956 obj = SLOT(solabel); 1957 1958 /* 1959 * If there is a LOMAC label update for the socket, it may be an 1960 * update of single. 1961 */ 1962 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1963 if (error) 1964 return (error); 1965 1966 /* 1967 * To relabel a socket, the old socket single must be in the subject 1968 * range. 1969 */ 1970 if (!lomac_single_in_range(obj, subj)) 1971 return (EPERM); 1972 1973 /* 1974 * If the LOMAC label is to be changed, authorize as appropriate. 1975 */ 1976 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1977 /* 1978 * To relabel a socket, the new socket single must be in the 1979 * subject range. 1980 */ 1981 if (!lomac_single_in_range(new, subj)) 1982 return (EPERM); 1983 1984 /* 1985 * To change the LOMAC label on the socket to contain EQUAL, 1986 * the subject must have appropriate privilege. 1987 */ 1988 if (lomac_contains_equal(new)) { 1989 error = lomac_subject_privileged(subj); 1990 if (error) 1991 return (error); 1992 } 1993 } 1994 1995 return (0); 1996 } 1997 1998 static int 1999 lomac_socket_check_visible(struct ucred *cred, struct socket *so, 2000 struct label *solabel) 2001 { 2002 struct mac_lomac *subj, *obj; 2003 2004 if (!lomac_enabled) 2005 return (0); 2006 2007 subj = SLOT(cred->cr_label); 2008 obj = SLOT(solabel); 2009 2010 SOCK_LOCK(so); 2011 if (!lomac_dominate_single(obj, subj)) { 2012 SOCK_UNLOCK(so); 2013 return (ENOENT); 2014 } 2015 SOCK_UNLOCK(so); 2016 2017 return (0); 2018 } 2019 2020 static void 2021 lomac_socket_create(struct ucred *cred, struct socket *so, 2022 struct label *solabel) 2023 { 2024 struct mac_lomac *source, *dest; 2025 2026 source = SLOT(cred->cr_label); 2027 dest = SLOT(solabel); 2028 2029 lomac_copy_single(source, dest); 2030 } 2031 2032 static void 2033 lomac_socket_create_mbuf(struct socket *so, struct label *solabel, 2034 struct mbuf *m, struct label *mlabel) 2035 { 2036 struct mac_lomac *source, *dest; 2037 2038 source = SLOT(solabel); 2039 dest = SLOT(mlabel); 2040 2041 SOCK_LOCK(so); 2042 lomac_copy_single(source, dest); 2043 SOCK_UNLOCK(so); 2044 } 2045 2046 static void 2047 lomac_socket_newconn(struct socket *oldso, struct label *oldsolabel, 2048 struct socket *newso, struct label *newsolabel) 2049 { 2050 struct mac_lomac source, *dest; 2051 2052 SOCK_LOCK(oldso); 2053 source = *SLOT(oldsolabel); 2054 SOCK_UNLOCK(oldso); 2055 2056 dest = SLOT(newsolabel); 2057 2058 SOCK_LOCK(newso); 2059 lomac_copy_single(&source, dest); 2060 SOCK_UNLOCK(newso); 2061 } 2062 2063 static void 2064 lomac_socket_relabel(struct ucred *cred, struct socket *so, 2065 struct label *solabel, struct label *newlabel) 2066 { 2067 struct mac_lomac *source, *dest; 2068 2069 SOCK_LOCK_ASSERT(so); 2070 2071 source = SLOT(newlabel); 2072 dest = SLOT(solabel); 2073 2074 try_relabel(source, dest); 2075 } 2076 2077 static void 2078 lomac_socketpeer_set_from_mbuf(struct mbuf *m, struct label *mlabel, 2079 struct socket *so, struct label *sopeerlabel) 2080 { 2081 struct mac_lomac *source, *dest; 2082 2083 source = SLOT(mlabel); 2084 dest = SLOT(sopeerlabel); 2085 2086 SOCK_LOCK(so); 2087 lomac_copy_single(source, dest); 2088 SOCK_UNLOCK(so); 2089 } 2090 2091 static void 2092 lomac_socketpeer_set_from_socket(struct socket *oldso, 2093 struct label *oldsolabel, struct socket *newso, 2094 struct label *newsopeerlabel) 2095 { 2096 struct mac_lomac source, *dest; 2097 2098 SOCK_LOCK(oldso); 2099 source = *SLOT(oldsolabel); 2100 SOCK_UNLOCK(oldso); 2101 2102 dest = SLOT(newsopeerlabel); 2103 2104 SOCK_LOCK(newso); 2105 lomac_copy_single(&source, dest); 2106 SOCK_UNLOCK(newso); 2107 } 2108 2109 static void 2110 lomac_syncache_create(struct label *label, struct inpcb *inp) 2111 { 2112 struct mac_lomac *source, *dest; 2113 2114 source = SLOT(inp->inp_label); 2115 dest = SLOT(label); 2116 lomac_copy(source, dest); 2117 } 2118 2119 static void 2120 lomac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m, 2121 struct label *mlabel) 2122 { 2123 struct mac_lomac *source, *dest; 2124 2125 source = SLOT(sc_label); 2126 dest = SLOT(mlabel); 2127 lomac_copy(source, dest); 2128 } 2129 2130 static int 2131 lomac_system_check_acct(struct ucred *cred, struct vnode *vp, 2132 struct label *vplabel) 2133 { 2134 struct mac_lomac *subj, *obj; 2135 2136 if (!lomac_enabled) 2137 return (0); 2138 2139 subj = SLOT(cred->cr_label); 2140 obj = SLOT(vplabel); 2141 2142 if (lomac_subject_privileged(subj)) 2143 return (EPERM); 2144 2145 if (!lomac_high_single(obj)) 2146 return (EACCES); 2147 2148 return (0); 2149 } 2150 2151 static int 2152 lomac_system_check_auditctl(struct ucred *cred, struct vnode *vp, 2153 struct label *vplabel) 2154 { 2155 struct mac_lomac *subj, *obj; 2156 2157 if (!lomac_enabled) 2158 return (0); 2159 2160 subj = SLOT(cred->cr_label); 2161 obj = SLOT(vplabel); 2162 2163 if (lomac_subject_privileged(subj)) 2164 return (EPERM); 2165 2166 if (!lomac_high_single(obj)) 2167 return (EACCES); 2168 2169 return (0); 2170 } 2171 2172 static int 2173 lomac_system_check_swapoff(struct ucred *cred, struct vnode *vp, 2174 struct label *vplabel) 2175 { 2176 struct mac_lomac *subj; 2177 2178 if (!lomac_enabled) 2179 return (0); 2180 2181 subj = SLOT(cred->cr_label); 2182 2183 if (lomac_subject_privileged(subj)) 2184 return (EPERM); 2185 2186 return (0); 2187 } 2188 2189 static int 2190 lomac_system_check_swapon(struct ucred *cred, struct vnode *vp, 2191 struct label *vplabel) 2192 { 2193 struct mac_lomac *subj, *obj; 2194 2195 if (!lomac_enabled) 2196 return (0); 2197 2198 subj = SLOT(cred->cr_label); 2199 obj = SLOT(vplabel); 2200 2201 if (lomac_subject_privileged(subj)) 2202 return (EPERM); 2203 2204 if (!lomac_high_single(obj)) 2205 return (EACCES); 2206 2207 return (0); 2208 } 2209 2210 static int 2211 lomac_system_check_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2212 void *arg1, int arg2, struct sysctl_req *req) 2213 { 2214 struct mac_lomac *subj; 2215 2216 if (!lomac_enabled) 2217 return (0); 2218 2219 subj = SLOT(cred->cr_label); 2220 2221 /* 2222 * Treat sysctl variables without CTLFLAG_ANYBODY flag as lomac/high, 2223 * but also require privilege to change them. 2224 */ 2225 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2226 #ifdef notdef 2227 if (!lomac_subject_dominate_high(subj)) 2228 return (EACCES); 2229 #endif 2230 2231 if (lomac_subject_privileged(subj)) 2232 return (EPERM); 2233 } 2234 2235 return (0); 2236 } 2237 2238 static void 2239 lomac_thread_userret(struct thread *td) 2240 { 2241 struct proc *p = td->td_proc; 2242 struct mac_lomac_proc *subj = PSLOT(p->p_label); 2243 struct ucred *newcred, *oldcred; 2244 int dodrop; 2245 2246 mtx_lock(&subj->mtx); 2247 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 2248 dodrop = 0; 2249 mtx_unlock(&subj->mtx); 2250 newcred = crget(); 2251 /* 2252 * Prevent a lock order reversal in mac_proc_vm_revoke; 2253 * ideally, the other user of subj->mtx wouldn't be holding 2254 * Giant. 2255 */ 2256 mtx_lock(&Giant); 2257 PROC_LOCK(p); 2258 mtx_lock(&subj->mtx); 2259 /* 2260 * Check if we lost the race while allocating the cred. 2261 */ 2262 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2263 crfree(newcred); 2264 goto out; 2265 } 2266 oldcred = p->p_ucred; 2267 crcopy(newcred, oldcred); 2268 crhold(newcred); 2269 lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2270 proc_set_cred(p, newcred); 2271 crfree(oldcred); 2272 dodrop = 1; 2273 out: 2274 mtx_unlock(&subj->mtx); 2275 PROC_UNLOCK(p); 2276 if (dodrop) 2277 mac_proc_vm_revoke(curthread); 2278 mtx_unlock(&Giant); 2279 } else { 2280 mtx_unlock(&subj->mtx); 2281 } 2282 } 2283 2284 static int 2285 lomac_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2286 struct vnode *vp, struct label *vplabel) 2287 { 2288 struct mac_lomac ml_temp, *source, *dest; 2289 int buflen, error; 2290 2291 source = SLOT(mplabel); 2292 dest = SLOT(vplabel); 2293 2294 buflen = sizeof(ml_temp); 2295 bzero(&ml_temp, buflen); 2296 2297 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2298 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&ml_temp, curthread); 2299 if (error == ENOATTR || error == EOPNOTSUPP) { 2300 /* Fall back to the mntlabel. */ 2301 lomac_copy_single(source, dest); 2302 return (0); 2303 } else if (error) 2304 return (error); 2305 2306 if (buflen != sizeof(ml_temp)) { 2307 if (buflen != sizeof(ml_temp) - sizeof(ml_temp.ml_auxsingle)) { 2308 printf("lomac_vnode_associate_extattr: bad size %d\n", 2309 buflen); 2310 return (EPERM); 2311 } 2312 bzero(&ml_temp.ml_auxsingle, sizeof(ml_temp.ml_auxsingle)); 2313 buflen = sizeof(ml_temp); 2314 (void)vn_extattr_set(vp, IO_NODELOCKED, 2315 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 2316 buflen, (char *)&ml_temp, curthread); 2317 } 2318 if (lomac_valid(&ml_temp) != 0) { 2319 printf("lomac_vnode_associate_extattr: invalid\n"); 2320 return (EPERM); 2321 } 2322 if ((ml_temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != 2323 MAC_LOMAC_FLAG_SINGLE) { 2324 printf("lomac_vnode_associate_extattr: not single\n"); 2325 return (EPERM); 2326 } 2327 2328 lomac_copy_single(&ml_temp, dest); 2329 return (0); 2330 } 2331 2332 static void 2333 lomac_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2334 struct vnode *vp, struct label *vplabel) 2335 { 2336 struct mac_lomac *source, *dest; 2337 2338 source = SLOT(mplabel); 2339 dest = SLOT(vplabel); 2340 2341 lomac_copy_single(source, dest); 2342 } 2343 2344 static int 2345 lomac_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2346 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2347 { 2348 struct mac_lomac *subj, *obj; 2349 2350 if (!lomac_enabled) 2351 return (0); 2352 2353 subj = SLOT(cred->cr_label); 2354 obj = SLOT(dvplabel); 2355 2356 if (!lomac_subject_dominate(subj, obj)) 2357 return (EACCES); 2358 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2359 !lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2360 return (EACCES); 2361 2362 return (0); 2363 } 2364 2365 static int 2366 lomac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2367 struct label *vplabel, acl_type_t type) 2368 { 2369 struct mac_lomac *subj, *obj; 2370 2371 if (!lomac_enabled) 2372 return (0); 2373 2374 subj = SLOT(cred->cr_label); 2375 obj = SLOT(vplabel); 2376 2377 if (!lomac_subject_dominate(subj, obj)) 2378 return (EACCES); 2379 2380 return (0); 2381 } 2382 2383 static int 2384 lomac_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2385 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2386 struct componentname *cnp) 2387 { 2388 struct mac_lomac *subj, *obj; 2389 2390 if (!lomac_enabled) 2391 return (0); 2392 2393 subj = SLOT(cred->cr_label); 2394 obj = SLOT(dvplabel); 2395 2396 if (!lomac_subject_dominate(subj, obj)) 2397 return (EACCES); 2398 2399 obj = SLOT(vplabel); 2400 2401 if (!lomac_subject_dominate(subj, obj)) 2402 return (EACCES); 2403 2404 return (0); 2405 } 2406 2407 static int 2408 lomac_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2409 struct label *vplabel, int prot, int flags) 2410 { 2411 struct mac_lomac *subj, *obj; 2412 2413 /* 2414 * Rely on the use of open()-time protections to handle 2415 * non-revocation cases. 2416 */ 2417 if (!lomac_enabled) 2418 return (0); 2419 2420 subj = SLOT(cred->cr_label); 2421 obj = SLOT(vplabel); 2422 2423 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2424 if (!lomac_subject_dominate(subj, obj)) 2425 return (EACCES); 2426 } 2427 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2428 if (!lomac_dominate_single(obj, subj)) 2429 return (maybe_demote(subj, obj, "mapping", "file", vp)); 2430 } 2431 2432 return (0); 2433 } 2434 2435 static void 2436 lomac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp, 2437 struct label *vplabel, /* XXX vm_prot_t */ int *prot) 2438 { 2439 struct mac_lomac *subj, *obj; 2440 2441 /* 2442 * Rely on the use of open()-time protections to handle 2443 * non-revocation cases. 2444 */ 2445 if (!lomac_enabled || !revocation_enabled) 2446 return; 2447 2448 subj = SLOT(cred->cr_label); 2449 obj = SLOT(vplabel); 2450 2451 if (!lomac_subject_dominate(subj, obj)) 2452 *prot &= ~VM_PROT_WRITE; 2453 } 2454 2455 static int 2456 lomac_vnode_check_open(struct ucred *cred, struct vnode *vp, 2457 struct label *vplabel, accmode_t accmode) 2458 { 2459 struct mac_lomac *subj, *obj; 2460 2461 if (!lomac_enabled) 2462 return (0); 2463 2464 subj = SLOT(cred->cr_label); 2465 obj = SLOT(vplabel); 2466 2467 /* XXX privilege override for admin? */ 2468 if (accmode & VMODIFY_PERMS) { 2469 if (!lomac_subject_dominate(subj, obj)) 2470 return (EACCES); 2471 } 2472 2473 return (0); 2474 } 2475 2476 static int 2477 lomac_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2478 struct vnode *vp, struct label *vplabel) 2479 { 2480 struct mac_lomac *subj, *obj; 2481 2482 if (!lomac_enabled || !revocation_enabled) 2483 return (0); 2484 2485 subj = SLOT(active_cred->cr_label); 2486 obj = SLOT(vplabel); 2487 2488 if (!lomac_dominate_single(obj, subj)) 2489 return (maybe_demote(subj, obj, "reading", "file", vp)); 2490 2491 return (0); 2492 } 2493 2494 static int 2495 lomac_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2496 struct label *vplabel, struct label *newlabel) 2497 { 2498 struct mac_lomac *old, *new, *subj; 2499 int error; 2500 2501 old = SLOT(vplabel); 2502 new = SLOT(newlabel); 2503 subj = SLOT(cred->cr_label); 2504 2505 /* 2506 * If there is a LOMAC label update for the vnode, it must be a 2507 * single label, with an optional explicit auxiliary single. 2508 */ 2509 error = lomac_atmostflags(new, 2510 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2511 if (error) 2512 return (error); 2513 2514 /* 2515 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2516 * authorize the relabel. 2517 */ 2518 if (!lomac_single_in_range(old, subj)) 2519 return (EPERM); 2520 2521 /* 2522 * If the LOMAC label is to be changed, authorize as appropriate. 2523 */ 2524 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2525 /* 2526 * To change the LOMAC label on a vnode, the new vnode label 2527 * must be in the subject range. 2528 */ 2529 if (!lomac_single_in_range(new, subj)) 2530 return (EPERM); 2531 2532 /* 2533 * To change the LOMAC label on the vnode to be EQUAL, the 2534 * subject must have appropriate privilege. 2535 */ 2536 if (lomac_contains_equal(new)) { 2537 error = lomac_subject_privileged(subj); 2538 if (error) 2539 return (error); 2540 } 2541 } 2542 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2543 /* 2544 * Fill in the missing parts from the previous label. 2545 */ 2546 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2547 lomac_copy_single(subj, new); 2548 2549 /* 2550 * To change the auxiliary LOMAC label on a vnode, the new 2551 * vnode label must be in the subject range. 2552 */ 2553 if (!lomac_auxsingle_in_range(new, subj)) 2554 return (EPERM); 2555 2556 /* 2557 * To change the auxiliary LOMAC label on the vnode to be 2558 * EQUAL, the subject must have appropriate privilege. 2559 */ 2560 if (lomac_contains_equal(new)) { 2561 error = lomac_subject_privileged(subj); 2562 if (error) 2563 return (error); 2564 } 2565 } 2566 2567 return (0); 2568 } 2569 2570 static int 2571 lomac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2572 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2573 struct componentname *cnp) 2574 { 2575 struct mac_lomac *subj, *obj; 2576 2577 if (!lomac_enabled) 2578 return (0); 2579 2580 subj = SLOT(cred->cr_label); 2581 obj = SLOT(dvplabel); 2582 2583 if (!lomac_subject_dominate(subj, obj)) 2584 return (EACCES); 2585 2586 obj = SLOT(vplabel); 2587 2588 if (!lomac_subject_dominate(subj, obj)) 2589 return (EACCES); 2590 2591 return (0); 2592 } 2593 2594 static int 2595 lomac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2596 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2597 int samedir, struct componentname *cnp) 2598 { 2599 struct mac_lomac *subj, *obj; 2600 2601 if (!lomac_enabled) 2602 return (0); 2603 2604 subj = SLOT(cred->cr_label); 2605 obj = SLOT(dvplabel); 2606 2607 if (!lomac_subject_dominate(subj, obj)) 2608 return (EACCES); 2609 2610 if (vp != NULL) { 2611 obj = SLOT(vplabel); 2612 2613 if (!lomac_subject_dominate(subj, obj)) 2614 return (EACCES); 2615 } 2616 2617 return (0); 2618 } 2619 2620 static int 2621 lomac_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2622 struct label *vplabel) 2623 { 2624 struct mac_lomac *subj, *obj; 2625 2626 if (!lomac_enabled) 2627 return (0); 2628 2629 subj = SLOT(cred->cr_label); 2630 obj = SLOT(vplabel); 2631 2632 if (!lomac_subject_dominate(subj, obj)) 2633 return (EACCES); 2634 2635 return (0); 2636 } 2637 2638 static int 2639 lomac_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2640 struct label *vplabel, acl_type_t type, struct acl *acl) 2641 { 2642 struct mac_lomac *subj, *obj; 2643 2644 if (!lomac_enabled) 2645 return (0); 2646 2647 subj = SLOT(cred->cr_label); 2648 obj = SLOT(vplabel); 2649 2650 if (!lomac_subject_dominate(subj, obj)) 2651 return (EACCES); 2652 2653 return (0); 2654 } 2655 2656 static int 2657 lomac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2658 struct label *vplabel, int attrnamespace, const char *name) 2659 { 2660 struct mac_lomac *subj, *obj; 2661 2662 if (!lomac_enabled) 2663 return (0); 2664 2665 subj = SLOT(cred->cr_label); 2666 obj = SLOT(vplabel); 2667 2668 if (!lomac_subject_dominate(subj, obj)) 2669 return (EACCES); 2670 2671 /* XXX: protect the MAC EA in a special way? */ 2672 2673 return (0); 2674 } 2675 2676 static int 2677 lomac_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2678 struct label *vplabel, u_long flags) 2679 { 2680 struct mac_lomac *subj, *obj; 2681 2682 if (!lomac_enabled) 2683 return (0); 2684 2685 subj = SLOT(cred->cr_label); 2686 obj = SLOT(vplabel); 2687 2688 if (!lomac_subject_dominate(subj, obj)) 2689 return (EACCES); 2690 2691 return (0); 2692 } 2693 2694 static int 2695 lomac_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 2696 struct label *vplabel, mode_t mode) 2697 { 2698 struct mac_lomac *subj, *obj; 2699 2700 if (!lomac_enabled) 2701 return (0); 2702 2703 subj = SLOT(cred->cr_label); 2704 obj = SLOT(vplabel); 2705 2706 if (!lomac_subject_dominate(subj, obj)) 2707 return (EACCES); 2708 2709 return (0); 2710 } 2711 2712 static int 2713 lomac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 2714 struct label *vplabel, uid_t uid, gid_t gid) 2715 { 2716 struct mac_lomac *subj, *obj; 2717 2718 if (!lomac_enabled) 2719 return (0); 2720 2721 subj = SLOT(cred->cr_label); 2722 obj = SLOT(vplabel); 2723 2724 if (!lomac_subject_dominate(subj, obj)) 2725 return (EACCES); 2726 2727 return (0); 2728 } 2729 2730 static int 2731 lomac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 2732 struct label *vplabel, struct timespec atime, struct timespec mtime) 2733 { 2734 struct mac_lomac *subj, *obj; 2735 2736 if (!lomac_enabled) 2737 return (0); 2738 2739 subj = SLOT(cred->cr_label); 2740 obj = SLOT(vplabel); 2741 2742 if (!lomac_subject_dominate(subj, obj)) 2743 return (EACCES); 2744 2745 return (0); 2746 } 2747 2748 static int 2749 lomac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 2750 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2751 struct componentname *cnp) 2752 { 2753 struct mac_lomac *subj, *obj; 2754 2755 if (!lomac_enabled) 2756 return (0); 2757 2758 subj = SLOT(cred->cr_label); 2759 obj = SLOT(dvplabel); 2760 2761 if (!lomac_subject_dominate(subj, obj)) 2762 return (EACCES); 2763 2764 obj = SLOT(vplabel); 2765 2766 if (!lomac_subject_dominate(subj, obj)) 2767 return (EACCES); 2768 2769 return (0); 2770 } 2771 2772 static int 2773 lomac_vnode_check_write(struct ucred *active_cred, 2774 struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 2775 { 2776 struct mac_lomac *subj, *obj; 2777 2778 if (!lomac_enabled || !revocation_enabled) 2779 return (0); 2780 2781 subj = SLOT(active_cred->cr_label); 2782 obj = SLOT(vplabel); 2783 2784 if (!lomac_subject_dominate(subj, obj)) 2785 return (EACCES); 2786 2787 return (0); 2788 } 2789 2790 static int 2791 lomac_vnode_create_extattr(struct ucred *cred, struct mount *mp, 2792 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 2793 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 2794 { 2795 struct mac_lomac *source, *dest, *dir, temp; 2796 size_t buflen; 2797 int error; 2798 2799 buflen = sizeof(temp); 2800 bzero(&temp, buflen); 2801 2802 source = SLOT(cred->cr_label); 2803 dest = SLOT(vplabel); 2804 dir = SLOT(dvplabel); 2805 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 2806 lomac_copy_auxsingle(dir, &temp); 2807 lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 2808 dir->ml_auxsingle.mle_grade); 2809 } else { 2810 lomac_copy_single(source, &temp); 2811 } 2812 2813 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2814 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2815 if (error == 0) 2816 lomac_copy(&temp, dest); 2817 return (error); 2818 } 2819 2820 static void 2821 lomac_vnode_execve_transition(struct ucred *old, struct ucred *new, 2822 struct vnode *vp, struct label *vplabel, struct label *interpvplabel, 2823 struct image_params *imgp, struct label *execlabel) 2824 { 2825 struct mac_lomac *source, *dest, *obj, *robj; 2826 2827 source = SLOT(old->cr_label); 2828 dest = SLOT(new->cr_label); 2829 obj = SLOT(vplabel); 2830 robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2831 2832 lomac_copy(source, dest); 2833 /* 2834 * If there's an auxiliary label on the real object, respect it and 2835 * assume that this level should be assumed immediately if a higher 2836 * level is currently in place. 2837 */ 2838 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2839 !lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 2840 && lomac_auxsingle_in_range(robj, dest)) 2841 lomac_set_single(dest, robj->ml_auxsingle.mle_type, 2842 robj->ml_auxsingle.mle_grade); 2843 /* 2844 * Restructuring to use the execve transitioning mechanism instead of 2845 * the normal demotion mechanism here would be difficult, so just 2846 * copy the label over and perform standard demotion. This is also 2847 * non-optimal because it will result in the intermediate label "new" 2848 * being created and immediately recycled. 2849 */ 2850 if (lomac_enabled && revocation_enabled && 2851 !lomac_dominate_single(obj, source)) 2852 (void)maybe_demote(source, obj, "executing", "file", vp); 2853 } 2854 2855 static int 2856 lomac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp, 2857 struct label *vplabel, struct label *interpvplabel, 2858 struct image_params *imgp, struct label *execlabel) 2859 { 2860 struct mac_lomac *subj, *obj, *robj; 2861 2862 if (!lomac_enabled || !revocation_enabled) 2863 return (0); 2864 2865 subj = SLOT(old->cr_label); 2866 obj = SLOT(vplabel); 2867 robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2868 2869 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2870 !lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 2871 && lomac_auxsingle_in_range(robj, subj)) || 2872 !lomac_dominate_single(obj, subj)); 2873 } 2874 2875 static void 2876 lomac_vnode_relabel(struct ucred *cred, struct vnode *vp, 2877 struct label *vplabel, struct label *newlabel) 2878 { 2879 struct mac_lomac *source, *dest; 2880 2881 source = SLOT(newlabel); 2882 dest = SLOT(vplabel); 2883 2884 try_relabel(source, dest); 2885 } 2886 2887 static int 2888 lomac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 2889 struct label *vplabel, struct label *intlabel) 2890 { 2891 struct mac_lomac *source, temp; 2892 size_t buflen; 2893 int error; 2894 2895 buflen = sizeof(temp); 2896 bzero(&temp, buflen); 2897 2898 source = SLOT(intlabel); 2899 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2900 return (0); 2901 2902 lomac_copy_single(source, &temp); 2903 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2904 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2905 return (error); 2906 } 2907 2908 static struct mac_policy_ops lomac_ops = 2909 { 2910 .mpo_init = lomac_init, 2911 .mpo_destroy = lomac_fini, 2912 2913 .mpo_bpfdesc_check_receive = lomac_bpfdesc_check_receive, 2914 .mpo_bpfdesc_create = lomac_bpfdesc_create, 2915 .mpo_bpfdesc_create_mbuf = lomac_bpfdesc_create_mbuf, 2916 .mpo_bpfdesc_destroy_label = lomac_destroy_label, 2917 .mpo_bpfdesc_init_label = lomac_init_label, 2918 2919 .mpo_cred_check_relabel = lomac_cred_check_relabel, 2920 .mpo_cred_check_visible = lomac_cred_check_visible, 2921 .mpo_cred_copy_label = lomac_copy_label, 2922 .mpo_cred_create_swapper = lomac_cred_create_swapper, 2923 .mpo_cred_create_init = lomac_cred_create_init, 2924 .mpo_cred_destroy_label = lomac_destroy_label, 2925 .mpo_cred_externalize_label = lomac_externalize_label, 2926 .mpo_cred_init_label = lomac_init_label, 2927 .mpo_cred_internalize_label = lomac_internalize_label, 2928 .mpo_cred_relabel = lomac_cred_relabel, 2929 2930 .mpo_devfs_create_device = lomac_devfs_create_device, 2931 .mpo_devfs_create_directory = lomac_devfs_create_directory, 2932 .mpo_devfs_create_symlink = lomac_devfs_create_symlink, 2933 .mpo_devfs_destroy_label = lomac_destroy_label, 2934 .mpo_devfs_init_label = lomac_init_label, 2935 .mpo_devfs_update = lomac_devfs_update, 2936 .mpo_devfs_vnode_associate = lomac_devfs_vnode_associate, 2937 2938 .mpo_ifnet_check_relabel = lomac_ifnet_check_relabel, 2939 .mpo_ifnet_check_transmit = lomac_ifnet_check_transmit, 2940 .mpo_ifnet_copy_label = lomac_copy_label, 2941 .mpo_ifnet_create = lomac_ifnet_create, 2942 .mpo_ifnet_create_mbuf = lomac_ifnet_create_mbuf, 2943 .mpo_ifnet_destroy_label = lomac_destroy_label, 2944 .mpo_ifnet_externalize_label = lomac_externalize_label, 2945 .mpo_ifnet_init_label = lomac_init_label, 2946 .mpo_ifnet_internalize_label = lomac_internalize_label, 2947 .mpo_ifnet_relabel = lomac_ifnet_relabel, 2948 2949 .mpo_syncache_create = lomac_syncache_create, 2950 .mpo_syncache_destroy_label = lomac_destroy_label, 2951 .mpo_syncache_init_label = lomac_init_label_waitcheck, 2952 2953 .mpo_inpcb_check_deliver = lomac_inpcb_check_deliver, 2954 .mpo_inpcb_check_visible = lomac_inpcb_check_visible, 2955 .mpo_inpcb_create = lomac_inpcb_create, 2956 .mpo_inpcb_create_mbuf = lomac_inpcb_create_mbuf, 2957 .mpo_inpcb_destroy_label = lomac_destroy_label, 2958 .mpo_inpcb_init_label = lomac_init_label_waitcheck, 2959 .mpo_inpcb_sosetlabel = lomac_inpcb_sosetlabel, 2960 2961 .mpo_ip6q_create = lomac_ip6q_create, 2962 .mpo_ip6q_destroy_label = lomac_destroy_label, 2963 .mpo_ip6q_init_label = lomac_init_label_waitcheck, 2964 .mpo_ip6q_match = lomac_ip6q_match, 2965 .mpo_ip6q_reassemble = lomac_ip6q_reassemble, 2966 .mpo_ip6q_update = lomac_ip6q_update, 2967 2968 .mpo_ipq_create = lomac_ipq_create, 2969 .mpo_ipq_destroy_label = lomac_destroy_label, 2970 .mpo_ipq_init_label = lomac_init_label_waitcheck, 2971 .mpo_ipq_match = lomac_ipq_match, 2972 .mpo_ipq_reassemble = lomac_ipq_reassemble, 2973 .mpo_ipq_update = lomac_ipq_update, 2974 2975 .mpo_kld_check_load = lomac_kld_check_load, 2976 2977 .mpo_mbuf_copy_label = lomac_copy_label, 2978 .mpo_mbuf_destroy_label = lomac_destroy_label, 2979 .mpo_mbuf_init_label = lomac_init_label_waitcheck, 2980 2981 .mpo_mount_create = lomac_mount_create, 2982 .mpo_mount_destroy_label = lomac_destroy_label, 2983 .mpo_mount_init_label = lomac_init_label, 2984 2985 .mpo_netinet_arp_send = lomac_netinet_arp_send, 2986 .mpo_netinet_firewall_reply = lomac_netinet_firewall_reply, 2987 .mpo_netinet_firewall_send = lomac_netinet_firewall_send, 2988 .mpo_netinet_fragment = lomac_netinet_fragment, 2989 .mpo_netinet_icmp_reply = lomac_netinet_icmp_reply, 2990 .mpo_netinet_igmp_send = lomac_netinet_igmp_send, 2991 2992 .mpo_netinet6_nd6_send = lomac_netinet6_nd6_send, 2993 2994 .mpo_pipe_check_ioctl = lomac_pipe_check_ioctl, 2995 .mpo_pipe_check_read = lomac_pipe_check_read, 2996 .mpo_pipe_check_relabel = lomac_pipe_check_relabel, 2997 .mpo_pipe_check_write = lomac_pipe_check_write, 2998 .mpo_pipe_copy_label = lomac_copy_label, 2999 .mpo_pipe_create = lomac_pipe_create, 3000 .mpo_pipe_destroy_label = lomac_destroy_label, 3001 .mpo_pipe_externalize_label = lomac_externalize_label, 3002 .mpo_pipe_init_label = lomac_init_label, 3003 .mpo_pipe_internalize_label = lomac_internalize_label, 3004 .mpo_pipe_relabel = lomac_pipe_relabel, 3005 3006 .mpo_priv_check = lomac_priv_check, 3007 3008 .mpo_proc_check_debug = lomac_proc_check_debug, 3009 .mpo_proc_check_sched = lomac_proc_check_sched, 3010 .mpo_proc_check_signal = lomac_proc_check_signal, 3011 .mpo_proc_destroy_label = lomac_proc_destroy_label, 3012 .mpo_proc_init_label = lomac_proc_init_label, 3013 3014 .mpo_socket_check_deliver = lomac_socket_check_deliver, 3015 .mpo_socket_check_relabel = lomac_socket_check_relabel, 3016 .mpo_socket_check_visible = lomac_socket_check_visible, 3017 .mpo_socket_copy_label = lomac_copy_label, 3018 .mpo_socket_create = lomac_socket_create, 3019 .mpo_socket_create_mbuf = lomac_socket_create_mbuf, 3020 .mpo_socket_destroy_label = lomac_destroy_label, 3021 .mpo_socket_externalize_label = lomac_externalize_label, 3022 .mpo_socket_init_label = lomac_init_label_waitcheck, 3023 .mpo_socket_internalize_label = lomac_internalize_label, 3024 .mpo_socket_newconn = lomac_socket_newconn, 3025 .mpo_socket_relabel = lomac_socket_relabel, 3026 3027 .mpo_socketpeer_destroy_label = lomac_destroy_label, 3028 .mpo_socketpeer_externalize_label = lomac_externalize_label, 3029 .mpo_socketpeer_init_label = lomac_init_label_waitcheck, 3030 .mpo_socketpeer_set_from_mbuf = lomac_socketpeer_set_from_mbuf, 3031 .mpo_socketpeer_set_from_socket = lomac_socketpeer_set_from_socket, 3032 3033 .mpo_syncache_create_mbuf = lomac_syncache_create_mbuf, 3034 3035 .mpo_system_check_acct = lomac_system_check_acct, 3036 .mpo_system_check_auditctl = lomac_system_check_auditctl, 3037 .mpo_system_check_swapoff = lomac_system_check_swapoff, 3038 .mpo_system_check_swapon = lomac_system_check_swapon, 3039 .mpo_system_check_sysctl = lomac_system_check_sysctl, 3040 3041 .mpo_thread_userret = lomac_thread_userret, 3042 3043 .mpo_vnode_associate_extattr = lomac_vnode_associate_extattr, 3044 .mpo_vnode_associate_singlelabel = lomac_vnode_associate_singlelabel, 3045 .mpo_vnode_check_access = lomac_vnode_check_open, 3046 .mpo_vnode_check_create = lomac_vnode_check_create, 3047 .mpo_vnode_check_deleteacl = lomac_vnode_check_deleteacl, 3048 .mpo_vnode_check_link = lomac_vnode_check_link, 3049 .mpo_vnode_check_mmap = lomac_vnode_check_mmap, 3050 .mpo_vnode_check_mmap_downgrade = lomac_vnode_check_mmap_downgrade, 3051 .mpo_vnode_check_open = lomac_vnode_check_open, 3052 .mpo_vnode_check_read = lomac_vnode_check_read, 3053 .mpo_vnode_check_relabel = lomac_vnode_check_relabel, 3054 .mpo_vnode_check_rename_from = lomac_vnode_check_rename_from, 3055 .mpo_vnode_check_rename_to = lomac_vnode_check_rename_to, 3056 .mpo_vnode_check_revoke = lomac_vnode_check_revoke, 3057 .mpo_vnode_check_setacl = lomac_vnode_check_setacl, 3058 .mpo_vnode_check_setextattr = lomac_vnode_check_setextattr, 3059 .mpo_vnode_check_setflags = lomac_vnode_check_setflags, 3060 .mpo_vnode_check_setmode = lomac_vnode_check_setmode, 3061 .mpo_vnode_check_setowner = lomac_vnode_check_setowner, 3062 .mpo_vnode_check_setutimes = lomac_vnode_check_setutimes, 3063 .mpo_vnode_check_unlink = lomac_vnode_check_unlink, 3064 .mpo_vnode_check_write = lomac_vnode_check_write, 3065 .mpo_vnode_copy_label = lomac_copy_label, 3066 .mpo_vnode_create_extattr = lomac_vnode_create_extattr, 3067 .mpo_vnode_destroy_label = lomac_destroy_label, 3068 .mpo_vnode_execve_transition = lomac_vnode_execve_transition, 3069 .mpo_vnode_execve_will_transition = lomac_vnode_execve_will_transition, 3070 .mpo_vnode_externalize_label = lomac_externalize_label, 3071 .mpo_vnode_init_label = lomac_init_label, 3072 .mpo_vnode_internalize_label = lomac_internalize_label, 3073 .mpo_vnode_relabel = lomac_vnode_relabel, 3074 .mpo_vnode_setlabel_extattr = lomac_vnode_setlabel_extattr, 3075 }; 3076 3077 MAC_POLICY_SET(&lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC", 3078 MPC_LOADTIME_FLAG_NOTLATE, &lomac_slot); 3079