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