1 /*- 2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3 * Copyright (c) 2001 Ilmar S. Habibulin 4 * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 5 * All rights reserved. 6 * 7 * This software was developed by Robert Watson and Ilmar Habibulin for the 8 * TrustedBSD Project. 9 * 10 * This software was developed for the FreeBSD Project in part by Network 11 * Associates Laboratories, the Security Research Division of Network 12 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 13 * as part of the DARPA CHATS research program. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * $FreeBSD$ 37 */ 38 /* 39 * Developed by the TrustedBSD Project. 40 * 41 * Framework for extensible kernel access control. Kernel and userland 42 * interface to the framework, policy registration and composition. 43 */ 44 45 #include "opt_mac.h" 46 #include "opt_devfs.h" 47 48 #include <sys/param.h> 49 #include <sys/condvar.h> 50 #include <sys/extattr.h> 51 #include <sys/imgact.h> 52 #include <sys/kernel.h> 53 #include <sys/lock.h> 54 #include <sys/malloc.h> 55 #include <sys/mutex.h> 56 #include <sys/mac.h> 57 #include <sys/module.h> 58 #include <sys/proc.h> 59 #include <sys/systm.h> 60 #include <sys/sysproto.h> 61 #include <sys/sysent.h> 62 #include <sys/vnode.h> 63 #include <sys/mount.h> 64 #include <sys/file.h> 65 #include <sys/namei.h> 66 #include <sys/socket.h> 67 #include <sys/pipe.h> 68 #include <sys/socketvar.h> 69 #include <sys/sysctl.h> 70 71 #include <vm/vm.h> 72 #include <vm/pmap.h> 73 #include <vm/vm_map.h> 74 #include <vm/vm_object.h> 75 76 #include <sys/mac_policy.h> 77 78 #include <fs/devfs/devfs.h> 79 80 #include <net/bpfdesc.h> 81 #include <net/if.h> 82 #include <net/if_var.h> 83 84 #include <netinet/in.h> 85 #include <netinet/ip_var.h> 86 87 #ifdef MAC 88 89 /* 90 * Declare that the kernel provides MAC support, version 1. This permits 91 * modules to refuse to be loaded if the necessary support isn't present, 92 * even if it's pre-boot. 93 */ 94 MODULE_VERSION(kernel_mac_support, 1); 95 96 SYSCTL_DECL(_security); 97 98 SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, 99 "TrustedBSD MAC policy controls"); 100 101 #if MAC_MAX_POLICIES > 32 102 #error "MAC_MAX_POLICIES too large" 103 #endif 104 105 static unsigned int mac_max_policies = MAC_MAX_POLICIES; 106 static unsigned int mac_policy_offsets_free = (1 << MAC_MAX_POLICIES) - 1; 107 SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD, 108 &mac_max_policies, 0, ""); 109 110 /* 111 * Has the kernel started generating labeled objects yet? All read/write 112 * access to this variable is serialized during the boot process. Following 113 * the end of serialization, we don't update this flag; no locking. 114 */ 115 static int mac_late = 0; 116 117 /* 118 * Warn about EA transactions only the first time they happen. 119 * Weak coherency, no locking. 120 */ 121 static int ea_warn_once = 0; 122 123 static int mac_enforce_fs = 1; 124 SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW, 125 &mac_enforce_fs, 0, "Enforce MAC policy on file system objects"); 126 TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs); 127 128 static int mac_enforce_kld = 1; 129 SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW, 130 &mac_enforce_kld, 0, "Enforce MAC policy on kld operations"); 131 TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld); 132 133 static int mac_enforce_network = 1; 134 SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 135 &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 136 TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 137 138 static int mac_enforce_pipe = 1; 139 SYSCTL_INT(_security_mac, OID_AUTO, enforce_pipe, CTLFLAG_RW, 140 &mac_enforce_pipe, 0, "Enforce MAC policy on pipe operations"); 141 TUNABLE_INT("security.mac.enforce_pipe", &mac_enforce_pipe); 142 143 static int mac_enforce_process = 1; 144 SYSCTL_INT(_security_mac, OID_AUTO, enforce_process, CTLFLAG_RW, 145 &mac_enforce_process, 0, "Enforce MAC policy on inter-process operations"); 146 TUNABLE_INT("security.mac.enforce_process", &mac_enforce_process); 147 148 static int mac_enforce_socket = 1; 149 SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 150 &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 151 TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 152 153 static int mac_enforce_system = 1; 154 SYSCTL_INT(_security_mac, OID_AUTO, enforce_system, CTLFLAG_RW, 155 &mac_enforce_system, 0, "Enforce MAC policy on system operations"); 156 TUNABLE_INT("security.mac.enforce_system", &mac_enforce_system); 157 158 static int mac_enforce_vm = 1; 159 SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW, 160 &mac_enforce_vm, 0, "Enforce MAC policy on vm operations"); 161 TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm); 162 163 static int mac_mmap_revocation = 1; 164 SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW, 165 &mac_mmap_revocation, 0, "Revoke mmap access to files on subject " 166 "relabel"); 167 static int mac_mmap_revocation_via_cow = 0; 168 SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation_via_cow, CTLFLAG_RW, 169 &mac_mmap_revocation_via_cow, 0, "Revoke mmap access to files via " 170 "copy-on-write semantics, or by removing all write access"); 171 172 #ifdef MAC_DEBUG 173 SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, 174 "TrustedBSD MAC debug info"); 175 176 static int mac_debug_label_fallback = 0; 177 SYSCTL_INT(_security_mac_debug, OID_AUTO, label_fallback, CTLFLAG_RW, 178 &mac_debug_label_fallback, 0, "Filesystems should fall back to fs label" 179 "when label is corrupted."); 180 TUNABLE_INT("security.mac.debug_label_fallback", 181 &mac_debug_label_fallback); 182 183 SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, 184 "TrustedBSD MAC object counters"); 185 186 static unsigned int nmacmbufs, nmaccreds, nmacifnets, nmacbpfdescs, 187 nmacsockets, nmacmounts, nmactemp, nmacvnodes, nmacdevfsdirents, 188 nmacipqs, nmacpipes, nmacprocs; 189 190 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 191 &nmacmbufs, 0, "number of mbufs in use"); 192 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, creds, CTLFLAG_RD, 193 &nmaccreds, 0, "number of ucreds in use"); 194 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 195 &nmacifnets, 0, "number of ifnets in use"); 196 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 197 &nmacipqs, 0, "number of ipqs in use"); 198 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 199 &nmacbpfdescs, 0, "number of bpfdescs in use"); 200 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 201 &nmacsockets, 0, "number of sockets in use"); 202 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, pipes, CTLFLAG_RD, 203 &nmacpipes, 0, "number of pipes in use"); 204 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, procs, CTLFLAG_RD, 205 &nmacprocs, 0, "number of procs in use"); 206 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mounts, CTLFLAG_RD, 207 &nmacmounts, 0, "number of mounts in use"); 208 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, 209 &nmactemp, 0, "number of temporary labels in use"); 210 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, vnodes, CTLFLAG_RD, 211 &nmacvnodes, 0, "number of vnodes in use"); 212 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD, 213 &nmacdevfsdirents, 0, "number of devfs dirents inuse"); 214 #endif 215 216 static int error_select(int error1, int error2); 217 static int mac_policy_register(struct mac_policy_conf *mpc); 218 static int mac_policy_unregister(struct mac_policy_conf *mpc); 219 220 static void mac_check_vnode_mmap_downgrade(struct ucred *cred, 221 struct vnode *vp, int *prot); 222 static void mac_cred_mmapped_drop_perms_recurse(struct thread *td, 223 struct ucred *cred, struct vm_map *map); 224 225 static void mac_destroy_socket_label(struct label *label); 226 227 static int mac_setlabel_vnode_extattr(struct ucred *cred, 228 struct vnode *vp, struct label *intlabel); 229 230 MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes"); 231 MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); 232 233 /* 234 * mac_policy_list stores the list of active policies. A busy count is 235 * maintained for the list, stored in mac_policy_busy. The busy count 236 * is protected by mac_policy_list_lock; the list may be modified only 237 * while the busy count is 0, requiring that the lock be held to 238 * prevent new references to the list from being acquired. For almost 239 * all operations, incrementing the busy count is sufficient to 240 * guarantee consistency, as the list cannot be modified while the 241 * busy count is elevated. For a few special operations involving a 242 * change to the list of active policies, the lock itself must be held. 243 * A condition variable, mac_policy_list_not_busy, is used to signal 244 * potential exclusive consumers that they should try to acquire the 245 * lock if a first attempt at exclusive access fails. 246 */ 247 static struct mtx mac_policy_list_lock; 248 static struct cv mac_policy_list_not_busy; 249 static LIST_HEAD(, mac_policy_conf) mac_policy_list; 250 static int mac_policy_list_busy; 251 252 #define MAC_POLICY_LIST_LOCKINIT() do { \ 253 mtx_init(&mac_policy_list_lock, "mac_policy_list_lock", NULL, \ 254 MTX_DEF); \ 255 cv_init(&mac_policy_list_not_busy, "mac_policy_list_not_busy"); \ 256 } while (0) 257 258 #define MAC_POLICY_LIST_LOCK() do { \ 259 mtx_lock(&mac_policy_list_lock); \ 260 } while (0) 261 262 #define MAC_POLICY_LIST_UNLOCK() do { \ 263 mtx_unlock(&mac_policy_list_lock); \ 264 } while (0) 265 266 /* 267 * We manually invoke WITNESS_SLEEP() to allow Witness to generate 268 * warnings even if we don't end up ever triggering the wait at 269 * run-time. The consumer of the exclusive interface must not hold 270 * any locks (other than potentially Giant) since we may sleep for 271 * long (potentially indefinite) periods of time waiting for the 272 * framework to become quiescent so that a policy list change may 273 * be made. 274 */ 275 #define MAC_POLICY_LIST_EXCLUSIVE() do { \ 276 WITNESS_SLEEP(1, NULL); \ 277 mtx_lock(&mac_policy_list_lock); \ 278 while (mac_policy_list_busy != 0) \ 279 cv_wait(&mac_policy_list_not_busy, \ 280 &mac_policy_list_lock); \ 281 } while (0) 282 283 #define MAC_POLICY_LIST_BUSY() do { \ 284 MAC_POLICY_LIST_LOCK(); \ 285 mac_policy_list_busy++; \ 286 MAC_POLICY_LIST_UNLOCK(); \ 287 } while (0) 288 289 #define MAC_POLICY_LIST_UNBUSY() do { \ 290 MAC_POLICY_LIST_LOCK(); \ 291 mac_policy_list_busy--; \ 292 KASSERT(mac_policy_list_busy >= 0, ("MAC_POLICY_LIST_LOCK")); \ 293 if (mac_policy_list_busy == 0) \ 294 cv_signal(&mac_policy_list_not_busy); \ 295 MAC_POLICY_LIST_UNLOCK(); \ 296 } while (0) 297 298 /* 299 * MAC_CHECK performs the designated check by walking the policy 300 * module list and checking with each as to how it feels about the 301 * request. Note that it returns its value via 'error' in the scope 302 * of the caller. 303 */ 304 #define MAC_CHECK(check, args...) do { \ 305 struct mac_policy_conf *mpc; \ 306 \ 307 error = 0; \ 308 MAC_POLICY_LIST_BUSY(); \ 309 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 310 if (mpc->mpc_ops->mpo_ ## check != NULL) \ 311 error = error_select( \ 312 mpc->mpc_ops->mpo_ ## check (args), \ 313 error); \ 314 } \ 315 MAC_POLICY_LIST_UNBUSY(); \ 316 } while (0) 317 318 /* 319 * MAC_BOOLEAN performs the designated boolean composition by walking 320 * the module list, invoking each instance of the operation, and 321 * combining the results using the passed C operator. Note that it 322 * returns its value via 'result' in the scope of the caller, which 323 * should be initialized by the caller in a meaningful way to get 324 * a meaningful result. 325 */ 326 #define MAC_BOOLEAN(operation, composition, args...) do { \ 327 struct mac_policy_conf *mpc; \ 328 \ 329 MAC_POLICY_LIST_BUSY(); \ 330 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 331 if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 332 result = result composition \ 333 mpc->mpc_ops->mpo_ ## operation (args); \ 334 } \ 335 MAC_POLICY_LIST_UNBUSY(); \ 336 } while (0) 337 338 #define MAC_EXTERNALIZE(type, label, elementlist, outbuf, \ 339 outbuflen) do { \ 340 char *curptr, *curptr_start, *element_name, *element_temp; \ 341 size_t left, left_start, len; \ 342 int claimed, first, first_start, ignorenotfound; \ 343 \ 344 error = 0; \ 345 element_temp = elementlist; \ 346 curptr = outbuf; \ 347 curptr[0] = '\0'; \ 348 left = outbuflen; \ 349 first = 1; \ 350 while ((element_name = strsep(&element_temp, ",")) != NULL) { \ 351 curptr_start = curptr; \ 352 left_start = left; \ 353 first_start = first; \ 354 if (element_name[0] == '?') { \ 355 element_name++; \ 356 ignorenotfound = 1; \ 357 } else \ 358 ignorenotfound = 0; \ 359 claimed = 0; \ 360 if (first) { \ 361 len = snprintf(curptr, left, "%s/", \ 362 element_name); \ 363 first = 0; \ 364 } else \ 365 len = snprintf(curptr, left, ",%s/", \ 366 element_name); \ 367 if (len >= left) { \ 368 error = EINVAL; /* XXXMAC: E2BIG */ \ 369 break; \ 370 } \ 371 curptr += len; \ 372 left -= len; \ 373 \ 374 MAC_CHECK(externalize_ ## type, label, element_name, \ 375 curptr, left, &len, &claimed); \ 376 if (error) \ 377 break; \ 378 if (claimed == 1) { \ 379 if (len >= outbuflen) { \ 380 error = EINVAL; /* XXXMAC: E2BIG */ \ 381 break; \ 382 } \ 383 curptr += len; \ 384 left -= len; \ 385 } else if (claimed == 0 && ignorenotfound) { \ 386 /* \ 387 * Revert addition of the label element \ 388 * name. \ 389 */ \ 390 curptr = curptr_start; \ 391 *curptr = '\0'; \ 392 left = left_start; \ 393 first = first_start; \ 394 } else { \ 395 error = EINVAL; /* XXXMAC: ENOLABEL */ \ 396 break; \ 397 } \ 398 } \ 399 } while (0) 400 401 #define MAC_INTERNALIZE(type, label, instring) do { \ 402 char *element, *element_name, *element_data; \ 403 int claimed; \ 404 \ 405 error = 0; \ 406 element = instring; \ 407 while ((element_name = strsep(&element, ",")) != NULL) { \ 408 element_data = element_name; \ 409 element_name = strsep(&element_data, "/"); \ 410 if (element_data == NULL) { \ 411 error = EINVAL; \ 412 break; \ 413 } \ 414 claimed = 0; \ 415 MAC_CHECK(internalize_ ## type, label, element_name, \ 416 element_data, &claimed); \ 417 if (error) \ 418 break; \ 419 if (claimed != 1) { \ 420 /* XXXMAC: Another error here? */ \ 421 error = EINVAL; \ 422 break; \ 423 } \ 424 } \ 425 } while (0) 426 427 /* 428 * MAC_PERFORM performs the designated operation by walking the policy 429 * module list and invoking that operation for each policy. 430 */ 431 #define MAC_PERFORM(operation, args...) do { \ 432 struct mac_policy_conf *mpc; \ 433 \ 434 MAC_POLICY_LIST_BUSY(); \ 435 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \ 436 if (mpc->mpc_ops->mpo_ ## operation != NULL) \ 437 mpc->mpc_ops->mpo_ ## operation (args); \ 438 } \ 439 MAC_POLICY_LIST_UNBUSY(); \ 440 } while (0) 441 442 /* 443 * Initialize the MAC subsystem, including appropriate SMP locks. 444 */ 445 static void 446 mac_init(void) 447 { 448 449 LIST_INIT(&mac_policy_list); 450 MAC_POLICY_LIST_LOCKINIT(); 451 } 452 453 /* 454 * For the purposes of modules that want to know if they were loaded 455 * "early", set the mac_late flag once we've processed modules either 456 * linked into the kernel, or loaded before the kernel startup. 457 */ 458 static void 459 mac_late_init(void) 460 { 461 462 mac_late = 1; 463 } 464 465 /* 466 * Allow MAC policy modules to register during boot, etc. 467 */ 468 int 469 mac_policy_modevent(module_t mod, int type, void *data) 470 { 471 struct mac_policy_conf *mpc; 472 int error; 473 474 error = 0; 475 mpc = (struct mac_policy_conf *) data; 476 477 switch (type) { 478 case MOD_LOAD: 479 if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && 480 mac_late) { 481 printf("mac_policy_modevent: can't load %s policy " 482 "after booting\n", mpc->mpc_name); 483 error = EBUSY; 484 break; 485 } 486 error = mac_policy_register(mpc); 487 break; 488 case MOD_UNLOAD: 489 /* Don't unregister the module if it was never registered. */ 490 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) 491 != 0) 492 error = mac_policy_unregister(mpc); 493 else 494 error = 0; 495 break; 496 default: 497 break; 498 } 499 500 return (error); 501 } 502 503 static int 504 mac_policy_register(struct mac_policy_conf *mpc) 505 { 506 struct mac_policy_conf *tmpc; 507 int slot; 508 509 MAC_POLICY_LIST_EXCLUSIVE(); 510 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { 511 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { 512 MAC_POLICY_LIST_UNLOCK(); 513 return (EEXIST); 514 } 515 } 516 if (mpc->mpc_field_off != NULL) { 517 slot = ffs(mac_policy_offsets_free); 518 if (slot == 0) { 519 MAC_POLICY_LIST_UNLOCK(); 520 return (ENOMEM); 521 } 522 slot--; 523 mac_policy_offsets_free &= ~(1 << slot); 524 *mpc->mpc_field_off = slot; 525 } 526 mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; 527 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); 528 529 /* Per-policy initialization. */ 530 if (mpc->mpc_ops->mpo_init != NULL) 531 (*(mpc->mpc_ops->mpo_init))(mpc); 532 MAC_POLICY_LIST_UNLOCK(); 533 534 printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, 535 mpc->mpc_name); 536 537 return (0); 538 } 539 540 static int 541 mac_policy_unregister(struct mac_policy_conf *mpc) 542 { 543 544 /* 545 * If we fail the load, we may get a request to unload. Check 546 * to see if we did the run-time registration, and if not, 547 * silently succeed. 548 */ 549 MAC_POLICY_LIST_EXCLUSIVE(); 550 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { 551 MAC_POLICY_LIST_UNLOCK(); 552 return (0); 553 } 554 #if 0 555 /* 556 * Don't allow unloading modules with private data. 557 */ 558 if (mpc->mpc_field_off != NULL) { 559 MAC_POLICY_LIST_UNLOCK(); 560 return (EBUSY); 561 } 562 #endif 563 /* 564 * Only allow the unload to proceed if the module is unloadable 565 * by its own definition. 566 */ 567 if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { 568 MAC_POLICY_LIST_UNLOCK(); 569 return (EBUSY); 570 } 571 if (mpc->mpc_ops->mpo_destroy != NULL) 572 (*(mpc->mpc_ops->mpo_destroy))(mpc); 573 574 LIST_REMOVE(mpc, mpc_list); 575 mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; 576 577 MAC_POLICY_LIST_UNLOCK(); 578 579 printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, 580 mpc->mpc_name); 581 582 return (0); 583 } 584 585 /* 586 * Define an error value precedence, and given two arguments, selects the 587 * value with the higher precedence. 588 */ 589 static int 590 error_select(int error1, int error2) 591 { 592 593 /* Certain decision-making errors take top priority. */ 594 if (error1 == EDEADLK || error2 == EDEADLK) 595 return (EDEADLK); 596 597 /* Invalid arguments should be reported where possible. */ 598 if (error1 == EINVAL || error2 == EINVAL) 599 return (EINVAL); 600 601 /* Precedence goes to "visibility", with both process and file. */ 602 if (error1 == ESRCH || error2 == ESRCH) 603 return (ESRCH); 604 605 if (error1 == ENOENT || error2 == ENOENT) 606 return (ENOENT); 607 608 /* Precedence goes to DAC/MAC protections. */ 609 if (error1 == EACCES || error2 == EACCES) 610 return (EACCES); 611 612 /* Precedence goes to privilege. */ 613 if (error1 == EPERM || error2 == EPERM) 614 return (EPERM); 615 616 /* Precedence goes to error over success; otherwise, arbitrary. */ 617 if (error1 != 0) 618 return (error1); 619 return (error2); 620 } 621 622 static void 623 mac_init_label(struct label *label) 624 { 625 626 bzero(label, sizeof(*label)); 627 label->l_flags = MAC_FLAG_INITIALIZED; 628 } 629 630 static void 631 mac_destroy_label(struct label *label) 632 { 633 634 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, 635 ("destroying uninitialized label")); 636 637 bzero(label, sizeof(*label)); 638 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ 639 } 640 641 void 642 mac_init_bpfdesc(struct bpf_d *bpf_d) 643 { 644 645 mac_init_label(&bpf_d->bd_label); 646 MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label); 647 #ifdef MAC_DEBUG 648 atomic_add_int(&nmacbpfdescs, 1); 649 #endif 650 } 651 652 static void 653 mac_init_cred_label(struct label *label) 654 { 655 656 mac_init_label(label); 657 MAC_PERFORM(init_cred_label, label); 658 #ifdef MAC_DEBUG 659 atomic_add_int(&nmaccreds, 1); 660 #endif 661 } 662 663 void 664 mac_init_cred(struct ucred *cred) 665 { 666 667 mac_init_cred_label(&cred->cr_label); 668 } 669 670 void 671 mac_init_devfsdirent(struct devfs_dirent *de) 672 { 673 674 mac_init_label(&de->de_label); 675 MAC_PERFORM(init_devfsdirent_label, &de->de_label); 676 #ifdef MAC_DEBUG 677 atomic_add_int(&nmacdevfsdirents, 1); 678 #endif 679 } 680 681 static void 682 mac_init_ifnet_label(struct label *label) 683 { 684 685 mac_init_label(label); 686 MAC_PERFORM(init_ifnet_label, label); 687 #ifdef MAC_DEBUG 688 atomic_add_int(&nmacifnets, 1); 689 #endif 690 } 691 692 void 693 mac_init_ifnet(struct ifnet *ifp) 694 { 695 696 mac_init_ifnet_label(&ifp->if_label); 697 } 698 699 void 700 mac_init_ipq(struct ipq *ipq) 701 { 702 703 mac_init_label(&ipq->ipq_label); 704 MAC_PERFORM(init_ipq_label, &ipq->ipq_label); 705 #ifdef MAC_DEBUG 706 atomic_add_int(&nmacipqs, 1); 707 #endif 708 } 709 710 int 711 mac_init_mbuf(struct mbuf *m, int flag) 712 { 713 int error; 714 715 KASSERT(m->m_flags & M_PKTHDR, ("mac_init_mbuf on non-header mbuf")); 716 717 mac_init_label(&m->m_pkthdr.label); 718 719 MAC_CHECK(init_mbuf_label, &m->m_pkthdr.label, flag); 720 if (error) { 721 MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 722 mac_destroy_label(&m->m_pkthdr.label); 723 } 724 725 #ifdef MAC_DEBUG 726 if (error == 0) 727 atomic_add_int(&nmacmbufs, 1); 728 #endif 729 return (error); 730 } 731 732 void 733 mac_init_mount(struct mount *mp) 734 { 735 736 mac_init_label(&mp->mnt_mntlabel); 737 mac_init_label(&mp->mnt_fslabel); 738 MAC_PERFORM(init_mount_label, &mp->mnt_mntlabel); 739 MAC_PERFORM(init_mount_fs_label, &mp->mnt_fslabel); 740 #ifdef MAC_DEBUG 741 atomic_add_int(&nmacmounts, 1); 742 #endif 743 } 744 745 static void 746 mac_init_pipe_label(struct label *label) 747 { 748 749 mac_init_label(label); 750 MAC_PERFORM(init_pipe_label, label); 751 #ifdef MAC_DEBUG 752 atomic_add_int(&nmacpipes, 1); 753 #endif 754 } 755 756 void 757 mac_init_pipe(struct pipe *pipe) 758 { 759 struct label *label; 760 761 label = malloc(sizeof(struct label), M_MACPIPELABEL, M_ZERO|M_WAITOK); 762 pipe->pipe_label = label; 763 pipe->pipe_peer->pipe_label = label; 764 mac_init_pipe_label(label); 765 } 766 767 void 768 mac_init_proc(struct proc *p) 769 { 770 771 mac_init_label(&p->p_label); 772 MAC_PERFORM(init_proc_label, &p->p_label); 773 #ifdef MAC_DEBUG 774 atomic_add_int(&nmacprocs, 1); 775 #endif 776 } 777 778 static int 779 mac_init_socket_label(struct label *label, int flag) 780 { 781 int error; 782 783 mac_init_label(label); 784 785 MAC_CHECK(init_socket_label, label, flag); 786 if (error) { 787 MAC_PERFORM(destroy_socket_label, label); 788 mac_destroy_label(label); 789 } 790 791 #ifdef MAC_DEBUG 792 if (error == 0) 793 atomic_add_int(&nmacsockets, 1); 794 #endif 795 796 return (error); 797 } 798 799 static int 800 mac_init_socket_peer_label(struct label *label, int flag) 801 { 802 int error; 803 804 mac_init_label(label); 805 806 MAC_CHECK(init_socket_peer_label, label, flag); 807 if (error) { 808 MAC_PERFORM(destroy_socket_label, label); 809 mac_destroy_label(label); 810 } 811 812 return (error); 813 } 814 815 int 816 mac_init_socket(struct socket *socket, int flag) 817 { 818 int error; 819 820 error = mac_init_socket_label(&socket->so_label, flag); 821 if (error) 822 return (error); 823 824 error = mac_init_socket_peer_label(&socket->so_peerlabel, flag); 825 if (error) 826 mac_destroy_socket_label(&socket->so_label); 827 828 return (error); 829 } 830 831 void 832 mac_init_vnode_label(struct label *label) 833 { 834 835 mac_init_label(label); 836 MAC_PERFORM(init_vnode_label, label); 837 #ifdef MAC_DEBUG 838 atomic_add_int(&nmacvnodes, 1); 839 #endif 840 } 841 842 void 843 mac_init_vnode(struct vnode *vp) 844 { 845 846 mac_init_vnode_label(&vp->v_label); 847 } 848 849 void 850 mac_destroy_bpfdesc(struct bpf_d *bpf_d) 851 { 852 853 MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label); 854 mac_destroy_label(&bpf_d->bd_label); 855 #ifdef MAC_DEBUG 856 atomic_subtract_int(&nmacbpfdescs, 1); 857 #endif 858 } 859 860 static void 861 mac_destroy_cred_label(struct label *label) 862 { 863 864 MAC_PERFORM(destroy_cred_label, label); 865 mac_destroy_label(label); 866 #ifdef MAC_DEBUG 867 atomic_subtract_int(&nmaccreds, 1); 868 #endif 869 } 870 871 void 872 mac_destroy_cred(struct ucred *cred) 873 { 874 875 mac_destroy_cred_label(&cred->cr_label); 876 } 877 878 void 879 mac_destroy_devfsdirent(struct devfs_dirent *de) 880 { 881 882 MAC_PERFORM(destroy_devfsdirent_label, &de->de_label); 883 mac_destroy_label(&de->de_label); 884 #ifdef MAC_DEBUG 885 atomic_subtract_int(&nmacdevfsdirents, 1); 886 #endif 887 } 888 889 static void 890 mac_destroy_ifnet_label(struct label *label) 891 { 892 893 MAC_PERFORM(destroy_ifnet_label, label); 894 mac_destroy_label(label); 895 #ifdef MAC_DEBUG 896 atomic_subtract_int(&nmacifnets, 1); 897 #endif 898 } 899 900 void 901 mac_destroy_ifnet(struct ifnet *ifp) 902 { 903 904 mac_destroy_ifnet_label(&ifp->if_label); 905 } 906 907 void 908 mac_destroy_ipq(struct ipq *ipq) 909 { 910 911 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label); 912 mac_destroy_label(&ipq->ipq_label); 913 #ifdef MAC_DEBUG 914 atomic_subtract_int(&nmacipqs, 1); 915 #endif 916 } 917 918 void 919 mac_destroy_mbuf(struct mbuf *m) 920 { 921 922 MAC_PERFORM(destroy_mbuf_label, &m->m_pkthdr.label); 923 mac_destroy_label(&m->m_pkthdr.label); 924 #ifdef MAC_DEBUG 925 atomic_subtract_int(&nmacmbufs, 1); 926 #endif 927 } 928 929 void 930 mac_destroy_mount(struct mount *mp) 931 { 932 933 MAC_PERFORM(destroy_mount_label, &mp->mnt_mntlabel); 934 MAC_PERFORM(destroy_mount_fs_label, &mp->mnt_fslabel); 935 mac_destroy_label(&mp->mnt_fslabel); 936 mac_destroy_label(&mp->mnt_mntlabel); 937 #ifdef MAC_DEBUG 938 atomic_subtract_int(&nmacmounts, 1); 939 #endif 940 } 941 942 static void 943 mac_destroy_pipe_label(struct label *label) 944 { 945 946 MAC_PERFORM(destroy_pipe_label, label); 947 mac_destroy_label(label); 948 #ifdef MAC_DEBUG 949 atomic_subtract_int(&nmacpipes, 1); 950 #endif 951 } 952 953 void 954 mac_destroy_pipe(struct pipe *pipe) 955 { 956 957 mac_destroy_pipe_label(pipe->pipe_label); 958 free(pipe->pipe_label, M_MACPIPELABEL); 959 } 960 961 void 962 mac_destroy_proc(struct proc *p) 963 { 964 965 MAC_PERFORM(destroy_proc_label, &p->p_label); 966 mac_destroy_label(&p->p_label); 967 #ifdef MAC_DEBUG 968 atomic_subtract_int(&nmacprocs, 1); 969 #endif 970 } 971 972 static void 973 mac_destroy_socket_label(struct label *label) 974 { 975 976 MAC_PERFORM(destroy_socket_label, label); 977 mac_destroy_label(label); 978 #ifdef MAC_DEBUG 979 atomic_subtract_int(&nmacsockets, 1); 980 #endif 981 } 982 983 static void 984 mac_destroy_socket_peer_label(struct label *label) 985 { 986 987 MAC_PERFORM(destroy_socket_peer_label, label); 988 mac_destroy_label(label); 989 } 990 991 void 992 mac_destroy_socket(struct socket *socket) 993 { 994 995 mac_destroy_socket_label(&socket->so_label); 996 mac_destroy_socket_peer_label(&socket->so_peerlabel); 997 } 998 999 void 1000 mac_destroy_vnode_label(struct label *label) 1001 { 1002 1003 MAC_PERFORM(destroy_vnode_label, label); 1004 mac_destroy_label(label); 1005 #ifdef MAC_DEBUG 1006 atomic_subtract_int(&nmacvnodes, 1); 1007 #endif 1008 } 1009 1010 void 1011 mac_destroy_vnode(struct vnode *vp) 1012 { 1013 1014 mac_destroy_vnode_label(&vp->v_label); 1015 } 1016 1017 static void 1018 mac_copy_pipe_label(struct label *src, struct label *dest) 1019 { 1020 1021 MAC_PERFORM(copy_pipe_label, src, dest); 1022 } 1023 1024 void 1025 mac_copy_vnode_label(struct label *src, struct label *dest) 1026 { 1027 1028 MAC_PERFORM(copy_vnode_label, src, dest); 1029 } 1030 1031 static int 1032 mac_check_structmac_consistent(struct mac *mac) 1033 { 1034 1035 if (mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) 1036 return (EINVAL); 1037 1038 return (0); 1039 } 1040 1041 static int 1042 mac_externalize_cred_label(struct label *label, char *elements, 1043 char *outbuf, size_t outbuflen, int flags) 1044 { 1045 int error; 1046 1047 MAC_EXTERNALIZE(cred_label, label, elements, outbuf, outbuflen); 1048 1049 return (error); 1050 } 1051 1052 static int 1053 mac_externalize_ifnet_label(struct label *label, char *elements, 1054 char *outbuf, size_t outbuflen, int flags) 1055 { 1056 int error; 1057 1058 MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen); 1059 1060 return (error); 1061 } 1062 1063 static int 1064 mac_externalize_pipe_label(struct label *label, char *elements, 1065 char *outbuf, size_t outbuflen, int flags) 1066 { 1067 int error; 1068 1069 MAC_EXTERNALIZE(pipe_label, label, elements, outbuf, outbuflen); 1070 1071 return (error); 1072 } 1073 1074 static int 1075 mac_externalize_socket_label(struct label *label, char *elements, 1076 char *outbuf, size_t outbuflen, int flags) 1077 { 1078 int error; 1079 1080 MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen); 1081 1082 return (error); 1083 } 1084 1085 static int 1086 mac_externalize_socket_peer_label(struct label *label, char *elements, 1087 char *outbuf, size_t outbuflen, int flags) 1088 { 1089 int error; 1090 1091 MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen); 1092 1093 return (error); 1094 } 1095 1096 static int 1097 mac_externalize_vnode_label(struct label *label, char *elements, 1098 char *outbuf, size_t outbuflen, int flags) 1099 { 1100 int error; 1101 1102 MAC_EXTERNALIZE(vnode_label, label, elements, outbuf, outbuflen); 1103 1104 return (error); 1105 } 1106 1107 static int 1108 mac_internalize_cred_label(struct label *label, char *string) 1109 { 1110 int error; 1111 1112 MAC_INTERNALIZE(cred_label, label, string); 1113 1114 return (error); 1115 } 1116 1117 static int 1118 mac_internalize_ifnet_label(struct label *label, char *string) 1119 { 1120 int error; 1121 1122 MAC_INTERNALIZE(ifnet_label, label, string); 1123 1124 return (error); 1125 } 1126 1127 static int 1128 mac_internalize_pipe_label(struct label *label, char *string) 1129 { 1130 int error; 1131 1132 MAC_INTERNALIZE(pipe_label, label, string); 1133 1134 return (error); 1135 } 1136 1137 static int 1138 mac_internalize_socket_label(struct label *label, char *string) 1139 { 1140 int error; 1141 1142 MAC_INTERNALIZE(socket_label, label, string); 1143 1144 return (error); 1145 } 1146 1147 static int 1148 mac_internalize_vnode_label(struct label *label, char *string) 1149 { 1150 int error; 1151 1152 MAC_INTERNALIZE(vnode_label, label, string); 1153 1154 return (error); 1155 } 1156 1157 /* 1158 * Initialize MAC label for the first kernel process, from which other 1159 * kernel processes and threads are spawned. 1160 */ 1161 void 1162 mac_create_proc0(struct ucred *cred) 1163 { 1164 1165 MAC_PERFORM(create_proc0, cred); 1166 } 1167 1168 /* 1169 * Initialize MAC label for the first userland process, from which other 1170 * userland processes and threads are spawned. 1171 */ 1172 void 1173 mac_create_proc1(struct ucred *cred) 1174 { 1175 1176 MAC_PERFORM(create_proc1, cred); 1177 } 1178 1179 void 1180 mac_thread_userret(struct thread *td) 1181 { 1182 1183 MAC_PERFORM(thread_userret, td); 1184 } 1185 1186 /* 1187 * When a new process is created, its label must be initialized. Generally, 1188 * this involves inheritence from the parent process, modulo possible 1189 * deltas. This function allows that processing to take place. 1190 */ 1191 void 1192 mac_create_cred(struct ucred *parent_cred, struct ucred *child_cred) 1193 { 1194 1195 MAC_PERFORM(create_cred, parent_cred, child_cred); 1196 } 1197 1198 void 1199 mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp) 1200 { 1201 1202 MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label); 1203 } 1204 1205 void 1206 mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, 1207 struct vnode *vp) 1208 { 1209 1210 MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de, 1211 &de->de_label, vp, &vp->v_label); 1212 } 1213 1214 int 1215 mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp) 1216 { 1217 int error; 1218 1219 ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr"); 1220 1221 MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp, 1222 &vp->v_label); 1223 1224 return (error); 1225 } 1226 1227 void 1228 mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp) 1229 { 1230 1231 MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp, 1232 &vp->v_label); 1233 } 1234 1235 int 1236 mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, 1237 struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1238 { 1239 int error; 1240 1241 ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr"); 1242 ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr"); 1243 1244 error = VOP_OPENEXTATTR(vp, cred, curthread); 1245 if (error == EOPNOTSUPP) { 1246 /* XXX: Optionally abort if transactions not supported. */ 1247 if (ea_warn_once == 0) { 1248 printf("Warning: transactions not supported " 1249 "in EA write.\n"); 1250 ea_warn_once = 1; 1251 } 1252 } else if (error) 1253 return (error); 1254 1255 MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel, 1256 dvp, &dvp->v_label, vp, &vp->v_label, cnp); 1257 1258 if (error) { 1259 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1260 return (error); 1261 } 1262 1263 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1264 1265 if (error == EOPNOTSUPP) 1266 error = 0; /* XXX */ 1267 1268 return (error); 1269 } 1270 1271 static int 1272 mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp, 1273 struct label *intlabel) 1274 { 1275 int error; 1276 1277 ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr"); 1278 1279 error = VOP_OPENEXTATTR(vp, cred, curthread); 1280 if (error == EOPNOTSUPP) { 1281 /* XXX: Optionally abort if transactions not supported. */ 1282 if (ea_warn_once == 0) { 1283 printf("Warning: transactions not supported " 1284 "in EA write.\n"); 1285 ea_warn_once = 1; 1286 } 1287 } else if (error) 1288 return (error); 1289 1290 MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel); 1291 1292 if (error) { 1293 VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread); 1294 return (error); 1295 } 1296 1297 error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread); 1298 1299 if (error == EOPNOTSUPP) 1300 error = 0; /* XXX */ 1301 1302 return (error); 1303 } 1304 1305 int 1306 mac_execve_enter(struct image_params *imgp, struct mac *mac_p, 1307 struct label *execlabelstorage) 1308 { 1309 struct mac mac; 1310 char *buffer; 1311 int error; 1312 1313 if (mac_p == NULL) 1314 return (0); 1315 1316 error = copyin(mac_p, &mac, sizeof(mac)); 1317 if (error) 1318 return (error); 1319 1320 error = mac_check_structmac_consistent(&mac); 1321 if (error) 1322 return (error); 1323 1324 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 1325 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 1326 if (error) { 1327 free(buffer, M_MACTEMP); 1328 return (error); 1329 } 1330 1331 mac_init_cred_label(execlabelstorage); 1332 error = mac_internalize_cred_label(execlabelstorage, buffer); 1333 free(buffer, M_MACTEMP); 1334 if (error) { 1335 mac_destroy_cred_label(execlabelstorage); 1336 return (error); 1337 } 1338 imgp->execlabel = execlabelstorage; 1339 return (0); 1340 } 1341 1342 void 1343 mac_execve_exit(struct image_params *imgp) 1344 { 1345 if (imgp->execlabel != NULL) 1346 mac_destroy_cred_label(imgp->execlabel); 1347 } 1348 1349 void 1350 mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp, 1351 struct label *interpvnodelabel, struct image_params *imgp) 1352 { 1353 1354 ASSERT_VOP_LOCKED(vp, "mac_execve_transition"); 1355 1356 if (!mac_enforce_process && !mac_enforce_fs) 1357 return; 1358 1359 MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label, 1360 interpvnodelabel, imgp, imgp->execlabel); 1361 } 1362 1363 int 1364 mac_execve_will_transition(struct ucred *old, struct vnode *vp, 1365 struct label *interpvnodelabel, struct image_params *imgp) 1366 { 1367 int result; 1368 1369 ASSERT_VOP_LOCKED(vp, "mac_execve_will_transition"); 1370 1371 if (!mac_enforce_process && !mac_enforce_fs) 1372 return (0); 1373 1374 result = 0; 1375 MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label, 1376 interpvnodelabel, imgp, imgp->execlabel); 1377 1378 return (result); 1379 } 1380 1381 int 1382 mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int acc_mode) 1383 { 1384 int error; 1385 1386 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_access"); 1387 1388 if (!mac_enforce_fs) 1389 return (0); 1390 1391 MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, acc_mode); 1392 return (error); 1393 } 1394 1395 int 1396 mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp) 1397 { 1398 int error; 1399 1400 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chdir"); 1401 1402 if (!mac_enforce_fs) 1403 return (0); 1404 1405 MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label); 1406 return (error); 1407 } 1408 1409 int 1410 mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp) 1411 { 1412 int error; 1413 1414 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_chroot"); 1415 1416 if (!mac_enforce_fs) 1417 return (0); 1418 1419 MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label); 1420 return (error); 1421 } 1422 1423 int 1424 mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, 1425 struct componentname *cnp, struct vattr *vap) 1426 { 1427 int error; 1428 1429 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_create"); 1430 1431 if (!mac_enforce_fs) 1432 return (0); 1433 1434 MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap); 1435 return (error); 1436 } 1437 1438 int 1439 mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp, 1440 struct componentname *cnp) 1441 { 1442 int error; 1443 1444 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_delete"); 1445 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_delete"); 1446 1447 if (!mac_enforce_fs) 1448 return (0); 1449 1450 MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp, 1451 &vp->v_label, cnp); 1452 return (error); 1453 } 1454 1455 int 1456 mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 1457 acl_type_t type) 1458 { 1459 int error; 1460 1461 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_deleteacl"); 1462 1463 if (!mac_enforce_fs) 1464 return (0); 1465 1466 MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type); 1467 return (error); 1468 } 1469 1470 int 1471 mac_check_vnode_exec(struct ucred *cred, struct vnode *vp, 1472 struct image_params *imgp) 1473 { 1474 int error; 1475 1476 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_exec"); 1477 1478 if (!mac_enforce_process && !mac_enforce_fs) 1479 return (0); 1480 1481 MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label, imgp, 1482 imgp->execlabel); 1483 1484 return (error); 1485 } 1486 1487 int 1488 mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type) 1489 { 1490 int error; 1491 1492 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getacl"); 1493 1494 if (!mac_enforce_fs) 1495 return (0); 1496 1497 MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type); 1498 return (error); 1499 } 1500 1501 int 1502 mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 1503 int attrnamespace, const char *name, struct uio *uio) 1504 { 1505 int error; 1506 1507 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_getextattr"); 1508 1509 if (!mac_enforce_fs) 1510 return (0); 1511 1512 MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label, 1513 attrnamespace, name, uio); 1514 return (error); 1515 } 1516 1517 int 1518 mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, 1519 struct vnode *vp, struct componentname *cnp) 1520 { 1521 int error; 1522 1523 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_link"); 1524 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_link"); 1525 1526 if (!mac_enforce_fs) 1527 return (0); 1528 1529 MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp, 1530 &vp->v_label, cnp); 1531 return (error); 1532 } 1533 1534 int 1535 mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 1536 struct componentname *cnp) 1537 { 1538 int error; 1539 1540 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_lookup"); 1541 1542 if (!mac_enforce_fs) 1543 return (0); 1544 1545 MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp); 1546 return (error); 1547 } 1548 1549 int 1550 mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot) 1551 { 1552 int error; 1553 1554 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap"); 1555 1556 if (!mac_enforce_fs || !mac_enforce_vm) 1557 return (0); 1558 1559 MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot); 1560 return (error); 1561 } 1562 1563 void 1564 mac_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp, int *prot) 1565 { 1566 int result = *prot; 1567 1568 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mmap_downgrade"); 1569 1570 if (!mac_enforce_fs || !mac_enforce_vm) 1571 return; 1572 1573 MAC_PERFORM(check_vnode_mmap_downgrade, cred, vp, &vp->v_label, 1574 &result); 1575 1576 *prot = result; 1577 } 1578 1579 int 1580 mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot) 1581 { 1582 int error; 1583 1584 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_mprotect"); 1585 1586 if (!mac_enforce_fs || !mac_enforce_vm) 1587 return (0); 1588 1589 MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot); 1590 return (error); 1591 } 1592 1593 int 1594 mac_check_vnode_open(struct ucred *cred, struct vnode *vp, int acc_mode) 1595 { 1596 int error; 1597 1598 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_open"); 1599 1600 if (!mac_enforce_fs) 1601 return (0); 1602 1603 MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode); 1604 return (error); 1605 } 1606 1607 int 1608 mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred, 1609 struct vnode *vp) 1610 { 1611 int error; 1612 1613 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_poll"); 1614 1615 if (!mac_enforce_fs) 1616 return (0); 1617 1618 MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp, 1619 &vp->v_label); 1620 1621 return (error); 1622 } 1623 1624 int 1625 mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred, 1626 struct vnode *vp) 1627 { 1628 int error; 1629 1630 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_read"); 1631 1632 if (!mac_enforce_fs) 1633 return (0); 1634 1635 MAC_CHECK(check_vnode_read, active_cred, file_cred, vp, 1636 &vp->v_label); 1637 1638 return (error); 1639 } 1640 1641 int 1642 mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp) 1643 { 1644 int error; 1645 1646 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_readdir"); 1647 1648 if (!mac_enforce_fs) 1649 return (0); 1650 1651 MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label); 1652 return (error); 1653 } 1654 1655 int 1656 mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp) 1657 { 1658 int error; 1659 1660 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_readlink"); 1661 1662 if (!mac_enforce_fs) 1663 return (0); 1664 1665 MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label); 1666 return (error); 1667 } 1668 1669 static int 1670 mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp, 1671 struct label *newlabel) 1672 { 1673 int error; 1674 1675 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel"); 1676 1677 MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel); 1678 1679 return (error); 1680 } 1681 1682 int 1683 mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 1684 struct vnode *vp, struct componentname *cnp) 1685 { 1686 int error; 1687 1688 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_from"); 1689 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_from"); 1690 1691 if (!mac_enforce_fs) 1692 return (0); 1693 1694 MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp, 1695 &vp->v_label, cnp); 1696 return (error); 1697 } 1698 1699 int 1700 mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 1701 struct vnode *vp, int samedir, struct componentname *cnp) 1702 { 1703 int error; 1704 1705 ASSERT_VOP_LOCKED(dvp, "mac_check_vnode_rename_to"); 1706 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_rename_to"); 1707 1708 if (!mac_enforce_fs) 1709 return (0); 1710 1711 MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp, 1712 vp != NULL ? &vp->v_label : NULL, samedir, cnp); 1713 return (error); 1714 } 1715 1716 int 1717 mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp) 1718 { 1719 int error; 1720 1721 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_revoke"); 1722 1723 if (!mac_enforce_fs) 1724 return (0); 1725 1726 MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label); 1727 return (error); 1728 } 1729 1730 int 1731 mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type, 1732 struct acl *acl) 1733 { 1734 int error; 1735 1736 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setacl"); 1737 1738 if (!mac_enforce_fs) 1739 return (0); 1740 1741 MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl); 1742 return (error); 1743 } 1744 1745 int 1746 mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 1747 int attrnamespace, const char *name, struct uio *uio) 1748 { 1749 int error; 1750 1751 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setextattr"); 1752 1753 if (!mac_enforce_fs) 1754 return (0); 1755 1756 MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label, 1757 attrnamespace, name, uio); 1758 return (error); 1759 } 1760 1761 int 1762 mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags) 1763 { 1764 int error; 1765 1766 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setflags"); 1767 1768 if (!mac_enforce_fs) 1769 return (0); 1770 1771 MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags); 1772 return (error); 1773 } 1774 1775 int 1776 mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode) 1777 { 1778 int error; 1779 1780 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setmode"); 1781 1782 if (!mac_enforce_fs) 1783 return (0); 1784 1785 MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode); 1786 return (error); 1787 } 1788 1789 int 1790 mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid, 1791 gid_t gid) 1792 { 1793 int error; 1794 1795 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setowner"); 1796 1797 if (!mac_enforce_fs) 1798 return (0); 1799 1800 MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid); 1801 return (error); 1802 } 1803 1804 int 1805 mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 1806 struct timespec atime, struct timespec mtime) 1807 { 1808 int error; 1809 1810 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_setutimes"); 1811 1812 if (!mac_enforce_fs) 1813 return (0); 1814 1815 MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime, 1816 mtime); 1817 return (error); 1818 } 1819 1820 int 1821 mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred, 1822 struct vnode *vp) 1823 { 1824 int error; 1825 1826 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_stat"); 1827 1828 if (!mac_enforce_fs) 1829 return (0); 1830 1831 MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp, 1832 &vp->v_label); 1833 return (error); 1834 } 1835 1836 int 1837 mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred, 1838 struct vnode *vp) 1839 { 1840 int error; 1841 1842 ASSERT_VOP_LOCKED(vp, "mac_check_vnode_write"); 1843 1844 if (!mac_enforce_fs) 1845 return (0); 1846 1847 MAC_CHECK(check_vnode_write, active_cred, file_cred, vp, 1848 &vp->v_label); 1849 1850 return (error); 1851 } 1852 1853 /* 1854 * When relabeling a process, call out to the policies for the maximum 1855 * permission allowed for each object type we know about in its 1856 * memory space, and revoke access (in the least surprising ways we 1857 * know) when necessary. The process lock is not held here. 1858 */ 1859 void 1860 mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred) 1861 { 1862 1863 /* XXX freeze all other threads */ 1864 mac_cred_mmapped_drop_perms_recurse(td, cred, 1865 &td->td_proc->p_vmspace->vm_map); 1866 /* XXX allow other threads to continue */ 1867 } 1868 1869 static __inline const char * 1870 prot2str(vm_prot_t prot) 1871 { 1872 1873 switch (prot & VM_PROT_ALL) { 1874 case VM_PROT_READ: 1875 return ("r--"); 1876 case VM_PROT_READ | VM_PROT_WRITE: 1877 return ("rw-"); 1878 case VM_PROT_READ | VM_PROT_EXECUTE: 1879 return ("r-x"); 1880 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE: 1881 return ("rwx"); 1882 case VM_PROT_WRITE: 1883 return ("-w-"); 1884 case VM_PROT_EXECUTE: 1885 return ("--x"); 1886 case VM_PROT_WRITE | VM_PROT_EXECUTE: 1887 return ("-wx"); 1888 default: 1889 return ("---"); 1890 } 1891 } 1892 1893 static void 1894 mac_cred_mmapped_drop_perms_recurse(struct thread *td, struct ucred *cred, 1895 struct vm_map *map) 1896 { 1897 struct vm_map_entry *vme; 1898 int result; 1899 vm_prot_t revokeperms; 1900 vm_object_t object; 1901 vm_ooffset_t offset; 1902 struct vnode *vp; 1903 1904 if (!mac_mmap_revocation) 1905 return; 1906 1907 vm_map_lock_read(map); 1908 for (vme = map->header.next; vme != &map->header; vme = vme->next) { 1909 if (vme->eflags & MAP_ENTRY_IS_SUB_MAP) { 1910 mac_cred_mmapped_drop_perms_recurse(td, cred, 1911 vme->object.sub_map); 1912 continue; 1913 } 1914 /* 1915 * Skip over entries that obviously are not shared. 1916 */ 1917 if (vme->eflags & (MAP_ENTRY_COW | MAP_ENTRY_NOSYNC) || 1918 !vme->max_protection) 1919 continue; 1920 /* 1921 * Drill down to the deepest backing object. 1922 */ 1923 offset = vme->offset; 1924 object = vme->object.vm_object; 1925 if (object == NULL) 1926 continue; 1927 while (object->backing_object != NULL) { 1928 object = object->backing_object; 1929 offset += object->backing_object_offset; 1930 } 1931 /* 1932 * At the moment, vm_maps and objects aren't considered 1933 * by the MAC system, so only things with backing by a 1934 * normal object (read: vnodes) are checked. 1935 */ 1936 if (object->type != OBJT_VNODE) 1937 continue; 1938 vp = (struct vnode *)object->handle; 1939 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1940 result = vme->max_protection; 1941 mac_check_vnode_mmap_downgrade(cred, vp, &result); 1942 VOP_UNLOCK(vp, 0, td); 1943 /* 1944 * Find out what maximum protection we may be allowing 1945 * now but a policy needs to get removed. 1946 */ 1947 revokeperms = vme->max_protection & ~result; 1948 if (!revokeperms) 1949 continue; 1950 printf("pid %ld: revoking %s perms from %#lx:%ld " 1951 "(max %s/cur %s)\n", (long)td->td_proc->p_pid, 1952 prot2str(revokeperms), (u_long)vme->start, 1953 (long)(vme->end - vme->start), 1954 prot2str(vme->max_protection), prot2str(vme->protection)); 1955 vm_map_lock_upgrade(map); 1956 /* 1957 * This is the really simple case: if a map has more 1958 * max_protection than is allowed, but it's not being 1959 * actually used (that is, the current protection is 1960 * still allowed), we can just wipe it out and do 1961 * nothing more. 1962 */ 1963 if ((vme->protection & revokeperms) == 0) { 1964 vme->max_protection -= revokeperms; 1965 } else { 1966 if (revokeperms & VM_PROT_WRITE) { 1967 /* 1968 * In the more complicated case, flush out all 1969 * pending changes to the object then turn it 1970 * copy-on-write. 1971 */ 1972 vm_object_reference(object); 1973 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 1974 vm_object_page_clean(object, 1975 OFF_TO_IDX(offset), 1976 OFF_TO_IDX(offset + vme->end - vme->start + 1977 PAGE_MASK), 1978 OBJPC_SYNC); 1979 VOP_UNLOCK(vp, 0, td); 1980 vm_object_deallocate(object); 1981 /* 1982 * Why bother if there's no read permissions 1983 * anymore? For the rest, we need to leave 1984 * the write permissions on for COW, or 1985 * remove them entirely if configured to. 1986 */ 1987 if (!mac_mmap_revocation_via_cow) { 1988 vme->max_protection &= ~VM_PROT_WRITE; 1989 vme->protection &= ~VM_PROT_WRITE; 1990 } if ((revokeperms & VM_PROT_READ) == 0) 1991 vme->eflags |= MAP_ENTRY_COW | 1992 MAP_ENTRY_NEEDS_COPY; 1993 } 1994 if (revokeperms & VM_PROT_EXECUTE) { 1995 vme->max_protection &= ~VM_PROT_EXECUTE; 1996 vme->protection &= ~VM_PROT_EXECUTE; 1997 } 1998 if (revokeperms & VM_PROT_READ) { 1999 vme->max_protection = 0; 2000 vme->protection = 0; 2001 } 2002 pmap_protect(map->pmap, vme->start, vme->end, 2003 vme->protection & ~revokeperms); 2004 vm_map_simplify_entry(map, vme); 2005 } 2006 vm_map_lock_downgrade(map); 2007 } 2008 vm_map_unlock_read(map); 2009 } 2010 2011 /* 2012 * When the subject's label changes, it may require revocation of privilege 2013 * to mapped objects. This can't be done on-the-fly later with a unified 2014 * buffer cache. 2015 */ 2016 static void 2017 mac_relabel_cred(struct ucred *cred, struct label *newlabel) 2018 { 2019 2020 MAC_PERFORM(relabel_cred, cred, newlabel); 2021 } 2022 2023 void 2024 mac_relabel_vnode(struct ucred *cred, struct vnode *vp, struct label *newlabel) 2025 { 2026 2027 MAC_PERFORM(relabel_vnode, cred, vp, &vp->v_label, newlabel); 2028 } 2029 2030 void 2031 mac_create_ifnet(struct ifnet *ifnet) 2032 { 2033 2034 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label); 2035 } 2036 2037 void 2038 mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 2039 { 2040 2041 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label); 2042 } 2043 2044 void 2045 mac_create_socket(struct ucred *cred, struct socket *socket) 2046 { 2047 2048 MAC_PERFORM(create_socket, cred, socket, &socket->so_label); 2049 } 2050 2051 void 2052 mac_create_pipe(struct ucred *cred, struct pipe *pipe) 2053 { 2054 2055 MAC_PERFORM(create_pipe, cred, pipe, pipe->pipe_label); 2056 } 2057 2058 void 2059 mac_create_socket_from_socket(struct socket *oldsocket, 2060 struct socket *newsocket) 2061 { 2062 2063 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label, 2064 newsocket, &newsocket->so_label); 2065 } 2066 2067 static void 2068 mac_relabel_socket(struct ucred *cred, struct socket *socket, 2069 struct label *newlabel) 2070 { 2071 2072 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel); 2073 } 2074 2075 static void 2076 mac_relabel_pipe(struct ucred *cred, struct pipe *pipe, struct label *newlabel) 2077 { 2078 2079 MAC_PERFORM(relabel_pipe, cred, pipe, pipe->pipe_label, newlabel); 2080 } 2081 2082 void 2083 mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 2084 { 2085 2086 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, &mbuf->m_pkthdr.label, 2087 socket, &socket->so_peerlabel); 2088 } 2089 2090 void 2091 mac_set_socket_peer_from_socket(struct socket *oldsocket, 2092 struct socket *newsocket) 2093 { 2094 2095 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 2096 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel); 2097 } 2098 2099 void 2100 mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 2101 { 2102 2103 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label, 2104 datagram, &datagram->m_pkthdr.label); 2105 } 2106 2107 void 2108 mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 2109 { 2110 2111 MAC_PERFORM(create_fragment, datagram, &datagram->m_pkthdr.label, 2112 fragment, &fragment->m_pkthdr.label); 2113 } 2114 2115 void 2116 mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 2117 { 2118 2119 MAC_PERFORM(create_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2120 &ipq->ipq_label); 2121 } 2122 2123 void 2124 mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2125 { 2126 2127 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, &oldmbuf->m_pkthdr.label, 2128 newmbuf, &newmbuf->m_pkthdr.label); 2129 } 2130 2131 void 2132 mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 2133 { 2134 2135 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf, 2136 &mbuf->m_pkthdr.label); 2137 } 2138 2139 void 2140 mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 2141 { 2142 2143 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf, 2144 &mbuf->m_pkthdr.label); 2145 } 2146 2147 void 2148 mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 2149 { 2150 2151 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf, 2152 &mbuf->m_pkthdr.label); 2153 } 2154 2155 void 2156 mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 2157 struct mbuf *newmbuf) 2158 { 2159 2160 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, 2161 &oldmbuf->m_pkthdr.label, ifnet, &ifnet->if_label, newmbuf, 2162 &newmbuf->m_pkthdr.label); 2163 } 2164 2165 void 2166 mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 2167 { 2168 2169 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, &oldmbuf->m_pkthdr.label, 2170 newmbuf, &newmbuf->m_pkthdr.label); 2171 } 2172 2173 int 2174 mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 2175 { 2176 int result; 2177 2178 result = 1; 2179 MAC_BOOLEAN(fragment_match, &&, fragment, &fragment->m_pkthdr.label, 2180 ipq, &ipq->ipq_label); 2181 2182 return (result); 2183 } 2184 2185 void 2186 mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 2187 { 2188 2189 MAC_PERFORM(update_ipq, fragment, &fragment->m_pkthdr.label, ipq, 2190 &ipq->ipq_label); 2191 } 2192 2193 void 2194 mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 2195 { 2196 2197 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf, 2198 &mbuf->m_pkthdr.label); 2199 } 2200 2201 void 2202 mac_create_mount(struct ucred *cred, struct mount *mp) 2203 { 2204 2205 MAC_PERFORM(create_mount, cred, mp, &mp->mnt_mntlabel, 2206 &mp->mnt_fslabel); 2207 } 2208 2209 void 2210 mac_create_root_mount(struct ucred *cred, struct mount *mp) 2211 { 2212 2213 MAC_PERFORM(create_root_mount, cred, mp, &mp->mnt_mntlabel, 2214 &mp->mnt_fslabel); 2215 } 2216 2217 int 2218 mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 2219 { 2220 int error; 2221 2222 if (!mac_enforce_network) 2223 return (0); 2224 2225 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet, 2226 &ifnet->if_label); 2227 2228 return (error); 2229 } 2230 2231 static int 2232 mac_check_cred_relabel(struct ucred *cred, struct label *newlabel) 2233 { 2234 int error; 2235 2236 MAC_CHECK(check_cred_relabel, cred, newlabel); 2237 2238 return (error); 2239 } 2240 2241 int 2242 mac_check_cred_visible(struct ucred *u1, struct ucred *u2) 2243 { 2244 int error; 2245 2246 if (!mac_enforce_process) 2247 return (0); 2248 2249 MAC_CHECK(check_cred_visible, u1, u2); 2250 2251 return (error); 2252 } 2253 2254 int 2255 mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 2256 { 2257 int error; 2258 2259 if (!mac_enforce_network) 2260 return (0); 2261 2262 KASSERT(mbuf->m_flags & M_PKTHDR, ("packet has no pkthdr")); 2263 if (!(mbuf->m_pkthdr.label.l_flags & MAC_FLAG_INITIALIZED)) 2264 if_printf(ifnet, "not initialized\n"); 2265 2266 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf, 2267 &mbuf->m_pkthdr.label); 2268 2269 return (error); 2270 } 2271 2272 int 2273 mac_check_kenv_dump(struct ucred *cred) 2274 { 2275 int error; 2276 2277 if (!mac_enforce_system) 2278 return (0); 2279 2280 MAC_CHECK(check_kenv_dump, cred); 2281 2282 return (error); 2283 } 2284 2285 int 2286 mac_check_kenv_get(struct ucred *cred, char *name) 2287 { 2288 int error; 2289 2290 if (!mac_enforce_system) 2291 return (0); 2292 2293 MAC_CHECK(check_kenv_get, cred, name); 2294 2295 return (error); 2296 } 2297 2298 int 2299 mac_check_kenv_set(struct ucred *cred, char *name, char *value) 2300 { 2301 int error; 2302 2303 if (!mac_enforce_system) 2304 return (0); 2305 2306 MAC_CHECK(check_kenv_set, cred, name, value); 2307 2308 return (error); 2309 } 2310 2311 int 2312 mac_check_kenv_unset(struct ucred *cred, char *name) 2313 { 2314 int error; 2315 2316 if (!mac_enforce_system) 2317 return (0); 2318 2319 MAC_CHECK(check_kenv_unset, cred, name); 2320 2321 return (error); 2322 } 2323 2324 int 2325 mac_check_kld_load(struct ucred *cred, struct vnode *vp) 2326 { 2327 int error; 2328 2329 ASSERT_VOP_LOCKED(vp, "mac_check_kld_load"); 2330 2331 if (!mac_enforce_kld) 2332 return (0); 2333 2334 MAC_CHECK(check_kld_load, cred, vp, &vp->v_label); 2335 2336 return (error); 2337 } 2338 2339 int 2340 mac_check_kld_stat(struct ucred *cred) 2341 { 2342 int error; 2343 2344 if (!mac_enforce_kld) 2345 return (0); 2346 2347 MAC_CHECK(check_kld_stat, cred); 2348 2349 return (error); 2350 } 2351 2352 int 2353 mac_check_kld_unload(struct ucred *cred) 2354 { 2355 int error; 2356 2357 if (!mac_enforce_kld) 2358 return (0); 2359 2360 MAC_CHECK(check_kld_unload, cred); 2361 2362 return (error); 2363 } 2364 2365 int 2366 mac_check_mount_stat(struct ucred *cred, struct mount *mount) 2367 { 2368 int error; 2369 2370 if (!mac_enforce_fs) 2371 return (0); 2372 2373 MAC_CHECK(check_mount_stat, cred, mount, &mount->mnt_mntlabel); 2374 2375 return (error); 2376 } 2377 2378 int 2379 mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, unsigned long cmd, 2380 void *data) 2381 { 2382 int error; 2383 2384 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2385 2386 if (!mac_enforce_pipe) 2387 return (0); 2388 2389 MAC_CHECK(check_pipe_ioctl, cred, pipe, pipe->pipe_label, cmd, data); 2390 2391 return (error); 2392 } 2393 2394 int 2395 mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe) 2396 { 2397 int error; 2398 2399 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2400 2401 if (!mac_enforce_pipe) 2402 return (0); 2403 2404 MAC_CHECK(check_pipe_poll, cred, pipe, pipe->pipe_label); 2405 2406 return (error); 2407 } 2408 2409 int 2410 mac_check_pipe_read(struct ucred *cred, struct pipe *pipe) 2411 { 2412 int error; 2413 2414 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2415 2416 if (!mac_enforce_pipe) 2417 return (0); 2418 2419 MAC_CHECK(check_pipe_read, cred, pipe, pipe->pipe_label); 2420 2421 return (error); 2422 } 2423 2424 static int 2425 mac_check_pipe_relabel(struct ucred *cred, struct pipe *pipe, 2426 struct label *newlabel) 2427 { 2428 int error; 2429 2430 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2431 2432 if (!mac_enforce_pipe) 2433 return (0); 2434 2435 MAC_CHECK(check_pipe_relabel, cred, pipe, pipe->pipe_label, newlabel); 2436 2437 return (error); 2438 } 2439 2440 int 2441 mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe) 2442 { 2443 int error; 2444 2445 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2446 2447 if (!mac_enforce_pipe) 2448 return (0); 2449 2450 MAC_CHECK(check_pipe_stat, cred, pipe, pipe->pipe_label); 2451 2452 return (error); 2453 } 2454 2455 int 2456 mac_check_pipe_write(struct ucred *cred, struct pipe *pipe) 2457 { 2458 int error; 2459 2460 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2461 2462 if (!mac_enforce_pipe) 2463 return (0); 2464 2465 MAC_CHECK(check_pipe_write, cred, pipe, pipe->pipe_label); 2466 2467 return (error); 2468 } 2469 2470 int 2471 mac_check_proc_debug(struct ucred *cred, struct proc *proc) 2472 { 2473 int error; 2474 2475 PROC_LOCK_ASSERT(proc, MA_OWNED); 2476 2477 if (!mac_enforce_process) 2478 return (0); 2479 2480 MAC_CHECK(check_proc_debug, cred, proc); 2481 2482 return (error); 2483 } 2484 2485 int 2486 mac_check_proc_sched(struct ucred *cred, struct proc *proc) 2487 { 2488 int error; 2489 2490 PROC_LOCK_ASSERT(proc, MA_OWNED); 2491 2492 if (!mac_enforce_process) 2493 return (0); 2494 2495 MAC_CHECK(check_proc_sched, cred, proc); 2496 2497 return (error); 2498 } 2499 2500 int 2501 mac_check_proc_signal(struct ucred *cred, struct proc *proc, int signum) 2502 { 2503 int error; 2504 2505 PROC_LOCK_ASSERT(proc, MA_OWNED); 2506 2507 if (!mac_enforce_process) 2508 return (0); 2509 2510 MAC_CHECK(check_proc_signal, cred, proc, signum); 2511 2512 return (error); 2513 } 2514 2515 int 2516 mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 2517 struct sockaddr *sockaddr) 2518 { 2519 int error; 2520 2521 if (!mac_enforce_socket) 2522 return (0); 2523 2524 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label, 2525 sockaddr); 2526 2527 return (error); 2528 } 2529 2530 int 2531 mac_check_socket_connect(struct ucred *cred, struct socket *socket, 2532 struct sockaddr *sockaddr) 2533 { 2534 int error; 2535 2536 if (!mac_enforce_socket) 2537 return (0); 2538 2539 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label, 2540 sockaddr); 2541 2542 return (error); 2543 } 2544 2545 int 2546 mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 2547 { 2548 int error; 2549 2550 if (!mac_enforce_socket) 2551 return (0); 2552 2553 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf, 2554 &mbuf->m_pkthdr.label); 2555 2556 return (error); 2557 } 2558 2559 int 2560 mac_check_socket_listen(struct ucred *cred, struct socket *socket) 2561 { 2562 int error; 2563 2564 if (!mac_enforce_socket) 2565 return (0); 2566 2567 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label); 2568 return (error); 2569 } 2570 2571 int 2572 mac_check_socket_receive(struct ucred *cred, struct socket *so) 2573 { 2574 int error; 2575 2576 if (!mac_enforce_socket) 2577 return (0); 2578 2579 MAC_CHECK(check_socket_receive, cred, so, &so->so_label); 2580 2581 return (error); 2582 } 2583 2584 static int 2585 mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 2586 struct label *newlabel) 2587 { 2588 int error; 2589 2590 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label, 2591 newlabel); 2592 2593 return (error); 2594 } 2595 2596 int 2597 mac_check_socket_send(struct ucred *cred, struct socket *so) 2598 { 2599 int error; 2600 2601 if (!mac_enforce_socket) 2602 return (0); 2603 2604 MAC_CHECK(check_socket_send, cred, so, &so->so_label); 2605 2606 return (error); 2607 } 2608 2609 int 2610 mac_check_socket_visible(struct ucred *cred, struct socket *socket) 2611 { 2612 int error; 2613 2614 if (!mac_enforce_socket) 2615 return (0); 2616 2617 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label); 2618 2619 return (error); 2620 } 2621 2622 int 2623 mac_check_system_acct(struct ucred *cred, struct vnode *vp) 2624 { 2625 int error; 2626 2627 if (vp != NULL) { 2628 ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); 2629 } 2630 2631 if (!mac_enforce_system) 2632 return (0); 2633 2634 MAC_CHECK(check_system_acct, cred, vp, 2635 vp != NULL ? &vp->v_label : NULL); 2636 2637 return (error); 2638 } 2639 2640 int 2641 mac_check_system_nfsd(struct ucred *cred) 2642 { 2643 int error; 2644 2645 if (!mac_enforce_system) 2646 return (0); 2647 2648 MAC_CHECK(check_system_nfsd, cred); 2649 2650 return (error); 2651 } 2652 2653 int 2654 mac_check_system_reboot(struct ucred *cred, int howto) 2655 { 2656 int error; 2657 2658 if (!mac_enforce_system) 2659 return (0); 2660 2661 MAC_CHECK(check_system_reboot, cred, howto); 2662 2663 return (error); 2664 } 2665 2666 int 2667 mac_check_system_settime(struct ucred *cred) 2668 { 2669 int error; 2670 2671 if (!mac_enforce_system) 2672 return (0); 2673 2674 MAC_CHECK(check_system_settime, cred); 2675 2676 return (error); 2677 } 2678 2679 int 2680 mac_check_system_swapon(struct ucred *cred, struct vnode *vp) 2681 { 2682 int error; 2683 2684 ASSERT_VOP_LOCKED(vp, "mac_check_system_swapon"); 2685 2686 if (!mac_enforce_system) 2687 return (0); 2688 2689 MAC_CHECK(check_system_swapon, cred, vp, &vp->v_label); 2690 return (error); 2691 } 2692 2693 int 2694 mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen, 2695 void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen) 2696 { 2697 int error; 2698 2699 /* 2700 * XXXMAC: We're very much like to assert the SYSCTL_LOCK here, 2701 * but since it's not exported from kern_sysctl.c, we can't. 2702 */ 2703 if (!mac_enforce_system) 2704 return (0); 2705 2706 MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp, 2707 inkernel, new, newlen); 2708 2709 return (error); 2710 } 2711 2712 int 2713 mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 2714 struct ifnet *ifnet) 2715 { 2716 char *elements, *buffer; 2717 struct mac mac; 2718 int error; 2719 2720 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2721 if (error) 2722 return (error); 2723 2724 error = mac_check_structmac_consistent(&mac); 2725 if (error) 2726 return (error); 2727 2728 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2729 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 2730 if (error) { 2731 free(elements, M_MACTEMP); 2732 return (error); 2733 } 2734 2735 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2736 error = mac_externalize_ifnet_label(&ifnet->if_label, elements, 2737 buffer, mac.m_buflen, M_WAITOK); 2738 if (error == 0) 2739 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 2740 2741 free(buffer, M_MACTEMP); 2742 free(elements, M_MACTEMP); 2743 2744 return (error); 2745 } 2746 2747 int 2748 mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 2749 struct ifnet *ifnet) 2750 { 2751 struct label intlabel; 2752 struct mac mac; 2753 char *buffer; 2754 int error; 2755 2756 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 2757 if (error) 2758 return (error); 2759 2760 error = mac_check_structmac_consistent(&mac); 2761 if (error) 2762 return (error); 2763 2764 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 2765 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 2766 if (error) { 2767 free(buffer, M_MACTEMP); 2768 return (error); 2769 } 2770 2771 mac_init_ifnet_label(&intlabel); 2772 error = mac_internalize_ifnet_label(&intlabel, buffer); 2773 free(buffer, M_MACTEMP); 2774 if (error) { 2775 mac_destroy_ifnet_label(&intlabel); 2776 return (error); 2777 } 2778 2779 /* 2780 * XXX: Note that this is a redundant privilege check, since 2781 * policies impose this check themselves if required by the 2782 * policy. Eventually, this should go away. 2783 */ 2784 error = suser_cred(cred, 0); 2785 if (error) { 2786 mac_destroy_ifnet_label(&intlabel); 2787 return (error); 2788 } 2789 2790 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label, 2791 &intlabel); 2792 if (error) { 2793 mac_destroy_ifnet_label(&intlabel); 2794 return (error); 2795 } 2796 2797 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel); 2798 2799 mac_destroy_ifnet_label(&intlabel); 2800 return (0); 2801 } 2802 2803 void 2804 mac_create_devfs_device(dev_t dev, struct devfs_dirent *de) 2805 { 2806 2807 MAC_PERFORM(create_devfs_device, dev, de, &de->de_label); 2808 } 2809 2810 void 2811 mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd, 2812 struct devfs_dirent *de) 2813 { 2814 2815 MAC_PERFORM(create_devfs_symlink, cred, dd, &dd->de_label, de, 2816 &de->de_label); 2817 } 2818 2819 void 2820 mac_create_devfs_directory(char *dirname, int dirnamelen, 2821 struct devfs_dirent *de) 2822 { 2823 2824 MAC_PERFORM(create_devfs_directory, dirname, dirnamelen, de, 2825 &de->de_label); 2826 } 2827 2828 int 2829 mac_setsockopt_label_set(struct ucred *cred, struct socket *so, 2830 struct mac *mac) 2831 { 2832 struct label intlabel; 2833 char *buffer; 2834 int error; 2835 2836 error = mac_check_structmac_consistent(mac); 2837 if (error) 2838 return (error); 2839 2840 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2841 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 2842 if (error) { 2843 free(buffer, M_MACTEMP); 2844 return (error); 2845 } 2846 2847 mac_init_socket_label(&intlabel, M_WAITOK); 2848 error = mac_internalize_socket_label(&intlabel, buffer); 2849 free(buffer, M_MACTEMP); 2850 if (error) { 2851 mac_destroy_socket_label(&intlabel); 2852 return (error); 2853 } 2854 2855 mac_check_socket_relabel(cred, so, &intlabel); 2856 if (error) { 2857 mac_destroy_socket_label(&intlabel); 2858 return (error); 2859 } 2860 2861 mac_relabel_socket(cred, so, &intlabel); 2862 2863 mac_destroy_socket_label(&intlabel); 2864 return (0); 2865 } 2866 2867 int 2868 mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, struct label *label) 2869 { 2870 int error; 2871 2872 PIPE_LOCK_ASSERT(pipe, MA_OWNED); 2873 2874 error = mac_check_pipe_relabel(cred, pipe, label); 2875 if (error) 2876 return (error); 2877 2878 mac_relabel_pipe(cred, pipe, label); 2879 2880 return (0); 2881 } 2882 2883 int 2884 mac_getsockopt_label_get(struct ucred *cred, struct socket *so, 2885 struct mac *mac) 2886 { 2887 char *buffer, *elements; 2888 int error; 2889 2890 error = mac_check_structmac_consistent(mac); 2891 if (error) 2892 return (error); 2893 2894 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2895 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2896 if (error) { 2897 free(elements, M_MACTEMP); 2898 return (error); 2899 } 2900 2901 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2902 error = mac_externalize_socket_label(&so->so_label, elements, 2903 buffer, mac->m_buflen, M_WAITOK); 2904 if (error == 0) 2905 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2906 2907 free(buffer, M_MACTEMP); 2908 free(elements, M_MACTEMP); 2909 2910 return (error); 2911 } 2912 2913 int 2914 mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so, 2915 struct mac *mac) 2916 { 2917 char *elements, *buffer; 2918 int error; 2919 2920 error = mac_check_structmac_consistent(mac); 2921 if (error) 2922 return (error); 2923 2924 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 2925 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 2926 if (error) { 2927 free(elements, M_MACTEMP); 2928 return (error); 2929 } 2930 2931 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 2932 error = mac_externalize_socket_peer_label(&so->so_peerlabel, 2933 elements, buffer, mac->m_buflen, M_WAITOK); 2934 if (error == 0) 2935 error = copyout(buffer, mac->m_string, strlen(buffer)+1); 2936 2937 free(buffer, M_MACTEMP); 2938 free(elements, M_MACTEMP); 2939 2940 return (error); 2941 } 2942 2943 /* 2944 * Implementation of VOP_SETLABEL() that relies on extended attributes 2945 * to store label data. Can be referenced by filesystems supporting 2946 * extended attributes. 2947 */ 2948 int 2949 vop_stdsetlabel_ea(struct vop_setlabel_args *ap) 2950 { 2951 struct vnode *vp = ap->a_vp; 2952 struct label *intlabel = ap->a_label; 2953 int error; 2954 2955 ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea"); 2956 2957 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2958 return (EOPNOTSUPP); 2959 2960 error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel); 2961 if (error) 2962 return (error); 2963 2964 mac_relabel_vnode(ap->a_cred, vp, intlabel); 2965 2966 return (0); 2967 } 2968 2969 static int 2970 vn_setlabel(struct vnode *vp, struct label *intlabel, struct ucred *cred) 2971 { 2972 int error; 2973 2974 if (vp->v_mount == NULL) { 2975 /* printf("vn_setlabel: null v_mount\n"); */ 2976 if (vp->v_type != VNON) 2977 printf("vn_setlabel: null v_mount with non-VNON\n"); 2978 return (EBADF); 2979 } 2980 2981 if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) 2982 return (EOPNOTSUPP); 2983 2984 /* 2985 * Multi-phase commit. First check the policies to confirm the 2986 * change is OK. Then commit via the filesystem. Finally, 2987 * update the actual vnode label. Question: maybe the filesystem 2988 * should update the vnode at the end as part of VOP_SETLABEL()? 2989 */ 2990 error = mac_check_vnode_relabel(cred, vp, intlabel); 2991 if (error) 2992 return (error); 2993 2994 /* 2995 * VADMIN provides the opportunity for the filesystem to make 2996 * decisions about who is and is not able to modify labels 2997 * and protections on files. This might not be right. We can't 2998 * assume VOP_SETLABEL() will do it, because we might implement 2999 * that as part of vop_stdsetlabel_ea(). 3000 */ 3001 error = VOP_ACCESS(vp, VADMIN, cred, curthread); 3002 if (error) 3003 return (error); 3004 3005 error = VOP_SETLABEL(vp, intlabel, cred, curthread); 3006 if (error) 3007 return (error); 3008 3009 return (0); 3010 } 3011 3012 int 3013 __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3014 { 3015 char *elements, *buffer; 3016 struct mac mac; 3017 struct proc *tproc; 3018 struct ucred *tcred; 3019 int error; 3020 3021 error = copyin(SCARG(uap, mac_p), &mac, sizeof(mac)); 3022 if (error) 3023 return (error); 3024 3025 error = mac_check_structmac_consistent(&mac); 3026 if (error) 3027 return (error); 3028 3029 tproc = pfind(uap->pid); 3030 if (tproc == NULL) 3031 return (ESRCH); 3032 3033 tcred = NULL; /* Satisfy gcc. */ 3034 error = p_cansee(td, tproc); 3035 if (error == 0) 3036 tcred = crhold(tproc->p_ucred); 3037 PROC_UNLOCK(tproc); 3038 if (error) 3039 return (error); 3040 3041 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3042 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3043 if (error) { 3044 free(elements, M_MACTEMP); 3045 crfree(tcred); 3046 return (error); 3047 } 3048 3049 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3050 error = mac_externalize_cred_label(&tcred->cr_label, elements, 3051 buffer, mac.m_buflen, M_WAITOK); 3052 if (error == 0) 3053 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3054 3055 free(buffer, M_MACTEMP); 3056 free(elements, M_MACTEMP); 3057 crfree(tcred); 3058 return (error); 3059 } 3060 3061 /* 3062 * MPSAFE 3063 */ 3064 int 3065 __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3066 { 3067 char *elements, *buffer; 3068 struct mac mac; 3069 int error; 3070 3071 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3072 if (error) 3073 return (error); 3074 3075 error = mac_check_structmac_consistent(&mac); 3076 if (error) 3077 return (error); 3078 3079 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3080 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3081 if (error) { 3082 free(elements, M_MACTEMP); 3083 return (error); 3084 } 3085 3086 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3087 error = mac_externalize_cred_label(&td->td_ucred->cr_label, 3088 elements, buffer, mac.m_buflen, M_WAITOK); 3089 if (error == 0) 3090 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3091 3092 free(buffer, M_MACTEMP); 3093 free(elements, M_MACTEMP); 3094 return (error); 3095 } 3096 3097 /* 3098 * MPSAFE 3099 */ 3100 int 3101 __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3102 { 3103 struct ucred *newcred, *oldcred; 3104 struct label intlabel; 3105 struct proc *p; 3106 struct mac mac; 3107 char *buffer; 3108 int error; 3109 3110 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3111 if (error) 3112 return (error); 3113 3114 error = mac_check_structmac_consistent(&mac); 3115 if (error) 3116 return (error); 3117 3118 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3119 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3120 if (error) { 3121 free(buffer, M_MACTEMP); 3122 return (error); 3123 } 3124 3125 mac_init_cred_label(&intlabel); 3126 error = mac_internalize_cred_label(&intlabel, buffer); 3127 free(buffer, M_MACTEMP); 3128 if (error) { 3129 mac_destroy_cred_label(&intlabel); 3130 return (error); 3131 } 3132 3133 newcred = crget(); 3134 3135 p = td->td_proc; 3136 PROC_LOCK(p); 3137 oldcred = p->p_ucred; 3138 3139 error = mac_check_cred_relabel(oldcred, &intlabel); 3140 if (error) { 3141 PROC_UNLOCK(p); 3142 crfree(newcred); 3143 goto out; 3144 } 3145 3146 setsugid(p); 3147 crcopy(newcred, oldcred); 3148 mac_relabel_cred(newcred, &intlabel); 3149 p->p_ucred = newcred; 3150 3151 /* 3152 * Grab additional reference for use while revoking mmaps, prior 3153 * to releasing the proc lock and sharing the cred. 3154 */ 3155 crhold(newcred); 3156 PROC_UNLOCK(p); 3157 3158 if (mac_enforce_vm) { 3159 mtx_lock(&Giant); 3160 mac_cred_mmapped_drop_perms(td, newcred); 3161 mtx_unlock(&Giant); 3162 } 3163 3164 crfree(newcred); /* Free revocation reference. */ 3165 crfree(oldcred); 3166 3167 out: 3168 mac_destroy_cred_label(&intlabel); 3169 return (error); 3170 } 3171 3172 /* 3173 * MPSAFE 3174 */ 3175 int 3176 __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3177 { 3178 char *elements, *buffer; 3179 struct label intlabel; 3180 struct file *fp; 3181 struct mac mac; 3182 struct vnode *vp; 3183 struct pipe *pipe; 3184 short label_type; 3185 int error; 3186 3187 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3188 if (error) 3189 return (error); 3190 3191 error = mac_check_structmac_consistent(&mac); 3192 if (error) 3193 return (error); 3194 3195 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3196 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3197 if (error) { 3198 free(elements, M_MACTEMP); 3199 return (error); 3200 } 3201 3202 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3203 mtx_lock(&Giant); /* VFS */ 3204 error = fget(td, SCARG(uap, fd), &fp); 3205 if (error) 3206 goto out; 3207 3208 label_type = fp->f_type; 3209 switch (fp->f_type) { 3210 case DTYPE_FIFO: 3211 case DTYPE_VNODE: 3212 vp = (struct vnode *)fp->f_data; 3213 3214 mac_init_vnode_label(&intlabel); 3215 3216 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3217 mac_copy_vnode_label(&vp->v_label, &intlabel); 3218 VOP_UNLOCK(vp, 0, td); 3219 3220 break; 3221 case DTYPE_PIPE: 3222 pipe = (struct pipe *)fp->f_data; 3223 3224 mac_init_pipe_label(&intlabel); 3225 3226 PIPE_LOCK(pipe); 3227 mac_copy_pipe_label(pipe->pipe_label, &intlabel); 3228 PIPE_UNLOCK(pipe); 3229 break; 3230 default: 3231 error = EINVAL; 3232 fdrop(fp, td); 3233 goto out; 3234 } 3235 fdrop(fp, td); 3236 3237 switch (label_type) { 3238 case DTYPE_FIFO: 3239 case DTYPE_VNODE: 3240 if (error == 0) 3241 error = mac_externalize_vnode_label(&intlabel, 3242 elements, buffer, mac.m_buflen, M_WAITOK); 3243 mac_destroy_vnode_label(&intlabel); 3244 break; 3245 case DTYPE_PIPE: 3246 error = mac_externalize_pipe_label(&intlabel, elements, 3247 buffer, mac.m_buflen, M_WAITOK); 3248 mac_destroy_pipe_label(&intlabel); 3249 break; 3250 default: 3251 panic("__mac_get_fd: corrupted label_type"); 3252 } 3253 3254 if (error == 0) 3255 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3256 3257 out: 3258 mtx_unlock(&Giant); /* VFS */ 3259 free(buffer, M_MACTEMP); 3260 free(elements, M_MACTEMP); 3261 3262 return (error); 3263 } 3264 3265 /* 3266 * MPSAFE 3267 */ 3268 int 3269 __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3270 { 3271 char *elements, *buffer; 3272 struct nameidata nd; 3273 struct label intlabel; 3274 struct mac mac; 3275 int error; 3276 3277 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3278 if (error) 3279 return (error); 3280 3281 error = mac_check_structmac_consistent(&mac); 3282 if (error) 3283 return (error); 3284 3285 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3286 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3287 if (error) { 3288 free(elements, M_MACTEMP); 3289 return (error); 3290 } 3291 3292 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3293 mtx_lock(&Giant); /* VFS */ 3294 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3295 td); 3296 error = namei(&nd); 3297 if (error) 3298 goto out; 3299 3300 mac_init_vnode_label(&intlabel); 3301 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3302 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3303 mac.m_buflen, M_WAITOK); 3304 3305 NDFREE(&nd, 0); 3306 mac_destroy_vnode_label(&intlabel); 3307 3308 if (error == 0) 3309 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3310 3311 out: 3312 mtx_unlock(&Giant); /* VFS */ 3313 3314 free(buffer, M_MACTEMP); 3315 free(elements, M_MACTEMP); 3316 3317 return (error); 3318 } 3319 3320 /* 3321 * MPSAFE 3322 */ 3323 int 3324 __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3325 { 3326 char *elements, *buffer; 3327 struct nameidata nd; 3328 struct label intlabel; 3329 struct mac mac; 3330 int error; 3331 3332 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3333 if (error) 3334 return (error); 3335 3336 error = mac_check_structmac_consistent(&mac); 3337 if (error) 3338 return (error); 3339 3340 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3341 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 3342 if (error) { 3343 free(elements, M_MACTEMP); 3344 return (error); 3345 } 3346 3347 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 3348 mtx_lock(&Giant); /* VFS */ 3349 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3350 td); 3351 error = namei(&nd); 3352 if (error) 3353 goto out; 3354 3355 mac_init_vnode_label(&intlabel); 3356 mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel); 3357 error = mac_externalize_vnode_label(&intlabel, elements, buffer, 3358 mac.m_buflen, M_WAITOK); 3359 NDFREE(&nd, 0); 3360 mac_destroy_vnode_label(&intlabel); 3361 3362 if (error == 0) 3363 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 3364 3365 out: 3366 mtx_unlock(&Giant); /* VFS */ 3367 3368 free(buffer, M_MACTEMP); 3369 free(elements, M_MACTEMP); 3370 3371 return (error); 3372 } 3373 3374 /* 3375 * MPSAFE 3376 */ 3377 int 3378 __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3379 { 3380 struct label intlabel; 3381 struct pipe *pipe; 3382 struct file *fp; 3383 struct mount *mp; 3384 struct vnode *vp; 3385 struct mac mac; 3386 char *buffer; 3387 int error; 3388 3389 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3390 if (error) 3391 return (error); 3392 3393 error = mac_check_structmac_consistent(&mac); 3394 if (error) 3395 return (error); 3396 3397 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3398 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3399 if (error) { 3400 free(buffer, M_MACTEMP); 3401 return (error); 3402 } 3403 3404 mtx_lock(&Giant); /* VFS */ 3405 3406 error = fget(td, SCARG(uap, fd), &fp); 3407 if (error) 3408 goto out; 3409 3410 switch (fp->f_type) { 3411 case DTYPE_FIFO: 3412 case DTYPE_VNODE: 3413 mac_init_vnode_label(&intlabel); 3414 error = mac_internalize_vnode_label(&intlabel, buffer); 3415 if (error) { 3416 mac_destroy_vnode_label(&intlabel); 3417 break; 3418 } 3419 3420 vp = (struct vnode *)fp->f_data; 3421 error = vn_start_write(vp, &mp, V_WAIT | PCATCH); 3422 if (error != 0) { 3423 mac_destroy_vnode_label(&intlabel); 3424 break; 3425 } 3426 3427 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 3428 error = vn_setlabel(vp, &intlabel, td->td_ucred); 3429 VOP_UNLOCK(vp, 0, td); 3430 vn_finished_write(mp); 3431 3432 mac_destroy_vnode_label(&intlabel); 3433 break; 3434 3435 case DTYPE_PIPE: 3436 mac_init_pipe_label(&intlabel); 3437 error = mac_internalize_pipe_label(&intlabel, buffer); 3438 if (error == 0) { 3439 pipe = (struct pipe *)fp->f_data; 3440 PIPE_LOCK(pipe); 3441 error = mac_pipe_label_set(td->td_ucred, pipe, 3442 &intlabel); 3443 PIPE_UNLOCK(pipe); 3444 } 3445 3446 mac_destroy_pipe_label(&intlabel); 3447 break; 3448 3449 default: 3450 error = EINVAL; 3451 } 3452 3453 fdrop(fp, td); 3454 out: 3455 mtx_unlock(&Giant); /* VFS */ 3456 3457 free(buffer, M_MACTEMP); 3458 3459 return (error); 3460 } 3461 3462 /* 3463 * MPSAFE 3464 */ 3465 int 3466 __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3467 { 3468 struct label intlabel; 3469 struct nameidata nd; 3470 struct mount *mp; 3471 struct mac mac; 3472 char *buffer; 3473 int error; 3474 3475 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3476 if (error) 3477 return (error); 3478 3479 error = mac_check_structmac_consistent(&mac); 3480 if (error) 3481 return (error); 3482 3483 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3484 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3485 if (error) { 3486 free(buffer, M_MACTEMP); 3487 return (error); 3488 } 3489 3490 mac_init_vnode_label(&intlabel); 3491 error = mac_internalize_vnode_label(&intlabel, buffer); 3492 free(buffer, M_MACTEMP); 3493 if (error) { 3494 mac_destroy_vnode_label(&intlabel); 3495 return (error); 3496 } 3497 3498 mtx_lock(&Giant); /* VFS */ 3499 3500 NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, 3501 td); 3502 error = namei(&nd); 3503 if (error == 0) { 3504 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3505 if (error == 0) 3506 error = vn_setlabel(nd.ni_vp, &intlabel, 3507 td->td_ucred); 3508 vn_finished_write(mp); 3509 } 3510 3511 NDFREE(&nd, 0); 3512 mtx_unlock(&Giant); /* VFS */ 3513 mac_destroy_vnode_label(&intlabel); 3514 3515 return (error); 3516 } 3517 3518 /* 3519 * MPSAFE 3520 */ 3521 int 3522 __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3523 { 3524 struct label intlabel; 3525 struct nameidata nd; 3526 struct mount *mp; 3527 struct mac mac; 3528 char *buffer; 3529 int error; 3530 3531 error = copyin(uap->mac_p, &mac, sizeof(mac)); 3532 if (error) 3533 return (error); 3534 3535 error = mac_check_structmac_consistent(&mac); 3536 if (error) 3537 return (error); 3538 3539 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 3540 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 3541 if (error) { 3542 free(buffer, M_MACTEMP); 3543 return (error); 3544 } 3545 3546 mac_init_vnode_label(&intlabel); 3547 error = mac_internalize_vnode_label(&intlabel, buffer); 3548 free(buffer, M_MACTEMP); 3549 if (error) { 3550 mac_destroy_vnode_label(&intlabel); 3551 return (error); 3552 } 3553 3554 mtx_lock(&Giant); /* VFS */ 3555 3556 NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, 3557 td); 3558 error = namei(&nd); 3559 if (error == 0) { 3560 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); 3561 if (error == 0) 3562 error = vn_setlabel(nd.ni_vp, &intlabel, 3563 td->td_ucred); 3564 vn_finished_write(mp); 3565 } 3566 3567 NDFREE(&nd, 0); 3568 mtx_unlock(&Giant); /* VFS */ 3569 mac_destroy_vnode_label(&intlabel); 3570 3571 return (error); 3572 } 3573 3574 /* 3575 * MPSAFE 3576 */ 3577 int 3578 mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3579 { 3580 struct mac_policy_conf *mpc; 3581 char target[MAC_MAX_POLICY_NAME]; 3582 int error; 3583 3584 error = copyinstr(SCARG(uap, policy), target, sizeof(target), NULL); 3585 if (error) 3586 return (error); 3587 3588 error = ENOSYS; 3589 MAC_POLICY_LIST_BUSY(); 3590 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { 3591 if (strcmp(mpc->mpc_name, target) == 0 && 3592 mpc->mpc_ops->mpo_syscall != NULL) { 3593 error = mpc->mpc_ops->mpo_syscall(td, 3594 SCARG(uap, call), SCARG(uap, arg)); 3595 goto out; 3596 } 3597 } 3598 3599 out: 3600 MAC_POLICY_LIST_UNBUSY(); 3601 return (error); 3602 } 3603 3604 SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); 3605 SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); 3606 3607 #else /* !MAC */ 3608 3609 int 3610 __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) 3611 { 3612 3613 return (ENOSYS); 3614 } 3615 3616 int 3617 __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) 3618 { 3619 3620 return (ENOSYS); 3621 } 3622 3623 int 3624 __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) 3625 { 3626 3627 return (ENOSYS); 3628 } 3629 3630 int 3631 __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) 3632 { 3633 3634 return (ENOSYS); 3635 } 3636 3637 int 3638 __mac_get_file(struct thread *td, struct __mac_get_file_args *uap) 3639 { 3640 3641 return (ENOSYS); 3642 } 3643 3644 int 3645 __mac_get_link(struct thread *td, struct __mac_get_link_args *uap) 3646 { 3647 3648 return (ENOSYS); 3649 } 3650 3651 int 3652 __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) 3653 { 3654 3655 return (ENOSYS); 3656 } 3657 3658 int 3659 __mac_set_file(struct thread *td, struct __mac_set_file_args *uap) 3660 { 3661 3662 return (ENOSYS); 3663 } 3664 3665 int 3666 __mac_set_link(struct thread *td, struct __mac_set_link_args *uap) 3667 { 3668 3669 return (ENOSYS); 3670 } 3671 3672 int 3673 mac_syscall(struct thread *td, struct mac_syscall_args *uap) 3674 { 3675 3676 return (ENOSYS); 3677 } 3678 3679 #endif 3680