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