diff options
Diffstat (limited to 'sys/security')
| -rw-r--r-- | sys/security/mac/mac_framework.c | 1209 | ||||
| -rw-r--r-- | sys/security/mac/mac_framework.h | 365 | ||||
| -rw-r--r-- | sys/security/mac/mac_policy.h | 492 | ||||
| -rw-r--r-- | sys/security/mac/mac_syscalls.c | 1209 |
4 files changed, 0 insertions, 3275 deletions
diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c deleted file mode 100644 index f42b075e68fd..000000000000 --- a/sys/security/mac/mac_framework.c +++ /dev/null @@ -1,1209 +0,0 @@ -/*- - * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson - * Copyright (c) 2001 Ilmar S. Habibulin - * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed by Robert Watson and Ilmar Habibulin for the - * TrustedBSD Project. - * - * This software was developed for the FreeBSD Project in part by Network - * Associates Laboratories, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), - * as part of the DARPA CHATS research program. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/*- - * Framework for extensible kernel access control. This file contains - * Kernel and userland interface to the framework, policy registration - * and composition. Per-object interfaces, controls, and labeling may be - * found in src/sys/mac/. Sample policies may be found in src/sys/mac*. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_mac.h" -#include "opt_devfs.h" - -#include <sys/param.h> -#include <sys/condvar.h> -#include <sys/extattr.h> -#include <sys/imgact.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mutex.h> -#include <sys/mac.h> -#include <sys/module.h> -#include <sys/proc.h> -#include <sys/sbuf.h> -#include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/sysent.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/file.h> -#include <sys/namei.h> -#include <sys/socket.h> -#include <sys/pipe.h> -#include <sys/socketvar.h> -#include <sys/sysctl.h> - -#include <vm/vm.h> -#include <vm/pmap.h> -#include <vm/vm_map.h> -#include <vm/vm_object.h> - -#include <sys/mac_policy.h> - -#include <fs/devfs/devfs.h> - -#include <net/bpfdesc.h> -#include <net/if.h> -#include <net/if_var.h> - -#include <netinet/in.h> -#include <netinet/ip_var.h> - -#include <security/mac/mac_internal.h> - -#ifdef MAC - -/* - * Declare that the kernel provides MAC support, version 1. This permits - * modules to refuse to be loaded if the necessary support isn't present, - * even if it's pre-boot. - */ -MODULE_VERSION(kernel_mac_support, 1); - -SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, - "TrustedBSD MAC policy controls"); - -#if MAC_MAX_SLOTS > 32 -#error "MAC_MAX_SLOTS too large" -#endif - -static unsigned int mac_max_slots = MAC_MAX_SLOTS; -static unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1; -SYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD, - &mac_max_slots, 0, ""); - -/* - * Has the kernel started generating labeled objects yet? All read/write - * access to this variable is serialized during the boot process. Following - * the end of serialization, we don't update this flag; no locking. - */ -int mac_late = 0; - -/* - * Flag to indicate whether or not we should allocate label storage for - * new mbufs. Since most dynamic policies we currently work with don't - * rely on mbuf labeling, try to avoid paying the cost of mtag allocation - * unless specifically notified of interest. One result of this is - * that if a dynamically loaded policy requests mbuf labels, it must - * be able to deal with a NULL label being returned on any mbufs that - * were already in flight when the policy was loaded. Since the policy - * already has to deal with uninitialized labels, this probably won't - * be a problem. Note: currently no locking. Will this be a problem? - */ -#ifndef MAC_ALWAYS_LABEL_MBUF -int mac_labelmbufs = 0; -#endif - -#ifdef MAC_DEBUG -SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, - "TrustedBSD MAC debug info"); -SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, - "TrustedBSD MAC object counters"); - -static unsigned int nmactemp; -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, - &nmactemp, 0, "number of temporary labels in use"); -#endif - -static int mac_policy_register(struct mac_policy_conf *mpc); -static int mac_policy_unregister(struct mac_policy_conf *mpc); - -MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); - -/* - * mac_static_policy_list holds a list of policy modules that are not - * loaded while the system is "live", and cannot be unloaded. These - * policies can be invoked without holding the busy count. - * - * mac_policy_list stores the list of dynamic policies. A busy count is - * maintained for the list, stored in mac_policy_busy. The busy count - * is protected by mac_policy_mtx; the list may be modified only - * while the busy count is 0, requiring that the lock be held to - * prevent new references to the list from being acquired. For almost - * all operations, incrementing the busy count is sufficient to - * guarantee consistency, as the list cannot be modified while the - * busy count is elevated. For a few special operations involving a - * change to the list of active policies, the mtx itself must be held. - * A condition variable, mac_policy_cv, is used to signal potential - * exclusive consumers that they should try to acquire the lock if a - * first attempt at exclusive access fails. - */ -static struct mtx mac_policy_mtx; -static struct cv mac_policy_cv; -static int mac_policy_count; -struct mac_policy_list_head mac_policy_list; -struct mac_policy_list_head mac_static_policy_list; - -/* - * We manually invoke WITNESS_WARN() to allow Witness to generate - * warnings even if we don't end up ever triggering the wait at - * run-time. The consumer of the exclusive interface must not hold - * any locks (other than potentially Giant) since we may sleep for - * long (potentially indefinite) periods of time waiting for the - * framework to become quiescent so that a policy list change may - * be made. - */ -void -mac_policy_grab_exclusive(void) -{ - - WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, - "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__); - mtx_lock(&mac_policy_mtx); - while (mac_policy_count != 0) - cv_wait(&mac_policy_cv, &mac_policy_mtx); -} - -void -mac_policy_assert_exclusive(void) -{ - - mtx_assert(&mac_policy_mtx, MA_OWNED); - KASSERT(mac_policy_count == 0, - ("mac_policy_assert_exclusive(): not exclusive")); -} - -void -mac_policy_release_exclusive(void) -{ - - KASSERT(mac_policy_count == 0, - ("mac_policy_release_exclusive(): not exclusive")); - mtx_unlock(&mac_policy_mtx); - cv_signal(&mac_policy_cv); -} - -void -mac_policy_list_busy(void) -{ - - mtx_lock(&mac_policy_mtx); - mac_policy_count++; - mtx_unlock(&mac_policy_mtx); -} - -int -mac_policy_list_conditional_busy(void) -{ - int ret; - - mtx_lock(&mac_policy_mtx); - if (!LIST_EMPTY(&mac_policy_list)) { - mac_policy_count++; - ret = 1; - } else - ret = 0; - mtx_unlock(&mac_policy_mtx); - return (ret); -} - -void -mac_policy_list_unbusy(void) -{ - - mtx_lock(&mac_policy_mtx); - mac_policy_count--; - KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK")); - if (mac_policy_count == 0) - cv_signal(&mac_policy_cv); - mtx_unlock(&mac_policy_mtx); -} - -/* - * Initialize the MAC subsystem, including appropriate SMP locks. - */ -static void -mac_init(void) -{ - - LIST_INIT(&mac_static_policy_list); - LIST_INIT(&mac_policy_list); - mac_labelzone_init(); - - mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF); - cv_init(&mac_policy_cv, "mac_policy_cv"); -} - -/* - * For the purposes of modules that want to know if they were loaded - * "early", set the mac_late flag once we've processed modules either - * linked into the kernel, or loaded before the kernel startup. - */ -static void -mac_late_init(void) -{ - - mac_late = 1; -} - -/* - * After the policy list has changed, walk the list to update any global - * flags. Currently, we support only one flag, and it's conditionally - * defined; as a result, the entire function is conditional. Eventually, - * the #else case might also iterate across the policies. - */ -static void -mac_policy_updateflags(void) -{ -#ifndef MAC_ALWAYS_LABEL_MBUF - struct mac_policy_conf *tmpc; - int labelmbufs; - - mac_policy_assert_exclusive(); - - labelmbufs = 0; - LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { - if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) - labelmbufs++; - } - LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { - if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) - labelmbufs++; - } - mac_labelmbufs = (labelmbufs != 0); -#endif -} - -/* - * Allow MAC policy modules to register during boot, etc. - */ -int -mac_policy_modevent(module_t mod, int type, void *data) -{ - struct mac_policy_conf *mpc; - int error; - - error = 0; - mpc = (struct mac_policy_conf *) data; - - switch (type) { - case MOD_LOAD: - if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && - mac_late) { - printf("mac_policy_modevent: can't load %s policy " - "after booting\n", mpc->mpc_name); - error = EBUSY; - break; - } - error = mac_policy_register(mpc); - break; - case MOD_UNLOAD: - /* Don't unregister the module if it was never registered. */ - if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) - != 0) - error = mac_policy_unregister(mpc); - else - error = 0; - break; - default: - break; - } - - return (error); -} - -static int -mac_policy_register(struct mac_policy_conf *mpc) -{ - struct mac_policy_conf *tmpc; - int error, slot, static_entry; - - error = 0; - - /* - * We don't technically need exclusive access while !mac_late, - * but hold it for assertion consistency. - */ - mac_policy_grab_exclusive(); - - /* - * If the module can potentially be unloaded, or we're loading - * late, we have to stick it in the non-static list and pay - * an extra performance overhead. Otherwise, we can pay a - * light locking cost and stick it in the static list. - */ - static_entry = (!mac_late && - !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK)); - - if (static_entry) { - LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { - if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { - error = EEXIST; - goto out; - } - } - } else { - LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { - if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { - error = EEXIST; - goto out; - } - } - } - if (mpc->mpc_field_off != NULL) { - slot = ffs(mac_slot_offsets_free); - if (slot == 0) { - error = ENOMEM; - goto out; - } - slot--; - mac_slot_offsets_free &= ~(1 << slot); - *mpc->mpc_field_off = slot; - } - mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; - - /* - * If we're loading a MAC module after the framework has - * initialized, it has to go into the dynamic list. If - * we're loading it before we've finished initializing, - * it can go into the static list with weaker locker - * requirements. - */ - if (static_entry) - LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list); - else - LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); - - /* Per-policy initialization. */ - if (mpc->mpc_ops->mpo_init != NULL) - (*(mpc->mpc_ops->mpo_init))(mpc); - mac_policy_updateflags(); - - printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, - mpc->mpc_name); - -out: - mac_policy_release_exclusive(); - return (error); -} - -static int -mac_policy_unregister(struct mac_policy_conf *mpc) -{ - - /* - * If we fail the load, we may get a request to unload. Check - * to see if we did the run-time registration, and if not, - * silently succeed. - */ - mac_policy_grab_exclusive(); - if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { - mac_policy_release_exclusive(); - return (0); - } -#if 0 - /* - * Don't allow unloading modules with private data. - */ - if (mpc->mpc_field_off != NULL) { - MAC_POLICY_LIST_UNLOCK(); - return (EBUSY); - } -#endif - /* - * Only allow the unload to proceed if the module is unloadable - * by its own definition. - */ - if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { - mac_policy_release_exclusive(); - return (EBUSY); - } - if (mpc->mpc_ops->mpo_destroy != NULL) - (*(mpc->mpc_ops->mpo_destroy))(mpc); - - LIST_REMOVE(mpc, mpc_list); - mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; - mac_policy_updateflags(); - - mac_policy_release_exclusive(); - - printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, - mpc->mpc_name); - - return (0); -} - -/* - * Define an error value precedence, and given two arguments, selects the - * value with the higher precedence. - */ -int -mac_error_select(int error1, int error2) -{ - - /* Certain decision-making errors take top priority. */ - if (error1 == EDEADLK || error2 == EDEADLK) - return (EDEADLK); - - /* Invalid arguments should be reported where possible. */ - if (error1 == EINVAL || error2 == EINVAL) - return (EINVAL); - - /* Precedence goes to "visibility", with both process and file. */ - if (error1 == ESRCH || error2 == ESRCH) - return (ESRCH); - - if (error1 == ENOENT || error2 == ENOENT) - return (ENOENT); - - /* Precedence goes to DAC/MAC protections. */ - if (error1 == EACCES || error2 == EACCES) - return (EACCES); - - /* Precedence goes to privilege. */ - if (error1 == EPERM || error2 == EPERM) - return (EPERM); - - /* Precedence goes to error over success; otherwise, arbitrary. */ - if (error1 != 0) - return (error1); - return (error2); -} - -void -mac_init_label(struct label *label) -{ - - bzero(label, sizeof(*label)); - label->l_flags = MAC_FLAG_INITIALIZED; -} - -void -mac_destroy_label(struct label *label) -{ - - KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, - ("destroying uninitialized label")); - - bzero(label, sizeof(*label)); - /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ -} - -int -mac_check_structmac_consistent(struct mac *mac) -{ - - if (mac->m_buflen < 0 || - mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) - return (EINVAL); - - return (0); -} - -/* - * MPSAFE - */ -int -__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) -{ - char *elements, *buffer; - struct mac mac; - struct proc *tproc; - struct ucred *tcred; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - tproc = pfind(uap->pid); - if (tproc == NULL) - return (ESRCH); - - tcred = NULL; /* Satisfy gcc. */ - error = p_cansee(td, tproc); - if (error == 0) - tcred = crhold(tproc->p_ucred); - PROC_UNLOCK(tproc); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - crfree(tcred); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - error = mac_externalize_cred_label(tcred->cr_label, elements, - buffer, mac.m_buflen); - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - crfree(tcred); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) -{ - char *elements, *buffer; - struct mac mac; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - error = mac_externalize_cred_label(td->td_ucred->cr_label, - elements, buffer, mac.m_buflen); - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) -{ - struct ucred *newcred, *oldcred; - struct label *intlabel; - struct proc *p; - struct mac mac; - char *buffer; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); - if (error) { - free(buffer, M_MACTEMP); - return (error); - } - - intlabel = mac_cred_label_alloc(); - error = mac_internalize_cred_label(intlabel, buffer); - free(buffer, M_MACTEMP); - if (error) - goto out; - - newcred = crget(); - - p = td->td_proc; - PROC_LOCK(p); - oldcred = p->p_ucred; - - error = mac_check_cred_relabel(oldcred, intlabel); - if (error) { - PROC_UNLOCK(p); - crfree(newcred); - goto out; - } - - setsugid(p); - crcopy(newcred, oldcred); - mac_relabel_cred(newcred, intlabel); - p->p_ucred = newcred; - - /* - * Grab additional reference for use while revoking mmaps, prior - * to releasing the proc lock and sharing the cred. - */ - crhold(newcred); - PROC_UNLOCK(p); - - if (mac_enforce_vm) { - mtx_lock(&Giant); - mac_cred_mmapped_drop_perms(td, newcred); - mtx_unlock(&Giant); - } - - crfree(newcred); /* Free revocation reference. */ - crfree(oldcred); - -out: - mac_cred_label_free(intlabel); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) -{ - char *elements, *buffer; - struct label *intlabel; - struct file *fp; - struct mac mac; - struct vnode *vp; - struct pipe *pipe; - struct socket *so; - short label_type; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - error = fget(td, uap->fd, &fp); - if (error) - goto out; - - label_type = fp->f_type; - switch (fp->f_type) { - case DTYPE_FIFO: - case DTYPE_VNODE: - vp = fp->f_vnode; - intlabel = mac_vnode_label_alloc(); - mtx_lock(&Giant); /* VFS */ - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - mac_copy_vnode_label(vp->v_label, intlabel); - VOP_UNLOCK(vp, 0, td); - mtx_unlock(&Giant); /* VFS */ - error = mac_externalize_vnode_label(intlabel, elements, - buffer, mac.m_buflen); - mac_vnode_label_free(intlabel); - break; - - case DTYPE_PIPE: - pipe = fp->f_data; - intlabel = mac_pipe_label_alloc(); - PIPE_LOCK(pipe); - mac_copy_pipe_label(pipe->pipe_label, intlabel); - PIPE_UNLOCK(pipe); - error = mac_externalize_pipe_label(intlabel, elements, - buffer, mac.m_buflen); - mac_pipe_label_free(intlabel); - break; - - case DTYPE_SOCKET: - so = fp->f_data; - intlabel = mac_socket_label_alloc(M_WAITOK); - mtx_lock(&Giant); /* Sockets */ - /* XXX: Socket lock here. */ - mac_copy_socket_label(so->so_label, intlabel); - /* XXX: Socket unlock here. */ - mtx_unlock(&Giant); /* Sockets */ - error = mac_externalize_socket_label(intlabel, elements, - buffer, mac.m_buflen); - mac_socket_label_free(intlabel); - break; - - default: - error = EINVAL; - } - fdrop(fp, td); - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - -out: - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) -{ - char *elements, *buffer; - struct nameidata nd; - struct label *intlabel; - struct mac mac; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - mtx_lock(&Giant); /* VFS */ - NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, - td); - error = namei(&nd); - if (error) - goto out; - - intlabel = mac_vnode_label_alloc(); - mac_copy_vnode_label(nd.ni_vp->v_label, intlabel); - error = mac_externalize_vnode_label(intlabel, elements, buffer, - mac.m_buflen); - - NDFREE(&nd, 0); - mac_vnode_label_free(intlabel); - - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - -out: - mtx_unlock(&Giant); /* VFS */ - - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - - return (error); -} - -/* - * MPSAFE - */ -int -__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) -{ - char *elements, *buffer; - struct nameidata nd; - struct label *intlabel; - struct mac mac; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - mtx_lock(&Giant); /* VFS */ - NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, - td); - error = namei(&nd); - if (error) - goto out; - - intlabel = mac_vnode_label_alloc(); - mac_copy_vnode_label(nd.ni_vp->v_label, intlabel); - error = mac_externalize_vnode_label(intlabel, elements, buffer, - mac.m_buflen); - NDFREE(&nd, 0); - mac_vnode_label_free(intlabel); - - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - -out: - mtx_unlock(&Giant); /* VFS */ - - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - - return (error); -} - -/* - * MPSAFE - */ -int -__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) -{ - struct label *intlabel; - struct pipe *pipe; - struct socket *so; - struct file *fp; - struct mount *mp; - struct vnode *vp; - struct mac mac; - char *buffer; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); - if (error) { - free(buffer, M_MACTEMP); - return (error); - } - - error = fget(td, uap->fd, &fp); - if (error) - goto out; - - switch (fp->f_type) { - case DTYPE_FIFO: - case DTYPE_VNODE: - intlabel = mac_vnode_label_alloc(); - error = mac_internalize_vnode_label(intlabel, buffer); - if (error) { - mac_vnode_label_free(intlabel); - break; - } - vp = fp->f_vnode; - mtx_lock(&Giant); /* VFS */ - error = vn_start_write(vp, &mp, V_WAIT | PCATCH); - if (error != 0) { - mtx_unlock(&Giant); /* VFS */ - mac_vnode_label_free(intlabel); - break; - } - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - error = vn_setlabel(vp, intlabel, td->td_ucred); - VOP_UNLOCK(vp, 0, td); - vn_finished_write(mp); - mtx_unlock(&Giant); /* VFS */ - mac_vnode_label_free(intlabel); - break; - - case DTYPE_PIPE: - intlabel = mac_pipe_label_alloc(); - error = mac_internalize_pipe_label(intlabel, buffer); - if (error == 0) { - pipe = fp->f_data; - PIPE_LOCK(pipe); - error = mac_pipe_label_set(td->td_ucred, pipe, - intlabel); - PIPE_UNLOCK(pipe); - } - mac_pipe_label_free(intlabel); - break; - - case DTYPE_SOCKET: - intlabel = mac_socket_label_alloc(M_WAITOK); - error = mac_internalize_socket_label(intlabel, buffer); - if (error == 0) { - so = fp->f_data; - mtx_lock(&Giant); /* Sockets */ - /* XXX: Socket lock here. */ - error = mac_socket_label_set(td->td_ucred, so, - intlabel); - /* XXX: Socket unlock here. */ - mtx_unlock(&Giant); /* Sockets */ - } - mac_socket_label_free(intlabel); - break; - - default: - error = EINVAL; - } - fdrop(fp, td); -out: - free(buffer, M_MACTEMP); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) -{ - struct label *intlabel; - struct nameidata nd; - struct mount *mp; - struct mac mac; - char *buffer; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); - if (error) { - free(buffer, M_MACTEMP); - return (error); - } - - intlabel = mac_vnode_label_alloc(); - error = mac_internalize_vnode_label(intlabel, buffer); - free(buffer, M_MACTEMP); - if (error) - goto out; - - mtx_lock(&Giant); /* VFS */ - - NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, - td); - error = namei(&nd); - if (error == 0) { - error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); - if (error == 0) - error = vn_setlabel(nd.ni_vp, intlabel, - td->td_ucred); - vn_finished_write(mp); - } - - NDFREE(&nd, 0); - mtx_unlock(&Giant); /* VFS */ -out: - mac_vnode_label_free(intlabel); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) -{ - struct label *intlabel; - struct nameidata nd; - struct mount *mp; - struct mac mac; - char *buffer; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); - if (error) { - free(buffer, M_MACTEMP); - return (error); - } - - intlabel = mac_vnode_label_alloc(); - error = mac_internalize_vnode_label(intlabel, buffer); - free(buffer, M_MACTEMP); - if (error) - goto out; - - mtx_lock(&Giant); /* VFS */ - - NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, - td); - error = namei(&nd); - if (error == 0) { - error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); - if (error == 0) - error = vn_setlabel(nd.ni_vp, intlabel, - td->td_ucred); - vn_finished_write(mp); - } - - NDFREE(&nd, 0); - mtx_unlock(&Giant); /* VFS */ -out: - mac_vnode_label_free(intlabel); - return (error); -} - -/* - * MPSAFE - */ -int -mac_syscall(struct thread *td, struct mac_syscall_args *uap) -{ - struct mac_policy_conf *mpc; - char target[MAC_MAX_POLICY_NAME]; - int entrycount, error; - - error = copyinstr(uap->policy, target, sizeof(target), NULL); - if (error) - return (error); - - error = ENOSYS; - LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { - if (strcmp(mpc->mpc_name, target) == 0 && - mpc->mpc_ops->mpo_syscall != NULL) { - error = mpc->mpc_ops->mpo_syscall(td, - uap->call, uap->arg); - goto out; - } - } - - if ((entrycount = mac_policy_list_conditional_busy()) != 0) { - LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { - if (strcmp(mpc->mpc_name, target) == 0 && - mpc->mpc_ops->mpo_syscall != NULL) { - error = mpc->mpc_ops->mpo_syscall(td, - uap->call, uap->arg); - break; - } - } - mac_policy_list_unbusy(); - } -out: - return (error); -} - -SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); -SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); - -#else /* !MAC */ - -int -__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) -{ - - return (ENOSYS); -} - -int -mac_syscall(struct thread *td, struct mac_syscall_args *uap) -{ - - return (ENOSYS); -} - -#endif diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h deleted file mode 100644 index 098a2bde828c..000000000000 --- a/sys/security/mac/mac_framework.h +++ /dev/null @@ -1,365 +0,0 @@ -/*- - * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson - * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed by Robert Watson for the TrustedBSD Project. - * - * This software was developed for the FreeBSD Project in part by Network - * Associates Laboratories, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), - * as part of the DARPA CHATS research program. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -/* - * Userland/kernel interface for Mandatory Access Control. - * - * The POSIX.1e implementation page may be reached at: - * http://www.trustedbsd.org/ - */ -#ifndef _SYS_MAC_H -#define _SYS_MAC_H - -#include <sys/_label.h> - -#ifndef _POSIX_MAC -#define _POSIX_MAC -#endif - -/* - * MAC framework-related constants and limits. - */ -#define MAC_MAX_POLICY_NAME 32 -#define MAC_MAX_LABEL_ELEMENT_NAME 32 -#define MAC_MAX_LABEL_ELEMENT_DATA 4096 -#define MAC_MAX_LABEL_BUF_LEN 8192 - -struct mac { - size_t m_buflen; - char *m_string; -}; - -typedef struct mac *mac_t; - -#ifndef _KERNEL - -/* - * Location of the userland MAC framework configuration file. mac.conf - * binds policy names to shared libraries that understand those policies, - * as well as setting defaults for MAC-aware applications. - */ -#define MAC_CONFFILE "/etc/mac.conf" - -/* - * Extended non-POSIX.1e interfaces that offer additional services - * available from the userland and kernel MAC frameworks. - */ -__BEGIN_DECLS -int mac_execve(char *fname, char **argv, char **envv, mac_t _label); -int mac_free(mac_t _label); -int mac_from_text(mac_t *_label, const char *_text); -int mac_get_fd(int _fd, mac_t _label); -int mac_get_file(const char *_path, mac_t _label); -int mac_get_link(const char *_path, mac_t _label); -int mac_get_peer(int _fd, mac_t _label); -int mac_get_pid(pid_t _pid, mac_t _label); -int mac_get_proc(mac_t _label); -int mac_is_present(const char *_policyname); -int mac_prepare(mac_t *_label, const char *_elements); -int mac_prepare_file_label(mac_t *_label); -int mac_prepare_ifnet_label(mac_t *_label); -int mac_prepare_process_label(mac_t *_label); -int mac_prepare_type(mac_t *_label, const char *_type); -int mac_set_fd(int _fildes, const mac_t _label); -int mac_set_file(const char *_path, mac_t _label); -int mac_set_link(const char *_path, mac_t _label); -int mac_set_proc(const mac_t _label); -int mac_syscall(const char *_policyname, int _call, void *_arg); -int mac_to_text(mac_t mac, char **_text); -__END_DECLS - -#else /* _KERNEL */ - -/* - * Kernel functions to manage and evaluate labels. - */ -struct bpf_d; -struct componentname; -struct devfs_dirent; -struct ifnet; -struct ifreq; -struct inpcb; -struct image_params; -struct inpcb; -struct ipq; -struct m_tag; -struct mbuf; -struct mount; -struct proc; -struct sockaddr; -struct socket; -struct pipe; -struct thread; -struct timespec; -struct ucred; -struct uio; -struct vattr; -struct vnode; - -#include <sys/acl.h> /* XXX acl_type_t */ - -struct vop_setlabel_args; - -/* - * Label operations. - */ -void mac_init_bpfdesc(struct bpf_d *); -void mac_init_cred(struct ucred *); -void mac_init_devfsdirent(struct devfs_dirent *); -void mac_init_ifnet(struct ifnet *); -int mac_init_inpcb(struct inpcb *, int flag); -int mac_init_ipq(struct ipq *, int flag); -int mac_init_socket(struct socket *, int flag); -void mac_init_pipe(struct pipe *); -int mac_init_mbuf(struct mbuf *mbuf, int flag); -int mac_init_mbuf_tag(struct m_tag *, int flag); -void mac_init_mount(struct mount *); -void mac_init_proc(struct proc *); -void mac_init_vnode(struct vnode *); -void mac_copy_mbuf_tag(struct m_tag *, struct m_tag *); -void mac_copy_vnode_label(struct label *, struct label *label); -void mac_destroy_bpfdesc(struct bpf_d *); -void mac_destroy_cred(struct ucred *); -void mac_destroy_devfsdirent(struct devfs_dirent *); -void mac_destroy_ifnet(struct ifnet *); -void mac_destroy_inpcb(struct inpcb *); -void mac_destroy_ipq(struct ipq *); -void mac_destroy_socket(struct socket *); -void mac_destroy_pipe(struct pipe *); -void mac_destroy_proc(struct proc *); -void mac_destroy_mbuf_tag(struct m_tag *); -void mac_destroy_mount(struct mount *); -void mac_destroy_vnode(struct vnode *); - -struct label *mac_cred_label_alloc(void); -void mac_cred_label_free(struct label *label); -struct label *mac_vnode_label_alloc(void); -void mac_vnode_label_free(struct label *label); - -/* - * Labeling event operations: file system objects, and things that - * look a lot like file system objects. - */ -void mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de, - struct vnode *vp); -int mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp); -void mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp); -void mac_create_devfs_device(struct mount *mp, dev_t dev, - struct devfs_dirent *de); -void mac_create_devfs_directory(struct mount *mp, char *dirname, - int dirnamelen, struct devfs_dirent *de); -void mac_create_devfs_symlink(struct ucred *cred, struct mount *mp, - struct devfs_dirent *dd, struct devfs_dirent *de); -int mac_create_vnode_extattr(struct ucred *cred, struct mount *mp, - struct vnode *dvp, struct vnode *vp, struct componentname *cnp); -void mac_create_mount(struct ucred *cred, struct mount *mp); -void mac_create_root_mount(struct ucred *cred, struct mount *mp); -void mac_relabel_vnode(struct ucred *cred, struct vnode *vp, - struct label *newlabel); -void mac_update_devfsdirent(struct mount *mp, struct devfs_dirent *de, - struct vnode *vp); - -/* - * Labeling event operations: IPC objects. - */ -void mac_create_mbuf_from_socket(struct socket *so, struct mbuf *m); -void mac_create_socket(struct ucred *cred, struct socket *socket); -void mac_create_socket_from_socket(struct socket *oldsocket, - struct socket *newsocket); -void mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, - struct socket *socket); -void mac_set_socket_peer_from_socket(struct socket *oldsocket, - struct socket *newsocket); -void mac_create_pipe(struct ucred *cred, struct pipe *pipe); - -/* - * Labeling event operations: network objects. - */ -void mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d); -void mac_create_ifnet(struct ifnet *ifp); -void mac_create_inpcb_from_socket(struct socket *so, struct inpcb *inp); -void mac_create_ipq(struct mbuf *fragment, struct ipq *ipq); -void mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram); -void mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment); -void mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf); -void mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *m); -void mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *m); -void mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *m); -void mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, - struct ifnet *ifnet, struct mbuf *newmbuf); -void mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf); -int mac_fragment_match(struct mbuf *fragment, struct ipq *ipq); -void mac_reflect_mbuf_icmp(struct mbuf *m); -void mac_reflect_mbuf_tcp(struct mbuf *m); -void mac_update_ipq(struct mbuf *fragment, struct ipq *ipq); -void mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp); - -/* - * Labeling event operations: processes. - */ -void mac_copy_cred(struct ucred *cr1, struct ucred *cr2); -int mac_execve_enter(struct image_params *imgp, struct mac *mac_p); -void mac_execve_exit(struct image_params *imgp); -void mac_execve_transition(struct ucred *old, struct ucred *new, - struct vnode *vp, struct label *interpvnodelabel, - struct image_params *imgp); -int mac_execve_will_transition(struct ucred *old, struct vnode *vp, - struct label *interpvnodelabel, struct image_params *imgp); -void mac_create_proc0(struct ucred *cred); -void mac_create_proc1(struct ucred *cred); -void mac_thread_userret(struct thread *td); - -/* Access control checks. */ -int mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet); -int mac_check_cred_visible(struct ucred *u1, struct ucred *u2); -int mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *m); -int mac_check_inpcb_deliver(struct inpcb *inp, struct mbuf *m); -int mac_check_kenv_dump(struct ucred *cred); -int mac_check_kenv_get(struct ucred *cred, char *name); -int mac_check_kenv_set(struct ucred *cred, char *name, char *value); -int mac_check_kenv_unset(struct ucred *cred, char *name); -int mac_check_kld_load(struct ucred *cred, struct vnode *vp); -int mac_check_kld_stat(struct ucred *cred); -int mac_check_kld_unload(struct ucred *cred); -int mac_check_mount_stat(struct ucred *cred, struct mount *mp); -int mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe, - unsigned long cmd, void *data); -int mac_check_pipe_poll(struct ucred *cred, struct pipe *pipe); -int mac_check_pipe_read(struct ucred *cred, struct pipe *pipe); -int mac_check_pipe_stat(struct ucred *cred, struct pipe *pipe); -int mac_check_pipe_write(struct ucred *cred, struct pipe *pipe); -int mac_check_proc_debug(struct ucred *cred, struct proc *proc); -int mac_check_proc_sched(struct ucred *cred, struct proc *proc); -int mac_check_proc_signal(struct ucred *cred, struct proc *proc, - int signum); -int mac_check_socket_bind(struct ucred *cred, struct socket *so, - struct sockaddr *sockaddr); -int mac_check_socket_connect(struct ucred *cred, struct socket *so, - struct sockaddr *sockaddr); -int mac_check_socket_deliver(struct socket *so, struct mbuf *m); -int mac_check_socket_listen(struct ucred *cred, struct socket *so); -int mac_check_socket_receive(struct ucred *cred, struct socket *so); -int mac_check_socket_send(struct ucred *cred, struct socket *so); -int mac_check_socket_visible(struct ucred *cred, struct socket *so); -int mac_check_sysarch_ioperm(struct ucred *cred); -int mac_check_system_acct(struct ucred *cred, struct vnode *vp); -int mac_check_system_nfsd(struct ucred *cred); -int mac_check_system_reboot(struct ucred *cred, int howto); -int mac_check_system_settime(struct ucred *cred); -int mac_check_system_swapon(struct ucred *cred, struct vnode *vp); -int mac_check_system_swapoff(struct ucred *cred, struct vnode *vp); -int mac_check_system_sysctl(struct ucred *cred, int *name, - u_int namelen, void *old, size_t *oldlenp, int inkernel, - void *new, size_t newlen); -int mac_check_vnode_access(struct ucred *cred, struct vnode *vp, - int acc_mode); -int mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp); -int mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp); -int mac_check_vnode_create(struct ucred *cred, struct vnode *dvp, - struct componentname *cnp, struct vattr *vap); -int mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, - struct vnode *vp, struct componentname *cnp); -int mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, - acl_type_t type); -int mac_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, - int attrnamespace, const char *name); -int mac_check_vnode_exec(struct ucred *cred, struct vnode *vp, - struct image_params *imgp); -int mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, - acl_type_t type); -int mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, - int attrnamespace, const char *name, struct uio *uio); -int mac_check_vnode_link(struct ucred *cred, struct vnode *dvp, - struct vnode *vp, struct componentname *cnp); -int mac_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, - int attrnamespace); -int mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, - struct componentname *cnp); -int mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, - int prot); -int mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, - int prot); -int mac_check_vnode_open(struct ucred *cred, struct vnode *vp, - int acc_mode); -int mac_check_vnode_poll(struct ucred *active_cred, - struct ucred *file_cred, struct vnode *vp); -int mac_check_vnode_read(struct ucred *active_cred, - struct ucred *file_cred, struct vnode *vp); -int mac_check_vnode_readdir(struct ucred *cred, struct vnode *vp); -int mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp); -int mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, - struct vnode *vp, struct componentname *cnp); -int mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, - struct vnode *vp, int samedir, struct componentname *cnp); -int mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp); -int mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, - acl_type_t type, struct acl *acl); -int mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, - int attrnamespace, const char *name, struct uio *uio); -int mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, - u_long flags); -int mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, - mode_t mode); -int mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, - uid_t uid, gid_t gid); -int mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, - struct timespec atime, struct timespec mtime); -int mac_check_vnode_stat(struct ucred *active_cred, - struct ucred *file_cred, struct vnode *vp); -int mac_check_vnode_write(struct ucred *active_cred, - struct ucred *file_cred, struct vnode *vp); -int mac_getsockopt_label(struct ucred *cred, struct socket *so, - struct mac *extmac); -int mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so, - struct mac *extmac); -int mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, - struct ifnet *ifnet); -int mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, - struct ifnet *ifnet); -int mac_setsockopt_label(struct ucred *cred, struct socket *so, - struct mac *extmac); -int mac_pipe_label_set(struct ucred *cred, struct pipe *pipe, - struct label *label); -void mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred); - -/* - * Calls to help various file systems implement labeling functionality - * using their existing EA implementation. - */ -int vop_stdsetlabel_ea(struct vop_setlabel_args *ap); - -#endif /* !_KERNEL */ - -#endif /* !_SYS_MAC_H */ diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h deleted file mode 100644 index be432535c7a8..000000000000 --- a/sys/security/mac/mac_policy.h +++ /dev/null @@ -1,492 +0,0 @@ -/*- - * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson - * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed by Robert Watson for the TrustedBSD Project. - * - * This software was developed for the FreeBSD Project in part by Network - * Associates Laboratories, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), - * as part of the DARPA CHATS research program. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ -/* - * Kernel interface for MAC policy modules. - */ -#ifndef _SYS_MAC_POLICY_H -#define _SYS_MAC_POLICY_H - -/*- - * Pluggable access control policy definition structure. - * - * List of operations that are performed as part of the implementation - * of a MAC policy. Policy implementors declare operations with a - * mac_policy_ops structure, and using the MAC_POLICY_SET() macro. - * If an entry point is not declared, then then the policy will be ignored - * during evaluation of that event or check. - * - * Operations are sorted first by general class of operation, then - * alphabetically. - */ -struct acl; -struct componentname; -struct devfs_dirent; -struct inpcb; -struct ipq; -struct label; -struct mac_policy_conf; -struct mbuf; -struct mount; -struct pipe; -struct sbuf; -struct socket; -struct ucred; -struct uio; -struct vnode; -struct mac_policy_ops { - /* - * Policy module operations. - */ - void (*mpo_destroy)(struct mac_policy_conf *mpc); - void (*mpo_init)(struct mac_policy_conf *mpc); - - /* - * General policy-directed security system call so that policies - * may implement new services without reserving explicit - * system call numbers. - */ - int (*mpo_syscall)(struct thread *td, int call, void *arg); - - /* - * Label operations. - */ - void (*mpo_init_bpfdesc_label)(struct label *label); - void (*mpo_init_cred_label)(struct label *label); - void (*mpo_init_devfsdirent_label)(struct label *label); - void (*mpo_init_ifnet_label)(struct label *label); - int (*mpo_init_inpcb_label)(struct label *label, int flag); - int (*mpo_init_ipq_label)(struct label *label, int flag); - int (*mpo_init_mbuf_label)(struct label *label, int flag); - void (*mpo_init_mount_label)(struct label *label); - void (*mpo_init_mount_fs_label)(struct label *label); - int (*mpo_init_socket_label)(struct label *label, int flag); - int (*mpo_init_socket_peer_label)(struct label *label, int flag); - void (*mpo_init_pipe_label)(struct label *label); - void (*mpo_init_proc_label)(struct label *label); - void (*mpo_init_vnode_label)(struct label *label); - void (*mpo_destroy_bpfdesc_label)(struct label *label); - void (*mpo_destroy_cred_label)(struct label *label); - void (*mpo_destroy_devfsdirent_label)(struct label *label); - void (*mpo_destroy_ifnet_label)(struct label *label); - void (*mpo_destroy_inpcb_label)(struct label *label); - void (*mpo_destroy_ipq_label)(struct label *label); - void (*mpo_destroy_mbuf_label)(struct label *label); - void (*mpo_destroy_mount_label)(struct label *label); - void (*mpo_destroy_mount_fs_label)(struct label *label); - void (*mpo_destroy_socket_label)(struct label *label); - void (*mpo_destroy_socket_peer_label)(struct label *label); - void (*mpo_destroy_pipe_label)(struct label *label); - void (*mpo_destroy_proc_label)(struct label *label); - void (*mpo_destroy_vnode_label)(struct label *label); - void (*mpo_copy_cred_label)(struct label *src, - struct label *dest); - void (*mpo_copy_mbuf_label)(struct label *src, - struct label *dest); - void (*mpo_copy_pipe_label)(struct label *src, - struct label *dest); - void (*mpo_copy_socket_label)(struct label *src, - struct label *dest); - void (*mpo_copy_vnode_label)(struct label *src, - struct label *dest); - int (*mpo_externalize_cred_label)(struct label *label, - char *element_name, struct sbuf *sb, int *claimed); - int (*mpo_externalize_ifnet_label)(struct label *label, - char *element_name, struct sbuf *sb, int *claimed); - int (*mpo_externalize_pipe_label)(struct label *label, - char *element_name, struct sbuf *sb, int *claimed); - int (*mpo_externalize_socket_label)(struct label *label, - char *element_name, struct sbuf *sb, int *claimed); - int (*mpo_externalize_socket_peer_label)(struct label *label, - char *element_name, struct sbuf *sb, int *claimed); - int (*mpo_externalize_vnode_label)(struct label *label, - char *element_name, struct sbuf *sb, int *claimed); - int (*mpo_internalize_cred_label)(struct label *label, - char *element_name, char *element_data, int *claimed); - int (*mpo_internalize_ifnet_label)(struct label *label, - char *element_name, char *element_data, int *claimed); - int (*mpo_internalize_pipe_label)(struct label *label, - char *element_name, char *element_data, int *claimed); - int (*mpo_internalize_socket_label)(struct label *label, - char *element_name, char *element_data, int *claimed); - int (*mpo_internalize_vnode_label)(struct label *label, - char *element_name, char *element_data, int *claimed); - - /* - * Labeling event operations: file system objects, and things that - * look a lot like file system objects. - */ - void (*mpo_associate_vnode_devfs)(struct mount *mp, - struct label *fslabel, struct devfs_dirent *de, - struct label *delabel, struct vnode *vp, - struct label *vlabel); - int (*mpo_associate_vnode_extattr)(struct mount *mp, - struct label *fslabel, struct vnode *vp, - struct label *vlabel); - void (*mpo_associate_vnode_singlelabel)(struct mount *mp, - struct label *fslabel, struct vnode *vp, - struct label *vlabel); - void (*mpo_create_devfs_device)(struct mount *mp, dev_t dev, - struct devfs_dirent *de, struct label *label); - void (*mpo_create_devfs_directory)(struct mount *mp, char *dirname, - int dirnamelen, struct devfs_dirent *de, - struct label *label); - void (*mpo_create_devfs_symlink)(struct ucred *cred, - struct mount *mp, struct devfs_dirent *dd, - struct label *ddlabel, struct devfs_dirent *de, - struct label *delabel); - int (*mpo_create_vnode_extattr)(struct ucred *cred, - struct mount *mp, struct label *fslabel, - struct vnode *dvp, struct label *dlabel, - struct vnode *vp, struct label *vlabel, - struct componentname *cnp); - void (*mpo_create_mount)(struct ucred *cred, struct mount *mp, - struct label *mntlabel, struct label *fslabel); - void (*mpo_create_root_mount)(struct ucred *cred, struct mount *mp, - struct label *mountlabel, struct label *fslabel); - void (*mpo_relabel_vnode)(struct ucred *cred, struct vnode *vp, - struct label *vnodelabel, struct label *label); - int (*mpo_setlabel_vnode_extattr)(struct ucred *cred, - struct vnode *vp, struct label *vlabel, - struct label *intlabel); - void (*mpo_update_devfsdirent)(struct mount *mp, - struct devfs_dirent *devfs_dirent, - struct label *direntlabel, struct vnode *vp, - struct label *vnodelabel); - - /* - * Labeling event operations: IPC objects. - */ - void (*mpo_create_mbuf_from_socket)(struct socket *so, - struct label *socketlabel, struct mbuf *m, - struct label *mbuflabel); - void (*mpo_create_socket)(struct ucred *cred, struct socket *so, - struct label *socketlabel); - void (*mpo_create_socket_from_socket)(struct socket *oldsocket, - struct label *oldsocketlabel, struct socket *newsocket, - struct label *newsocketlabel); - void (*mpo_relabel_socket)(struct ucred *cred, struct socket *so, - struct label *oldlabel, struct label *newlabel); - void (*mpo_relabel_pipe)(struct ucred *cred, struct pipe *pipe, - struct label *oldlabel, struct label *newlabel); - void (*mpo_set_socket_peer_from_mbuf)(struct mbuf *mbuf, - struct label *mbuflabel, struct socket *so, - struct label *socketpeerlabel); - void (*mpo_set_socket_peer_from_socket)(struct socket *oldsocket, - struct label *oldsocketlabel, struct socket *newsocket, - struct label *newsocketpeerlabel); - void (*mpo_create_pipe)(struct ucred *cred, struct pipe *pipe, - struct label *pipelabel); - - /* - * Labeling event operations: network objects. - */ - void (*mpo_create_bpfdesc)(struct ucred *cred, struct bpf_d *bpf_d, - struct label *bpflabel); - void (*mpo_create_ifnet)(struct ifnet *ifnet, - struct label *ifnetlabel); - void (*mpo_create_inpcb_from_socket)(struct socket *so, - struct label *solabel, struct inpcb *inp, - struct label *inplabel); - void (*mpo_create_ipq)(struct mbuf *fragment, - struct label *fragmentlabel, struct ipq *ipq, - struct label *ipqlabel); - void (*mpo_create_datagram_from_ipq) - (struct ipq *ipq, struct label *ipqlabel, - struct mbuf *datagram, struct label *datagramlabel); - void (*mpo_create_fragment)(struct mbuf *datagram, - struct label *datagramlabel, struct mbuf *fragment, - struct label *fragmentlabel); - void (*mpo_create_mbuf_from_mbuf)(struct mbuf *oldmbuf, - struct label *oldlabel, struct mbuf *newmbuf, - struct label *newlabel); - void (*mpo_create_mbuf_linklayer)(struct ifnet *ifnet, - struct label *ifnetlabel, struct mbuf *mbuf, - struct label *mbuflabel); - void (*mpo_create_mbuf_from_bpfdesc)(struct bpf_d *bpf_d, - struct label *bpflabel, struct mbuf *mbuf, - struct label *mbuflabel); - void (*mpo_create_mbuf_from_ifnet)(struct ifnet *ifnet, - struct label *ifnetlabel, struct mbuf *mbuf, - struct label *mbuflabel); - void (*mpo_create_mbuf_multicast_encap)(struct mbuf *oldmbuf, - struct label *oldmbuflabel, struct ifnet *ifnet, - struct label *ifnetlabel, struct mbuf *newmbuf, - struct label *newmbuflabel); - void (*mpo_create_mbuf_netlayer)(struct mbuf *oldmbuf, - struct label *oldmbuflabel, struct mbuf *newmbuf, - struct label *newmbuflabel); - int (*mpo_fragment_match)(struct mbuf *fragment, - struct label *fragmentlabel, struct ipq *ipq, - struct label *ipqlabel); - void (*mpo_reflect_mbuf_icmp)(struct mbuf *m, - struct label *mlabel); - void (*mpo_reflect_mbuf_tcp)(struct mbuf *m, struct label *mlabel); - void (*mpo_relabel_ifnet)(struct ucred *cred, struct ifnet *ifnet, - struct label *ifnetlabel, struct label *newlabel); - void (*mpo_update_ipq)(struct mbuf *fragment, - struct label *fragmentlabel, struct ipq *ipq, - struct label *ipqlabel); - void (*mpo_inpcb_sosetlabel)(struct socket *so, - struct label *label, struct inpcb *inp, - struct label *inplabel); - - /* - * Labeling event operations: processes. - */ - void (*mpo_execve_transition)(struct ucred *old, struct ucred *new, - struct vnode *vp, struct label *vnodelabel, - struct label *interpvnodelabel, - struct image_params *imgp, struct label *execlabel); - int (*mpo_execve_will_transition)(struct ucred *old, - struct vnode *vp, struct label *vnodelabel, - struct label *interpvnodelabel, - struct image_params *imgp, struct label *execlabel); - void (*mpo_create_proc0)(struct ucred *cred); - void (*mpo_create_proc1)(struct ucred *cred); - void (*mpo_relabel_cred)(struct ucred *cred, - struct label *newlabel); - void (*mpo_thread_userret)(struct thread *thread); - - /* - * Access control checks. - */ - int (*mpo_check_bpfdesc_receive)(struct bpf_d *bpf_d, - struct label *bpflabel, struct ifnet *ifnet, - struct label *ifnetlabel); - int (*mpo_check_cred_relabel)(struct ucred *cred, - struct label *newlabel); - int (*mpo_check_cred_visible)(struct ucred *u1, struct ucred *u2); - int (*mpo_check_ifnet_relabel)(struct ucred *cred, - struct ifnet *ifnet, struct label *ifnetlabel, - struct label *newlabel); - int (*mpo_check_ifnet_transmit)(struct ifnet *ifnet, - struct label *ifnetlabel, struct mbuf *m, - struct label *mbuflabel); - int (*mpo_check_inpcb_deliver)(struct inpcb *inp, - struct label *inplabel, struct mbuf *m, - struct label *mlabel); - int (*mpo_check_kenv_dump)(struct ucred *cred); - int (*mpo_check_kenv_get)(struct ucred *cred, char *name); - int (*mpo_check_kenv_set)(struct ucred *cred, char *name, - char *value); - int (*mpo_check_kenv_unset)(struct ucred *cred, char *name); - int (*mpo_check_kld_load)(struct ucred *cred, struct vnode *vp, - struct label *vlabel); - int (*mpo_check_kld_stat)(struct ucred *cred); - int (*mpo_check_kld_unload)(struct ucred *cred); - int (*mpo_check_mount_stat)(struct ucred *cred, struct mount *mp, - struct label *mntlabel); - int (*mpo_check_pipe_ioctl)(struct ucred *cred, struct pipe *pipe, - struct label *pipelabel, unsigned long cmd, void *data); - int (*mpo_check_pipe_poll)(struct ucred *cred, struct pipe *pipe, - struct label *pipelabel); - int (*mpo_check_pipe_read)(struct ucred *cred, struct pipe *pipe, - struct label *pipelabel); - int (*mpo_check_pipe_relabel)(struct ucred *cred, - struct pipe *pipe, struct label *pipelabel, - struct label *newlabel); - int (*mpo_check_pipe_stat)(struct ucred *cred, struct pipe *pipe, - struct label *pipelabel); - int (*mpo_check_pipe_write)(struct ucred *cred, struct pipe *pipe, - struct label *pipelabel); - int (*mpo_check_proc_debug)(struct ucred *cred, - struct proc *proc); - int (*mpo_check_proc_sched)(struct ucred *cred, - struct proc *proc); - int (*mpo_check_proc_signal)(struct ucred *cred, - struct proc *proc, int signum); - int (*mpo_check_socket_bind)(struct ucred *cred, - struct socket *so, struct label *socketlabel, - struct sockaddr *sockaddr); - int (*mpo_check_socket_connect)(struct ucred *cred, - struct socket *so, struct label *socketlabel, - struct sockaddr *sockaddr); - int (*mpo_check_socket_deliver)(struct socket *so, - struct label *socketlabel, struct mbuf *m, - struct label *mbuflabel); - int (*mpo_check_socket_listen)(struct ucred *cred, - struct socket *so, struct label *socketlabel); - int (*mpo_check_socket_receive)(struct ucred *cred, - struct socket *so, struct label *socketlabel); - int (*mpo_check_socket_relabel)(struct ucred *cred, - struct socket *so, struct label *socketlabel, - struct label *newlabel); - int (*mpo_check_socket_send)(struct ucred *cred, - struct socket *so, struct label *socketlabel); - int (*mpo_check_socket_visible)(struct ucred *cred, - struct socket *so, struct label *socketlabel); - int (*mpo_check_sysarch_ioperm)(struct ucred *cred); - int (*mpo_check_system_acct)(struct ucred *cred, - struct vnode *vp, struct label *vlabel); - int (*mpo_check_system_nfsd)(struct ucred *cred); - int (*mpo_check_system_reboot)(struct ucred *cred, int howto); - int (*mpo_check_system_settime)(struct ucred *cred); - int (*mpo_check_system_swapon)(struct ucred *cred, - struct vnode *vp, struct label *label); - int (*mpo_check_system_swapoff)(struct ucred *cred, - struct vnode *vp, struct label *label); - int (*mpo_check_system_sysctl)(struct ucred *cred, int *name, - u_int namelen, void *old, size_t *oldlenp, int inkernel, - void *new, size_t newlen); - int (*mpo_check_vnode_access)(struct ucred *cred, - struct vnode *vp, struct label *label, int acc_mode); - int (*mpo_check_vnode_chdir)(struct ucred *cred, - struct vnode *dvp, struct label *dlabel); - int (*mpo_check_vnode_chroot)(struct ucred *cred, - struct vnode *dvp, struct label *dlabel); - int (*mpo_check_vnode_create)(struct ucred *cred, - struct vnode *dvp, struct label *dlabel, - struct componentname *cnp, struct vattr *vap); - int (*mpo_check_vnode_delete)(struct ucred *cred, - struct vnode *dvp, struct label *dlabel, - struct vnode *vp, struct label *label, - struct componentname *cnp); - int (*mpo_check_vnode_deleteacl)(struct ucred *cred, - struct vnode *vp, struct label *label, acl_type_t type); - int (*mpo_check_vnode_deleteextattr)(struct ucred *cred, - struct vnode *vp, struct label *label, int attrnamespace, - const char *name); - int (*mpo_check_vnode_exec)(struct ucred *cred, struct vnode *vp, - struct label *label, struct image_params *imgp, - struct label *execlabel); - int (*mpo_check_vnode_getacl)(struct ucred *cred, - struct vnode *vp, struct label *label, acl_type_t type); - int (*mpo_check_vnode_getextattr)(struct ucred *cred, - struct vnode *vp, struct label *label, int attrnamespace, - const char *name, struct uio *uio); - int (*mpo_check_vnode_link)(struct ucred *cred, struct vnode *dvp, - struct label *dlabel, struct vnode *vp, - struct label *label, struct componentname *cnp); - int (*mpo_check_vnode_listextattr)(struct ucred *cred, - struct vnode *vp, struct label *label, int attrnamespace); - int (*mpo_check_vnode_lookup)(struct ucred *cred, - struct vnode *dvp, struct label *dlabel, - struct componentname *cnp); - int (*mpo_check_vnode_mmap)(struct ucred *cred, struct vnode *vp, - struct label *label, int prot); - void (*mpo_check_vnode_mmap_downgrade)(struct ucred *cred, - struct vnode *vp, struct label *label, int *prot); - int (*mpo_check_vnode_mprotect)(struct ucred *cred, - struct vnode *vp, struct label *label, int prot); - int (*mpo_check_vnode_open)(struct ucred *cred, struct vnode *vp, - struct label *label, int acc_mode); - int (*mpo_check_vnode_poll)(struct ucred *active_cred, - struct ucred *file_cred, struct vnode *vp, - struct label *label); - int (*mpo_check_vnode_read)(struct ucred *active_cred, - struct ucred *file_cred, struct vnode *vp, - struct label *label); - int (*mpo_check_vnode_readdir)(struct ucred *cred, - struct vnode *dvp, struct label *dlabel); - int (*mpo_check_vnode_readlink)(struct ucred *cred, - struct vnode *vp, struct label *label); - int (*mpo_check_vnode_relabel)(struct ucred *cred, - struct vnode *vp, struct label *vnodelabel, - struct label *newlabel); - int (*mpo_check_vnode_rename_from)(struct ucred *cred, - struct vnode *dvp, struct label *dlabel, struct vnode *vp, - struct label *label, struct componentname *cnp); - int (*mpo_check_vnode_rename_to)(struct ucred *cred, - struct vnode *dvp, struct label *dlabel, struct vnode *vp, - struct label *label, int samedir, - struct componentname *cnp); - int (*mpo_check_vnode_revoke)(struct ucred *cred, - struct vnode *vp, struct label *label); - int (*mpo_check_vnode_setacl)(struct ucred *cred, - struct vnode *vp, struct label *label, acl_type_t type, - struct acl *acl); - int (*mpo_check_vnode_setextattr)(struct ucred *cred, - struct vnode *vp, struct label *label, int attrnamespace, - const char *name, struct uio *uio); - int (*mpo_check_vnode_setflags)(struct ucred *cred, - struct vnode *vp, struct label *label, u_long flags); - int (*mpo_check_vnode_setmode)(struct ucred *cred, - struct vnode *vp, struct label *label, mode_t mode); - int (*mpo_check_vnode_setowner)(struct ucred *cred, - struct vnode *vp, struct label *label, uid_t uid, - gid_t gid); - int (*mpo_check_vnode_setutimes)(struct ucred *cred, - struct vnode *vp, struct label *label, - struct timespec atime, struct timespec mtime); - int (*mpo_check_vnode_stat)(struct ucred *active_cred, - struct ucred *file_cred, struct vnode *vp, - struct label *label); - int (*mpo_check_vnode_write)(struct ucred *active_cred, - struct ucred *file_cred, struct vnode *vp, - struct label *label); -}; - -struct mac_policy_conf { - char *mpc_name; /* policy name */ - char *mpc_fullname; /* policy full name */ - struct mac_policy_ops *mpc_ops; /* policy operations */ - int mpc_loadtime_flags; /* flags */ - int *mpc_field_off; /* security field */ - int mpc_runtime_flags; /* flags */ - LIST_ENTRY(mac_policy_conf) mpc_list; /* global list */ -}; - -/* Flags for the mpc_loadtime_flags field. */ -#define MPC_LOADTIME_FLAG_NOTLATE 0x00000001 -#define MPC_LOADTIME_FLAG_UNLOADOK 0x00000002 -#define MPC_LOADTIME_FLAG_LABELMBUFS 0x00000004 - -/* Flags for the mpc_runtime_flags field. */ -#define MPC_RUNTIME_FLAG_REGISTERED 0x00000001 - -#define MAC_POLICY_SET(mpops, mpname, mpfullname, mpflags, privdata_wanted) \ - static struct mac_policy_conf mpname##_mac_policy_conf = { \ - #mpname, \ - mpfullname, \ - mpops, \ - mpflags, \ - privdata_wanted, \ - 0, \ - }; \ - static moduledata_t mpname##_mod = { \ - #mpname, \ - mac_policy_modevent, \ - &mpname##_mac_policy_conf \ - }; \ - MODULE_DEPEND(mpname, kernel_mac_support, 1, 1, 1); \ - DECLARE_MODULE(mpname, mpname##_mod, SI_SUB_MAC_POLICY, \ - SI_ORDER_MIDDLE) - -int mac_policy_modevent(module_t mod, int type, void *data); - -#define LABEL_TO_SLOT(l, s) (l)->l_perpolicy[s] - -#endif /* !_SYS_MAC_POLICY_H */ diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c deleted file mode 100644 index f42b075e68fd..000000000000 --- a/sys/security/mac/mac_syscalls.c +++ /dev/null @@ -1,1209 +0,0 @@ -/*- - * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson - * Copyright (c) 2001 Ilmar S. Habibulin - * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. - * All rights reserved. - * - * This software was developed by Robert Watson and Ilmar Habibulin for the - * TrustedBSD Project. - * - * This software was developed for the FreeBSD Project in part by Network - * Associates Laboratories, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), - * as part of the DARPA CHATS research program. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/*- - * Framework for extensible kernel access control. This file contains - * Kernel and userland interface to the framework, policy registration - * and composition. Per-object interfaces, controls, and labeling may be - * found in src/sys/mac/. Sample policies may be found in src/sys/mac*. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_mac.h" -#include "opt_devfs.h" - -#include <sys/param.h> -#include <sys/condvar.h> -#include <sys/extattr.h> -#include <sys/imgact.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mutex.h> -#include <sys/mac.h> -#include <sys/module.h> -#include <sys/proc.h> -#include <sys/sbuf.h> -#include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/sysent.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/file.h> -#include <sys/namei.h> -#include <sys/socket.h> -#include <sys/pipe.h> -#include <sys/socketvar.h> -#include <sys/sysctl.h> - -#include <vm/vm.h> -#include <vm/pmap.h> -#include <vm/vm_map.h> -#include <vm/vm_object.h> - -#include <sys/mac_policy.h> - -#include <fs/devfs/devfs.h> - -#include <net/bpfdesc.h> -#include <net/if.h> -#include <net/if_var.h> - -#include <netinet/in.h> -#include <netinet/ip_var.h> - -#include <security/mac/mac_internal.h> - -#ifdef MAC - -/* - * Declare that the kernel provides MAC support, version 1. This permits - * modules to refuse to be loaded if the necessary support isn't present, - * even if it's pre-boot. - */ -MODULE_VERSION(kernel_mac_support, 1); - -SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0, - "TrustedBSD MAC policy controls"); - -#if MAC_MAX_SLOTS > 32 -#error "MAC_MAX_SLOTS too large" -#endif - -static unsigned int mac_max_slots = MAC_MAX_SLOTS; -static unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1; -SYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD, - &mac_max_slots, 0, ""); - -/* - * Has the kernel started generating labeled objects yet? All read/write - * access to this variable is serialized during the boot process. Following - * the end of serialization, we don't update this flag; no locking. - */ -int mac_late = 0; - -/* - * Flag to indicate whether or not we should allocate label storage for - * new mbufs. Since most dynamic policies we currently work with don't - * rely on mbuf labeling, try to avoid paying the cost of mtag allocation - * unless specifically notified of interest. One result of this is - * that if a dynamically loaded policy requests mbuf labels, it must - * be able to deal with a NULL label being returned on any mbufs that - * were already in flight when the policy was loaded. Since the policy - * already has to deal with uninitialized labels, this probably won't - * be a problem. Note: currently no locking. Will this be a problem? - */ -#ifndef MAC_ALWAYS_LABEL_MBUF -int mac_labelmbufs = 0; -#endif - -#ifdef MAC_DEBUG -SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0, - "TrustedBSD MAC debug info"); -SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0, - "TrustedBSD MAC object counters"); - -static unsigned int nmactemp; -SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD, - &nmactemp, 0, "number of temporary labels in use"); -#endif - -static int mac_policy_register(struct mac_policy_conf *mpc); -static int mac_policy_unregister(struct mac_policy_conf *mpc); - -MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage"); - -/* - * mac_static_policy_list holds a list of policy modules that are not - * loaded while the system is "live", and cannot be unloaded. These - * policies can be invoked without holding the busy count. - * - * mac_policy_list stores the list of dynamic policies. A busy count is - * maintained for the list, stored in mac_policy_busy. The busy count - * is protected by mac_policy_mtx; the list may be modified only - * while the busy count is 0, requiring that the lock be held to - * prevent new references to the list from being acquired. For almost - * all operations, incrementing the busy count is sufficient to - * guarantee consistency, as the list cannot be modified while the - * busy count is elevated. For a few special operations involving a - * change to the list of active policies, the mtx itself must be held. - * A condition variable, mac_policy_cv, is used to signal potential - * exclusive consumers that they should try to acquire the lock if a - * first attempt at exclusive access fails. - */ -static struct mtx mac_policy_mtx; -static struct cv mac_policy_cv; -static int mac_policy_count; -struct mac_policy_list_head mac_policy_list; -struct mac_policy_list_head mac_static_policy_list; - -/* - * We manually invoke WITNESS_WARN() to allow Witness to generate - * warnings even if we don't end up ever triggering the wait at - * run-time. The consumer of the exclusive interface must not hold - * any locks (other than potentially Giant) since we may sleep for - * long (potentially indefinite) periods of time waiting for the - * framework to become quiescent so that a policy list change may - * be made. - */ -void -mac_policy_grab_exclusive(void) -{ - - WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, - "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__); - mtx_lock(&mac_policy_mtx); - while (mac_policy_count != 0) - cv_wait(&mac_policy_cv, &mac_policy_mtx); -} - -void -mac_policy_assert_exclusive(void) -{ - - mtx_assert(&mac_policy_mtx, MA_OWNED); - KASSERT(mac_policy_count == 0, - ("mac_policy_assert_exclusive(): not exclusive")); -} - -void -mac_policy_release_exclusive(void) -{ - - KASSERT(mac_policy_count == 0, - ("mac_policy_release_exclusive(): not exclusive")); - mtx_unlock(&mac_policy_mtx); - cv_signal(&mac_policy_cv); -} - -void -mac_policy_list_busy(void) -{ - - mtx_lock(&mac_policy_mtx); - mac_policy_count++; - mtx_unlock(&mac_policy_mtx); -} - -int -mac_policy_list_conditional_busy(void) -{ - int ret; - - mtx_lock(&mac_policy_mtx); - if (!LIST_EMPTY(&mac_policy_list)) { - mac_policy_count++; - ret = 1; - } else - ret = 0; - mtx_unlock(&mac_policy_mtx); - return (ret); -} - -void -mac_policy_list_unbusy(void) -{ - - mtx_lock(&mac_policy_mtx); - mac_policy_count--; - KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK")); - if (mac_policy_count == 0) - cv_signal(&mac_policy_cv); - mtx_unlock(&mac_policy_mtx); -} - -/* - * Initialize the MAC subsystem, including appropriate SMP locks. - */ -static void -mac_init(void) -{ - - LIST_INIT(&mac_static_policy_list); - LIST_INIT(&mac_policy_list); - mac_labelzone_init(); - - mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF); - cv_init(&mac_policy_cv, "mac_policy_cv"); -} - -/* - * For the purposes of modules that want to know if they were loaded - * "early", set the mac_late flag once we've processed modules either - * linked into the kernel, or loaded before the kernel startup. - */ -static void -mac_late_init(void) -{ - - mac_late = 1; -} - -/* - * After the policy list has changed, walk the list to update any global - * flags. Currently, we support only one flag, and it's conditionally - * defined; as a result, the entire function is conditional. Eventually, - * the #else case might also iterate across the policies. - */ -static void -mac_policy_updateflags(void) -{ -#ifndef MAC_ALWAYS_LABEL_MBUF - struct mac_policy_conf *tmpc; - int labelmbufs; - - mac_policy_assert_exclusive(); - - labelmbufs = 0; - LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { - if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) - labelmbufs++; - } - LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { - if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS) - labelmbufs++; - } - mac_labelmbufs = (labelmbufs != 0); -#endif -} - -/* - * Allow MAC policy modules to register during boot, etc. - */ -int -mac_policy_modevent(module_t mod, int type, void *data) -{ - struct mac_policy_conf *mpc; - int error; - - error = 0; - mpc = (struct mac_policy_conf *) data; - - switch (type) { - case MOD_LOAD: - if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE && - mac_late) { - printf("mac_policy_modevent: can't load %s policy " - "after booting\n", mpc->mpc_name); - error = EBUSY; - break; - } - error = mac_policy_register(mpc); - break; - case MOD_UNLOAD: - /* Don't unregister the module if it was never registered. */ - if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) - != 0) - error = mac_policy_unregister(mpc); - else - error = 0; - break; - default: - break; - } - - return (error); -} - -static int -mac_policy_register(struct mac_policy_conf *mpc) -{ - struct mac_policy_conf *tmpc; - int error, slot, static_entry; - - error = 0; - - /* - * We don't technically need exclusive access while !mac_late, - * but hold it for assertion consistency. - */ - mac_policy_grab_exclusive(); - - /* - * If the module can potentially be unloaded, or we're loading - * late, we have to stick it in the non-static list and pay - * an extra performance overhead. Otherwise, we can pay a - * light locking cost and stick it in the static list. - */ - static_entry = (!mac_late && - !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK)); - - if (static_entry) { - LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) { - if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { - error = EEXIST; - goto out; - } - } - } else { - LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) { - if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) { - error = EEXIST; - goto out; - } - } - } - if (mpc->mpc_field_off != NULL) { - slot = ffs(mac_slot_offsets_free); - if (slot == 0) { - error = ENOMEM; - goto out; - } - slot--; - mac_slot_offsets_free &= ~(1 << slot); - *mpc->mpc_field_off = slot; - } - mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED; - - /* - * If we're loading a MAC module after the framework has - * initialized, it has to go into the dynamic list. If - * we're loading it before we've finished initializing, - * it can go into the static list with weaker locker - * requirements. - */ - if (static_entry) - LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list); - else - LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list); - - /* Per-policy initialization. */ - if (mpc->mpc_ops->mpo_init != NULL) - (*(mpc->mpc_ops->mpo_init))(mpc); - mac_policy_updateflags(); - - printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname, - mpc->mpc_name); - -out: - mac_policy_release_exclusive(); - return (error); -} - -static int -mac_policy_unregister(struct mac_policy_conf *mpc) -{ - - /* - * If we fail the load, we may get a request to unload. Check - * to see if we did the run-time registration, and if not, - * silently succeed. - */ - mac_policy_grab_exclusive(); - if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) { - mac_policy_release_exclusive(); - return (0); - } -#if 0 - /* - * Don't allow unloading modules with private data. - */ - if (mpc->mpc_field_off != NULL) { - MAC_POLICY_LIST_UNLOCK(); - return (EBUSY); - } -#endif - /* - * Only allow the unload to proceed if the module is unloadable - * by its own definition. - */ - if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) { - mac_policy_release_exclusive(); - return (EBUSY); - } - if (mpc->mpc_ops->mpo_destroy != NULL) - (*(mpc->mpc_ops->mpo_destroy))(mpc); - - LIST_REMOVE(mpc, mpc_list); - mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED; - mac_policy_updateflags(); - - mac_policy_release_exclusive(); - - printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname, - mpc->mpc_name); - - return (0); -} - -/* - * Define an error value precedence, and given two arguments, selects the - * value with the higher precedence. - */ -int -mac_error_select(int error1, int error2) -{ - - /* Certain decision-making errors take top priority. */ - if (error1 == EDEADLK || error2 == EDEADLK) - return (EDEADLK); - - /* Invalid arguments should be reported where possible. */ - if (error1 == EINVAL || error2 == EINVAL) - return (EINVAL); - - /* Precedence goes to "visibility", with both process and file. */ - if (error1 == ESRCH || error2 == ESRCH) - return (ESRCH); - - if (error1 == ENOENT || error2 == ENOENT) - return (ENOENT); - - /* Precedence goes to DAC/MAC protections. */ - if (error1 == EACCES || error2 == EACCES) - return (EACCES); - - /* Precedence goes to privilege. */ - if (error1 == EPERM || error2 == EPERM) - return (EPERM); - - /* Precedence goes to error over success; otherwise, arbitrary. */ - if (error1 != 0) - return (error1); - return (error2); -} - -void -mac_init_label(struct label *label) -{ - - bzero(label, sizeof(*label)); - label->l_flags = MAC_FLAG_INITIALIZED; -} - -void -mac_destroy_label(struct label *label) -{ - - KASSERT(label->l_flags & MAC_FLAG_INITIALIZED, - ("destroying uninitialized label")); - - bzero(label, sizeof(*label)); - /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */ -} - -int -mac_check_structmac_consistent(struct mac *mac) -{ - - if (mac->m_buflen < 0 || - mac->m_buflen > MAC_MAX_LABEL_BUF_LEN) - return (EINVAL); - - return (0); -} - -/* - * MPSAFE - */ -int -__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) -{ - char *elements, *buffer; - struct mac mac; - struct proc *tproc; - struct ucred *tcred; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - tproc = pfind(uap->pid); - if (tproc == NULL) - return (ESRCH); - - tcred = NULL; /* Satisfy gcc. */ - error = p_cansee(td, tproc); - if (error == 0) - tcred = crhold(tproc->p_ucred); - PROC_UNLOCK(tproc); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - crfree(tcred); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - error = mac_externalize_cred_label(tcred->cr_label, elements, - buffer, mac.m_buflen); - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - crfree(tcred); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) -{ - char *elements, *buffer; - struct mac mac; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - error = mac_externalize_cred_label(td->td_ucred->cr_label, - elements, buffer, mac.m_buflen); - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) -{ - struct ucred *newcred, *oldcred; - struct label *intlabel; - struct proc *p; - struct mac mac; - char *buffer; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); - if (error) { - free(buffer, M_MACTEMP); - return (error); - } - - intlabel = mac_cred_label_alloc(); - error = mac_internalize_cred_label(intlabel, buffer); - free(buffer, M_MACTEMP); - if (error) - goto out; - - newcred = crget(); - - p = td->td_proc; - PROC_LOCK(p); - oldcred = p->p_ucred; - - error = mac_check_cred_relabel(oldcred, intlabel); - if (error) { - PROC_UNLOCK(p); - crfree(newcred); - goto out; - } - - setsugid(p); - crcopy(newcred, oldcred); - mac_relabel_cred(newcred, intlabel); - p->p_ucred = newcred; - - /* - * Grab additional reference for use while revoking mmaps, prior - * to releasing the proc lock and sharing the cred. - */ - crhold(newcred); - PROC_UNLOCK(p); - - if (mac_enforce_vm) { - mtx_lock(&Giant); - mac_cred_mmapped_drop_perms(td, newcred); - mtx_unlock(&Giant); - } - - crfree(newcred); /* Free revocation reference. */ - crfree(oldcred); - -out: - mac_cred_label_free(intlabel); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) -{ - char *elements, *buffer; - struct label *intlabel; - struct file *fp; - struct mac mac; - struct vnode *vp; - struct pipe *pipe; - struct socket *so; - short label_type; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - error = fget(td, uap->fd, &fp); - if (error) - goto out; - - label_type = fp->f_type; - switch (fp->f_type) { - case DTYPE_FIFO: - case DTYPE_VNODE: - vp = fp->f_vnode; - intlabel = mac_vnode_label_alloc(); - mtx_lock(&Giant); /* VFS */ - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - mac_copy_vnode_label(vp->v_label, intlabel); - VOP_UNLOCK(vp, 0, td); - mtx_unlock(&Giant); /* VFS */ - error = mac_externalize_vnode_label(intlabel, elements, - buffer, mac.m_buflen); - mac_vnode_label_free(intlabel); - break; - - case DTYPE_PIPE: - pipe = fp->f_data; - intlabel = mac_pipe_label_alloc(); - PIPE_LOCK(pipe); - mac_copy_pipe_label(pipe->pipe_label, intlabel); - PIPE_UNLOCK(pipe); - error = mac_externalize_pipe_label(intlabel, elements, - buffer, mac.m_buflen); - mac_pipe_label_free(intlabel); - break; - - case DTYPE_SOCKET: - so = fp->f_data; - intlabel = mac_socket_label_alloc(M_WAITOK); - mtx_lock(&Giant); /* Sockets */ - /* XXX: Socket lock here. */ - mac_copy_socket_label(so->so_label, intlabel); - /* XXX: Socket unlock here. */ - mtx_unlock(&Giant); /* Sockets */ - error = mac_externalize_socket_label(intlabel, elements, - buffer, mac.m_buflen); - mac_socket_label_free(intlabel); - break; - - default: - error = EINVAL; - } - fdrop(fp, td); - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - -out: - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) -{ - char *elements, *buffer; - struct nameidata nd; - struct label *intlabel; - struct mac mac; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - mtx_lock(&Giant); /* VFS */ - NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, - td); - error = namei(&nd); - if (error) - goto out; - - intlabel = mac_vnode_label_alloc(); - mac_copy_vnode_label(nd.ni_vp->v_label, intlabel); - error = mac_externalize_vnode_label(intlabel, elements, buffer, - mac.m_buflen); - - NDFREE(&nd, 0); - mac_vnode_label_free(intlabel); - - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - -out: - mtx_unlock(&Giant); /* VFS */ - - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - - return (error); -} - -/* - * MPSAFE - */ -int -__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) -{ - char *elements, *buffer; - struct nameidata nd; - struct label *intlabel; - struct mac mac; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); - if (error) { - free(elements, M_MACTEMP); - return (error); - } - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - mtx_lock(&Giant); /* VFS */ - NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, - td); - error = namei(&nd); - if (error) - goto out; - - intlabel = mac_vnode_label_alloc(); - mac_copy_vnode_label(nd.ni_vp->v_label, intlabel); - error = mac_externalize_vnode_label(intlabel, elements, buffer, - mac.m_buflen); - NDFREE(&nd, 0); - mac_vnode_label_free(intlabel); - - if (error == 0) - error = copyout(buffer, mac.m_string, strlen(buffer)+1); - -out: - mtx_unlock(&Giant); /* VFS */ - - free(buffer, M_MACTEMP); - free(elements, M_MACTEMP); - - return (error); -} - -/* - * MPSAFE - */ -int -__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) -{ - struct label *intlabel; - struct pipe *pipe; - struct socket *so; - struct file *fp; - struct mount *mp; - struct vnode *vp; - struct mac mac; - char *buffer; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); - if (error) { - free(buffer, M_MACTEMP); - return (error); - } - - error = fget(td, uap->fd, &fp); - if (error) - goto out; - - switch (fp->f_type) { - case DTYPE_FIFO: - case DTYPE_VNODE: - intlabel = mac_vnode_label_alloc(); - error = mac_internalize_vnode_label(intlabel, buffer); - if (error) { - mac_vnode_label_free(intlabel); - break; - } - vp = fp->f_vnode; - mtx_lock(&Giant); /* VFS */ - error = vn_start_write(vp, &mp, V_WAIT | PCATCH); - if (error != 0) { - mtx_unlock(&Giant); /* VFS */ - mac_vnode_label_free(intlabel); - break; - } - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - error = vn_setlabel(vp, intlabel, td->td_ucred); - VOP_UNLOCK(vp, 0, td); - vn_finished_write(mp); - mtx_unlock(&Giant); /* VFS */ - mac_vnode_label_free(intlabel); - break; - - case DTYPE_PIPE: - intlabel = mac_pipe_label_alloc(); - error = mac_internalize_pipe_label(intlabel, buffer); - if (error == 0) { - pipe = fp->f_data; - PIPE_LOCK(pipe); - error = mac_pipe_label_set(td->td_ucred, pipe, - intlabel); - PIPE_UNLOCK(pipe); - } - mac_pipe_label_free(intlabel); - break; - - case DTYPE_SOCKET: - intlabel = mac_socket_label_alloc(M_WAITOK); - error = mac_internalize_socket_label(intlabel, buffer); - if (error == 0) { - so = fp->f_data; - mtx_lock(&Giant); /* Sockets */ - /* XXX: Socket lock here. */ - error = mac_socket_label_set(td->td_ucred, so, - intlabel); - /* XXX: Socket unlock here. */ - mtx_unlock(&Giant); /* Sockets */ - } - mac_socket_label_free(intlabel); - break; - - default: - error = EINVAL; - } - fdrop(fp, td); -out: - free(buffer, M_MACTEMP); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) -{ - struct label *intlabel; - struct nameidata nd; - struct mount *mp; - struct mac mac; - char *buffer; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); - if (error) { - free(buffer, M_MACTEMP); - return (error); - } - - intlabel = mac_vnode_label_alloc(); - error = mac_internalize_vnode_label(intlabel, buffer); - free(buffer, M_MACTEMP); - if (error) - goto out; - - mtx_lock(&Giant); /* VFS */ - - NDINIT(&nd, LOOKUP, LOCKLEAF | FOLLOW, UIO_USERSPACE, uap->path_p, - td); - error = namei(&nd); - if (error == 0) { - error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); - if (error == 0) - error = vn_setlabel(nd.ni_vp, intlabel, - td->td_ucred); - vn_finished_write(mp); - } - - NDFREE(&nd, 0); - mtx_unlock(&Giant); /* VFS */ -out: - mac_vnode_label_free(intlabel); - return (error); -} - -/* - * MPSAFE - */ -int -__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) -{ - struct label *intlabel; - struct nameidata nd; - struct mount *mp; - struct mac mac; - char *buffer; - int error; - - error = copyin(uap->mac_p, &mac, sizeof(mac)); - if (error) - return (error); - - error = mac_check_structmac_consistent(&mac); - if (error) - return (error); - - buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); - error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); - if (error) { - free(buffer, M_MACTEMP); - return (error); - } - - intlabel = mac_vnode_label_alloc(); - error = mac_internalize_vnode_label(intlabel, buffer); - free(buffer, M_MACTEMP); - if (error) - goto out; - - mtx_lock(&Giant); /* VFS */ - - NDINIT(&nd, LOOKUP, LOCKLEAF | NOFOLLOW, UIO_USERSPACE, uap->path_p, - td); - error = namei(&nd); - if (error == 0) { - error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH); - if (error == 0) - error = vn_setlabel(nd.ni_vp, intlabel, - td->td_ucred); - vn_finished_write(mp); - } - - NDFREE(&nd, 0); - mtx_unlock(&Giant); /* VFS */ -out: - mac_vnode_label_free(intlabel); - return (error); -} - -/* - * MPSAFE - */ -int -mac_syscall(struct thread *td, struct mac_syscall_args *uap) -{ - struct mac_policy_conf *mpc; - char target[MAC_MAX_POLICY_NAME]; - int entrycount, error; - - error = copyinstr(uap->policy, target, sizeof(target), NULL); - if (error) - return (error); - - error = ENOSYS; - LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { - if (strcmp(mpc->mpc_name, target) == 0 && - mpc->mpc_ops->mpo_syscall != NULL) { - error = mpc->mpc_ops->mpo_syscall(td, - uap->call, uap->arg); - goto out; - } - } - - if ((entrycount = mac_policy_list_conditional_busy()) != 0) { - LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { - if (strcmp(mpc->mpc_name, target) == 0 && - mpc->mpc_ops->mpo_syscall != NULL) { - error = mpc->mpc_ops->mpo_syscall(td, - uap->call, uap->arg); - break; - } - } - mac_policy_list_unbusy(); - } -out: - return (error); -} - -SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL); -SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL); - -#else /* !MAC */ - -int -__mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_get_file(struct thread *td, struct __mac_get_file_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_get_link(struct thread *td, struct __mac_get_link_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_set_file(struct thread *td, struct __mac_set_file_args *uap) -{ - - return (ENOSYS); -} - -int -__mac_set_link(struct thread *td, struct __mac_set_link_args *uap) -{ - - return (ENOSYS); -} - -int -mac_syscall(struct thread *td, struct mac_syscall_args *uap) -{ - - return (ENOSYS); -} - -#endif |
