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 PROC_LOCK(p); 2252 mtx_lock(&subj->mtx); 2253 /* 2254 * Check if we lost the race while allocating the cred. 2255 */ 2256 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2257 crfree(newcred); 2258 goto out; 2259 } 2260 oldcred = p->p_ucred; 2261 crcopy(newcred, oldcred); 2262 crhold(newcred); 2263 lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2264 proc_set_cred(p, newcred); 2265 crfree(oldcred); 2266 dodrop = 1; 2267 out: 2268 mtx_unlock(&subj->mtx); 2269 PROC_UNLOCK(p); 2270 if (dodrop) 2271 mac_proc_vm_revoke(curthread); 2272 } else { 2273 mtx_unlock(&subj->mtx); 2274 } 2275 } 2276 2277 static int 2278 lomac_vnode_associate_extattr(struct mount *mp, struct label *mplabel, 2279 struct vnode *vp, struct label *vplabel) 2280 { 2281 struct mac_lomac ml_temp, *source, *dest; 2282 int buflen, error; 2283 2284 source = SLOT(mplabel); 2285 dest = SLOT(vplabel); 2286 2287 buflen = sizeof(ml_temp); 2288 bzero(&ml_temp, buflen); 2289 2290 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2291 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&ml_temp, curthread); 2292 if (error == ENOATTR || error == EOPNOTSUPP) { 2293 /* Fall back to the mntlabel. */ 2294 lomac_copy_single(source, dest); 2295 return (0); 2296 } else if (error) 2297 return (error); 2298 2299 if (buflen != sizeof(ml_temp)) { 2300 if (buflen != sizeof(ml_temp) - sizeof(ml_temp.ml_auxsingle)) { 2301 printf("lomac_vnode_associate_extattr: bad size %d\n", 2302 buflen); 2303 return (EPERM); 2304 } 2305 bzero(&ml_temp.ml_auxsingle, sizeof(ml_temp.ml_auxsingle)); 2306 buflen = sizeof(ml_temp); 2307 (void)vn_extattr_set(vp, IO_NODELOCKED, 2308 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 2309 buflen, (char *)&ml_temp, curthread); 2310 } 2311 if (lomac_valid(&ml_temp) != 0) { 2312 printf("lomac_vnode_associate_extattr: invalid\n"); 2313 return (EPERM); 2314 } 2315 if ((ml_temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != 2316 MAC_LOMAC_FLAG_SINGLE) { 2317 printf("lomac_vnode_associate_extattr: not single\n"); 2318 return (EPERM); 2319 } 2320 2321 lomac_copy_single(&ml_temp, dest); 2322 return (0); 2323 } 2324 2325 static void 2326 lomac_vnode_associate_singlelabel(struct mount *mp, struct label *mplabel, 2327 struct vnode *vp, struct label *vplabel) 2328 { 2329 struct mac_lomac *source, *dest; 2330 2331 source = SLOT(mplabel); 2332 dest = SLOT(vplabel); 2333 2334 lomac_copy_single(source, dest); 2335 } 2336 2337 static int 2338 lomac_vnode_check_create(struct ucred *cred, struct vnode *dvp, 2339 struct label *dvplabel, struct componentname *cnp, struct vattr *vap) 2340 { 2341 struct mac_lomac *subj, *obj; 2342 2343 if (!lomac_enabled) 2344 return (0); 2345 2346 subj = SLOT(cred->cr_label); 2347 obj = SLOT(dvplabel); 2348 2349 if (!lomac_subject_dominate(subj, obj)) 2350 return (EACCES); 2351 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2352 !lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2353 return (EACCES); 2354 2355 return (0); 2356 } 2357 2358 static int 2359 lomac_vnode_check_deleteacl(struct ucred *cred, struct vnode *vp, 2360 struct label *vplabel, acl_type_t type) 2361 { 2362 struct mac_lomac *subj, *obj; 2363 2364 if (!lomac_enabled) 2365 return (0); 2366 2367 subj = SLOT(cred->cr_label); 2368 obj = SLOT(vplabel); 2369 2370 if (!lomac_subject_dominate(subj, obj)) 2371 return (EACCES); 2372 2373 return (0); 2374 } 2375 2376 static int 2377 lomac_vnode_check_link(struct ucred *cred, struct vnode *dvp, 2378 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2379 struct componentname *cnp) 2380 { 2381 struct mac_lomac *subj, *obj; 2382 2383 if (!lomac_enabled) 2384 return (0); 2385 2386 subj = SLOT(cred->cr_label); 2387 obj = SLOT(dvplabel); 2388 2389 if (!lomac_subject_dominate(subj, obj)) 2390 return (EACCES); 2391 2392 obj = SLOT(vplabel); 2393 2394 if (!lomac_subject_dominate(subj, obj)) 2395 return (EACCES); 2396 2397 return (0); 2398 } 2399 2400 static int 2401 lomac_vnode_check_mmap(struct ucred *cred, struct vnode *vp, 2402 struct label *vplabel, int prot, int flags) 2403 { 2404 struct mac_lomac *subj, *obj; 2405 2406 /* 2407 * Rely on the use of open()-time protections to handle 2408 * non-revocation cases. 2409 */ 2410 if (!lomac_enabled) 2411 return (0); 2412 2413 subj = SLOT(cred->cr_label); 2414 obj = SLOT(vplabel); 2415 2416 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2417 if (!lomac_subject_dominate(subj, obj)) 2418 return (EACCES); 2419 } 2420 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2421 if (!lomac_dominate_single(obj, subj)) 2422 return (maybe_demote(subj, obj, "mapping", "file", vp)); 2423 } 2424 2425 return (0); 2426 } 2427 2428 static void 2429 lomac_vnode_check_mmap_downgrade(struct ucred *cred, struct vnode *vp, 2430 struct label *vplabel, /* XXX vm_prot_t */ int *prot) 2431 { 2432 struct mac_lomac *subj, *obj; 2433 2434 /* 2435 * Rely on the use of open()-time protections to handle 2436 * non-revocation cases. 2437 */ 2438 if (!lomac_enabled || !revocation_enabled) 2439 return; 2440 2441 subj = SLOT(cred->cr_label); 2442 obj = SLOT(vplabel); 2443 2444 if (!lomac_subject_dominate(subj, obj)) 2445 *prot &= ~VM_PROT_WRITE; 2446 } 2447 2448 static int 2449 lomac_vnode_check_open(struct ucred *cred, struct vnode *vp, 2450 struct label *vplabel, accmode_t accmode) 2451 { 2452 struct mac_lomac *subj, *obj; 2453 2454 if (!lomac_enabled) 2455 return (0); 2456 2457 subj = SLOT(cred->cr_label); 2458 obj = SLOT(vplabel); 2459 2460 /* XXX privilege override for admin? */ 2461 if (accmode & VMODIFY_PERMS) { 2462 if (!lomac_subject_dominate(subj, obj)) 2463 return (EACCES); 2464 } 2465 2466 return (0); 2467 } 2468 2469 static int 2470 lomac_vnode_check_read(struct ucred *active_cred, struct ucred *file_cred, 2471 struct vnode *vp, struct label *vplabel) 2472 { 2473 struct mac_lomac *subj, *obj; 2474 2475 if (!lomac_enabled || !revocation_enabled) 2476 return (0); 2477 2478 subj = SLOT(active_cred->cr_label); 2479 obj = SLOT(vplabel); 2480 2481 if (!lomac_dominate_single(obj, subj)) 2482 return (maybe_demote(subj, obj, "reading", "file", vp)); 2483 2484 return (0); 2485 } 2486 2487 static int 2488 lomac_vnode_check_relabel(struct ucred *cred, struct vnode *vp, 2489 struct label *vplabel, struct label *newlabel) 2490 { 2491 struct mac_lomac *old, *new, *subj; 2492 int error; 2493 2494 old = SLOT(vplabel); 2495 new = SLOT(newlabel); 2496 subj = SLOT(cred->cr_label); 2497 2498 /* 2499 * If there is a LOMAC label update for the vnode, it must be a 2500 * single label, with an optional explicit auxiliary single. 2501 */ 2502 error = lomac_atmostflags(new, 2503 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2504 if (error) 2505 return (error); 2506 2507 /* 2508 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2509 * authorize the relabel. 2510 */ 2511 if (!lomac_single_in_range(old, subj)) 2512 return (EPERM); 2513 2514 /* 2515 * If the LOMAC label is to be changed, authorize as appropriate. 2516 */ 2517 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2518 /* 2519 * To change the LOMAC label on a vnode, the new vnode label 2520 * must be in the subject range. 2521 */ 2522 if (!lomac_single_in_range(new, subj)) 2523 return (EPERM); 2524 2525 /* 2526 * To change the LOMAC label on the vnode to be EQUAL, the 2527 * subject must have appropriate privilege. 2528 */ 2529 if (lomac_contains_equal(new)) { 2530 error = lomac_subject_privileged(subj); 2531 if (error) 2532 return (error); 2533 } 2534 } 2535 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2536 /* 2537 * Fill in the missing parts from the previous label. 2538 */ 2539 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2540 lomac_copy_single(subj, new); 2541 2542 /* 2543 * To change the auxiliary LOMAC label on a vnode, the new 2544 * vnode label must be in the subject range. 2545 */ 2546 if (!lomac_auxsingle_in_range(new, subj)) 2547 return (EPERM); 2548 2549 /* 2550 * To change the auxiliary LOMAC label on the vnode to be 2551 * EQUAL, the subject must have appropriate privilege. 2552 */ 2553 if (lomac_contains_equal(new)) { 2554 error = lomac_subject_privileged(subj); 2555 if (error) 2556 return (error); 2557 } 2558 } 2559 2560 return (0); 2561 } 2562 2563 static int 2564 lomac_vnode_check_rename_from(struct ucred *cred, struct vnode *dvp, 2565 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2566 struct componentname *cnp) 2567 { 2568 struct mac_lomac *subj, *obj; 2569 2570 if (!lomac_enabled) 2571 return (0); 2572 2573 subj = SLOT(cred->cr_label); 2574 obj = SLOT(dvplabel); 2575 2576 if (!lomac_subject_dominate(subj, obj)) 2577 return (EACCES); 2578 2579 obj = SLOT(vplabel); 2580 2581 if (!lomac_subject_dominate(subj, obj)) 2582 return (EACCES); 2583 2584 return (0); 2585 } 2586 2587 static int 2588 lomac_vnode_check_rename_to(struct ucred *cred, struct vnode *dvp, 2589 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2590 int samedir, struct componentname *cnp) 2591 { 2592 struct mac_lomac *subj, *obj; 2593 2594 if (!lomac_enabled) 2595 return (0); 2596 2597 subj = SLOT(cred->cr_label); 2598 obj = SLOT(dvplabel); 2599 2600 if (!lomac_subject_dominate(subj, obj)) 2601 return (EACCES); 2602 2603 if (vp != NULL) { 2604 obj = SLOT(vplabel); 2605 2606 if (!lomac_subject_dominate(subj, obj)) 2607 return (EACCES); 2608 } 2609 2610 return (0); 2611 } 2612 2613 static int 2614 lomac_vnode_check_revoke(struct ucred *cred, struct vnode *vp, 2615 struct label *vplabel) 2616 { 2617 struct mac_lomac *subj, *obj; 2618 2619 if (!lomac_enabled) 2620 return (0); 2621 2622 subj = SLOT(cred->cr_label); 2623 obj = SLOT(vplabel); 2624 2625 if (!lomac_subject_dominate(subj, obj)) 2626 return (EACCES); 2627 2628 return (0); 2629 } 2630 2631 static int 2632 lomac_vnode_check_setacl(struct ucred *cred, struct vnode *vp, 2633 struct label *vplabel, acl_type_t type, struct acl *acl) 2634 { 2635 struct mac_lomac *subj, *obj; 2636 2637 if (!lomac_enabled) 2638 return (0); 2639 2640 subj = SLOT(cred->cr_label); 2641 obj = SLOT(vplabel); 2642 2643 if (!lomac_subject_dominate(subj, obj)) 2644 return (EACCES); 2645 2646 return (0); 2647 } 2648 2649 static int 2650 lomac_vnode_check_setextattr(struct ucred *cred, struct vnode *vp, 2651 struct label *vplabel, int attrnamespace, const char *name) 2652 { 2653 struct mac_lomac *subj, *obj; 2654 2655 if (!lomac_enabled) 2656 return (0); 2657 2658 subj = SLOT(cred->cr_label); 2659 obj = SLOT(vplabel); 2660 2661 if (!lomac_subject_dominate(subj, obj)) 2662 return (EACCES); 2663 2664 /* XXX: protect the MAC EA in a special way? */ 2665 2666 return (0); 2667 } 2668 2669 static int 2670 lomac_vnode_check_setflags(struct ucred *cred, struct vnode *vp, 2671 struct label *vplabel, u_long flags) 2672 { 2673 struct mac_lomac *subj, *obj; 2674 2675 if (!lomac_enabled) 2676 return (0); 2677 2678 subj = SLOT(cred->cr_label); 2679 obj = SLOT(vplabel); 2680 2681 if (!lomac_subject_dominate(subj, obj)) 2682 return (EACCES); 2683 2684 return (0); 2685 } 2686 2687 static int 2688 lomac_vnode_check_setmode(struct ucred *cred, struct vnode *vp, 2689 struct label *vplabel, mode_t mode) 2690 { 2691 struct mac_lomac *subj, *obj; 2692 2693 if (!lomac_enabled) 2694 return (0); 2695 2696 subj = SLOT(cred->cr_label); 2697 obj = SLOT(vplabel); 2698 2699 if (!lomac_subject_dominate(subj, obj)) 2700 return (EACCES); 2701 2702 return (0); 2703 } 2704 2705 static int 2706 lomac_vnode_check_setowner(struct ucred *cred, struct vnode *vp, 2707 struct label *vplabel, uid_t uid, gid_t gid) 2708 { 2709 struct mac_lomac *subj, *obj; 2710 2711 if (!lomac_enabled) 2712 return (0); 2713 2714 subj = SLOT(cred->cr_label); 2715 obj = SLOT(vplabel); 2716 2717 if (!lomac_subject_dominate(subj, obj)) 2718 return (EACCES); 2719 2720 return (0); 2721 } 2722 2723 static int 2724 lomac_vnode_check_setutimes(struct ucred *cred, struct vnode *vp, 2725 struct label *vplabel, struct timespec atime, struct timespec mtime) 2726 { 2727 struct mac_lomac *subj, *obj; 2728 2729 if (!lomac_enabled) 2730 return (0); 2731 2732 subj = SLOT(cred->cr_label); 2733 obj = SLOT(vplabel); 2734 2735 if (!lomac_subject_dominate(subj, obj)) 2736 return (EACCES); 2737 2738 return (0); 2739 } 2740 2741 static int 2742 lomac_vnode_check_unlink(struct ucred *cred, struct vnode *dvp, 2743 struct label *dvplabel, struct vnode *vp, struct label *vplabel, 2744 struct componentname *cnp) 2745 { 2746 struct mac_lomac *subj, *obj; 2747 2748 if (!lomac_enabled) 2749 return (0); 2750 2751 subj = SLOT(cred->cr_label); 2752 obj = SLOT(dvplabel); 2753 2754 if (!lomac_subject_dominate(subj, obj)) 2755 return (EACCES); 2756 2757 obj = SLOT(vplabel); 2758 2759 if (!lomac_subject_dominate(subj, obj)) 2760 return (EACCES); 2761 2762 return (0); 2763 } 2764 2765 static int 2766 lomac_vnode_check_write(struct ucred *active_cred, 2767 struct ucred *file_cred, struct vnode *vp, struct label *vplabel) 2768 { 2769 struct mac_lomac *subj, *obj; 2770 2771 if (!lomac_enabled || !revocation_enabled) 2772 return (0); 2773 2774 subj = SLOT(active_cred->cr_label); 2775 obj = SLOT(vplabel); 2776 2777 if (!lomac_subject_dominate(subj, obj)) 2778 return (EACCES); 2779 2780 return (0); 2781 } 2782 2783 static int 2784 lomac_vnode_create_extattr(struct ucred *cred, struct mount *mp, 2785 struct label *mplabel, struct vnode *dvp, struct label *dvplabel, 2786 struct vnode *vp, struct label *vplabel, struct componentname *cnp) 2787 { 2788 struct mac_lomac *source, *dest, *dir, temp; 2789 size_t buflen; 2790 int error; 2791 2792 buflen = sizeof(temp); 2793 bzero(&temp, buflen); 2794 2795 source = SLOT(cred->cr_label); 2796 dest = SLOT(vplabel); 2797 dir = SLOT(dvplabel); 2798 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 2799 lomac_copy_auxsingle(dir, &temp); 2800 lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 2801 dir->ml_auxsingle.mle_grade); 2802 } else { 2803 lomac_copy_single(source, &temp); 2804 } 2805 2806 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2807 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2808 if (error == 0) 2809 lomac_copy(&temp, dest); 2810 return (error); 2811 } 2812 2813 static void 2814 lomac_vnode_execve_transition(struct ucred *old, struct ucred *new, 2815 struct vnode *vp, struct label *vplabel, struct label *interpvplabel, 2816 struct image_params *imgp, struct label *execlabel) 2817 { 2818 struct mac_lomac *source, *dest, *obj, *robj; 2819 2820 source = SLOT(old->cr_label); 2821 dest = SLOT(new->cr_label); 2822 obj = SLOT(vplabel); 2823 robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2824 2825 lomac_copy(source, dest); 2826 /* 2827 * If there's an auxiliary label on the real object, respect it and 2828 * assume that this level should be assumed immediately if a higher 2829 * level is currently in place. 2830 */ 2831 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2832 !lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 2833 && lomac_auxsingle_in_range(robj, dest)) 2834 lomac_set_single(dest, robj->ml_auxsingle.mle_type, 2835 robj->ml_auxsingle.mle_grade); 2836 /* 2837 * Restructuring to use the execve transitioning mechanism instead of 2838 * the normal demotion mechanism here would be difficult, so just 2839 * copy the label over and perform standard demotion. This is also 2840 * non-optimal because it will result in the intermediate label "new" 2841 * being created and immediately recycled. 2842 */ 2843 if (lomac_enabled && revocation_enabled && 2844 !lomac_dominate_single(obj, source)) 2845 (void)maybe_demote(source, obj, "executing", "file", vp); 2846 } 2847 2848 static int 2849 lomac_vnode_execve_will_transition(struct ucred *old, struct vnode *vp, 2850 struct label *vplabel, struct label *interpvplabel, 2851 struct image_params *imgp, struct label *execlabel) 2852 { 2853 struct mac_lomac *subj, *obj, *robj; 2854 2855 if (!lomac_enabled || !revocation_enabled) 2856 return (0); 2857 2858 subj = SLOT(old->cr_label); 2859 obj = SLOT(vplabel); 2860 robj = interpvplabel != NULL ? SLOT(interpvplabel) : obj; 2861 2862 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 2863 !lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 2864 && lomac_auxsingle_in_range(robj, subj)) || 2865 !lomac_dominate_single(obj, subj)); 2866 } 2867 2868 static void 2869 lomac_vnode_relabel(struct ucred *cred, struct vnode *vp, 2870 struct label *vplabel, struct label *newlabel) 2871 { 2872 struct mac_lomac *source, *dest; 2873 2874 source = SLOT(newlabel); 2875 dest = SLOT(vplabel); 2876 2877 try_relabel(source, dest); 2878 } 2879 2880 static int 2881 lomac_vnode_setlabel_extattr(struct ucred *cred, struct vnode *vp, 2882 struct label *vplabel, struct label *intlabel) 2883 { 2884 struct mac_lomac *source, temp; 2885 size_t buflen; 2886 int error; 2887 2888 buflen = sizeof(temp); 2889 bzero(&temp, buflen); 2890 2891 source = SLOT(intlabel); 2892 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2893 return (0); 2894 2895 lomac_copy_single(source, &temp); 2896 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 2897 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 2898 return (error); 2899 } 2900 2901 static struct mac_policy_ops lomac_ops = 2902 { 2903 .mpo_init = lomac_init, 2904 .mpo_destroy = lomac_fini, 2905 2906 .mpo_bpfdesc_check_receive = lomac_bpfdesc_check_receive, 2907 .mpo_bpfdesc_create = lomac_bpfdesc_create, 2908 .mpo_bpfdesc_create_mbuf = lomac_bpfdesc_create_mbuf, 2909 .mpo_bpfdesc_destroy_label = lomac_destroy_label, 2910 .mpo_bpfdesc_init_label = lomac_init_label, 2911 2912 .mpo_cred_check_relabel = lomac_cred_check_relabel, 2913 .mpo_cred_check_visible = lomac_cred_check_visible, 2914 .mpo_cred_copy_label = lomac_copy_label, 2915 .mpo_cred_create_swapper = lomac_cred_create_swapper, 2916 .mpo_cred_create_init = lomac_cred_create_init, 2917 .mpo_cred_destroy_label = lomac_destroy_label, 2918 .mpo_cred_externalize_label = lomac_externalize_label, 2919 .mpo_cred_init_label = lomac_init_label, 2920 .mpo_cred_internalize_label = lomac_internalize_label, 2921 .mpo_cred_relabel = lomac_cred_relabel, 2922 2923 .mpo_devfs_create_device = lomac_devfs_create_device, 2924 .mpo_devfs_create_directory = lomac_devfs_create_directory, 2925 .mpo_devfs_create_symlink = lomac_devfs_create_symlink, 2926 .mpo_devfs_destroy_label = lomac_destroy_label, 2927 .mpo_devfs_init_label = lomac_init_label, 2928 .mpo_devfs_update = lomac_devfs_update, 2929 .mpo_devfs_vnode_associate = lomac_devfs_vnode_associate, 2930 2931 .mpo_ifnet_check_relabel = lomac_ifnet_check_relabel, 2932 .mpo_ifnet_check_transmit = lomac_ifnet_check_transmit, 2933 .mpo_ifnet_copy_label = lomac_copy_label, 2934 .mpo_ifnet_create = lomac_ifnet_create, 2935 .mpo_ifnet_create_mbuf = lomac_ifnet_create_mbuf, 2936 .mpo_ifnet_destroy_label = lomac_destroy_label, 2937 .mpo_ifnet_externalize_label = lomac_externalize_label, 2938 .mpo_ifnet_init_label = lomac_init_label, 2939 .mpo_ifnet_internalize_label = lomac_internalize_label, 2940 .mpo_ifnet_relabel = lomac_ifnet_relabel, 2941 2942 .mpo_syncache_create = lomac_syncache_create, 2943 .mpo_syncache_destroy_label = lomac_destroy_label, 2944 .mpo_syncache_init_label = lomac_init_label_waitcheck, 2945 2946 .mpo_inpcb_check_deliver = lomac_inpcb_check_deliver, 2947 .mpo_inpcb_check_visible = lomac_inpcb_check_visible, 2948 .mpo_inpcb_create = lomac_inpcb_create, 2949 .mpo_inpcb_create_mbuf = lomac_inpcb_create_mbuf, 2950 .mpo_inpcb_destroy_label = lomac_destroy_label, 2951 .mpo_inpcb_init_label = lomac_init_label_waitcheck, 2952 .mpo_inpcb_sosetlabel = lomac_inpcb_sosetlabel, 2953 2954 .mpo_ip6q_create = lomac_ip6q_create, 2955 .mpo_ip6q_destroy_label = lomac_destroy_label, 2956 .mpo_ip6q_init_label = lomac_init_label_waitcheck, 2957 .mpo_ip6q_match = lomac_ip6q_match, 2958 .mpo_ip6q_reassemble = lomac_ip6q_reassemble, 2959 .mpo_ip6q_update = lomac_ip6q_update, 2960 2961 .mpo_ipq_create = lomac_ipq_create, 2962 .mpo_ipq_destroy_label = lomac_destroy_label, 2963 .mpo_ipq_init_label = lomac_init_label_waitcheck, 2964 .mpo_ipq_match = lomac_ipq_match, 2965 .mpo_ipq_reassemble = lomac_ipq_reassemble, 2966 .mpo_ipq_update = lomac_ipq_update, 2967 2968 .mpo_kld_check_load = lomac_kld_check_load, 2969 2970 .mpo_mbuf_copy_label = lomac_copy_label, 2971 .mpo_mbuf_destroy_label = lomac_destroy_label, 2972 .mpo_mbuf_init_label = lomac_init_label_waitcheck, 2973 2974 .mpo_mount_create = lomac_mount_create, 2975 .mpo_mount_destroy_label = lomac_destroy_label, 2976 .mpo_mount_init_label = lomac_init_label, 2977 2978 .mpo_netinet_arp_send = lomac_netinet_arp_send, 2979 .mpo_netinet_firewall_reply = lomac_netinet_firewall_reply, 2980 .mpo_netinet_firewall_send = lomac_netinet_firewall_send, 2981 .mpo_netinet_fragment = lomac_netinet_fragment, 2982 .mpo_netinet_icmp_reply = lomac_netinet_icmp_reply, 2983 .mpo_netinet_igmp_send = lomac_netinet_igmp_send, 2984 2985 .mpo_netinet6_nd6_send = lomac_netinet6_nd6_send, 2986 2987 .mpo_pipe_check_ioctl = lomac_pipe_check_ioctl, 2988 .mpo_pipe_check_read = lomac_pipe_check_read, 2989 .mpo_pipe_check_relabel = lomac_pipe_check_relabel, 2990 .mpo_pipe_check_write = lomac_pipe_check_write, 2991 .mpo_pipe_copy_label = lomac_copy_label, 2992 .mpo_pipe_create = lomac_pipe_create, 2993 .mpo_pipe_destroy_label = lomac_destroy_label, 2994 .mpo_pipe_externalize_label = lomac_externalize_label, 2995 .mpo_pipe_init_label = lomac_init_label, 2996 .mpo_pipe_internalize_label = lomac_internalize_label, 2997 .mpo_pipe_relabel = lomac_pipe_relabel, 2998 2999 .mpo_priv_check = lomac_priv_check, 3000 3001 .mpo_proc_check_debug = lomac_proc_check_debug, 3002 .mpo_proc_check_sched = lomac_proc_check_sched, 3003 .mpo_proc_check_signal = lomac_proc_check_signal, 3004 .mpo_proc_destroy_label = lomac_proc_destroy_label, 3005 .mpo_proc_init_label = lomac_proc_init_label, 3006 3007 .mpo_socket_check_deliver = lomac_socket_check_deliver, 3008 .mpo_socket_check_relabel = lomac_socket_check_relabel, 3009 .mpo_socket_check_visible = lomac_socket_check_visible, 3010 .mpo_socket_copy_label = lomac_copy_label, 3011 .mpo_socket_create = lomac_socket_create, 3012 .mpo_socket_create_mbuf = lomac_socket_create_mbuf, 3013 .mpo_socket_destroy_label = lomac_destroy_label, 3014 .mpo_socket_externalize_label = lomac_externalize_label, 3015 .mpo_socket_init_label = lomac_init_label_waitcheck, 3016 .mpo_socket_internalize_label = lomac_internalize_label, 3017 .mpo_socket_newconn = lomac_socket_newconn, 3018 .mpo_socket_relabel = lomac_socket_relabel, 3019 3020 .mpo_socketpeer_destroy_label = lomac_destroy_label, 3021 .mpo_socketpeer_externalize_label = lomac_externalize_label, 3022 .mpo_socketpeer_init_label = lomac_init_label_waitcheck, 3023 .mpo_socketpeer_set_from_mbuf = lomac_socketpeer_set_from_mbuf, 3024 .mpo_socketpeer_set_from_socket = lomac_socketpeer_set_from_socket, 3025 3026 .mpo_syncache_create_mbuf = lomac_syncache_create_mbuf, 3027 3028 .mpo_system_check_acct = lomac_system_check_acct, 3029 .mpo_system_check_auditctl = lomac_system_check_auditctl, 3030 .mpo_system_check_swapoff = lomac_system_check_swapoff, 3031 .mpo_system_check_swapon = lomac_system_check_swapon, 3032 .mpo_system_check_sysctl = lomac_system_check_sysctl, 3033 3034 .mpo_thread_userret = lomac_thread_userret, 3035 3036 .mpo_vnode_associate_extattr = lomac_vnode_associate_extattr, 3037 .mpo_vnode_associate_singlelabel = lomac_vnode_associate_singlelabel, 3038 .mpo_vnode_check_access = lomac_vnode_check_open, 3039 .mpo_vnode_check_create = lomac_vnode_check_create, 3040 .mpo_vnode_check_deleteacl = lomac_vnode_check_deleteacl, 3041 .mpo_vnode_check_link = lomac_vnode_check_link, 3042 .mpo_vnode_check_mmap = lomac_vnode_check_mmap, 3043 .mpo_vnode_check_mmap_downgrade = lomac_vnode_check_mmap_downgrade, 3044 .mpo_vnode_check_open = lomac_vnode_check_open, 3045 .mpo_vnode_check_read = lomac_vnode_check_read, 3046 .mpo_vnode_check_relabel = lomac_vnode_check_relabel, 3047 .mpo_vnode_check_rename_from = lomac_vnode_check_rename_from, 3048 .mpo_vnode_check_rename_to = lomac_vnode_check_rename_to, 3049 .mpo_vnode_check_revoke = lomac_vnode_check_revoke, 3050 .mpo_vnode_check_setacl = lomac_vnode_check_setacl, 3051 .mpo_vnode_check_setextattr = lomac_vnode_check_setextattr, 3052 .mpo_vnode_check_setflags = lomac_vnode_check_setflags, 3053 .mpo_vnode_check_setmode = lomac_vnode_check_setmode, 3054 .mpo_vnode_check_setowner = lomac_vnode_check_setowner, 3055 .mpo_vnode_check_setutimes = lomac_vnode_check_setutimes, 3056 .mpo_vnode_check_unlink = lomac_vnode_check_unlink, 3057 .mpo_vnode_check_write = lomac_vnode_check_write, 3058 .mpo_vnode_copy_label = lomac_copy_label, 3059 .mpo_vnode_create_extattr = lomac_vnode_create_extattr, 3060 .mpo_vnode_destroy_label = lomac_destroy_label, 3061 .mpo_vnode_execve_transition = lomac_vnode_execve_transition, 3062 .mpo_vnode_execve_will_transition = lomac_vnode_execve_will_transition, 3063 .mpo_vnode_externalize_label = lomac_externalize_label, 3064 .mpo_vnode_init_label = lomac_init_label, 3065 .mpo_vnode_internalize_label = lomac_internalize_label, 3066 .mpo_vnode_relabel = lomac_vnode_relabel, 3067 .mpo_vnode_setlabel_extattr = lomac_vnode_setlabel_extattr, 3068 }; 3069 3070 MAC_POLICY_SET(&lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC", 3071 MPC_LOADTIME_FLAG_NOTLATE, &lomac_slot); 3072