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