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