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