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