2 * Copyright (c) 1999-2002 Robert N. M. Watson
3 * Copyright (c) 2001 Ilmar S. Habibulin
4 * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
5 * Copyright (c) 2005 SPARTA, Inc.
8 * This software was developed by Robert Watson and Ilmar Habibulin for the
11 * This software was developed for the FreeBSD Project in part by Network
12 * Associates Laboratories, the Security Research Division of Network
13 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
14 * as part of the DARPA CHATS research program.
16 * This software was enhanced by SPARTA ISSO under SPAWAR contract
17 * N66001-04-C-6019 ("SEFOS").
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
28 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * Framework for extensible kernel access control. This file contains
43 * Kernel and userland interface to the framework, policy registration
44 * and composition. Per-object interfaces, controls, and labeling may be
45 * found in src/sys/security/mac/. Sample policies may be found in
46 * src/sys/security/mac_*.
49 #include <sys/cdefs.h>
50 __FBSDID("$FreeBSD$");
53 #include "opt_devfs.h"
55 #include <sys/param.h>
56 #include <sys/condvar.h>
57 #include <sys/extattr.h>
58 #include <sys/imgact.h>
59 #include <sys/kernel.h>
61 #include <sys/malloc.h>
62 #include <sys/mutex.h>
64 #include <sys/module.h>
67 #include <sys/systm.h>
68 #include <sys/sysproto.h>
69 #include <sys/sysent.h>
70 #include <sys/vnode.h>
71 #include <sys/mount.h>
73 #include <sys/namei.h>
74 #include <sys/socket.h>
76 #include <sys/socketvar.h>
77 #include <sys/sysctl.h>
81 #include <vm/vm_map.h>
82 #include <vm/vm_object.h>
84 #include <sys/mac_policy.h>
86 #include <fs/devfs/devfs.h>
88 #include <net/bpfdesc.h>
90 #include <net/if_var.h>
92 #include <netinet/in.h>
93 #include <netinet/ip_var.h>
95 #include <security/mac/mac_internal.h>
100 * Declare that the kernel provides MAC support, version 1. This permits
101 * modules to refuse to be loaded if the necessary support isn't present,
102 * even if it's pre-boot.
104 MODULE_VERSION(kernel_mac_support, 3);
106 SYSCTL_NODE(_security, OID_AUTO, mac, CTLFLAG_RW, 0,
107 "TrustedBSD MAC policy controls");
109 #if MAC_MAX_SLOTS > 32
110 #error "MAC_MAX_SLOTS too large"
113 static unsigned int mac_max_slots = MAC_MAX_SLOTS;
114 static unsigned int mac_slot_offsets_free = (1 << MAC_MAX_SLOTS) - 1;
115 SYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD,
116 &mac_max_slots, 0, "");
119 * Has the kernel started generating labeled objects yet? All read/write
120 * access to this variable is serialized during the boot process. Following
121 * the end of serialization, we don't update this flag; no locking.
126 * Flag to indicate whether or not we should allocate label storage for
127 * new mbufs. Since most dynamic policies we currently work with don't
128 * rely on mbuf labeling, try to avoid paying the cost of mtag allocation
129 * unless specifically notified of interest. One result of this is
130 * that if a dynamically loaded policy requests mbuf labels, it must
131 * be able to deal with a NULL label being returned on any mbufs that
132 * were already in flight when the policy was loaded. Since the policy
133 * already has to deal with uninitialized labels, this probably won't
134 * be a problem. Note: currently no locking. Will this be a problem?
136 #ifndef MAC_ALWAYS_LABEL_MBUF
137 int mac_labelmbufs = 0;
141 SYSCTL_NODE(_security_mac, OID_AUTO, debug, CTLFLAG_RW, 0,
142 "TrustedBSD MAC debug info");
143 SYSCTL_NODE(_security_mac_debug, OID_AUTO, counters, CTLFLAG_RW, 0,
144 "TrustedBSD MAC object counters");
146 static unsigned int nmactemp;
147 SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, temp, CTLFLAG_RD,
148 &nmactemp, 0, "number of temporary labels in use");
151 static int mac_policy_register(struct mac_policy_conf *mpc);
152 static int mac_policy_unregister(struct mac_policy_conf *mpc);
154 MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
157 * mac_static_policy_list holds a list of policy modules that are not
158 * loaded while the system is "live", and cannot be unloaded. These
159 * policies can be invoked without holding the busy count.
161 * mac_policy_list stores the list of dynamic policies. A busy count is
162 * maintained for the list, stored in mac_policy_busy. The busy count
163 * is protected by mac_policy_mtx; the list may be modified only
164 * while the busy count is 0, requiring that the lock be held to
165 * prevent new references to the list from being acquired. For almost
166 * all operations, incrementing the busy count is sufficient to
167 * guarantee consistency, as the list cannot be modified while the
168 * busy count is elevated. For a few special operations involving a
169 * change to the list of active policies, the mtx itself must be held.
170 * A condition variable, mac_policy_cv, is used to signal potential
171 * exclusive consumers that they should try to acquire the lock if a
172 * first attempt at exclusive access fails.
175 static struct mtx mac_policy_mtx;
176 static struct cv mac_policy_cv;
177 static int mac_policy_count;
179 struct mac_policy_list_head mac_policy_list;
180 struct mac_policy_list_head mac_static_policy_list;
183 * We manually invoke WITNESS_WARN() to allow Witness to generate
184 * warnings even if we don't end up ever triggering the wait at
185 * run-time. The consumer of the exclusive interface must not hold
186 * any locks (other than potentially Giant) since we may sleep for
187 * long (potentially indefinite) periods of time waiting for the
188 * framework to become quiescent so that a policy list change may
192 mac_policy_grab_exclusive(void)
199 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
200 "mac_policy_grab_exclusive() at %s:%d", __FILE__, __LINE__);
201 mtx_lock(&mac_policy_mtx);
202 while (mac_policy_count != 0)
203 cv_wait(&mac_policy_cv, &mac_policy_mtx);
208 mac_policy_assert_exclusive(void)
215 mtx_assert(&mac_policy_mtx, MA_OWNED);
216 KASSERT(mac_policy_count == 0,
217 ("mac_policy_assert_exclusive(): not exclusive"));
222 mac_policy_release_exclusive(void)
229 KASSERT(mac_policy_count == 0,
230 ("mac_policy_release_exclusive(): not exclusive"));
231 mtx_unlock(&mac_policy_mtx);
232 cv_signal(&mac_policy_cv);
237 mac_policy_list_busy(void)
244 mtx_lock(&mac_policy_mtx);
246 mtx_unlock(&mac_policy_mtx);
251 mac_policy_list_conditional_busy(void)
259 mtx_lock(&mac_policy_mtx);
260 if (!LIST_EMPTY(&mac_policy_list)) {
265 mtx_unlock(&mac_policy_mtx);
276 mac_policy_list_unbusy(void)
283 mtx_lock(&mac_policy_mtx);
285 KASSERT(mac_policy_count >= 0, ("MAC_POLICY_LIST_LOCK"));
286 if (mac_policy_count == 0)
287 cv_signal(&mac_policy_cv);
288 mtx_unlock(&mac_policy_mtx);
293 * Initialize the MAC subsystem, including appropriate SMP locks.
299 LIST_INIT(&mac_static_policy_list);
300 LIST_INIT(&mac_policy_list);
301 mac_labelzone_init();
304 mtx_init(&mac_policy_mtx, "mac_policy_mtx", NULL, MTX_DEF);
305 cv_init(&mac_policy_cv, "mac_policy_cv");
310 * For the purposes of modules that want to know if they were loaded
311 * "early", set the mac_late flag once we've processed modules either
312 * linked into the kernel, or loaded before the kernel startup.
322 * After the policy list has changed, walk the list to update any global
323 * flags. Currently, we support only one flag, and it's conditionally
324 * defined; as a result, the entire function is conditional. Eventually,
325 * the #else case might also iterate across the policies.
328 mac_policy_updateflags(void)
330 #ifndef MAC_ALWAYS_LABEL_MBUF
331 struct mac_policy_conf *tmpc;
334 mac_policy_assert_exclusive();
337 LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
338 if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
341 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
342 if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
345 mac_labelmbufs = (labelmbufs != 0);
350 * Allow MAC policy modules to register during boot, etc.
353 mac_policy_modevent(module_t mod, int type, void *data)
355 struct mac_policy_conf *mpc;
359 mpc = (struct mac_policy_conf *) data;
363 printf("mac_policy_modevent: MAC_STATIC and late\n");
370 if (mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_NOTLATE &&
372 printf("mac_policy_modevent: can't load %s policy "
373 "after booting\n", mpc->mpc_name);
377 error = mac_policy_register(mpc);
380 /* Don't unregister the module if it was never registered. */
381 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED)
383 error = mac_policy_unregister(mpc);
396 mac_policy_register(struct mac_policy_conf *mpc)
398 struct mac_policy_conf *tmpc;
399 int error, slot, static_entry;
404 * We don't technically need exclusive access while !mac_late,
405 * but hold it for assertion consistency.
407 mac_policy_grab_exclusive();
410 * If the module can potentially be unloaded, or we're loading
411 * late, we have to stick it in the non-static list and pay
412 * an extra performance overhead. Otherwise, we can pay a
413 * light locking cost and stick it in the static list.
415 static_entry = (!mac_late &&
416 !(mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK));
419 LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
420 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
426 LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
427 if (strcmp(tmpc->mpc_name, mpc->mpc_name) == 0) {
433 if (mpc->mpc_field_off != NULL) {
434 slot = ffs(mac_slot_offsets_free);
440 mac_slot_offsets_free &= ~(1 << slot);
441 *mpc->mpc_field_off = slot;
443 mpc->mpc_runtime_flags |= MPC_RUNTIME_FLAG_REGISTERED;
446 * If we're loading a MAC module after the framework has
447 * initialized, it has to go into the dynamic list. If
448 * we're loading it before we've finished initializing,
449 * it can go into the static list with weaker locker
453 LIST_INSERT_HEAD(&mac_static_policy_list, mpc, mpc_list);
455 LIST_INSERT_HEAD(&mac_policy_list, mpc, mpc_list);
457 /* Per-policy initialization. */
458 if (mpc->mpc_ops->mpo_init != NULL)
459 (*(mpc->mpc_ops->mpo_init))(mpc);
460 mac_policy_updateflags();
462 printf("Security policy loaded: %s (%s)\n", mpc->mpc_fullname,
466 mac_policy_release_exclusive();
471 mac_policy_unregister(struct mac_policy_conf *mpc)
475 * If we fail the load, we may get a request to unload. Check
476 * to see if we did the run-time registration, and if not,
479 mac_policy_grab_exclusive();
480 if ((mpc->mpc_runtime_flags & MPC_RUNTIME_FLAG_REGISTERED) == 0) {
481 mac_policy_release_exclusive();
486 * Don't allow unloading modules with private data.
488 if (mpc->mpc_field_off != NULL) {
489 MAC_POLICY_LIST_UNLOCK();
494 * Only allow the unload to proceed if the module is unloadable
495 * by its own definition.
497 if ((mpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_UNLOADOK) == 0) {
498 mac_policy_release_exclusive();
501 if (mpc->mpc_ops->mpo_destroy != NULL)
502 (*(mpc->mpc_ops->mpo_destroy))(mpc);
504 LIST_REMOVE(mpc, mpc_list);
505 mpc->mpc_runtime_flags &= ~MPC_RUNTIME_FLAG_REGISTERED;
506 mac_policy_updateflags();
508 mac_policy_release_exclusive();
510 printf("Security policy unload: %s (%s)\n", mpc->mpc_fullname,
517 * Define an error value precedence, and given two arguments, selects the
518 * value with the higher precedence.
521 mac_error_select(int error1, int error2)
524 /* Certain decision-making errors take top priority. */
525 if (error1 == EDEADLK || error2 == EDEADLK)
528 /* Invalid arguments should be reported where possible. */
529 if (error1 == EINVAL || error2 == EINVAL)
532 /* Precedence goes to "visibility", with both process and file. */
533 if (error1 == ESRCH || error2 == ESRCH)
536 if (error1 == ENOENT || error2 == ENOENT)
539 /* Precedence goes to DAC/MAC protections. */
540 if (error1 == EACCES || error2 == EACCES)
543 /* Precedence goes to privilege. */
544 if (error1 == EPERM || error2 == EPERM)
547 /* Precedence goes to error over success; otherwise, arbitrary. */
554 mac_init_label(struct label *label)
557 bzero(label, sizeof(*label));
558 label->l_flags = MAC_FLAG_INITIALIZED;
562 mac_destroy_label(struct label *label)
565 KASSERT(label->l_flags & MAC_FLAG_INITIALIZED,
566 ("destroying uninitialized label"));
568 bzero(label, sizeof(*label));
569 /* implicit: label->l_flags &= ~MAC_FLAG_INITIALIZED; */
573 mac_check_structmac_consistent(struct mac *mac)
576 if (mac->m_buflen < 0 ||
577 mac->m_buflen > MAC_MAX_LABEL_BUF_LEN)
587 __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
589 char *elements, *buffer;
595 error = copyin(uap->mac_p, &mac, sizeof(mac));
599 error = mac_check_structmac_consistent(&mac);
603 tproc = pfind(uap->pid);
607 tcred = NULL; /* Satisfy gcc. */
608 error = p_cansee(td, tproc);
610 tcred = crhold(tproc->p_ucred);
615 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
616 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
618 free(elements, M_MACTEMP);
623 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
624 error = mac_externalize_cred_label(tcred->cr_label, elements,
625 buffer, mac.m_buflen);
627 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
629 free(buffer, M_MACTEMP);
630 free(elements, M_MACTEMP);
639 __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
641 char *elements, *buffer;
645 error = copyin(uap->mac_p, &mac, sizeof(mac));
649 error = mac_check_structmac_consistent(&mac);
653 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
654 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
656 free(elements, M_MACTEMP);
660 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
661 error = mac_externalize_cred_label(td->td_ucred->cr_label,
662 elements, buffer, mac.m_buflen);
664 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
666 free(buffer, M_MACTEMP);
667 free(elements, M_MACTEMP);
675 __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
677 struct ucred *newcred, *oldcred;
678 struct label *intlabel;
684 error = copyin(uap->mac_p, &mac, sizeof(mac));
688 error = mac_check_structmac_consistent(&mac);
692 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
693 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
695 free(buffer, M_MACTEMP);
699 intlabel = mac_cred_label_alloc();
700 error = mac_internalize_cred_label(intlabel, buffer);
701 free(buffer, M_MACTEMP);
709 oldcred = p->p_ucred;
711 error = mac_check_cred_relabel(oldcred, intlabel);
719 crcopy(newcred, oldcred);
720 mac_relabel_cred(newcred, intlabel);
721 p->p_ucred = newcred;
724 * Grab additional reference for use while revoking mmaps, prior
725 * to releasing the proc lock and sharing the cred.
730 if (mac_enforce_vm) {
731 mac_cred_mmapped_drop_perms(td, newcred);
734 crfree(newcred); /* Free revocation reference. */
738 mac_cred_label_free(intlabel);
746 __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
748 char *elements, *buffer;
749 struct label *intlabel;
756 int vfslocked, error;
758 error = copyin(uap->mac_p, &mac, sizeof(mac));
762 error = mac_check_structmac_consistent(&mac);
766 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
767 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
769 free(elements, M_MACTEMP);
773 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
774 error = fget(td, uap->fd, &fp);
778 label_type = fp->f_type;
779 switch (fp->f_type) {
783 intlabel = mac_vnode_label_alloc();
784 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
785 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
786 mac_copy_vnode_label(vp->v_label, intlabel);
787 VOP_UNLOCK(vp, 0, td);
788 VFS_UNLOCK_GIANT(vfslocked);
789 error = mac_externalize_vnode_label(intlabel, elements,
790 buffer, mac.m_buflen);
791 mac_vnode_label_free(intlabel);
796 intlabel = mac_pipe_label_alloc();
798 mac_copy_pipe_label(pipe->pipe_pair->pp_label, intlabel);
800 error = mac_externalize_pipe_label(intlabel, elements,
801 buffer, mac.m_buflen);
802 mac_pipe_label_free(intlabel);
807 intlabel = mac_socket_label_alloc(M_WAITOK);
810 mac_copy_socket_label(so->so_label, intlabel);
813 error = mac_externalize_socket_label(intlabel, elements,
814 buffer, mac.m_buflen);
815 mac_socket_label_free(intlabel);
823 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
826 free(buffer, M_MACTEMP);
827 free(elements, M_MACTEMP);
835 __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
837 char *elements, *buffer;
839 struct label *intlabel;
841 int vfslocked, error;
843 error = copyin(uap->mac_p, &mac, sizeof(mac));
847 error = mac_check_structmac_consistent(&mac);
851 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
852 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
854 free(elements, M_MACTEMP);
858 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
859 NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE,
865 intlabel = mac_vnode_label_alloc();
866 vfslocked = NDHASGIANT(&nd);
867 mac_copy_vnode_label(nd.ni_vp->v_label, intlabel);
868 error = mac_externalize_vnode_label(intlabel, elements, buffer,
872 VFS_UNLOCK_GIANT(vfslocked);
873 mac_vnode_label_free(intlabel);
875 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
878 free(buffer, M_MACTEMP);
879 free(elements, M_MACTEMP);
888 __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
890 char *elements, *buffer;
892 struct label *intlabel;
894 int vfslocked, error;
896 error = copyin(uap->mac_p, &mac, sizeof(mac));
900 error = mac_check_structmac_consistent(&mac);
904 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
905 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
907 free(elements, M_MACTEMP);
911 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
912 NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE,
918 intlabel = mac_vnode_label_alloc();
919 vfslocked = NDHASGIANT(&nd);
920 mac_copy_vnode_label(nd.ni_vp->v_label, intlabel);
921 error = mac_externalize_vnode_label(intlabel, elements, buffer,
924 VFS_UNLOCK_GIANT(vfslocked);
925 mac_vnode_label_free(intlabel);
928 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
931 free(buffer, M_MACTEMP);
932 free(elements, M_MACTEMP);
941 __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
943 struct label *intlabel;
951 int error, vfslocked;
953 error = copyin(uap->mac_p, &mac, sizeof(mac));
957 error = mac_check_structmac_consistent(&mac);
961 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
962 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
964 free(buffer, M_MACTEMP);
968 error = fget(td, uap->fd, &fp);
972 switch (fp->f_type) {
975 intlabel = mac_vnode_label_alloc();
976 error = mac_internalize_vnode_label(intlabel, buffer);
978 mac_vnode_label_free(intlabel);
982 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
983 error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
985 VFS_UNLOCK_GIANT(vfslocked);
986 mac_vnode_label_free(intlabel);
989 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
990 error = vn_setlabel(vp, intlabel, td->td_ucred);
991 VOP_UNLOCK(vp, 0, td);
992 vn_finished_write(mp);
993 VFS_UNLOCK_GIANT(vfslocked);
994 mac_vnode_label_free(intlabel);
998 intlabel = mac_pipe_label_alloc();
999 error = mac_internalize_pipe_label(intlabel, buffer);
1003 error = mac_pipe_label_set(td->td_ucred,
1004 pipe->pipe_pair, intlabel);
1007 mac_pipe_label_free(intlabel);
1011 intlabel = mac_socket_label_alloc(M_WAITOK);
1012 error = mac_internalize_socket_label(intlabel, buffer);
1016 error = mac_socket_label_set(td->td_ucred, so,
1020 mac_socket_label_free(intlabel);
1028 free(buffer, M_MACTEMP);
1036 __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
1038 struct label *intlabel;
1039 struct nameidata nd;
1043 int vfslocked, error;
1045 error = copyin(uap->mac_p, &mac, sizeof(mac));
1049 error = mac_check_structmac_consistent(&mac);
1053 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
1054 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
1056 free(buffer, M_MACTEMP);
1060 intlabel = mac_vnode_label_alloc();
1061 error = mac_internalize_vnode_label(intlabel, buffer);
1062 free(buffer, M_MACTEMP);
1066 NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | FOLLOW, UIO_USERSPACE,
1069 vfslocked = NDHASGIANT(&nd);
1071 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
1073 error = vn_setlabel(nd.ni_vp, intlabel,
1075 vn_finished_write(mp);
1079 VFS_UNLOCK_GIANT(vfslocked);
1081 mac_vnode_label_free(intlabel);
1089 __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
1091 struct label *intlabel;
1092 struct nameidata nd;
1096 int vfslocked, error;
1098 error = copyin(uap->mac_p, &mac, sizeof(mac));
1102 error = mac_check_structmac_consistent(&mac);
1106 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
1107 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
1109 free(buffer, M_MACTEMP);
1113 intlabel = mac_vnode_label_alloc();
1114 error = mac_internalize_vnode_label(intlabel, buffer);
1115 free(buffer, M_MACTEMP);
1119 NDINIT(&nd, LOOKUP, MPSAFE | LOCKLEAF | NOFOLLOW, UIO_USERSPACE,
1122 vfslocked = NDHASGIANT(&nd);
1124 error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH);
1126 error = vn_setlabel(nd.ni_vp, intlabel,
1128 vn_finished_write(mp);
1132 VFS_UNLOCK_GIANT(vfslocked);
1134 mac_vnode_label_free(intlabel);
1142 mac_syscall(struct thread *td, struct mac_syscall_args *uap)
1144 struct mac_policy_conf *mpc;
1145 char target[MAC_MAX_POLICY_NAME];
1146 int entrycount, error;
1148 error = copyinstr(uap->policy, target, sizeof(target), NULL);
1153 LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) {
1154 if (strcmp(mpc->mpc_name, target) == 0 &&
1155 mpc->mpc_ops->mpo_syscall != NULL) {
1156 error = mpc->mpc_ops->mpo_syscall(td,
1157 uap->call, uap->arg);
1162 if ((entrycount = mac_policy_list_conditional_busy()) != 0) {
1163 LIST_FOREACH(mpc, &mac_policy_list, mpc_list) {
1164 if (strcmp(mpc->mpc_name, target) == 0 &&
1165 mpc->mpc_ops->mpo_syscall != NULL) {
1166 error = mpc->mpc_ops->mpo_syscall(td,
1167 uap->call, uap->arg);
1171 mac_policy_list_unbusy();
1177 SYSINIT(mac, SI_SUB_MAC, SI_ORDER_FIRST, mac_init, NULL);
1178 SYSINIT(mac_late, SI_SUB_MAC_LATE, SI_ORDER_FIRST, mac_late_init, NULL);
1183 __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
1190 __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
1197 __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
1204 __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
1211 __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
1218 __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
1225 __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
1232 __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
1239 __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
1246 mac_syscall(struct thread *td, struct mac_syscall_args *uap)