mac_lomac.c revision 168954
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: head/sys/security/mac_lomac/mac_lomac.c 168954 2007-04-22 16:18:10Z rwatson $ 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 85struct mac_lomac_proc { 86 struct mac_lomac mac_lomac; 87 struct mtx mtx; 88}; 89 90SYSCTL_DECL(_security_mac); 91 92SYSCTL_NODE(_security_mac, OID_AUTO, lomac, CTLFLAG_RW, 0, 93 "TrustedBSD mac_lomac policy controls"); 94 95static int mac_lomac_label_size = sizeof(struct mac_lomac); 96SYSCTL_INT(_security_mac_lomac, OID_AUTO, label_size, CTLFLAG_RD, 97 &mac_lomac_label_size, 0, "Size of struct mac_lomac"); 98 99static int mac_lomac_enabled = 1; 100SYSCTL_INT(_security_mac_lomac, OID_AUTO, enabled, CTLFLAG_RW, 101 &mac_lomac_enabled, 0, "Enforce MAC/LOMAC policy"); 102TUNABLE_INT("security.mac.lomac.enabled", &mac_lomac_enabled); 103 104static int destroyed_not_inited; 105SYSCTL_INT(_security_mac_lomac, OID_AUTO, destroyed_not_inited, CTLFLAG_RD, 106 &destroyed_not_inited, 0, "Count of labels destroyed but not inited"); 107 108static int trust_all_interfaces = 0; 109SYSCTL_INT(_security_mac_lomac, OID_AUTO, trust_all_interfaces, CTLFLAG_RD, 110 &trust_all_interfaces, 0, "Consider all interfaces 'trusted' by MAC/LOMAC"); 111TUNABLE_INT("security.mac.lomac.trust_all_interfaces", &trust_all_interfaces); 112 113static char trusted_interfaces[128]; 114SYSCTL_STRING(_security_mac_lomac, OID_AUTO, trusted_interfaces, CTLFLAG_RD, 115 trusted_interfaces, 0, "Interfaces considered 'trusted' by MAC/LOMAC"); 116TUNABLE_STR("security.mac.lomac.trusted_interfaces", trusted_interfaces, 117 sizeof(trusted_interfaces)); 118 119static int ptys_equal = 0; 120SYSCTL_INT(_security_mac_lomac, OID_AUTO, ptys_equal, CTLFLAG_RW, 121 &ptys_equal, 0, "Label pty devices as lomac/equal on create"); 122TUNABLE_INT("security.mac.lomac.ptys_equal", &ptys_equal); 123 124static int revocation_enabled = 1; 125SYSCTL_INT(_security_mac_lomac, OID_AUTO, revocation_enabled, CTLFLAG_RW, 126 &revocation_enabled, 0, "Revoke access to objects on relabel"); 127TUNABLE_INT("security.mac.lomac.revocation_enabled", &revocation_enabled); 128 129static 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 136MALLOC_DEFINE(M_MACLOMAC, "mac_lomac_label", "MAC/LOMAC labels"); 137 138static struct mac_lomac * 139lomac_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 148static void 149lomac_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 158static int 159lomac_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 167static int 168mac_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 212static int 213mac_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 222static int 223mac_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 237static int 238mac_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 252static int 253mac_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 263static int 264mac_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 276static int 277mac_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 287static int 288mac_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 299static int 300mac_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 320static int 321mac_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 346static int 347mac_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 356static int 357mac_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 426static void 427mac_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 438static void 439mac_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 447static void 448mac_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 459static void 460mac_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 470static void 471mac_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 481static void 482mac_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 493static int mac_lomac_to_string(struct sbuf *sb, 494 struct mac_lomac *mac_lomac); 495 496static int 497maybe_demote(struct mac_lomac *subjlabel, struct mac_lomac *objlabel, 498 const char *actionname, const char *objname, struct vnode *vpq) 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 mtx_lock_spin(&sched_lock); 540 curthread->td_flags |= TDF_ASTPENDING; 541 curthread->td_proc->p_sflag |= PS_MACPEND; 542 mtx_unlock_spin(&sched_lock); 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 (vpq != NULL && VOP_GETATTR(vpq, &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, vpq->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 */ 594static void 595try_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 */ 607static void 608mac_lomac_init(struct mac_policy_conf *conf) 609{ 610 611} 612 613/* 614 * Label operations. 615 */ 616static void 617mac_lomac_init_label(struct label *label) 618{ 619 620 SLOT_SET(label, lomac_alloc(M_WAITOK)); 621} 622 623static int 624mac_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 634static void 635mac_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 643static void 644mac_lomac_destroy_label(struct label *label) 645{ 646 647 lomac_free(SLOT(label)); 648 SLOT_SET(label, NULL); 649} 650 651static void 652mac_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 660static int 661mac_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 683static int 684mac_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 727static int 728mac_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 743static int 744mac_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 */ 782static int 783mac_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 871static int 872mac_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 893static void 894mac_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 */ 904static void 905mac_lomac_create_devfs_device(struct ucred *cred, struct mount *mp, 906 struct cdev *dev, struct devfs_dirent *devfs_dirent, struct label *label) 907{ 908 struct mac_lomac *mac_lomac; 909 int lomac_type; 910 911 mac_lomac = SLOT(label); 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 927static void 928mac_lomac_create_devfs_directory(struct mount *mp, char *dirname, 929 int dirnamelen, struct devfs_dirent *devfs_dirent, struct label *label) 930{ 931 struct mac_lomac *mac_lomac; 932 933 mac_lomac = SLOT(label); 934 mac_lomac_set_single(mac_lomac, MAC_LOMAC_TYPE_HIGH, 0); 935} 936 937static void 938mac_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 950static void 951mac_lomac_create_mount(struct ucred *cred, struct mount *mp, 952 struct label *mntlabel) 953{ 954 struct mac_lomac *source, *dest; 955 956 source = SLOT(cred->cr_label); 957 dest = SLOT(mntlabel); 958 mac_lomac_copy_single(source, dest); 959} 960 961static void 962mac_lomac_relabel_vnode(struct ucred *cred, struct vnode *vp, 963 struct label *vnodelabel, struct label *label) 964{ 965 struct mac_lomac *source, *dest; 966 967 source = SLOT(label); 968 dest = SLOT(vnodelabel); 969 970 try_relabel(source, dest); 971} 972 973static void 974mac_lomac_update_devfsdirent(struct mount *mp, 975 struct devfs_dirent *devfs_dirent, struct label *direntlabel, 976 struct vnode *vp, struct label *vnodelabel) 977{ 978 struct mac_lomac *source, *dest; 979 980 source = SLOT(vnodelabel); 981 dest = SLOT(direntlabel); 982 983 mac_lomac_copy(source, dest); 984} 985 986static void 987mac_lomac_associate_vnode_devfs(struct mount *mp, struct label *mntlabel, 988 struct devfs_dirent *de, struct label *delabel, struct vnode *vp, 989 struct label *vlabel) 990{ 991 struct mac_lomac *source, *dest; 992 993 source = SLOT(delabel); 994 dest = SLOT(vlabel); 995 996 mac_lomac_copy_single(source, dest); 997} 998 999static int 1000mac_lomac_associate_vnode_extattr(struct mount *mp, struct label *mntlabel, 1001 struct vnode *vp, struct label *vlabel) 1002{ 1003 struct mac_lomac temp, *source, *dest; 1004 int buflen, error; 1005 1006 source = SLOT(mntlabel); 1007 dest = SLOT(vlabel); 1008 1009 buflen = sizeof(temp); 1010 bzero(&temp, buflen); 1011 1012 error = vn_extattr_get(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1013 MAC_LOMAC_EXTATTR_NAME, &buflen, (char *)&temp, curthread); 1014 if (error == ENOATTR || error == EOPNOTSUPP) { 1015 /* Fall back to the mntlabel. */ 1016 mac_lomac_copy_single(source, dest); 1017 return (0); 1018 } else if (error) 1019 return (error); 1020 1021 if (buflen != sizeof(temp)) { 1022 if (buflen != sizeof(temp) - sizeof(temp.ml_auxsingle)) { 1023 printf("mac_lomac_associate_vnode_extattr: bad size %d\n", 1024 buflen); 1025 return (EPERM); 1026 } 1027 bzero(&temp.ml_auxsingle, sizeof(temp.ml_auxsingle)); 1028 buflen = sizeof(temp); 1029 (void)vn_extattr_set(vp, IO_NODELOCKED, 1030 MAC_LOMAC_EXTATTR_NAMESPACE, MAC_LOMAC_EXTATTR_NAME, 1031 buflen, (char *)&temp, curthread); 1032 } 1033 if (mac_lomac_valid(&temp) != 0) { 1034 printf("mac_lomac_associate_vnode_extattr: invalid\n"); 1035 return (EPERM); 1036 } 1037 if ((temp.ml_flags & MAC_LOMAC_FLAGS_BOTH) != MAC_LOMAC_FLAG_SINGLE) { 1038 printf("mac_lomac_associate_vnode_extattr: not single\n"); 1039 return (EPERM); 1040 } 1041 1042 mac_lomac_copy_single(&temp, dest); 1043 return (0); 1044} 1045 1046static void 1047mac_lomac_associate_vnode_singlelabel(struct mount *mp, 1048 struct label *mntlabel, struct vnode *vp, struct label *vlabel) 1049{ 1050 struct mac_lomac *source, *dest; 1051 1052 source = SLOT(mntlabel); 1053 dest = SLOT(vlabel); 1054 1055 mac_lomac_copy_single(source, dest); 1056} 1057 1058static int 1059mac_lomac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1060 struct label *mntlabel, struct vnode *dvp, struct label *dlabel, 1061 struct vnode *vp, struct label *vlabel, struct componentname *cnp) 1062{ 1063 struct mac_lomac *source, *dest, *dir, temp; 1064 size_t buflen; 1065 int error; 1066 1067 buflen = sizeof(temp); 1068 bzero(&temp, buflen); 1069 1070 source = SLOT(cred->cr_label); 1071 dest = SLOT(vlabel); 1072 dir = SLOT(dlabel); 1073 if (dir->ml_flags & MAC_LOMAC_FLAG_AUX) { 1074 mac_lomac_copy_auxsingle(dir, &temp); 1075 mac_lomac_set_single(&temp, dir->ml_auxsingle.mle_type, 1076 dir->ml_auxsingle.mle_grade); 1077 } else { 1078 mac_lomac_copy_single(source, &temp); 1079 } 1080 1081 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1082 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1083 if (error == 0) 1084 mac_lomac_copy(&temp, dest); 1085 return (error); 1086} 1087 1088static int 1089mac_lomac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1090 struct label *vlabel, struct label *intlabel) 1091{ 1092 struct mac_lomac *source, temp; 1093 size_t buflen; 1094 int error; 1095 1096 buflen = sizeof(temp); 1097 bzero(&temp, buflen); 1098 1099 source = SLOT(intlabel); 1100 if ((source->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1101 return (0); 1102 1103 mac_lomac_copy_single(source, &temp); 1104 error = vn_extattr_set(vp, IO_NODELOCKED, MAC_LOMAC_EXTATTR_NAMESPACE, 1105 MAC_LOMAC_EXTATTR_NAME, buflen, (char *)&temp, curthread); 1106 return (error); 1107} 1108 1109/* 1110 * Labeling event operations: IPC object. 1111 */ 1112static void 1113mac_lomac_create_inpcb_from_socket(struct socket *so, struct label *solabel, 1114 struct inpcb *inp, struct label *inplabel) 1115{ 1116 struct mac_lomac *source, *dest; 1117 1118 source = SLOT(solabel); 1119 dest = SLOT(inplabel); 1120 1121 mac_lomac_copy_single(source, dest); 1122} 1123 1124static void 1125mac_lomac_create_mbuf_from_socket(struct socket *so, struct label *socketlabel, 1126 struct mbuf *m, struct label *mbuflabel) 1127{ 1128 struct mac_lomac *source, *dest; 1129 1130 source = SLOT(socketlabel); 1131 dest = SLOT(mbuflabel); 1132 1133 mac_lomac_copy_single(source, dest); 1134} 1135 1136static void 1137mac_lomac_create_socket(struct ucred *cred, struct socket *socket, 1138 struct label *socketlabel) 1139{ 1140 struct mac_lomac *source, *dest; 1141 1142 source = SLOT(cred->cr_label); 1143 dest = SLOT(socketlabel); 1144 1145 mac_lomac_copy_single(source, dest); 1146} 1147 1148static void 1149mac_lomac_create_pipe(struct ucred *cred, struct pipepair *pp, 1150 struct label *pipelabel) 1151{ 1152 struct mac_lomac *source, *dest; 1153 1154 source = SLOT(cred->cr_label); 1155 dest = SLOT(pipelabel); 1156 1157 mac_lomac_copy_single(source, dest); 1158} 1159 1160static void 1161mac_lomac_create_socket_from_socket(struct socket *oldsocket, 1162 struct label *oldsocketlabel, struct socket *newsocket, 1163 struct label *newsocketlabel) 1164{ 1165 struct mac_lomac *source, *dest; 1166 1167 source = SLOT(oldsocketlabel); 1168 dest = SLOT(newsocketlabel); 1169 1170 mac_lomac_copy_single(source, dest); 1171} 1172 1173static void 1174mac_lomac_relabel_socket(struct ucred *cred, struct socket *socket, 1175 struct label *socketlabel, struct label *newlabel) 1176{ 1177 struct mac_lomac *source, *dest; 1178 1179 source = SLOT(newlabel); 1180 dest = SLOT(socketlabel); 1181 1182 try_relabel(source, dest); 1183} 1184 1185static void 1186mac_lomac_relabel_pipe(struct ucred *cred, struct pipepair *pp, 1187 struct label *pipelabel, struct label *newlabel) 1188{ 1189 struct mac_lomac *source, *dest; 1190 1191 source = SLOT(newlabel); 1192 dest = SLOT(pipelabel); 1193 1194 try_relabel(source, dest); 1195} 1196 1197static void 1198mac_lomac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel, 1199 struct socket *socket, struct label *socketpeerlabel) 1200{ 1201 struct mac_lomac *source, *dest; 1202 1203 source = SLOT(mbuflabel); 1204 dest = SLOT(socketpeerlabel); 1205 1206 mac_lomac_copy_single(source, dest); 1207} 1208 1209/* 1210 * Labeling event operations: network objects. 1211 */ 1212static void 1213mac_lomac_set_socket_peer_from_socket(struct socket *oldsocket, 1214 struct label *oldsocketlabel, struct socket *newsocket, 1215 struct label *newsocketpeerlabel) 1216{ 1217 struct mac_lomac *source, *dest; 1218 1219 source = SLOT(oldsocketlabel); 1220 dest = SLOT(newsocketpeerlabel); 1221 1222 mac_lomac_copy_single(source, dest); 1223} 1224 1225static void 1226mac_lomac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d, 1227 struct label *bpflabel) 1228{ 1229 struct mac_lomac *source, *dest; 1230 1231 source = SLOT(cred->cr_label); 1232 dest = SLOT(bpflabel); 1233 1234 mac_lomac_copy_single(source, dest); 1235} 1236 1237static void 1238mac_lomac_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel) 1239{ 1240 char tifname[IFNAMSIZ], *p, *q; 1241 char tiflist[sizeof(trusted_interfaces)]; 1242 struct mac_lomac *dest; 1243 int len, grade; 1244 1245 dest = SLOT(ifnetlabel); 1246 1247 if (ifnet->if_type == IFT_LOOP) { 1248 grade = MAC_LOMAC_TYPE_EQUAL; 1249 goto set; 1250 } 1251 1252 if (trust_all_interfaces) { 1253 grade = MAC_LOMAC_TYPE_HIGH; 1254 goto set; 1255 } 1256 1257 grade = MAC_LOMAC_TYPE_LOW; 1258 1259 if (trusted_interfaces[0] == '\0' || 1260 !strvalid(trusted_interfaces, sizeof(trusted_interfaces))) 1261 goto set; 1262 1263 bzero(tiflist, sizeof(tiflist)); 1264 for (p = trusted_interfaces, q = tiflist; *p != '\0'; p++, q++) 1265 if(*p != ' ' && *p != '\t') 1266 *q = *p; 1267 1268 for (p = q = tiflist;; p++) { 1269 if (*p == ',' || *p == '\0') { 1270 len = p - q; 1271 if (len < IFNAMSIZ) { 1272 bzero(tifname, sizeof(tifname)); 1273 bcopy(q, tifname, len); 1274 if (strcmp(tifname, ifnet->if_xname) == 0) { 1275 grade = MAC_LOMAC_TYPE_HIGH; 1276 break; 1277 } 1278 } 1279 else { 1280 *p = '\0'; 1281 printf("MAC/LOMAC warning: interface name " 1282 "\"%s\" is too long (must be < %d)\n", 1283 q, IFNAMSIZ); 1284 } 1285 if (*p == '\0') 1286 break; 1287 q = p + 1; 1288 } 1289 } 1290set: 1291 mac_lomac_set_single(dest, grade, 0); 1292 mac_lomac_set_range(dest, grade, 0, grade, 0); 1293} 1294 1295static void 1296mac_lomac_create_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1297 struct ipq *ipq, struct label *ipqlabel) 1298{ 1299 struct mac_lomac *source, *dest; 1300 1301 source = SLOT(fragmentlabel); 1302 dest = SLOT(ipqlabel); 1303 1304 mac_lomac_copy_single(source, dest); 1305} 1306 1307static void 1308mac_lomac_create_datagram_from_ipq(struct ipq *ipq, struct label *ipqlabel, 1309 struct mbuf *datagram, struct label *datagramlabel) 1310{ 1311 struct mac_lomac *source, *dest; 1312 1313 source = SLOT(ipqlabel); 1314 dest = SLOT(datagramlabel); 1315 1316 /* Just use the head, since we require them all to match. */ 1317 mac_lomac_copy_single(source, dest); 1318} 1319 1320static void 1321mac_lomac_create_fragment(struct mbuf *datagram, struct label *datagramlabel, 1322 struct mbuf *fragment, struct label *fragmentlabel) 1323{ 1324 struct mac_lomac *source, *dest; 1325 1326 source = SLOT(datagramlabel); 1327 dest = SLOT(fragmentlabel); 1328 1329 mac_lomac_copy_single(source, dest); 1330} 1331 1332static void 1333mac_lomac_create_mbuf_from_inpcb(struct inpcb *inp, struct label *inplabel, 1334 struct mbuf *m, struct label *mlabel) 1335{ 1336 struct mac_lomac *source, *dest; 1337 1338 source = SLOT(inplabel); 1339 dest = SLOT(mlabel); 1340 1341 mac_lomac_copy_single(source, dest); 1342} 1343 1344static void 1345mac_lomac_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel, 1346 struct mbuf *mbuf, struct label *mbuflabel) 1347{ 1348 struct mac_lomac *dest; 1349 1350 dest = SLOT(mbuflabel); 1351 1352 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1353} 1354 1355static void 1356mac_lomac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel, 1357 struct mbuf *mbuf, struct label *mbuflabel) 1358{ 1359 struct mac_lomac *source, *dest; 1360 1361 source = SLOT(bpflabel); 1362 dest = SLOT(mbuflabel); 1363 1364 mac_lomac_copy_single(source, dest); 1365} 1366 1367static void 1368mac_lomac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel, 1369 struct mbuf *m, struct label *mbuflabel) 1370{ 1371 struct mac_lomac *source, *dest; 1372 1373 source = SLOT(ifnetlabel); 1374 dest = SLOT(mbuflabel); 1375 1376 mac_lomac_copy_single(source, dest); 1377} 1378 1379static void 1380mac_lomac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, 1381 struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel, 1382 struct mbuf *newmbuf, struct label *newmbuflabel) 1383{ 1384 struct mac_lomac *source, *dest; 1385 1386 source = SLOT(oldmbuflabel); 1387 dest = SLOT(newmbuflabel); 1388 1389 mac_lomac_copy_single(source, dest); 1390} 1391 1392static void 1393mac_lomac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel, 1394 struct mbuf *newmbuf, struct label *newmbuflabel) 1395{ 1396 struct mac_lomac *source, *dest; 1397 1398 source = SLOT(oldmbuflabel); 1399 dest = SLOT(newmbuflabel); 1400 1401 mac_lomac_copy_single(source, dest); 1402} 1403 1404static int 1405mac_lomac_fragment_match(struct mbuf *fragment, struct label *fragmentlabel, 1406 struct ipq *ipq, struct label *ipqlabel) 1407{ 1408 struct mac_lomac *a, *b; 1409 1410 a = SLOT(ipqlabel); 1411 b = SLOT(fragmentlabel); 1412 1413 return (mac_lomac_equal_single(a, b)); 1414} 1415 1416static void 1417mac_lomac_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet, 1418 struct label *ifnetlabel, struct label *newlabel) 1419{ 1420 struct mac_lomac *source, *dest; 1421 1422 source = SLOT(newlabel); 1423 dest = SLOT(ifnetlabel); 1424 1425 try_relabel(source, dest); 1426} 1427 1428static void 1429mac_lomac_update_ipq(struct mbuf *fragment, struct label *fragmentlabel, 1430 struct ipq *ipq, struct label *ipqlabel) 1431{ 1432 1433 /* NOOP: we only accept matching labels, so no need to update */ 1434} 1435 1436static void 1437mac_lomac_inpcb_sosetlabel(struct socket *so, struct label *solabel, 1438 struct inpcb *inp, struct label *inplabel) 1439{ 1440 struct mac_lomac *source, *dest; 1441 1442 source = SLOT(solabel); 1443 dest = SLOT(inplabel); 1444 1445 mac_lomac_copy_single(source, dest); 1446} 1447 1448static void 1449mac_lomac_init_syncache_from_inpcb(struct label *label, struct inpcb *inp) 1450{ 1451 struct mac_lomac *source, *dest; 1452 1453 source = SLOT(inp->inp_label); 1454 dest = SLOT(label); 1455 mac_lomac_copy(source, dest); 1456} 1457 1458static void 1459mac_lomac_create_mbuf_from_syncache(struct label *sc_label, struct mbuf *m, 1460 struct label *mbuf_label) 1461{ 1462 struct mac_lomac *source, *dest; 1463 1464 source = SLOT(sc_label); 1465 dest = SLOT(mbuf_label); 1466 mac_lomac_copy(source, dest); 1467} 1468 1469static void 1470mac_lomac_create_mbuf_from_firewall(struct mbuf *m, struct label *label) 1471{ 1472 struct mac_lomac *dest; 1473 1474 dest = SLOT(label); 1475 1476 /* XXX: where is the label for the firewall really comming from? */ 1477 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1478} 1479 1480/* 1481 * Labeling event operations: processes. 1482 */ 1483static void 1484mac_lomac_execve_transition(struct ucred *old, struct ucred *new, 1485 struct vnode *vp, struct label *vnodelabel, 1486 struct label *interpvnodelabel, struct image_params *imgp, 1487 struct label *execlabel) 1488{ 1489 struct mac_lomac *source, *dest, *obj, *robj; 1490 1491 source = SLOT(old->cr_label); 1492 dest = SLOT(new->cr_label); 1493 obj = SLOT(vnodelabel); 1494 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1495 1496 mac_lomac_copy(source, dest); 1497 /* 1498 * If there's an auxiliary label on the real object, respect it 1499 * and assume that this level should be assumed immediately if 1500 * a higher level is currently in place. 1501 */ 1502 if (robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1503 !mac_lomac_dominate_element(&robj->ml_auxsingle, &dest->ml_single) 1504 && mac_lomac_auxsingle_in_range(robj, dest)) 1505 mac_lomac_set_single(dest, robj->ml_auxsingle.mle_type, 1506 robj->ml_auxsingle.mle_grade); 1507 /* 1508 * Restructuring to use the execve transitioning mechanism 1509 * instead of the normal demotion mechanism here would be 1510 * difficult, so just copy the label over and perform standard 1511 * demotion. This is also non-optimal because it will result 1512 * in the intermediate label "new" being created and immediately 1513 * recycled. 1514 */ 1515 if (mac_lomac_enabled && revocation_enabled && 1516 !mac_lomac_dominate_single(obj, source)) 1517 (void)maybe_demote(source, obj, "executing", "file", vp); 1518} 1519 1520static int 1521mac_lomac_execve_will_transition(struct ucred *old, struct vnode *vp, 1522 struct label *vnodelabel, struct label *interpvnodelabel, 1523 struct image_params *imgp, struct label *execlabel) 1524{ 1525 struct mac_lomac *subj, *obj, *robj; 1526 1527 if (!mac_lomac_enabled || !revocation_enabled) 1528 return (0); 1529 1530 subj = SLOT(old->cr_label); 1531 obj = SLOT(vnodelabel); 1532 robj = interpvnodelabel != NULL ? SLOT(interpvnodelabel) : obj; 1533 1534 return ((robj->ml_flags & MAC_LOMAC_FLAG_AUX && 1535 !mac_lomac_dominate_element(&robj->ml_auxsingle, &subj->ml_single) 1536 && mac_lomac_auxsingle_in_range(robj, subj)) || 1537 !mac_lomac_dominate_single(obj, subj)); 1538} 1539 1540static void 1541mac_lomac_create_proc0(struct ucred *cred) 1542{ 1543 struct mac_lomac *dest; 1544 1545 dest = SLOT(cred->cr_label); 1546 1547 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_EQUAL, 0); 1548 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1549 0); 1550} 1551 1552static void 1553mac_lomac_create_proc1(struct ucred *cred) 1554{ 1555 struct mac_lomac *dest; 1556 1557 dest = SLOT(cred->cr_label); 1558 1559 mac_lomac_set_single(dest, MAC_LOMAC_TYPE_HIGH, 0); 1560 mac_lomac_set_range(dest, MAC_LOMAC_TYPE_LOW, 0, MAC_LOMAC_TYPE_HIGH, 1561 0); 1562} 1563 1564static void 1565mac_lomac_relabel_cred(struct ucred *cred, struct label *newlabel) 1566{ 1567 struct mac_lomac *source, *dest; 1568 1569 source = SLOT(newlabel); 1570 dest = SLOT(cred->cr_label); 1571 1572 try_relabel(source, dest); 1573} 1574 1575/* 1576 * Access control checks. 1577 */ 1578static int 1579mac_lomac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel, 1580 struct ifnet *ifnet, struct label *ifnetlabel) 1581{ 1582 struct mac_lomac *a, *b; 1583 1584 if (!mac_lomac_enabled) 1585 return (0); 1586 1587 a = SLOT(bpflabel); 1588 b = SLOT(ifnetlabel); 1589 1590 if (mac_lomac_equal_single(a, b)) 1591 return (0); 1592 return (EACCES); 1593} 1594 1595static int 1596mac_lomac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 1597{ 1598 struct mac_lomac *subj, *new; 1599 int error; 1600 1601 subj = SLOT(cred->cr_label); 1602 new = SLOT(newlabel); 1603 1604 /* 1605 * If there is a LOMAC label update for the credential, it may 1606 * be an update of the single, range, or both. 1607 */ 1608 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1609 if (error) 1610 return (error); 1611 1612 /* 1613 * If the LOMAC label is to be changed, authorize as appropriate. 1614 */ 1615 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1616 /* 1617 * Fill in the missing parts from the previous label. 1618 */ 1619 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1620 mac_lomac_copy_single(subj, new); 1621 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1622 mac_lomac_copy_range(subj, new); 1623 1624 /* 1625 * To change the LOMAC range on a credential, the new 1626 * range label must be in the current range. 1627 */ 1628 if (!mac_lomac_range_in_range(new, subj)) 1629 return (EPERM); 1630 1631 /* 1632 * To change the LOMAC single label on a credential, the 1633 * new single label must be in the new range. Implicitly 1634 * from the previous check, the new single is in the old 1635 * range. 1636 */ 1637 if (!mac_lomac_single_in_range(new, new)) 1638 return (EPERM); 1639 1640 /* 1641 * To have EQUAL in any component of the new credential 1642 * LOMAC label, the subject must already have EQUAL in 1643 * their label. 1644 */ 1645 if (mac_lomac_contains_equal(new)) { 1646 error = mac_lomac_subject_privileged(subj); 1647 if (error) 1648 return (error); 1649 } 1650 1651 /* 1652 * XXXMAC: Additional consistency tests regarding the 1653 * single and range of the new label might be performed 1654 * here. 1655 */ 1656 } 1657 1658 return (0); 1659} 1660 1661static int 1662mac_lomac_check_cred_visible(struct ucred *u1, struct ucred *u2) 1663{ 1664 struct mac_lomac *subj, *obj; 1665 1666 if (!mac_lomac_enabled) 1667 return (0); 1668 1669 subj = SLOT(u1->cr_label); 1670 obj = SLOT(u2->cr_label); 1671 1672 /* XXX: range */ 1673 if (!mac_lomac_dominate_single(obj, subj)) 1674 return (ESRCH); 1675 1676 return (0); 1677} 1678 1679static int 1680mac_lomac_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet, 1681 struct label *ifnetlabel, struct label *newlabel) 1682{ 1683 struct mac_lomac *subj, *new; 1684 int error; 1685 1686 subj = SLOT(cred->cr_label); 1687 new = SLOT(newlabel); 1688 1689 /* 1690 * If there is a LOMAC label update for the interface, it may 1691 * be an update of the single, range, or both. 1692 */ 1693 error = lomac_atmostflags(new, MAC_LOMAC_FLAGS_BOTH); 1694 if (error) 1695 return (error); 1696 1697 /* 1698 * Relabling network interfaces requires LOMAC privilege. 1699 */ 1700 error = mac_lomac_subject_privileged(subj); 1701 if (error) 1702 return (error); 1703 1704 /* 1705 * If the LOMAC label is to be changed, authorize as appropriate. 1706 */ 1707 if (new->ml_flags & MAC_LOMAC_FLAGS_BOTH) { 1708 /* 1709 * Fill in the missing parts from the previous label. 1710 */ 1711 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 1712 mac_lomac_copy_single(subj, new); 1713 if ((new->ml_flags & MAC_LOMAC_FLAG_RANGE) == 0) 1714 mac_lomac_copy_range(subj, new); 1715 1716 /* 1717 * Rely on the traditional superuser status for the LOMAC 1718 * interface relabel requirements. XXXMAC: This will go 1719 * away. 1720 * 1721 * XXXRW: This is also redundant to a higher layer check. 1722 */ 1723 error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0); 1724 if (error) 1725 return (EPERM); 1726 1727 /* 1728 * XXXMAC: Additional consistency tests regarding the single 1729 * and the range of the new label might be performed here. 1730 */ 1731 } 1732 1733 return (0); 1734} 1735 1736static int 1737mac_lomac_check_ifnet_transmit(struct ifnet *ifnet, struct label *ifnetlabel, 1738 struct mbuf *m, struct label *mbuflabel) 1739{ 1740 struct mac_lomac *p, *i; 1741 1742 if (!mac_lomac_enabled) 1743 return (0); 1744 1745 p = SLOT(mbuflabel); 1746 i = SLOT(ifnetlabel); 1747 1748 return (mac_lomac_single_in_range(p, i) ? 0 : EACCES); 1749} 1750 1751static int 1752mac_lomac_check_inpcb_deliver(struct inpcb *inp, struct label *inplabel, 1753 struct mbuf *m, struct label *mlabel) 1754{ 1755 struct mac_lomac *p, *i; 1756 1757 if (!mac_lomac_enabled) 1758 return (0); 1759 1760 p = SLOT(mlabel); 1761 i = SLOT(inplabel); 1762 1763 return (mac_lomac_equal_single(p, i) ? 0 : EACCES); 1764} 1765 1766static int 1767mac_lomac_check_kld_load(struct ucred *cred, struct vnode *vp, 1768 struct label *label) 1769{ 1770 struct mac_lomac *subj, *obj; 1771 1772 if (!mac_lomac_enabled) 1773 return (0); 1774 1775 subj = SLOT(cred->cr_label); 1776 obj = SLOT(label); 1777 1778 if (mac_lomac_subject_privileged(subj)) 1779 return (EPERM); 1780 1781 if (!mac_lomac_high_single(obj)) 1782 return (EACCES); 1783 1784 return (0); 1785} 1786 1787static int 1788mac_lomac_check_pipe_ioctl(struct ucred *cred, struct pipepair *pp, 1789 struct label *pipelabel, unsigned long cmd, void /* caddr_t */ *data) 1790{ 1791 1792 if(!mac_lomac_enabled) 1793 return (0); 1794 1795 /* XXX: This will be implemented soon... */ 1796 1797 return (0); 1798} 1799 1800static int 1801mac_lomac_check_pipe_read(struct ucred *cred, struct pipepair *pp, 1802 struct label *pipelabel) 1803{ 1804 struct mac_lomac *subj, *obj; 1805 1806 if (!mac_lomac_enabled) 1807 return (0); 1808 1809 subj = SLOT(cred->cr_label); 1810 obj = SLOT((pipelabel)); 1811 1812 if (!mac_lomac_dominate_single(obj, subj)) 1813 return (maybe_demote(subj, obj, "reading", "pipe", NULL)); 1814 1815 return (0); 1816} 1817 1818static int 1819mac_lomac_check_pipe_relabel(struct ucred *cred, struct pipepair *pp, 1820 struct label *pipelabel, struct label *newlabel) 1821{ 1822 struct mac_lomac *subj, *obj, *new; 1823 int error; 1824 1825 new = SLOT(newlabel); 1826 subj = SLOT(cred->cr_label); 1827 obj = SLOT(pipelabel); 1828 1829 /* 1830 * If there is a LOMAC label update for a pipe, it must be a 1831 * single update. 1832 */ 1833 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1834 if (error) 1835 return (error); 1836 1837 /* 1838 * To perform a relabel of a pipe (LOMAC label or not), LOMAC must 1839 * authorize the relabel. 1840 */ 1841 if (!mac_lomac_single_in_range(obj, subj)) 1842 return (EPERM); 1843 1844 /* 1845 * If the LOMAC label is to be changed, authorize as appropriate. 1846 */ 1847 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1848 /* 1849 * To change the LOMAC label on a pipe, the new pipe label 1850 * must be in the subject range. 1851 */ 1852 if (!mac_lomac_single_in_range(new, subj)) 1853 return (EPERM); 1854 1855 /* 1856 * To change the LOMAC label on a pipe to be EQUAL, the 1857 * subject must have appropriate privilege. 1858 */ 1859 if (mac_lomac_contains_equal(new)) { 1860 error = mac_lomac_subject_privileged(subj); 1861 if (error) 1862 return (error); 1863 } 1864 } 1865 1866 return (0); 1867} 1868 1869static int 1870mac_lomac_check_pipe_write(struct ucred *cred, struct pipepair *pp, 1871 struct label *pipelabel) 1872{ 1873 struct mac_lomac *subj, *obj; 1874 1875 if (!mac_lomac_enabled) 1876 return (0); 1877 1878 subj = SLOT(cred->cr_label); 1879 obj = SLOT((pipelabel)); 1880 1881 if (!mac_lomac_subject_dominate(subj, obj)) 1882 return (EACCES); 1883 1884 return (0); 1885} 1886 1887static int 1888mac_lomac_check_proc_debug(struct ucred *cred, struct proc *proc) 1889{ 1890 struct mac_lomac *subj, *obj; 1891 1892 if (!mac_lomac_enabled) 1893 return (0); 1894 1895 subj = SLOT(cred->cr_label); 1896 obj = SLOT(proc->p_ucred->cr_label); 1897 1898 /* XXX: range checks */ 1899 if (!mac_lomac_dominate_single(obj, subj)) 1900 return (ESRCH); 1901 if (!mac_lomac_subject_dominate(subj, obj)) 1902 return (EACCES); 1903 1904 return (0); 1905} 1906 1907static int 1908mac_lomac_check_proc_sched(struct ucred *cred, struct proc *proc) 1909{ 1910 struct mac_lomac *subj, *obj; 1911 1912 if (!mac_lomac_enabled) 1913 return (0); 1914 1915 subj = SLOT(cred->cr_label); 1916 obj = SLOT(proc->p_ucred->cr_label); 1917 1918 /* XXX: range checks */ 1919 if (!mac_lomac_dominate_single(obj, subj)) 1920 return (ESRCH); 1921 if (!mac_lomac_subject_dominate(subj, obj)) 1922 return (EACCES); 1923 1924 return (0); 1925} 1926 1927static int 1928mac_lomac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 1929{ 1930 struct mac_lomac *subj, *obj; 1931 1932 if (!mac_lomac_enabled) 1933 return (0); 1934 1935 subj = SLOT(cred->cr_label); 1936 obj = SLOT(proc->p_ucred->cr_label); 1937 1938 /* XXX: range checks */ 1939 if (!mac_lomac_dominate_single(obj, subj)) 1940 return (ESRCH); 1941 if (!mac_lomac_subject_dominate(subj, obj)) 1942 return (EACCES); 1943 1944 return (0); 1945} 1946 1947static int 1948mac_lomac_check_socket_deliver(struct socket *so, struct label *socketlabel, 1949 struct mbuf *m, struct label *mbuflabel) 1950{ 1951 struct mac_lomac *p, *s; 1952 1953 if (!mac_lomac_enabled) 1954 return (0); 1955 1956 p = SLOT(mbuflabel); 1957 s = SLOT(socketlabel); 1958 1959 return (mac_lomac_equal_single(p, s) ? 0 : EACCES); 1960} 1961 1962static int 1963mac_lomac_check_socket_relabel(struct ucred *cred, struct socket *socket, 1964 struct label *socketlabel, struct label *newlabel) 1965{ 1966 struct mac_lomac *subj, *obj, *new; 1967 int error; 1968 1969 new = SLOT(newlabel); 1970 subj = SLOT(cred->cr_label); 1971 obj = SLOT(socketlabel); 1972 1973 /* 1974 * If there is a LOMAC label update for the socket, it may be 1975 * an update of single. 1976 */ 1977 error = lomac_atmostflags(new, MAC_LOMAC_FLAG_SINGLE); 1978 if (error) 1979 return (error); 1980 1981 /* 1982 * To relabel a socket, the old socket single must be in the subject 1983 * range. 1984 */ 1985 if (!mac_lomac_single_in_range(obj, subj)) 1986 return (EPERM); 1987 1988 /* 1989 * If the LOMAC label is to be changed, authorize as appropriate. 1990 */ 1991 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 1992 /* 1993 * To relabel a socket, the new socket single must be in 1994 * the subject range. 1995 */ 1996 if (!mac_lomac_single_in_range(new, subj)) 1997 return (EPERM); 1998 1999 /* 2000 * To change the LOMAC label on the socket to contain EQUAL, 2001 * the subject must have appropriate privilege. 2002 */ 2003 if (mac_lomac_contains_equal(new)) { 2004 error = mac_lomac_subject_privileged(subj); 2005 if (error) 2006 return (error); 2007 } 2008 } 2009 2010 return (0); 2011} 2012 2013static int 2014mac_lomac_check_socket_visible(struct ucred *cred, struct socket *socket, 2015 struct label *socketlabel) 2016{ 2017 struct mac_lomac *subj, *obj; 2018 2019 if (!mac_lomac_enabled) 2020 return (0); 2021 2022 subj = SLOT(cred->cr_label); 2023 obj = SLOT(socketlabel); 2024 2025 if (!mac_lomac_dominate_single(obj, subj)) 2026 return (ENOENT); 2027 2028 return (0); 2029} 2030 2031/* 2032 * Some system privileges are allowed regardless of integrity grade; others 2033 * are allowed only when running with privilege with respect to the LOMAC 2034 * policy as they might otherwise allow bypassing of the integrity policy. 2035 */ 2036static int 2037mac_lomac_priv_check(struct ucred *cred, int priv) 2038{ 2039 struct mac_lomac *subj; 2040 int error; 2041 2042 if (!mac_lomac_enabled) 2043 return (0); 2044 2045 /* 2046 * Exempt only specific privileges from the LOMAC integrity policy. 2047 */ 2048 switch (priv) { 2049 case PRIV_KTRACE: 2050 case PRIV_MSGBUF: 2051 2052 /* 2053 * Allow processes to manipulate basic process audit properties, and 2054 * to submit audit records. 2055 */ 2056 case PRIV_AUDIT_GETAUDIT: 2057 case PRIV_AUDIT_SETAUDIT: 2058 case PRIV_AUDIT_SUBMIT: 2059 2060 /* 2061 * Allow processes to manipulate their regular UNIX credentials. 2062 */ 2063 case PRIV_CRED_SETUID: 2064 case PRIV_CRED_SETEUID: 2065 case PRIV_CRED_SETGID: 2066 case PRIV_CRED_SETEGID: 2067 case PRIV_CRED_SETGROUPS: 2068 case PRIV_CRED_SETREUID: 2069 case PRIV_CRED_SETREGID: 2070 case PRIV_CRED_SETRESUID: 2071 case PRIV_CRED_SETRESGID: 2072 2073 /* 2074 * Allow processes to perform system monitoring. 2075 */ 2076 case PRIV_SEEOTHERGIDS: 2077 case PRIV_SEEOTHERUIDS: 2078 break; 2079 2080 /* 2081 * Allow access to general process debugging facilities. We 2082 * separately control debugging based on MAC label. 2083 */ 2084 case PRIV_DEBUG_DIFFCRED: 2085 case PRIV_DEBUG_SUGID: 2086 case PRIV_DEBUG_UNPRIV: 2087 2088 /* 2089 * Allow manipulating jails. 2090 */ 2091 case PRIV_JAIL_ATTACH: 2092 2093 /* 2094 * Allow privilege with respect to the Partition policy, but not the 2095 * Privs policy. 2096 */ 2097 case PRIV_MAC_PARTITION: 2098 2099 /* 2100 * Allow privilege with respect to process resource limits and login 2101 * context. 2102 */ 2103 case PRIV_PROC_LIMIT: 2104 case PRIV_PROC_SETLOGIN: 2105 case PRIV_PROC_SETRLIMIT: 2106 2107 /* 2108 * Allow System V and POSIX IPC privileges. 2109 */ 2110 case PRIV_IPC_READ: 2111 case PRIV_IPC_WRITE: 2112 case PRIV_IPC_ADMIN: 2113 case PRIV_IPC_MSGSIZE: 2114 case PRIV_MQ_ADMIN: 2115 2116 /* 2117 * Allow certain scheduler manipulations -- possibly this should be 2118 * controlled by more fine-grained policy, as potentially low 2119 * integrity processes can deny CPU to higher integrity ones. 2120 */ 2121 case PRIV_SCHED_DIFFCRED: 2122 case PRIV_SCHED_SETPRIORITY: 2123 case PRIV_SCHED_RTPRIO: 2124 case PRIV_SCHED_SETPOLICY: 2125 case PRIV_SCHED_SET: 2126 case PRIV_SCHED_SETPARAM: 2127 2128 /* 2129 * More IPC privileges. 2130 */ 2131 case PRIV_SEM_WRITE: 2132 2133 /* 2134 * Allow signaling privileges subject to integrity policy. 2135 */ 2136 case PRIV_SIGNAL_DIFFCRED: 2137 case PRIV_SIGNAL_SUGID: 2138 2139 /* 2140 * Allow access to only limited sysctls from lower integrity levels; 2141 * piggy-back on the Jail definition. 2142 */ 2143 case PRIV_SYSCTL_WRITEJAIL: 2144 2145 /* 2146 * Allow TTY-based privileges, subject to general device access using 2147 * labels on TTY device nodes, but not console privilege. 2148 */ 2149 case PRIV_TTY_DRAINWAIT: 2150 case PRIV_TTY_DTRWAIT: 2151 case PRIV_TTY_EXCLUSIVE: 2152 case PRIV_TTY_PRISON: 2153 case PRIV_TTY_STI: 2154 case PRIV_TTY_SETA: 2155 2156 /* 2157 * Grant most VFS privileges, as almost all are in practice bounded 2158 * by more specific checks using labels. 2159 */ 2160 case PRIV_VFS_READ: 2161 case PRIV_VFS_WRITE: 2162 case PRIV_VFS_ADMIN: 2163 case PRIV_VFS_EXEC: 2164 case PRIV_VFS_LOOKUP: 2165 case PRIV_VFS_CHFLAGS_DEV: 2166 case PRIV_VFS_CHOWN: 2167 case PRIV_VFS_CHROOT: 2168 case PRIV_VFS_RETAINSUGID: 2169 case PRIV_VFS_EXCEEDQUOTA: 2170 case PRIV_VFS_FCHROOT: 2171 case PRIV_VFS_FHOPEN: 2172 case PRIV_VFS_FHSTATFS: 2173 case PRIV_VFS_GENERATION: 2174 case PRIV_VFS_GETFH: 2175 case PRIV_VFS_GETQUOTA: 2176 case PRIV_VFS_LINK: 2177 case PRIV_VFS_MOUNT: 2178 case PRIV_VFS_MOUNT_OWNER: 2179 case PRIV_VFS_MOUNT_PERM: 2180 case PRIV_VFS_MOUNT_SUIDDIR: 2181 case PRIV_VFS_MOUNT_NONUSER: 2182 case PRIV_VFS_SETGID: 2183 case PRIV_VFS_STICKYFILE: 2184 case PRIV_VFS_SYSFLAGS: 2185 case PRIV_VFS_UNMOUNT: 2186 2187 /* 2188 * Allow VM privileges; it would be nice if these were subject to 2189 * resource limits. 2190 */ 2191 case PRIV_VM_MADV_PROTECT: 2192 case PRIV_VM_MLOCK: 2193 case PRIV_VM_MUNLOCK: 2194 2195 /* 2196 * Allow some but not all network privileges. In general, dont allow 2197 * reconfiguring the network stack, just normal use. 2198 */ 2199 case PRIV_NETATALK_RESERVEDPORT: 2200 case PRIV_NETINET_RESERVEDPORT: 2201 case PRIV_NETINET_RAW: 2202 case PRIV_NETINET_REUSEPORT: 2203 case PRIV_NETIPX_RESERVEDPORT: 2204 case PRIV_NETIPX_RAW: 2205 break; 2206 2207 /* 2208 * All remaining system privileges are allow only if the process 2209 * holds privilege with respect to the LOMAC policy. 2210 */ 2211 default: 2212 subj = SLOT(cred->cr_label); 2213 error = mac_lomac_subject_privileged(subj); 2214 if (error) 2215 return (error); 2216 } 2217 return (0); 2218} 2219 2220 2221static int 2222mac_lomac_check_system_acct(struct ucred *cred, struct vnode *vp, 2223 struct label *label) 2224{ 2225 struct mac_lomac *subj, *obj; 2226 2227 if (!mac_lomac_enabled) 2228 return (0); 2229 2230 subj = SLOT(cred->cr_label); 2231 obj = SLOT(label); 2232 2233 if (mac_lomac_subject_privileged(subj)) 2234 return (EPERM); 2235 2236 if (!mac_lomac_high_single(obj)) 2237 return (EACCES); 2238 2239 return (0); 2240} 2241 2242static int 2243mac_lomac_check_system_auditctl(struct ucred *cred, struct vnode *vp, 2244 struct label *label) 2245{ 2246 struct mac_lomac *subj, *obj; 2247 2248 if (!mac_lomac_enabled) 2249 return (0); 2250 2251 subj = SLOT(cred->cr_label); 2252 obj = SLOT(label); 2253 2254 if (mac_lomac_subject_privileged(subj)) 2255 return (EPERM); 2256 2257 if (!mac_lomac_high_single(obj)) 2258 return (EACCES); 2259 2260 return (0); 2261} 2262 2263static int 2264mac_lomac_check_system_swapoff(struct ucred *cred, struct vnode *vp, 2265 struct label *label) 2266{ 2267 struct mac_lomac *subj; 2268 2269 if (!mac_lomac_enabled) 2270 return (0); 2271 2272 subj = SLOT(cred->cr_label); 2273 2274 if (mac_lomac_subject_privileged(subj)) 2275 return (EPERM); 2276 2277 return (0); 2278} 2279 2280static int 2281mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp, 2282 struct label *label) 2283{ 2284 struct mac_lomac *subj, *obj; 2285 2286 if (!mac_lomac_enabled) 2287 return (0); 2288 2289 subj = SLOT(cred->cr_label); 2290 obj = SLOT(label); 2291 2292 if (mac_lomac_subject_privileged(subj)) 2293 return (EPERM); 2294 2295 if (!mac_lomac_high_single(obj)) 2296 return (EACCES); 2297 2298 return (0); 2299} 2300 2301static int 2302mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, 2303 void *arg1, int arg2, struct sysctl_req *req) 2304{ 2305 struct mac_lomac *subj; 2306 2307 if (!mac_lomac_enabled) 2308 return (0); 2309 2310 subj = SLOT(cred->cr_label); 2311 2312 /* 2313 * Treat sysctl variables without CTLFLAG_ANYBODY flag as 2314 * lomac/high, but also require privilege to change them. 2315 */ 2316 if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) { 2317#ifdef notdef 2318 if (!mac_lomac_subject_dominate_high(subj)) 2319 return (EACCES); 2320#endif 2321 2322 if (mac_lomac_subject_privileged(subj)) 2323 return (EPERM); 2324 } 2325 2326 return (0); 2327} 2328 2329static int 2330mac_lomac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 2331 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 2332{ 2333 struct mac_lomac *subj, *obj; 2334 2335 if (!mac_lomac_enabled) 2336 return (0); 2337 2338 subj = SLOT(cred->cr_label); 2339 obj = SLOT(dlabel); 2340 2341 if (!mac_lomac_subject_dominate(subj, obj)) 2342 return (EACCES); 2343 if (obj->ml_flags & MAC_LOMAC_FLAG_AUX && 2344 !mac_lomac_dominate_element(&subj->ml_single, &obj->ml_auxsingle)) 2345 return (EACCES); 2346 2347 return (0); 2348} 2349 2350static int 2351mac_lomac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 2352 struct label *dlabel, struct vnode *vp, struct label *label, 2353 struct componentname *cnp) 2354{ 2355 struct mac_lomac *subj, *obj; 2356 2357 if (!mac_lomac_enabled) 2358 return (0); 2359 2360 subj = SLOT(cred->cr_label); 2361 obj = SLOT(dlabel); 2362 2363 if (!mac_lomac_subject_dominate(subj, obj)) 2364 return (EACCES); 2365 2366 obj = SLOT(label); 2367 2368 if (!mac_lomac_subject_dominate(subj, obj)) 2369 return (EACCES); 2370 2371 return (0); 2372} 2373 2374static int 2375mac_lomac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 2376 struct label *label, acl_type_t type) 2377{ 2378 struct mac_lomac *subj, *obj; 2379 2380 if (!mac_lomac_enabled) 2381 return (0); 2382 2383 subj = SLOT(cred->cr_label); 2384 obj = SLOT(label); 2385 2386 if (!mac_lomac_subject_dominate(subj, obj)) 2387 return (EACCES); 2388 2389 return (0); 2390} 2391 2392static int 2393mac_lomac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 2394 struct label *dlabel, struct vnode *vp, struct label *label, 2395 struct componentname *cnp) 2396{ 2397 struct mac_lomac *subj, *obj; 2398 2399 if (!mac_lomac_enabled) 2400 return (0); 2401 2402 subj = SLOT(cred->cr_label); 2403 obj = SLOT(dlabel); 2404 2405 if (!mac_lomac_subject_dominate(subj, obj)) 2406 return (EACCES); 2407 2408 obj = SLOT(label); 2409 2410 if (!mac_lomac_subject_dominate(subj, obj)) 2411 return (EACCES); 2412 2413 return (0); 2414} 2415 2416static int 2417mac_lomac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, 2418 struct label *label, int prot, int flags) 2419{ 2420 struct mac_lomac *subj, *obj; 2421 2422 /* 2423 * Rely on the use of open()-time protections to handle 2424 * non-revocation cases. 2425 */ 2426 if (!mac_lomac_enabled) 2427 return (0); 2428 2429 subj = SLOT(cred->cr_label); 2430 obj = SLOT(label); 2431 2432 if (((prot & VM_PROT_WRITE) != 0) && ((flags & MAP_SHARED) != 0)) { 2433 if (!mac_lomac_subject_dominate(subj, obj)) 2434 return (EACCES); 2435 } 2436 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { 2437 if (!mac_lomac_dominate_single(obj, subj)) 2438 return (maybe_demote(subj, obj, "mapping", "file", vp)); 2439 } 2440 2441 return (0); 2442} 2443 2444static void 2445mac_lomac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, 2446 struct label *label, /* XXX vm_prot_t */ int *prot) 2447{ 2448 struct mac_lomac *subj, *obj; 2449 2450 /* 2451 * Rely on the use of open()-time protections to handle 2452 * non-revocation cases. 2453 */ 2454 if (!mac_lomac_enabled || !revocation_enabled) 2455 return; 2456 2457 subj = SLOT(cred->cr_label); 2458 obj = SLOT(label); 2459 2460 if (!mac_lomac_subject_dominate(subj, obj)) 2461 *prot &= ~VM_PROT_WRITE; 2462} 2463 2464static int 2465mac_lomac_check_vnode_open(struct ucred *cred, struct vnode *vp, 2466 struct label *vnodelabel, int acc_mode) 2467{ 2468 struct mac_lomac *subj, *obj; 2469 2470 if (!mac_lomac_enabled) 2471 return (0); 2472 2473 subj = SLOT(cred->cr_label); 2474 obj = SLOT(vnodelabel); 2475 2476 /* XXX privilege override for admin? */ 2477 if (acc_mode & (VWRITE | VAPPEND | VADMIN)) { 2478 if (!mac_lomac_subject_dominate(subj, obj)) 2479 return (EACCES); 2480 } 2481 2482 return (0); 2483} 2484 2485static int 2486mac_lomac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 2487 struct vnode *vp, struct label *label) 2488{ 2489 struct mac_lomac *subj, *obj; 2490 2491 if (!mac_lomac_enabled || !revocation_enabled) 2492 return (0); 2493 2494 subj = SLOT(active_cred->cr_label); 2495 obj = SLOT(label); 2496 2497 if (!mac_lomac_dominate_single(obj, subj)) 2498 return (maybe_demote(subj, obj, "reading", "file", vp)); 2499 2500 return (0); 2501} 2502 2503static int 2504mac_lomac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 2505 struct label *vnodelabel, struct label *newlabel) 2506{ 2507 struct mac_lomac *old, *new, *subj; 2508 int error; 2509 2510 old = SLOT(vnodelabel); 2511 new = SLOT(newlabel); 2512 subj = SLOT(cred->cr_label); 2513 2514 /* 2515 * If there is a LOMAC label update for the vnode, it must be a 2516 * single label, with an optional explicit auxiliary single. 2517 */ 2518 error = lomac_atmostflags(new, 2519 MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); 2520 if (error) 2521 return (error); 2522 2523 /* 2524 * To perform a relabel of the vnode (LOMAC label or not), LOMAC must 2525 * authorize the relabel. 2526 */ 2527 if (!mac_lomac_single_in_range(old, subj)) 2528 return (EPERM); 2529 2530 /* 2531 * If the LOMAC label is to be changed, authorize as appropriate. 2532 */ 2533 if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { 2534 /* 2535 * To change the LOMAC label on a vnode, the new vnode label 2536 * must be in the subject range. 2537 */ 2538 if (!mac_lomac_single_in_range(new, subj)) 2539 return (EPERM); 2540 2541 /* 2542 * To change the LOMAC label on the vnode to be EQUAL, 2543 * the subject must have appropriate privilege. 2544 */ 2545 if (mac_lomac_contains_equal(new)) { 2546 error = mac_lomac_subject_privileged(subj); 2547 if (error) 2548 return (error); 2549 } 2550 } 2551 if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { 2552 /* 2553 * Fill in the missing parts from the previous label. 2554 */ 2555 if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) 2556 mac_lomac_copy_single(subj, new); 2557 2558 /* 2559 * To change the auxiliary LOMAC label on a vnode, the new 2560 * vnode label must be in the subject range. 2561 */ 2562 if (!mac_lomac_auxsingle_in_range(new, subj)) 2563 return (EPERM); 2564 2565 /* 2566 * To change the auxiliary LOMAC label on the vnode to be 2567 * EQUAL, the subject must have appropriate privilege. 2568 */ 2569 if (mac_lomac_contains_equal(new)) { 2570 error = mac_lomac_subject_privileged(subj); 2571 if (error) 2572 return (error); 2573 } 2574 } 2575 2576 return (0); 2577} 2578 2579static int 2580mac_lomac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 2581 struct label *dlabel, struct vnode *vp, struct label *label, 2582 struct componentname *cnp) 2583{ 2584 struct mac_lomac *subj, *obj; 2585 2586 if (!mac_lomac_enabled) 2587 return (0); 2588 2589 subj = SLOT(cred->cr_label); 2590 obj = SLOT(dlabel); 2591 2592 if (!mac_lomac_subject_dominate(subj, obj)) 2593 return (EACCES); 2594 2595 obj = SLOT(label); 2596 2597 if (!mac_lomac_subject_dominate(subj, obj)) 2598 return (EACCES); 2599 2600 return (0); 2601} 2602 2603static int 2604mac_lomac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 2605 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 2606 struct componentname *cnp) 2607{ 2608 struct mac_lomac *subj, *obj; 2609 2610 if (!mac_lomac_enabled) 2611 return (0); 2612 2613 subj = SLOT(cred->cr_label); 2614 obj = SLOT(dlabel); 2615 2616 if (!mac_lomac_subject_dominate(subj, obj)) 2617 return (EACCES); 2618 2619 if (vp != NULL) { 2620 obj = SLOT(label); 2621 2622 if (!mac_lomac_subject_dominate(subj, obj)) 2623 return (EACCES); 2624 } 2625 2626 return (0); 2627} 2628 2629static int 2630mac_lomac_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 2631 struct label *label) 2632{ 2633 struct mac_lomac *subj, *obj; 2634 2635 if (!mac_lomac_enabled) 2636 return (0); 2637 2638 subj = SLOT(cred->cr_label); 2639 obj = SLOT(label); 2640 2641 if (!mac_lomac_subject_dominate(subj, obj)) 2642 return (EACCES); 2643 2644 return (0); 2645} 2646 2647static int 2648mac_lomac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, 2649 struct label *label, acl_type_t type, struct acl *acl) 2650{ 2651 struct mac_lomac *subj, *obj; 2652 2653 if (!mac_lomac_enabled) 2654 return (0); 2655 2656 subj = SLOT(cred->cr_label); 2657 obj = SLOT(label); 2658 2659 if (!mac_lomac_subject_dominate(subj, obj)) 2660 return (EACCES); 2661 2662 return (0); 2663} 2664 2665static int 2666mac_lomac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 2667 struct label *vnodelabel, int attrnamespace, const char *name, 2668 struct uio *uio) 2669{ 2670 struct mac_lomac *subj, *obj; 2671 2672 if (!mac_lomac_enabled) 2673 return (0); 2674 2675 subj = SLOT(cred->cr_label); 2676 obj = SLOT(vnodelabel); 2677 2678 if (!mac_lomac_subject_dominate(subj, obj)) 2679 return (EACCES); 2680 2681 /* XXX: protect the MAC EA in a special way? */ 2682 2683 return (0); 2684} 2685 2686static int 2687mac_lomac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 2688 struct label *vnodelabel, u_long flags) 2689{ 2690 struct mac_lomac *subj, *obj; 2691 2692 if (!mac_lomac_enabled) 2693 return (0); 2694 2695 subj = SLOT(cred->cr_label); 2696 obj = SLOT(vnodelabel); 2697 2698 if (!mac_lomac_subject_dominate(subj, obj)) 2699 return (EACCES); 2700 2701 return (0); 2702} 2703 2704static int 2705mac_lomac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 2706 struct label *vnodelabel, mode_t mode) 2707{ 2708 struct mac_lomac *subj, *obj; 2709 2710 if (!mac_lomac_enabled) 2711 return (0); 2712 2713 subj = SLOT(cred->cr_label); 2714 obj = SLOT(vnodelabel); 2715 2716 if (!mac_lomac_subject_dominate(subj, obj)) 2717 return (EACCES); 2718 2719 return (0); 2720} 2721 2722static int 2723mac_lomac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 2724 struct label *vnodelabel, uid_t uid, gid_t gid) 2725{ 2726 struct mac_lomac *subj, *obj; 2727 2728 if (!mac_lomac_enabled) 2729 return (0); 2730 2731 subj = SLOT(cred->cr_label); 2732 obj = SLOT(vnodelabel); 2733 2734 if (!mac_lomac_subject_dominate(subj, obj)) 2735 return (EACCES); 2736 2737 return (0); 2738} 2739 2740static int 2741mac_lomac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 2742 struct label *vnodelabel, struct timespec atime, struct timespec mtime) 2743{ 2744 struct mac_lomac *subj, *obj; 2745 2746 if (!mac_lomac_enabled) 2747 return (0); 2748 2749 subj = SLOT(cred->cr_label); 2750 obj = SLOT(vnodelabel); 2751 2752 if (!mac_lomac_subject_dominate(subj, obj)) 2753 return (EACCES); 2754 2755 return (0); 2756} 2757 2758static int 2759mac_lomac_check_vnode_write(struct ucred *active_cred, 2760 struct ucred *file_cred, struct vnode *vp, struct label *label) 2761{ 2762 struct mac_lomac *subj, *obj; 2763 2764 if (!mac_lomac_enabled || !revocation_enabled) 2765 return (0); 2766 2767 subj = SLOT(active_cred->cr_label); 2768 obj = SLOT(label); 2769 2770 if (!mac_lomac_subject_dominate(subj, obj)) 2771 return (EACCES); 2772 2773 return (0); 2774} 2775 2776static void 2777mac_lomac_thread_userret(struct thread *td) 2778{ 2779 struct proc *p = td->td_proc; 2780 struct mac_lomac_proc *subj = PSLOT(p->p_label); 2781 struct ucred *newcred, *oldcred; 2782 int dodrop; 2783 2784 mtx_lock(&subj->mtx); 2785 if (subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) { 2786 dodrop = 0; 2787 mtx_unlock(&subj->mtx); 2788 newcred = crget(); 2789 /* 2790 * Prevent a lock order reversal in 2791 * mac_cred_mmapped_drop_perms; ideally, the other 2792 * user of subj->mtx wouldn't be holding Giant. 2793 */ 2794 mtx_lock(&Giant); 2795 PROC_LOCK(p); 2796 mtx_lock(&subj->mtx); 2797 /* 2798 * Check if we lost the race while allocating the cred. 2799 */ 2800 if ((subj->mac_lomac.ml_flags & MAC_LOMAC_FLAG_UPDATE) == 0) { 2801 crfree(newcred); 2802 goto out; 2803 } 2804 oldcred = p->p_ucred; 2805 crcopy(newcred, oldcred); 2806 crhold(newcred); 2807 mac_lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label)); 2808 p->p_ucred = newcred; 2809 crfree(oldcred); 2810 dodrop = 1; 2811 out: 2812 mtx_unlock(&subj->mtx); 2813 PROC_UNLOCK(p); 2814 if (dodrop) 2815 mac_cred_mmapped_drop_perms(curthread, newcred); 2816 mtx_unlock(&Giant); 2817 } else { 2818 mtx_unlock(&subj->mtx); 2819 } 2820} 2821 2822static struct mac_policy_ops mac_lomac_ops = 2823{ 2824 .mpo_init = mac_lomac_init, 2825 .mpo_init_bpfdesc_label = mac_lomac_init_label, 2826 .mpo_init_cred_label = mac_lomac_init_label, 2827 .mpo_init_devfsdirent_label = mac_lomac_init_label, 2828 .mpo_init_ifnet_label = mac_lomac_init_label, 2829 .mpo_init_syncache_label = mac_lomac_init_label_waitcheck, 2830 .mpo_init_inpcb_label = mac_lomac_init_label_waitcheck, 2831 .mpo_init_ipq_label = mac_lomac_init_label_waitcheck, 2832 .mpo_init_mbuf_label = mac_lomac_init_label_waitcheck, 2833 .mpo_init_mount_label = mac_lomac_init_label, 2834 .mpo_init_pipe_label = mac_lomac_init_label, 2835 .mpo_init_proc_label = mac_lomac_init_proc_label, 2836 .mpo_init_socket_label = mac_lomac_init_label_waitcheck, 2837 .mpo_init_socket_peer_label = mac_lomac_init_label_waitcheck, 2838 .mpo_init_vnode_label = mac_lomac_init_label, 2839 .mpo_init_syncache_from_inpcb = mac_lomac_init_syncache_from_inpcb, 2840 .mpo_destroy_bpfdesc_label = mac_lomac_destroy_label, 2841 .mpo_destroy_cred_label = mac_lomac_destroy_label, 2842 .mpo_destroy_devfsdirent_label = mac_lomac_destroy_label, 2843 .mpo_destroy_ifnet_label = mac_lomac_destroy_label, 2844 .mpo_destroy_inpcb_label = mac_lomac_destroy_label, 2845 .mpo_destroy_ipq_label = mac_lomac_destroy_label, 2846 .mpo_destroy_mbuf_label = mac_lomac_destroy_label, 2847 .mpo_destroy_mount_label = mac_lomac_destroy_label, 2848 .mpo_destroy_pipe_label = mac_lomac_destroy_label, 2849 .mpo_destroy_proc_label = mac_lomac_destroy_proc_label, 2850 .mpo_destroy_syncache_label = mac_lomac_destroy_label, 2851 .mpo_destroy_socket_label = mac_lomac_destroy_label, 2852 .mpo_destroy_socket_peer_label = mac_lomac_destroy_label, 2853 .mpo_destroy_vnode_label = mac_lomac_destroy_label, 2854 .mpo_copy_cred_label = mac_lomac_copy_label, 2855 .mpo_copy_ifnet_label = mac_lomac_copy_label, 2856 .mpo_copy_mbuf_label = mac_lomac_copy_label, 2857 .mpo_copy_pipe_label = mac_lomac_copy_label, 2858 .mpo_copy_socket_label = mac_lomac_copy_label, 2859 .mpo_copy_vnode_label = mac_lomac_copy_label, 2860 .mpo_externalize_cred_label = mac_lomac_externalize_label, 2861 .mpo_externalize_ifnet_label = mac_lomac_externalize_label, 2862 .mpo_externalize_pipe_label = mac_lomac_externalize_label, 2863 .mpo_externalize_socket_label = mac_lomac_externalize_label, 2864 .mpo_externalize_socket_peer_label = mac_lomac_externalize_label, 2865 .mpo_externalize_vnode_label = mac_lomac_externalize_label, 2866 .mpo_internalize_cred_label = mac_lomac_internalize_label, 2867 .mpo_internalize_ifnet_label = mac_lomac_internalize_label, 2868 .mpo_internalize_pipe_label = mac_lomac_internalize_label, 2869 .mpo_internalize_socket_label = mac_lomac_internalize_label, 2870 .mpo_internalize_vnode_label = mac_lomac_internalize_label, 2871 .mpo_create_devfs_device = mac_lomac_create_devfs_device, 2872 .mpo_create_devfs_directory = mac_lomac_create_devfs_directory, 2873 .mpo_create_devfs_symlink = mac_lomac_create_devfs_symlink, 2874 .mpo_create_mount = mac_lomac_create_mount, 2875 .mpo_relabel_vnode = mac_lomac_relabel_vnode, 2876 .mpo_update_devfsdirent = mac_lomac_update_devfsdirent, 2877 .mpo_associate_vnode_devfs = mac_lomac_associate_vnode_devfs, 2878 .mpo_associate_vnode_extattr = mac_lomac_associate_vnode_extattr, 2879 .mpo_associate_vnode_singlelabel = 2880 mac_lomac_associate_vnode_singlelabel, 2881 .mpo_create_vnode_extattr = mac_lomac_create_vnode_extattr, 2882 .mpo_setlabel_vnode_extattr = mac_lomac_setlabel_vnode_extattr, 2883 .mpo_create_mbuf_from_socket = mac_lomac_create_mbuf_from_socket, 2884 .mpo_create_mbuf_from_syncache = mac_lomac_create_mbuf_from_syncache, 2885 .mpo_create_pipe = mac_lomac_create_pipe, 2886 .mpo_create_socket = mac_lomac_create_socket, 2887 .mpo_create_socket_from_socket = mac_lomac_create_socket_from_socket, 2888 .mpo_relabel_pipe = mac_lomac_relabel_pipe, 2889 .mpo_relabel_socket = mac_lomac_relabel_socket, 2890 .mpo_set_socket_peer_from_mbuf = mac_lomac_set_socket_peer_from_mbuf, 2891 .mpo_set_socket_peer_from_socket = 2892 mac_lomac_set_socket_peer_from_socket, 2893 .mpo_create_bpfdesc = mac_lomac_create_bpfdesc, 2894 .mpo_create_datagram_from_ipq = mac_lomac_create_datagram_from_ipq, 2895 .mpo_create_fragment = mac_lomac_create_fragment, 2896 .mpo_create_ifnet = mac_lomac_create_ifnet, 2897 .mpo_create_inpcb_from_socket = mac_lomac_create_inpcb_from_socket, 2898 .mpo_create_ipq = mac_lomac_create_ipq, 2899 .mpo_create_mbuf_from_inpcb = mac_lomac_create_mbuf_from_inpcb, 2900 .mpo_create_mbuf_linklayer = mac_lomac_create_mbuf_linklayer, 2901 .mpo_create_mbuf_from_bpfdesc = mac_lomac_create_mbuf_from_bpfdesc, 2902 .mpo_create_mbuf_from_ifnet = mac_lomac_create_mbuf_from_ifnet, 2903 .mpo_create_mbuf_multicast_encap = 2904 mac_lomac_create_mbuf_multicast_encap, 2905 .mpo_create_mbuf_netlayer = mac_lomac_create_mbuf_netlayer, 2906 .mpo_fragment_match = mac_lomac_fragment_match, 2907 .mpo_relabel_ifnet = mac_lomac_relabel_ifnet, 2908 .mpo_update_ipq = mac_lomac_update_ipq, 2909 .mpo_inpcb_sosetlabel = mac_lomac_inpcb_sosetlabel, 2910 .mpo_execve_transition = mac_lomac_execve_transition, 2911 .mpo_execve_will_transition = mac_lomac_execve_will_transition, 2912 .mpo_create_proc0 = mac_lomac_create_proc0, 2913 .mpo_create_proc1 = mac_lomac_create_proc1, 2914 .mpo_relabel_cred = mac_lomac_relabel_cred, 2915 .mpo_check_bpfdesc_receive = mac_lomac_check_bpfdesc_receive, 2916 .mpo_check_cred_relabel = mac_lomac_check_cred_relabel, 2917 .mpo_check_cred_visible = mac_lomac_check_cred_visible, 2918 .mpo_check_ifnet_relabel = mac_lomac_check_ifnet_relabel, 2919 .mpo_check_ifnet_transmit = mac_lomac_check_ifnet_transmit, 2920 .mpo_check_inpcb_deliver = mac_lomac_check_inpcb_deliver, 2921 .mpo_check_kld_load = mac_lomac_check_kld_load, 2922 .mpo_check_pipe_ioctl = mac_lomac_check_pipe_ioctl, 2923 .mpo_check_pipe_read = mac_lomac_check_pipe_read, 2924 .mpo_check_pipe_relabel = mac_lomac_check_pipe_relabel, 2925 .mpo_check_pipe_write = mac_lomac_check_pipe_write, 2926 .mpo_check_proc_debug = mac_lomac_check_proc_debug, 2927 .mpo_check_proc_sched = mac_lomac_check_proc_sched, 2928 .mpo_check_proc_signal = mac_lomac_check_proc_signal, 2929 .mpo_check_socket_deliver = mac_lomac_check_socket_deliver, 2930 .mpo_check_socket_relabel = mac_lomac_check_socket_relabel, 2931 .mpo_check_socket_visible = mac_lomac_check_socket_visible, 2932 .mpo_check_system_acct = mac_lomac_check_system_acct, 2933 .mpo_check_system_auditctl = mac_lomac_check_system_auditctl, 2934 .mpo_check_system_swapoff = mac_lomac_check_system_swapoff, 2935 .mpo_check_system_swapon = mac_lomac_check_system_swapon, 2936 .mpo_check_system_sysctl = mac_lomac_check_system_sysctl, 2937 .mpo_check_vnode_access = mac_lomac_check_vnode_open, 2938 .mpo_check_vnode_create = mac_lomac_check_vnode_create, 2939 .mpo_check_vnode_delete = mac_lomac_check_vnode_delete, 2940 .mpo_check_vnode_deleteacl = mac_lomac_check_vnode_deleteacl, 2941 .mpo_check_vnode_link = mac_lomac_check_vnode_link, 2942 .mpo_check_vnode_mmap = mac_lomac_check_vnode_mmap, 2943 .mpo_check_vnode_mmap_downgrade = mac_lomac_check_vnode_mmap_downgrade, 2944 .mpo_check_vnode_open = mac_lomac_check_vnode_open, 2945 .mpo_check_vnode_read = mac_lomac_check_vnode_read, 2946 .mpo_check_vnode_relabel = mac_lomac_check_vnode_relabel, 2947 .mpo_check_vnode_rename_from = mac_lomac_check_vnode_rename_from, 2948 .mpo_check_vnode_rename_to = mac_lomac_check_vnode_rename_to, 2949 .mpo_check_vnode_revoke = mac_lomac_check_vnode_revoke, 2950 .mpo_check_vnode_setacl = mac_lomac_check_vnode_setacl, 2951 .mpo_check_vnode_setextattr = mac_lomac_check_vnode_setextattr, 2952 .mpo_check_vnode_setflags = mac_lomac_check_vnode_setflags, 2953 .mpo_check_vnode_setmode = mac_lomac_check_vnode_setmode, 2954 .mpo_check_vnode_setowner = mac_lomac_check_vnode_setowner, 2955 .mpo_check_vnode_setutimes = mac_lomac_check_vnode_setutimes, 2956 .mpo_check_vnode_write = mac_lomac_check_vnode_write, 2957 .mpo_thread_userret = mac_lomac_thread_userret, 2958 .mpo_create_mbuf_from_firewall = mac_lomac_create_mbuf_from_firewall, 2959 .mpo_priv_check = mac_lomac_priv_check, 2960}; 2961 2962MAC_POLICY_SET(&mac_lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC", 2963 MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, 2964 &mac_lomac_slot); 2965