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