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