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