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