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