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