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