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