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