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