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