summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/conf/files1
-rw-r--r--sys/fs/devfs/devfs_vnops.c2
-rw-r--r--sys/fs/procfs/procfs.c1
-rw-r--r--sys/fs/procfs/procfs.h3
-rw-r--r--sys/fs/procfs/procfs_mac.c68
-rw-r--r--sys/fs/pseudofs/pseudofs.h10
-rw-r--r--sys/fs/pseudofs/pseudofs_vnops.c47
-rw-r--r--sys/kern/kern_mac.c576
-rw-r--r--sys/kern/vfs_subr.c2
-rw-r--r--sys/modules/procfs/Makefile2
-rw-r--r--sys/security/mac/mac_framework.c576
-rw-r--r--sys/security/mac/mac_framework.h16
-rw-r--r--sys/security/mac/mac_internal.h576
-rw-r--r--sys/security/mac/mac_net.c576
-rw-r--r--sys/security/mac/mac_pipe.c576
-rw-r--r--sys/security/mac/mac_policy.h47
-rw-r--r--sys/security/mac/mac_process.c576
-rw-r--r--sys/security/mac/mac_syscalls.c576
-rw-r--r--sys/security/mac/mac_system.c576
-rw-r--r--sys/security/mac/mac_vfs.c576
-rw-r--r--sys/security/mac_biba/mac_biba.c181
-rw-r--r--sys/security/mac_mls/mac_mls.c159
-rw-r--r--sys/security/mac_none/mac_none.c82
-rw-r--r--sys/security/mac_stub/mac_stub.c82
-rw-r--r--sys/security/mac_test/mac_test.c83
-rw-r--r--sys/sys/mac.h16
-rw-r--r--sys/sys/mac_policy.h47
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c18
-rw-r--r--sys/ufs/ufs/ufs_vnops.c27
29 files changed, 1254 insertions, 4824 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 53978aa..8aec70d 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -829,7 +829,6 @@ fs/procfs/procfs_ctl.c optional procfs
fs/procfs/procfs_dbregs.c optional procfs
fs/procfs/procfs_fpregs.c optional procfs
fs/procfs/procfs_ioctl.c optional procfs
-fs/procfs/procfs_mac.c optional procfs
fs/procfs/procfs_map.c optional procfs
fs/procfs/procfs_mem.c optional procfs
fs/procfs/procfs_note.c optional procfs
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 869a20f..f7b99d5 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -167,7 +167,7 @@ loop:
de->de_vnode = vp;
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
#ifdef MAC
- mac_create_devfs_vnode(de, vp);
+ mac_associate_vnode_devfs(mp, de, vp);
#endif
*vpp = vp;
return (0);
diff --git a/sys/fs/procfs/procfs.c b/sys/fs/procfs/procfs.c
index e99653a..f6cab6a 100644
--- a/sys/fs/procfs/procfs.c
+++ b/sys/fs/procfs/procfs.c
@@ -153,7 +153,6 @@ procfs_init(PFS_INIT_ARGS)
dir = pfs_create_dir(root, "pid",
procfs_attr, NULL, PFS_PROCDEP);
- dir->pn_refreshlabel = procfs_piddir_refreshlabel;
pfs_create_file(dir, "cmdline", procfs_doproccmdline,
NULL, NULL, PFS_RD);
pfs_create_file(dir, "ctl", procfs_doprocctl,
diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h
index 61f6e954..4baaf50 100644
--- a/sys/fs/procfs/procfs.h
+++ b/sys/fs/procfs/procfs.h
@@ -61,9 +61,6 @@ int procfs_close(PFS_CLOSE_ARGS);
/* Attributes */
int procfs_attr(PFS_ATTR_ARGS);
-/* MAC */
-int procfs_piddir_refreshlabel(PFS_REFRESHLABEL_ARGS);
-
/* Visibility */
int procfs_notsystem(PFS_VIS_ARGS);
int procfs_candebug(PFS_VIS_ARGS);
diff --git a/sys/fs/procfs/procfs_mac.c b/sys/fs/procfs/procfs_mac.c
deleted file mode 100644
index ea5c9f5..0000000
--- a/sys/fs/procfs/procfs_mac.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*-
- * Copyright (c) 2002 Network Associates Technology, Inc.
- * All rights reserved.
- *
- * This software was developed in part by NAI Labs, 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.
- * 3. The names of the authors may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * 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$
- */
-
-#include "opt_mac.h"
-
-#include <sys/param.h>
-#include <sys/lock.h>
-#include <sys/mac.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/ucred.h>
-#include <sys/vnode.h>
-
-#include <fs/pseudofs/pseudofs.h>
-#include <fs/procfs/procfs.h>
-
-int
-procfs_piddir_refreshlabel(PFS_REFRESHLABEL_ARGS)
-{
-#ifdef MAC
-
- if (p == NULL)
- mac_update_vnode_from_mount(vp, vp->v_mount);
- else {
- PROC_LOCK(p);
- mac_update_procfsvnode(vp, p->p_ucred);
- PROC_UNLOCK(p);
- }
-
- return (0);
-#else
- return (EOPNOTSUPP);
-#endif
-}
diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h
index c7a64dd..2b9d01b 100644
--- a/sys/fs/pseudofs/pseudofs.h
+++ b/sys/fs/pseudofs/pseudofs.h
@@ -145,15 +145,6 @@ struct ucred;
typedef int (*pfs_getextattr_t)(PFS_GETEXTATTR_ARGS);
/*
- * Getlabel callback
- */
-#define PFS_REFRESHLABEL_ARGS \
- struct thread *td, struct proc *p, struct vnode *vp, \
- struct pfs_node *pn, struct ucred *cred
-struct mac;
-typedef int (*pfs_refreshlabel_t)(PFS_REFRESHLABEL_ARGS);
-
-/*
* Last-close callback
*/
#define PFS_CLOSE_ARGS \
@@ -194,7 +185,6 @@ struct pfs_node {
pfs_attr_t pn_attr;
pfs_vis_t pn_vis;
pfs_getextattr_t pn_getextattr;
- pfs_refreshlabel_t pn_refreshlabel;
void *pn_data;
int pn_flags;
diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c
index 932adc0..b797aeb 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -28,8 +28,6 @@
* $FreeBSD$
*/
-#include "opt_mac.h"
-
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
@@ -37,7 +35,6 @@
#include <sys/dirent.h>
#include <sys/fcntl.h>
#include <sys/lock.h>
-#include <sys/mac.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
@@ -732,50 +729,6 @@ pfs_reclaim(struct vop_reclaim_args *va)
return (pfs_vncache_free(va->a_vp));
}
-#ifdef MAC
-/*
- * Refresh the vnode label as appropriate for the pseudo-file system.
- */
-static int
-pfs_refreshlabel(struct vop_refreshlabel_args *va)
-{
- struct vnode *vn = va->a_vp;
- struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
- struct pfs_node *pn = pvd->pvd_pn;
- struct proc *proc = NULL;
- int error;
-
- PFS_TRACE((pd->pn_name));
-
- if (pn->pn_refreshlabel == NULL) {
- mac_update_vnode_from_mount(vn, vn->v_mount);
- return (0);
- }
-
- /*
- * This is necessary because either process' privileges may
- * have changed since the last open() call.
- */
- if (!pfs_visible(curthread, pn, pvd->pvd_pid))
- PFS_RETURN (EIO);
-
- /* XXX duplicate bits of pfs_visible() */
- if (pvd->pvd_pid != NO_PID) {
- if ((proc = pfind(pvd->pvd_pid)) == NULL)
- PFS_RETURN (EIO);
- _PHOLD(proc);
- PROC_UNLOCK(proc);
- }
-
- error = (pn->pn_refreshlabel)(curthread, proc, vn, pn, va->a_cred);
-
- if (proc != NULL)
- PRELE(proc);
-
- PFS_RETURN (error);
-}
-#endif
-
/*
* Set attributes
*/
diff --git a/sys/kern/kern_mac.c b/sys/kern/kern_mac.c
index 78bc485..2ff4162 100644
--- a/sys/kern/kern_mac.c
+++ b/sys/kern/kern_mac.c
@@ -115,6 +115,12 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
*/
static int mac_late = 0;
+/*
+ * Warn about EA transactions only the first time they happen.
+ * Weak coherency, no locking.
+ */
+static int ea_warn_once = 0;
+
static int mac_enforce_fs = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -145,23 +151,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
-static int mac_label_size = sizeof(struct oldmac);
-SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
- &mac_label_size, 0, "Pre-compiled MAC label size");
-
static int mac_cache_fslabel_in_vnode = 1;
SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
&mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
&mac_cache_fslabel_in_vnode);
-static int mac_vnode_label_cache_hits = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
- &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
-static int mac_vnode_label_cache_misses = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
- &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
-
static int mac_mmap_revocation = 1;
SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
&mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
@@ -214,12 +209,9 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
#endif
static int error_select(int error1, int error2);
-static int mac_externalize_vnode_oldmac(struct label *label,
- struct oldmac *extmac);
static int mac_policy_register(struct mac_policy_conf *mpc);
static int mac_policy_unregister(struct mac_policy_conf *mpc);
-static int mac_stdcreatevnode_ea(struct vnode *vp);
static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
struct vnode *vp, int *prot);
static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
@@ -227,6 +219,10 @@ static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
static void mac_destroy_socket_label(struct label *label);
+static int mac_setlabel_vnode_extattr(struct ucred *cred,
+ struct vnode *vp, struct label *intlabel);
+
+
MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@@ -623,10 +619,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_externalize_vnode_label =
mpe->mpe_function;
break;
- case MAC_EXTERNALIZE_VNODE_OLDMAC:
- mpc->mpc_ops->mpo_externalize_vnode_oldmac =
- mpe->mpe_function;
- break;
case MAC_INTERNALIZE_CRED_LABEL:
mpc->mpc_ops->mpo_internalize_cred_label =
mpe->mpe_function;
@@ -663,14 +655,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_create_devfs_vnode =
mpe->mpe_function;
break;
- case MAC_STDCREATEVNODE_EA:
- mpc->mpc_ops->mpo_stdcreatevnode_ea =
- mpe->mpe_function;
- break;
- case MAC_CREATE_VNODE:
- mpc->mpc_ops->mpo_create_vnode =
- mpe->mpe_function;
- break;
case MAC_CREATE_MOUNT:
mpc->mpc_ops->mpo_create_mount =
mpe->mpe_function;
@@ -687,20 +671,24 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_update_devfsdirent =
mpe->mpe_function;
break;
- case MAC_UPDATE_PROCFSVNODE:
- mpc->mpc_ops->mpo_update_procfsvnode =
+ case MAC_ASSOCIATE_VNODE_DEVFS:
+ mpc->mpc_ops->mpo_associate_vnode_devfs =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTATTR:
- mpc->mpc_ops->mpo_update_vnode_from_extattr =
+ case MAC_ASSOCIATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_associate_vnode_extattr =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
- mpc->mpc_ops->mpo_update_vnode_from_externalized =
+ case MAC_ASSOCIATE_VNODE_SINGLELABEL:
+ mpc->mpc_ops->mpo_associate_vnode_singlelabel =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_MOUNT:
- mpc->mpc_ops->mpo_update_vnode_from_mount =
+ case MAC_CREATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_create_vnode_extattr =
+ mpe->mpe_function;
+ break;
+ case MAC_SETLABEL_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_setlabel_vnode_extattr =
mpe->mpe_function;
break;
case MAC_CREATE_MBUF_FROM_SOCKET:
@@ -1379,7 +1367,7 @@ mac_init_socket(struct socket *socket, int flag)
return (error);
}
-static void
+void
mac_init_vnode_label(struct label *label)
{
@@ -1536,7 +1524,7 @@ mac_destroy_socket(struct socket *socket)
mac_destroy_socket_peer_label(&socket->so_peerlabel);
}
-static void
+void
mac_destroy_vnode_label(struct label *label)
{
@@ -1561,7 +1549,7 @@ mac_copy_pipe_label(struct label *src, struct label *dest)
MAC_PERFORM(copy_pipe_label, src, dest);
}
-static void
+void
mac_copy_vnode_label(struct label *src, struct label *dest)
{
@@ -1645,16 +1633,6 @@ mac_externalize_vnode_label(struct label *label, char *elements,
}
static int
-mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(externalize_vnode_oldmac, label, extmac);
-
- return (error);
-}
-
-static int
mac_internalize_cred_label(struct label *label, char *string)
{
int error;
@@ -1753,276 +1731,118 @@ mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
}
void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
+ struct vnode *vp)
{
- MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+ MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
+ &de->de_label, vp, &vp->v_label);
}
-/*
- * Support callout for policies that manage their own externalization
- * using extended attributes.
- */
-static int
-mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
+int
+mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
{
int error;
- MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- return (error);
-}
+ ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+ MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
return (error);
}
-/*
- * Call out to individual policies to update the label in a vnode from
- * the mountpoint.
- */
void
-mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
+mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
{
- MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
- if (mac_cache_fslabel_in_vnode)
- vp->v_vflag |= VV_CACHEDLABEL;
+ MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
}
-/*
- * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
- * to store label data. Can be referenced by filesystems supporting
- * extended attributes.
- */
int
-vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
+mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+ struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
- struct vnode *vp = ap->a_vp;
- struct oldmac extmac;
- int buflen, error;
+ int error;
- ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+ ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
+ ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
- /*
- * Call out to external policies first. Order doesn't really
- * matter, as long as failure of one assures failure of all.
- */
- error = mac_update_vnode_from_extattr(vp, vp->v_mount);
- if (error)
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
return (error);
- buflen = sizeof(extmac);
- error = vn_extattr_get(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
- (char *)&extmac, curthread);
- switch (error) {
- case 0:
- /* Got it */
- break;
-
- case ENOATTR:
- /*
- * Use the label from the mount point.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
+ MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
+ dvp, &dvp->v_label, vp, &vp->v_label, cnp);
- case EOPNOTSUPP:
- default:
- /* Fail horribly. */
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
- if (buflen != sizeof(extmac))
- error = EPERM; /* Fail very closed. */
- if (error == 0)
- error = mac_update_vnode_from_externalized(vp, &extmac);
- if (error == 0)
- vp->v_vflag |= VV_CACHEDLABEL;
- else {
- struct vattr va;
-
- printf("Corrupted label on %s",
- vp->v_mount->mnt_stat.f_mntonname);
- if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
- printf(" inum %ld", va.va_fileid);
-#ifdef MAC_DEBUG
- if (mac_debug_label_fallback) {
- printf(", falling back.\n");
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- } else {
-#endif
- printf(".\n");
- error = EPERM;
-#ifdef MAC_DEBUG
- }
-#endif
- }
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
+
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
return (error);
}
-/*
- * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle
- * the labeling activity outselves. Filesystems should be careful not
- * to change their minds regarding whether they support vop_refreshlabel()
- * for a vnode or not. Don't cache the vnode here, allow the file
- * system code to determine if it's safe to cache. If we update from
- * the mount, don't cache since a change to the mount label should affect
- * all vnodes.
- */
static int
-vn_refreshlabel(struct vnode *vp, struct ucred *cred)
+mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *intlabel)
{
int error;
- ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
-
- if (vp->v_mount == NULL) {
-/*
- Eventually, we probably want to special-case refreshing
- of deadfs vnodes, and if there's a lock-free race somewhere,
- that case might be handled here.
+ ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
- mac_update_vnode_deadfs(vp);
- return (0);
- */
- /* printf("vn_refreshlabel: null v_mount\n"); */
- if (vp->v_type != VNON)
- printf(
- "vn_refreshlabel: null v_mount with non-VNON\n");
- return (EBADF);
- }
-
- if (vp->v_vflag & VV_CACHEDLABEL) {
- mac_vnode_label_cache_hits++;
- return (0);
- } else
- mac_vnode_label_cache_misses++;
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
+ return (error);
- if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
- }
+ MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
- error = VOP_REFRESHLABEL(vp, cred, curthread);
- switch (error) {
- case EOPNOTSUPP:
- /*
- * If labels are not supported on this vnode, fall back to
- * the label in the mount and propagate it to the vnode.
- * There should probably be some sort of policy/flag/decision
- * about doing this.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- default:
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
-}
-/*
- * Helper function for file systems using the vop_std*_ea() calls. This
- * function must be called after EA service is available for the vnode,
- * but before it's hooked up to the namespace so that the node persists
- * if there's a crash, or before it can be accessed. On successful
- * commit of the label to disk (etc), do cache the label.
- */
-int
-vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
-{
- struct oldmac extmac;
- int error;
-
- ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
- if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(tvp, tvp->v_mount);
- } else {
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- /*
- * Stick the label in the vnode. Then try to write to
- * disk. If we fail, return a failure to abort the
- * create operation. Really, this failure shouldn't
- * happen except in fairly unusual circumstances (out
- * of disk, etc).
- */
- mac_create_vnode(cred, dvp, tvp);
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
- error = mac_stdcreatevnode_ea(tvp);
- if (error)
- return (error);
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
- /*
- * XXX: Eventually this will go away and all policies will
- * directly manage their extended attributes.
- */
- error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
- if (error)
- return (error);
-
- error = vn_extattr_set(tvp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
- if (error == 0)
- tvp->v_vflag |= VV_CACHEDLABEL;
- else {
-#if 0
- /*
- * In theory, we could have fall-back behavior here.
- * It would probably be incorrect.
- */
-#endif
- return (error);
- }
- }
-
- return (0);
+ return (error);
}
void
mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
{
- int error;
ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
- error = vn_refreshlabel(vp, old);
- if (error) {
- printf("mac_execve_transition: vn_refreshlabel returned %d\n",
- error);
- printf("mac_execve_transition: using old vnode label\n");
- }
-
MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
}
int
mac_execve_will_transition(struct ucred *old, struct vnode *vp)
{
- int error, result;
-
- error = vn_refreshlabel(vp, old);
- if (error)
- return (error);
+ int result;
result = 0;
MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
@@ -2040,10 +1860,6 @@ mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2058,10 +1874,6 @@ mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2076,10 +1888,6 @@ mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2095,10 +1903,6 @@ mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
return (error);
}
@@ -2115,13 +1919,6 @@ mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2138,10 +1935,6 @@ mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2156,9 +1949,6 @@ mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_process && !mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
return (error);
@@ -2174,10 +1964,6 @@ mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2193,10 +1979,6 @@ mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2214,14 +1996,6 @@ mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2238,10 +2012,6 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
return (error);
}
@@ -2256,10 +2026,6 @@ mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2290,10 +2056,6 @@ mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2308,10 +2070,6 @@ mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
return (error);
}
@@ -2327,10 +2085,6 @@ mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
&vp->v_label);
@@ -2348,10 +2102,6 @@ mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
&vp->v_label);
@@ -2368,10 +2118,6 @@ mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2386,10 +2132,6 @@ mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
return (error);
}
@@ -2402,10 +2144,6 @@ mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
return (error);
@@ -2423,13 +2161,6 @@ mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2447,14 +2178,6 @@ mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- if (vp != NULL) {
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
- }
MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
vp != NULL ? &vp->v_label : NULL, samedir, cnp);
return (error);
@@ -2470,10 +2193,6 @@ mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
return (error);
}
@@ -2489,10 +2208,6 @@ mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
return (error);
}
@@ -2508,10 +2223,6 @@ mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2527,10 +2238,6 @@ mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2545,10 +2252,6 @@ mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
return (error);
}
@@ -2564,10 +2267,6 @@ mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
return (error);
}
@@ -2583,10 +2282,6 @@ mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
mtime);
return (error);
@@ -2603,10 +2298,6 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
&vp->v_label);
return (error);
@@ -2622,10 +2313,6 @@ mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
@@ -2641,10 +2328,6 @@ mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
&vp->v_label);
@@ -3344,7 +3027,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3352,7 +3034,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3382,7 +3063,6 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3444,16 +3124,6 @@ mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
&de->de_label);
}
-static int
-mac_stdcreatevnode_ea(struct vnode *vp)
-{
- int error;
-
- MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
-
- return (error);
-}
-
void
mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de)
@@ -3463,29 +3133,6 @@ mac_create_devfs_directory(char *dirname, int dirnamelen,
&de->de_label);
}
-/*
- * When a new vnode is created, this call will initialize its label.
- */
-void
-mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child)
-{
- int error;
-
- ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
- ASSERT_VOP_LOCKED(child, "mac_create_vnode");
-
- error = vn_refreshlabel(parent, cred);
- if (error) {
- printf("mac_create_vnode: vn_refreshlabel returned %d\n",
- error);
- printf("mac_create_vnode: using old vnode label\n");
- }
-
- MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
- &child->v_label);
-}
-
int
mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
struct mac *mac)
@@ -3499,7 +3146,6 @@ mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
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);
@@ -3554,7 +3200,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
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);
@@ -3562,7 +3207,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_label(&so->so_label, elements,
buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3586,7 +3230,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
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);
@@ -3594,7 +3237,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_peer_label(&so->so_peerlabel,
elements, buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3616,35 +3258,19 @@ vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
{
struct vnode *vp = ap->a_vp;
struct label *intlabel = ap->a_label;
- struct oldmac extmac;
int error;
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
- /*
- * XXX: Eventually call out to EA check/set calls here.
- * Be particularly careful to avoid race conditions,
- * consistency problems, and stability problems when
- * dealing with multiple EAs. In particular, we require
- * the ability to write multiple EAs on the same file in
- * a single transaction, which the current EA interface
- * does not provide.
- */
-
- error = mac_externalize_vnode_oldmac(intlabel, &extmac);
- if (error)
- return (error);
+ if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+ return (EOPNOTSUPP);
- error = vn_extattr_set(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
+ error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
if (error)
return (error);
mac_relabel_vnode(ap->a_cred, vp, intlabel);
- vp->v_vflag |= VV_CACHEDLABEL;
-
return (0);
}
@@ -3721,7 +3347,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
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);
@@ -3730,7 +3355,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_cred_label(&tcred->cr_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3761,7 +3385,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
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);
@@ -3769,7 +3392,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
}
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, M_WAITOK);
if (error == 0)
@@ -3802,7 +3424,6 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
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);
@@ -3880,7 +3501,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
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);
@@ -3888,7 +3508,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
mtx_lock(&Giant); /* VFS */
error = fget(td, SCARG(uap, fd), &fp);
if (error)
@@ -3903,9 +3522,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
mac_init_vnode_label(&intlabel);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = vn_refreshlabel(vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&vp->v_label, &intlabel);
+ mac_copy_vnode_label(&vp->v_label, &intlabel);
VOP_UNLOCK(vp, 0, td);
break;
@@ -3974,7 +3591,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
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);
@@ -3982,7 +3598,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
}
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);
@@ -3991,12 +3606,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4034,7 +3646,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
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);
@@ -4042,7 +3653,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
}
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);
@@ -4051,12 +3661,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4096,7 +3703,6 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
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);
@@ -4183,7 +3789,6 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
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);
@@ -4240,7 +3845,6 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
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);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index c847563..dd377fc 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1004,6 +1004,8 @@ getnewvnode(tag, mp, vops, vpp)
VI_UNLOCK(vp);
#ifdef MAC
mac_init_vnode(vp);
+ if (mp != NULL && (mp->mnt_flag & MNT_MULTILABEL) == 0)
+ mac_associate_vnode_singlelabel(mp, vp);
#endif
insmntque(vp, mp);
diff --git a/sys/modules/procfs/Makefile b/sys/modules/procfs/Makefile
index d4f41b3..75e23a0 100644
--- a/sys/modules/procfs/Makefile
+++ b/sys/modules/procfs/Makefile
@@ -4,13 +4,11 @@
KMOD= procfs
SRCS=
-SRCS+= opt_mac.h
SRCS+= vnode_if.h
SRCS+= procfs_ctl.c
SRCS+= procfs_dbregs.c
SRCS+= procfs_fpregs.c
SRCS+= procfs_ioctl.c
-SRCS+= procfs_mac.c
SRCS+= procfs_map.c
SRCS+= procfs_mem.c
SRCS+= procfs_note.c
diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c
index 78bc485..2ff4162 100644
--- a/sys/security/mac/mac_framework.c
+++ b/sys/security/mac/mac_framework.c
@@ -115,6 +115,12 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
*/
static int mac_late = 0;
+/*
+ * Warn about EA transactions only the first time they happen.
+ * Weak coherency, no locking.
+ */
+static int ea_warn_once = 0;
+
static int mac_enforce_fs = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -145,23 +151,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
-static int mac_label_size = sizeof(struct oldmac);
-SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
- &mac_label_size, 0, "Pre-compiled MAC label size");
-
static int mac_cache_fslabel_in_vnode = 1;
SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
&mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
&mac_cache_fslabel_in_vnode);
-static int mac_vnode_label_cache_hits = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
- &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
-static int mac_vnode_label_cache_misses = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
- &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
-
static int mac_mmap_revocation = 1;
SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
&mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
@@ -214,12 +209,9 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
#endif
static int error_select(int error1, int error2);
-static int mac_externalize_vnode_oldmac(struct label *label,
- struct oldmac *extmac);
static int mac_policy_register(struct mac_policy_conf *mpc);
static int mac_policy_unregister(struct mac_policy_conf *mpc);
-static int mac_stdcreatevnode_ea(struct vnode *vp);
static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
struct vnode *vp, int *prot);
static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
@@ -227,6 +219,10 @@ static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
static void mac_destroy_socket_label(struct label *label);
+static int mac_setlabel_vnode_extattr(struct ucred *cred,
+ struct vnode *vp, struct label *intlabel);
+
+
MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@@ -623,10 +619,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_externalize_vnode_label =
mpe->mpe_function;
break;
- case MAC_EXTERNALIZE_VNODE_OLDMAC:
- mpc->mpc_ops->mpo_externalize_vnode_oldmac =
- mpe->mpe_function;
- break;
case MAC_INTERNALIZE_CRED_LABEL:
mpc->mpc_ops->mpo_internalize_cred_label =
mpe->mpe_function;
@@ -663,14 +655,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_create_devfs_vnode =
mpe->mpe_function;
break;
- case MAC_STDCREATEVNODE_EA:
- mpc->mpc_ops->mpo_stdcreatevnode_ea =
- mpe->mpe_function;
- break;
- case MAC_CREATE_VNODE:
- mpc->mpc_ops->mpo_create_vnode =
- mpe->mpe_function;
- break;
case MAC_CREATE_MOUNT:
mpc->mpc_ops->mpo_create_mount =
mpe->mpe_function;
@@ -687,20 +671,24 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_update_devfsdirent =
mpe->mpe_function;
break;
- case MAC_UPDATE_PROCFSVNODE:
- mpc->mpc_ops->mpo_update_procfsvnode =
+ case MAC_ASSOCIATE_VNODE_DEVFS:
+ mpc->mpc_ops->mpo_associate_vnode_devfs =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTATTR:
- mpc->mpc_ops->mpo_update_vnode_from_extattr =
+ case MAC_ASSOCIATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_associate_vnode_extattr =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
- mpc->mpc_ops->mpo_update_vnode_from_externalized =
+ case MAC_ASSOCIATE_VNODE_SINGLELABEL:
+ mpc->mpc_ops->mpo_associate_vnode_singlelabel =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_MOUNT:
- mpc->mpc_ops->mpo_update_vnode_from_mount =
+ case MAC_CREATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_create_vnode_extattr =
+ mpe->mpe_function;
+ break;
+ case MAC_SETLABEL_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_setlabel_vnode_extattr =
mpe->mpe_function;
break;
case MAC_CREATE_MBUF_FROM_SOCKET:
@@ -1379,7 +1367,7 @@ mac_init_socket(struct socket *socket, int flag)
return (error);
}
-static void
+void
mac_init_vnode_label(struct label *label)
{
@@ -1536,7 +1524,7 @@ mac_destroy_socket(struct socket *socket)
mac_destroy_socket_peer_label(&socket->so_peerlabel);
}
-static void
+void
mac_destroy_vnode_label(struct label *label)
{
@@ -1561,7 +1549,7 @@ mac_copy_pipe_label(struct label *src, struct label *dest)
MAC_PERFORM(copy_pipe_label, src, dest);
}
-static void
+void
mac_copy_vnode_label(struct label *src, struct label *dest)
{
@@ -1645,16 +1633,6 @@ mac_externalize_vnode_label(struct label *label, char *elements,
}
static int
-mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(externalize_vnode_oldmac, label, extmac);
-
- return (error);
-}
-
-static int
mac_internalize_cred_label(struct label *label, char *string)
{
int error;
@@ -1753,276 +1731,118 @@ mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
}
void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
+ struct vnode *vp)
{
- MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+ MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
+ &de->de_label, vp, &vp->v_label);
}
-/*
- * Support callout for policies that manage their own externalization
- * using extended attributes.
- */
-static int
-mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
+int
+mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
{
int error;
- MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- return (error);
-}
+ ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+ MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
return (error);
}
-/*
- * Call out to individual policies to update the label in a vnode from
- * the mountpoint.
- */
void
-mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
+mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
{
- MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
- if (mac_cache_fslabel_in_vnode)
- vp->v_vflag |= VV_CACHEDLABEL;
+ MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
}
-/*
- * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
- * to store label data. Can be referenced by filesystems supporting
- * extended attributes.
- */
int
-vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
+mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+ struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
- struct vnode *vp = ap->a_vp;
- struct oldmac extmac;
- int buflen, error;
+ int error;
- ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+ ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
+ ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
- /*
- * Call out to external policies first. Order doesn't really
- * matter, as long as failure of one assures failure of all.
- */
- error = mac_update_vnode_from_extattr(vp, vp->v_mount);
- if (error)
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
return (error);
- buflen = sizeof(extmac);
- error = vn_extattr_get(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
- (char *)&extmac, curthread);
- switch (error) {
- case 0:
- /* Got it */
- break;
-
- case ENOATTR:
- /*
- * Use the label from the mount point.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
+ MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
+ dvp, &dvp->v_label, vp, &vp->v_label, cnp);
- case EOPNOTSUPP:
- default:
- /* Fail horribly. */
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
- if (buflen != sizeof(extmac))
- error = EPERM; /* Fail very closed. */
- if (error == 0)
- error = mac_update_vnode_from_externalized(vp, &extmac);
- if (error == 0)
- vp->v_vflag |= VV_CACHEDLABEL;
- else {
- struct vattr va;
-
- printf("Corrupted label on %s",
- vp->v_mount->mnt_stat.f_mntonname);
- if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
- printf(" inum %ld", va.va_fileid);
-#ifdef MAC_DEBUG
- if (mac_debug_label_fallback) {
- printf(", falling back.\n");
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- } else {
-#endif
- printf(".\n");
- error = EPERM;
-#ifdef MAC_DEBUG
- }
-#endif
- }
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
+
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
return (error);
}
-/*
- * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle
- * the labeling activity outselves. Filesystems should be careful not
- * to change their minds regarding whether they support vop_refreshlabel()
- * for a vnode or not. Don't cache the vnode here, allow the file
- * system code to determine if it's safe to cache. If we update from
- * the mount, don't cache since a change to the mount label should affect
- * all vnodes.
- */
static int
-vn_refreshlabel(struct vnode *vp, struct ucred *cred)
+mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *intlabel)
{
int error;
- ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
-
- if (vp->v_mount == NULL) {
-/*
- Eventually, we probably want to special-case refreshing
- of deadfs vnodes, and if there's a lock-free race somewhere,
- that case might be handled here.
+ ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
- mac_update_vnode_deadfs(vp);
- return (0);
- */
- /* printf("vn_refreshlabel: null v_mount\n"); */
- if (vp->v_type != VNON)
- printf(
- "vn_refreshlabel: null v_mount with non-VNON\n");
- return (EBADF);
- }
-
- if (vp->v_vflag & VV_CACHEDLABEL) {
- mac_vnode_label_cache_hits++;
- return (0);
- } else
- mac_vnode_label_cache_misses++;
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
+ return (error);
- if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
- }
+ MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
- error = VOP_REFRESHLABEL(vp, cred, curthread);
- switch (error) {
- case EOPNOTSUPP:
- /*
- * If labels are not supported on this vnode, fall back to
- * the label in the mount and propagate it to the vnode.
- * There should probably be some sort of policy/flag/decision
- * about doing this.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- default:
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
-}
-/*
- * Helper function for file systems using the vop_std*_ea() calls. This
- * function must be called after EA service is available for the vnode,
- * but before it's hooked up to the namespace so that the node persists
- * if there's a crash, or before it can be accessed. On successful
- * commit of the label to disk (etc), do cache the label.
- */
-int
-vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
-{
- struct oldmac extmac;
- int error;
-
- ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
- if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(tvp, tvp->v_mount);
- } else {
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- /*
- * Stick the label in the vnode. Then try to write to
- * disk. If we fail, return a failure to abort the
- * create operation. Really, this failure shouldn't
- * happen except in fairly unusual circumstances (out
- * of disk, etc).
- */
- mac_create_vnode(cred, dvp, tvp);
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
- error = mac_stdcreatevnode_ea(tvp);
- if (error)
- return (error);
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
- /*
- * XXX: Eventually this will go away and all policies will
- * directly manage their extended attributes.
- */
- error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
- if (error)
- return (error);
-
- error = vn_extattr_set(tvp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
- if (error == 0)
- tvp->v_vflag |= VV_CACHEDLABEL;
- else {
-#if 0
- /*
- * In theory, we could have fall-back behavior here.
- * It would probably be incorrect.
- */
-#endif
- return (error);
- }
- }
-
- return (0);
+ return (error);
}
void
mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
{
- int error;
ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
- error = vn_refreshlabel(vp, old);
- if (error) {
- printf("mac_execve_transition: vn_refreshlabel returned %d\n",
- error);
- printf("mac_execve_transition: using old vnode label\n");
- }
-
MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
}
int
mac_execve_will_transition(struct ucred *old, struct vnode *vp)
{
- int error, result;
-
- error = vn_refreshlabel(vp, old);
- if (error)
- return (error);
+ int result;
result = 0;
MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
@@ -2040,10 +1860,6 @@ mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2058,10 +1874,6 @@ mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2076,10 +1888,6 @@ mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2095,10 +1903,6 @@ mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
return (error);
}
@@ -2115,13 +1919,6 @@ mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2138,10 +1935,6 @@ mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2156,9 +1949,6 @@ mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_process && !mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
return (error);
@@ -2174,10 +1964,6 @@ mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2193,10 +1979,6 @@ mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2214,14 +1996,6 @@ mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2238,10 +2012,6 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
return (error);
}
@@ -2256,10 +2026,6 @@ mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2290,10 +2056,6 @@ mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2308,10 +2070,6 @@ mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
return (error);
}
@@ -2327,10 +2085,6 @@ mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
&vp->v_label);
@@ -2348,10 +2102,6 @@ mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
&vp->v_label);
@@ -2368,10 +2118,6 @@ mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2386,10 +2132,6 @@ mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
return (error);
}
@@ -2402,10 +2144,6 @@ mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
return (error);
@@ -2423,13 +2161,6 @@ mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2447,14 +2178,6 @@ mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- if (vp != NULL) {
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
- }
MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
vp != NULL ? &vp->v_label : NULL, samedir, cnp);
return (error);
@@ -2470,10 +2193,6 @@ mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
return (error);
}
@@ -2489,10 +2208,6 @@ mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
return (error);
}
@@ -2508,10 +2223,6 @@ mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2527,10 +2238,6 @@ mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2545,10 +2252,6 @@ mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
return (error);
}
@@ -2564,10 +2267,6 @@ mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
return (error);
}
@@ -2583,10 +2282,6 @@ mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
mtime);
return (error);
@@ -2603,10 +2298,6 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
&vp->v_label);
return (error);
@@ -2622,10 +2313,6 @@ mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
@@ -2641,10 +2328,6 @@ mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
&vp->v_label);
@@ -3344,7 +3027,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3352,7 +3034,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3382,7 +3063,6 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3444,16 +3124,6 @@ mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
&de->de_label);
}
-static int
-mac_stdcreatevnode_ea(struct vnode *vp)
-{
- int error;
-
- MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
-
- return (error);
-}
-
void
mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de)
@@ -3463,29 +3133,6 @@ mac_create_devfs_directory(char *dirname, int dirnamelen,
&de->de_label);
}
-/*
- * When a new vnode is created, this call will initialize its label.
- */
-void
-mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child)
-{
- int error;
-
- ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
- ASSERT_VOP_LOCKED(child, "mac_create_vnode");
-
- error = vn_refreshlabel(parent, cred);
- if (error) {
- printf("mac_create_vnode: vn_refreshlabel returned %d\n",
- error);
- printf("mac_create_vnode: using old vnode label\n");
- }
-
- MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
- &child->v_label);
-}
-
int
mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
struct mac *mac)
@@ -3499,7 +3146,6 @@ mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
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);
@@ -3554,7 +3200,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
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);
@@ -3562,7 +3207,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_label(&so->so_label, elements,
buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3586,7 +3230,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
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);
@@ -3594,7 +3237,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_peer_label(&so->so_peerlabel,
elements, buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3616,35 +3258,19 @@ vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
{
struct vnode *vp = ap->a_vp;
struct label *intlabel = ap->a_label;
- struct oldmac extmac;
int error;
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
- /*
- * XXX: Eventually call out to EA check/set calls here.
- * Be particularly careful to avoid race conditions,
- * consistency problems, and stability problems when
- * dealing with multiple EAs. In particular, we require
- * the ability to write multiple EAs on the same file in
- * a single transaction, which the current EA interface
- * does not provide.
- */
-
- error = mac_externalize_vnode_oldmac(intlabel, &extmac);
- if (error)
- return (error);
+ if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+ return (EOPNOTSUPP);
- error = vn_extattr_set(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
+ error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
if (error)
return (error);
mac_relabel_vnode(ap->a_cred, vp, intlabel);
- vp->v_vflag |= VV_CACHEDLABEL;
-
return (0);
}
@@ -3721,7 +3347,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
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);
@@ -3730,7 +3355,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_cred_label(&tcred->cr_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3761,7 +3385,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
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);
@@ -3769,7 +3392,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
}
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, M_WAITOK);
if (error == 0)
@@ -3802,7 +3424,6 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
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);
@@ -3880,7 +3501,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
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);
@@ -3888,7 +3508,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
mtx_lock(&Giant); /* VFS */
error = fget(td, SCARG(uap, fd), &fp);
if (error)
@@ -3903,9 +3522,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
mac_init_vnode_label(&intlabel);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = vn_refreshlabel(vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&vp->v_label, &intlabel);
+ mac_copy_vnode_label(&vp->v_label, &intlabel);
VOP_UNLOCK(vp, 0, td);
break;
@@ -3974,7 +3591,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
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);
@@ -3982,7 +3598,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
}
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);
@@ -3991,12 +3606,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4034,7 +3646,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
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);
@@ -4042,7 +3653,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
}
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);
@@ -4051,12 +3661,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4096,7 +3703,6 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
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);
@@ -4183,7 +3789,6 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
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);
@@ -4240,7 +3845,6 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
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);
diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h
index bcf36e0..cc9552b 100644
--- a/sys/security/mac/mac_framework.h
+++ b/sys/security/mac/mac_framework.h
@@ -195,6 +195,8 @@ void mac_init_pipe(struct pipe *);
int mac_init_mbuf(struct mbuf *m, int flag);
void mac_init_mount(struct mount *);
void mac_init_vnode(struct vnode *);
+void mac_init_vnode_label(struct label *);
+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 *);
@@ -205,26 +207,29 @@ void mac_destroy_pipe(struct pipe *);
void mac_destroy_mbuf(struct mbuf *);
void mac_destroy_mount(struct mount *);
void mac_destroy_vnode(struct vnode *);
+void mac_destroy_vnode_label(struct 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(dev_t dev, struct devfs_dirent *de);
void mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de);
void mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
struct devfs_dirent *de);
void mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp);
-void mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child);
+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 devfs_dirent *de, struct vnode *vp);
-void mac_update_procfsvnode(struct vnode *vp, struct ucred *cred);
-void mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp);
/*
* Labeling event operations: IPC objects.
@@ -362,9 +367,6 @@ int mac_pipe_label_set(struct ucred *cred, struct pipe *pipe,
* Calls to help various file systems implement labeling functionality
* using their existing EA implementation.
*/
-int vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp,
- struct ucred *cred);
-int vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap);
int vop_stdsetlabel_ea(struct vop_setlabel_args *ap);
#endif /* _KERNEL */
diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h
index 78bc485..2ff4162 100644
--- a/sys/security/mac/mac_internal.h
+++ b/sys/security/mac/mac_internal.h
@@ -115,6 +115,12 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
*/
static int mac_late = 0;
+/*
+ * Warn about EA transactions only the first time they happen.
+ * Weak coherency, no locking.
+ */
+static int ea_warn_once = 0;
+
static int mac_enforce_fs = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -145,23 +151,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
-static int mac_label_size = sizeof(struct oldmac);
-SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
- &mac_label_size, 0, "Pre-compiled MAC label size");
-
static int mac_cache_fslabel_in_vnode = 1;
SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
&mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
&mac_cache_fslabel_in_vnode);
-static int mac_vnode_label_cache_hits = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
- &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
-static int mac_vnode_label_cache_misses = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
- &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
-
static int mac_mmap_revocation = 1;
SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
&mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
@@ -214,12 +209,9 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
#endif
static int error_select(int error1, int error2);
-static int mac_externalize_vnode_oldmac(struct label *label,
- struct oldmac *extmac);
static int mac_policy_register(struct mac_policy_conf *mpc);
static int mac_policy_unregister(struct mac_policy_conf *mpc);
-static int mac_stdcreatevnode_ea(struct vnode *vp);
static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
struct vnode *vp, int *prot);
static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
@@ -227,6 +219,10 @@ static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
static void mac_destroy_socket_label(struct label *label);
+static int mac_setlabel_vnode_extattr(struct ucred *cred,
+ struct vnode *vp, struct label *intlabel);
+
+
MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@@ -623,10 +619,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_externalize_vnode_label =
mpe->mpe_function;
break;
- case MAC_EXTERNALIZE_VNODE_OLDMAC:
- mpc->mpc_ops->mpo_externalize_vnode_oldmac =
- mpe->mpe_function;
- break;
case MAC_INTERNALIZE_CRED_LABEL:
mpc->mpc_ops->mpo_internalize_cred_label =
mpe->mpe_function;
@@ -663,14 +655,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_create_devfs_vnode =
mpe->mpe_function;
break;
- case MAC_STDCREATEVNODE_EA:
- mpc->mpc_ops->mpo_stdcreatevnode_ea =
- mpe->mpe_function;
- break;
- case MAC_CREATE_VNODE:
- mpc->mpc_ops->mpo_create_vnode =
- mpe->mpe_function;
- break;
case MAC_CREATE_MOUNT:
mpc->mpc_ops->mpo_create_mount =
mpe->mpe_function;
@@ -687,20 +671,24 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_update_devfsdirent =
mpe->mpe_function;
break;
- case MAC_UPDATE_PROCFSVNODE:
- mpc->mpc_ops->mpo_update_procfsvnode =
+ case MAC_ASSOCIATE_VNODE_DEVFS:
+ mpc->mpc_ops->mpo_associate_vnode_devfs =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTATTR:
- mpc->mpc_ops->mpo_update_vnode_from_extattr =
+ case MAC_ASSOCIATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_associate_vnode_extattr =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
- mpc->mpc_ops->mpo_update_vnode_from_externalized =
+ case MAC_ASSOCIATE_VNODE_SINGLELABEL:
+ mpc->mpc_ops->mpo_associate_vnode_singlelabel =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_MOUNT:
- mpc->mpc_ops->mpo_update_vnode_from_mount =
+ case MAC_CREATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_create_vnode_extattr =
+ mpe->mpe_function;
+ break;
+ case MAC_SETLABEL_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_setlabel_vnode_extattr =
mpe->mpe_function;
break;
case MAC_CREATE_MBUF_FROM_SOCKET:
@@ -1379,7 +1367,7 @@ mac_init_socket(struct socket *socket, int flag)
return (error);
}
-static void
+void
mac_init_vnode_label(struct label *label)
{
@@ -1536,7 +1524,7 @@ mac_destroy_socket(struct socket *socket)
mac_destroy_socket_peer_label(&socket->so_peerlabel);
}
-static void
+void
mac_destroy_vnode_label(struct label *label)
{
@@ -1561,7 +1549,7 @@ mac_copy_pipe_label(struct label *src, struct label *dest)
MAC_PERFORM(copy_pipe_label, src, dest);
}
-static void
+void
mac_copy_vnode_label(struct label *src, struct label *dest)
{
@@ -1645,16 +1633,6 @@ mac_externalize_vnode_label(struct label *label, char *elements,
}
static int
-mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(externalize_vnode_oldmac, label, extmac);
-
- return (error);
-}
-
-static int
mac_internalize_cred_label(struct label *label, char *string)
{
int error;
@@ -1753,276 +1731,118 @@ mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
}
void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
+ struct vnode *vp)
{
- MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+ MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
+ &de->de_label, vp, &vp->v_label);
}
-/*
- * Support callout for policies that manage their own externalization
- * using extended attributes.
- */
-static int
-mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
+int
+mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
{
int error;
- MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- return (error);
-}
+ ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+ MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
return (error);
}
-/*
- * Call out to individual policies to update the label in a vnode from
- * the mountpoint.
- */
void
-mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
+mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
{
- MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
- if (mac_cache_fslabel_in_vnode)
- vp->v_vflag |= VV_CACHEDLABEL;
+ MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
}
-/*
- * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
- * to store label data. Can be referenced by filesystems supporting
- * extended attributes.
- */
int
-vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
+mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+ struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
- struct vnode *vp = ap->a_vp;
- struct oldmac extmac;
- int buflen, error;
+ int error;
- ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+ ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
+ ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
- /*
- * Call out to external policies first. Order doesn't really
- * matter, as long as failure of one assures failure of all.
- */
- error = mac_update_vnode_from_extattr(vp, vp->v_mount);
- if (error)
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
return (error);
- buflen = sizeof(extmac);
- error = vn_extattr_get(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
- (char *)&extmac, curthread);
- switch (error) {
- case 0:
- /* Got it */
- break;
-
- case ENOATTR:
- /*
- * Use the label from the mount point.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
+ MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
+ dvp, &dvp->v_label, vp, &vp->v_label, cnp);
- case EOPNOTSUPP:
- default:
- /* Fail horribly. */
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
- if (buflen != sizeof(extmac))
- error = EPERM; /* Fail very closed. */
- if (error == 0)
- error = mac_update_vnode_from_externalized(vp, &extmac);
- if (error == 0)
- vp->v_vflag |= VV_CACHEDLABEL;
- else {
- struct vattr va;
-
- printf("Corrupted label on %s",
- vp->v_mount->mnt_stat.f_mntonname);
- if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
- printf(" inum %ld", va.va_fileid);
-#ifdef MAC_DEBUG
- if (mac_debug_label_fallback) {
- printf(", falling back.\n");
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- } else {
-#endif
- printf(".\n");
- error = EPERM;
-#ifdef MAC_DEBUG
- }
-#endif
- }
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
+
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
return (error);
}
-/*
- * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle
- * the labeling activity outselves. Filesystems should be careful not
- * to change their minds regarding whether they support vop_refreshlabel()
- * for a vnode or not. Don't cache the vnode here, allow the file
- * system code to determine if it's safe to cache. If we update from
- * the mount, don't cache since a change to the mount label should affect
- * all vnodes.
- */
static int
-vn_refreshlabel(struct vnode *vp, struct ucred *cred)
+mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *intlabel)
{
int error;
- ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
-
- if (vp->v_mount == NULL) {
-/*
- Eventually, we probably want to special-case refreshing
- of deadfs vnodes, and if there's a lock-free race somewhere,
- that case might be handled here.
+ ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
- mac_update_vnode_deadfs(vp);
- return (0);
- */
- /* printf("vn_refreshlabel: null v_mount\n"); */
- if (vp->v_type != VNON)
- printf(
- "vn_refreshlabel: null v_mount with non-VNON\n");
- return (EBADF);
- }
-
- if (vp->v_vflag & VV_CACHEDLABEL) {
- mac_vnode_label_cache_hits++;
- return (0);
- } else
- mac_vnode_label_cache_misses++;
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
+ return (error);
- if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
- }
+ MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
- error = VOP_REFRESHLABEL(vp, cred, curthread);
- switch (error) {
- case EOPNOTSUPP:
- /*
- * If labels are not supported on this vnode, fall back to
- * the label in the mount and propagate it to the vnode.
- * There should probably be some sort of policy/flag/decision
- * about doing this.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- default:
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
-}
-/*
- * Helper function for file systems using the vop_std*_ea() calls. This
- * function must be called after EA service is available for the vnode,
- * but before it's hooked up to the namespace so that the node persists
- * if there's a crash, or before it can be accessed. On successful
- * commit of the label to disk (etc), do cache the label.
- */
-int
-vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
-{
- struct oldmac extmac;
- int error;
-
- ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
- if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(tvp, tvp->v_mount);
- } else {
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- /*
- * Stick the label in the vnode. Then try to write to
- * disk. If we fail, return a failure to abort the
- * create operation. Really, this failure shouldn't
- * happen except in fairly unusual circumstances (out
- * of disk, etc).
- */
- mac_create_vnode(cred, dvp, tvp);
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
- error = mac_stdcreatevnode_ea(tvp);
- if (error)
- return (error);
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
- /*
- * XXX: Eventually this will go away and all policies will
- * directly manage their extended attributes.
- */
- error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
- if (error)
- return (error);
-
- error = vn_extattr_set(tvp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
- if (error == 0)
- tvp->v_vflag |= VV_CACHEDLABEL;
- else {
-#if 0
- /*
- * In theory, we could have fall-back behavior here.
- * It would probably be incorrect.
- */
-#endif
- return (error);
- }
- }
-
- return (0);
+ return (error);
}
void
mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
{
- int error;
ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
- error = vn_refreshlabel(vp, old);
- if (error) {
- printf("mac_execve_transition: vn_refreshlabel returned %d\n",
- error);
- printf("mac_execve_transition: using old vnode label\n");
- }
-
MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
}
int
mac_execve_will_transition(struct ucred *old, struct vnode *vp)
{
- int error, result;
-
- error = vn_refreshlabel(vp, old);
- if (error)
- return (error);
+ int result;
result = 0;
MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
@@ -2040,10 +1860,6 @@ mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2058,10 +1874,6 @@ mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2076,10 +1888,6 @@ mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2095,10 +1903,6 @@ mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
return (error);
}
@@ -2115,13 +1919,6 @@ mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2138,10 +1935,6 @@ mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2156,9 +1949,6 @@ mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_process && !mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
return (error);
@@ -2174,10 +1964,6 @@ mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2193,10 +1979,6 @@ mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2214,14 +1996,6 @@ mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2238,10 +2012,6 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
return (error);
}
@@ -2256,10 +2026,6 @@ mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2290,10 +2056,6 @@ mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2308,10 +2070,6 @@ mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
return (error);
}
@@ -2327,10 +2085,6 @@ mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
&vp->v_label);
@@ -2348,10 +2102,6 @@ mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
&vp->v_label);
@@ -2368,10 +2118,6 @@ mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2386,10 +2132,6 @@ mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
return (error);
}
@@ -2402,10 +2144,6 @@ mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
return (error);
@@ -2423,13 +2161,6 @@ mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2447,14 +2178,6 @@ mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- if (vp != NULL) {
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
- }
MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
vp != NULL ? &vp->v_label : NULL, samedir, cnp);
return (error);
@@ -2470,10 +2193,6 @@ mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
return (error);
}
@@ -2489,10 +2208,6 @@ mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
return (error);
}
@@ -2508,10 +2223,6 @@ mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2527,10 +2238,6 @@ mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2545,10 +2252,6 @@ mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
return (error);
}
@@ -2564,10 +2267,6 @@ mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
return (error);
}
@@ -2583,10 +2282,6 @@ mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
mtime);
return (error);
@@ -2603,10 +2298,6 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
&vp->v_label);
return (error);
@@ -2622,10 +2313,6 @@ mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
@@ -2641,10 +2328,6 @@ mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
&vp->v_label);
@@ -3344,7 +3027,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3352,7 +3034,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3382,7 +3063,6 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3444,16 +3124,6 @@ mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
&de->de_label);
}
-static int
-mac_stdcreatevnode_ea(struct vnode *vp)
-{
- int error;
-
- MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
-
- return (error);
-}
-
void
mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de)
@@ -3463,29 +3133,6 @@ mac_create_devfs_directory(char *dirname, int dirnamelen,
&de->de_label);
}
-/*
- * When a new vnode is created, this call will initialize its label.
- */
-void
-mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child)
-{
- int error;
-
- ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
- ASSERT_VOP_LOCKED(child, "mac_create_vnode");
-
- error = vn_refreshlabel(parent, cred);
- if (error) {
- printf("mac_create_vnode: vn_refreshlabel returned %d\n",
- error);
- printf("mac_create_vnode: using old vnode label\n");
- }
-
- MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
- &child->v_label);
-}
-
int
mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
struct mac *mac)
@@ -3499,7 +3146,6 @@ mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
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);
@@ -3554,7 +3200,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
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);
@@ -3562,7 +3207,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_label(&so->so_label, elements,
buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3586,7 +3230,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
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);
@@ -3594,7 +3237,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_peer_label(&so->so_peerlabel,
elements, buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3616,35 +3258,19 @@ vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
{
struct vnode *vp = ap->a_vp;
struct label *intlabel = ap->a_label;
- struct oldmac extmac;
int error;
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
- /*
- * XXX: Eventually call out to EA check/set calls here.
- * Be particularly careful to avoid race conditions,
- * consistency problems, and stability problems when
- * dealing with multiple EAs. In particular, we require
- * the ability to write multiple EAs on the same file in
- * a single transaction, which the current EA interface
- * does not provide.
- */
-
- error = mac_externalize_vnode_oldmac(intlabel, &extmac);
- if (error)
- return (error);
+ if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+ return (EOPNOTSUPP);
- error = vn_extattr_set(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
+ error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
if (error)
return (error);
mac_relabel_vnode(ap->a_cred, vp, intlabel);
- vp->v_vflag |= VV_CACHEDLABEL;
-
return (0);
}
@@ -3721,7 +3347,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
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);
@@ -3730,7 +3355,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_cred_label(&tcred->cr_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3761,7 +3385,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
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);
@@ -3769,7 +3392,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
}
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, M_WAITOK);
if (error == 0)
@@ -3802,7 +3424,6 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
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);
@@ -3880,7 +3501,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
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);
@@ -3888,7 +3508,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
mtx_lock(&Giant); /* VFS */
error = fget(td, SCARG(uap, fd), &fp);
if (error)
@@ -3903,9 +3522,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
mac_init_vnode_label(&intlabel);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = vn_refreshlabel(vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&vp->v_label, &intlabel);
+ mac_copy_vnode_label(&vp->v_label, &intlabel);
VOP_UNLOCK(vp, 0, td);
break;
@@ -3974,7 +3591,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
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);
@@ -3982,7 +3598,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
}
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);
@@ -3991,12 +3606,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4034,7 +3646,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
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);
@@ -4042,7 +3653,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
}
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);
@@ -4051,12 +3661,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4096,7 +3703,6 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
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);
@@ -4183,7 +3789,6 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
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);
@@ -4240,7 +3845,6 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
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);
diff --git a/sys/security/mac/mac_net.c b/sys/security/mac/mac_net.c
index 78bc485..2ff4162 100644
--- a/sys/security/mac/mac_net.c
+++ b/sys/security/mac/mac_net.c
@@ -115,6 +115,12 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
*/
static int mac_late = 0;
+/*
+ * Warn about EA transactions only the first time they happen.
+ * Weak coherency, no locking.
+ */
+static int ea_warn_once = 0;
+
static int mac_enforce_fs = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -145,23 +151,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
-static int mac_label_size = sizeof(struct oldmac);
-SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
- &mac_label_size, 0, "Pre-compiled MAC label size");
-
static int mac_cache_fslabel_in_vnode = 1;
SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
&mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
&mac_cache_fslabel_in_vnode);
-static int mac_vnode_label_cache_hits = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
- &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
-static int mac_vnode_label_cache_misses = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
- &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
-
static int mac_mmap_revocation = 1;
SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
&mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
@@ -214,12 +209,9 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
#endif
static int error_select(int error1, int error2);
-static int mac_externalize_vnode_oldmac(struct label *label,
- struct oldmac *extmac);
static int mac_policy_register(struct mac_policy_conf *mpc);
static int mac_policy_unregister(struct mac_policy_conf *mpc);
-static int mac_stdcreatevnode_ea(struct vnode *vp);
static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
struct vnode *vp, int *prot);
static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
@@ -227,6 +219,10 @@ static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
static void mac_destroy_socket_label(struct label *label);
+static int mac_setlabel_vnode_extattr(struct ucred *cred,
+ struct vnode *vp, struct label *intlabel);
+
+
MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@@ -623,10 +619,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_externalize_vnode_label =
mpe->mpe_function;
break;
- case MAC_EXTERNALIZE_VNODE_OLDMAC:
- mpc->mpc_ops->mpo_externalize_vnode_oldmac =
- mpe->mpe_function;
- break;
case MAC_INTERNALIZE_CRED_LABEL:
mpc->mpc_ops->mpo_internalize_cred_label =
mpe->mpe_function;
@@ -663,14 +655,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_create_devfs_vnode =
mpe->mpe_function;
break;
- case MAC_STDCREATEVNODE_EA:
- mpc->mpc_ops->mpo_stdcreatevnode_ea =
- mpe->mpe_function;
- break;
- case MAC_CREATE_VNODE:
- mpc->mpc_ops->mpo_create_vnode =
- mpe->mpe_function;
- break;
case MAC_CREATE_MOUNT:
mpc->mpc_ops->mpo_create_mount =
mpe->mpe_function;
@@ -687,20 +671,24 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_update_devfsdirent =
mpe->mpe_function;
break;
- case MAC_UPDATE_PROCFSVNODE:
- mpc->mpc_ops->mpo_update_procfsvnode =
+ case MAC_ASSOCIATE_VNODE_DEVFS:
+ mpc->mpc_ops->mpo_associate_vnode_devfs =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTATTR:
- mpc->mpc_ops->mpo_update_vnode_from_extattr =
+ case MAC_ASSOCIATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_associate_vnode_extattr =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
- mpc->mpc_ops->mpo_update_vnode_from_externalized =
+ case MAC_ASSOCIATE_VNODE_SINGLELABEL:
+ mpc->mpc_ops->mpo_associate_vnode_singlelabel =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_MOUNT:
- mpc->mpc_ops->mpo_update_vnode_from_mount =
+ case MAC_CREATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_create_vnode_extattr =
+ mpe->mpe_function;
+ break;
+ case MAC_SETLABEL_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_setlabel_vnode_extattr =
mpe->mpe_function;
break;
case MAC_CREATE_MBUF_FROM_SOCKET:
@@ -1379,7 +1367,7 @@ mac_init_socket(struct socket *socket, int flag)
return (error);
}
-static void
+void
mac_init_vnode_label(struct label *label)
{
@@ -1536,7 +1524,7 @@ mac_destroy_socket(struct socket *socket)
mac_destroy_socket_peer_label(&socket->so_peerlabel);
}
-static void
+void
mac_destroy_vnode_label(struct label *label)
{
@@ -1561,7 +1549,7 @@ mac_copy_pipe_label(struct label *src, struct label *dest)
MAC_PERFORM(copy_pipe_label, src, dest);
}
-static void
+void
mac_copy_vnode_label(struct label *src, struct label *dest)
{
@@ -1645,16 +1633,6 @@ mac_externalize_vnode_label(struct label *label, char *elements,
}
static int
-mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(externalize_vnode_oldmac, label, extmac);
-
- return (error);
-}
-
-static int
mac_internalize_cred_label(struct label *label, char *string)
{
int error;
@@ -1753,276 +1731,118 @@ mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
}
void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
+ struct vnode *vp)
{
- MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+ MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
+ &de->de_label, vp, &vp->v_label);
}
-/*
- * Support callout for policies that manage their own externalization
- * using extended attributes.
- */
-static int
-mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
+int
+mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
{
int error;
- MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- return (error);
-}
+ ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+ MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
return (error);
}
-/*
- * Call out to individual policies to update the label in a vnode from
- * the mountpoint.
- */
void
-mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
+mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
{
- MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
- if (mac_cache_fslabel_in_vnode)
- vp->v_vflag |= VV_CACHEDLABEL;
+ MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
}
-/*
- * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
- * to store label data. Can be referenced by filesystems supporting
- * extended attributes.
- */
int
-vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
+mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+ struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
- struct vnode *vp = ap->a_vp;
- struct oldmac extmac;
- int buflen, error;
+ int error;
- ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+ ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
+ ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
- /*
- * Call out to external policies first. Order doesn't really
- * matter, as long as failure of one assures failure of all.
- */
- error = mac_update_vnode_from_extattr(vp, vp->v_mount);
- if (error)
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
return (error);
- buflen = sizeof(extmac);
- error = vn_extattr_get(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
- (char *)&extmac, curthread);
- switch (error) {
- case 0:
- /* Got it */
- break;
-
- case ENOATTR:
- /*
- * Use the label from the mount point.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
+ MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
+ dvp, &dvp->v_label, vp, &vp->v_label, cnp);
- case EOPNOTSUPP:
- default:
- /* Fail horribly. */
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
- if (buflen != sizeof(extmac))
- error = EPERM; /* Fail very closed. */
- if (error == 0)
- error = mac_update_vnode_from_externalized(vp, &extmac);
- if (error == 0)
- vp->v_vflag |= VV_CACHEDLABEL;
- else {
- struct vattr va;
-
- printf("Corrupted label on %s",
- vp->v_mount->mnt_stat.f_mntonname);
- if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
- printf(" inum %ld", va.va_fileid);
-#ifdef MAC_DEBUG
- if (mac_debug_label_fallback) {
- printf(", falling back.\n");
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- } else {
-#endif
- printf(".\n");
- error = EPERM;
-#ifdef MAC_DEBUG
- }
-#endif
- }
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
+
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
return (error);
}
-/*
- * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle
- * the labeling activity outselves. Filesystems should be careful not
- * to change their minds regarding whether they support vop_refreshlabel()
- * for a vnode or not. Don't cache the vnode here, allow the file
- * system code to determine if it's safe to cache. If we update from
- * the mount, don't cache since a change to the mount label should affect
- * all vnodes.
- */
static int
-vn_refreshlabel(struct vnode *vp, struct ucred *cred)
+mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *intlabel)
{
int error;
- ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
-
- if (vp->v_mount == NULL) {
-/*
- Eventually, we probably want to special-case refreshing
- of deadfs vnodes, and if there's a lock-free race somewhere,
- that case might be handled here.
+ ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
- mac_update_vnode_deadfs(vp);
- return (0);
- */
- /* printf("vn_refreshlabel: null v_mount\n"); */
- if (vp->v_type != VNON)
- printf(
- "vn_refreshlabel: null v_mount with non-VNON\n");
- return (EBADF);
- }
-
- if (vp->v_vflag & VV_CACHEDLABEL) {
- mac_vnode_label_cache_hits++;
- return (0);
- } else
- mac_vnode_label_cache_misses++;
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
+ return (error);
- if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
- }
+ MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
- error = VOP_REFRESHLABEL(vp, cred, curthread);
- switch (error) {
- case EOPNOTSUPP:
- /*
- * If labels are not supported on this vnode, fall back to
- * the label in the mount and propagate it to the vnode.
- * There should probably be some sort of policy/flag/decision
- * about doing this.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- default:
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
-}
-/*
- * Helper function for file systems using the vop_std*_ea() calls. This
- * function must be called after EA service is available for the vnode,
- * but before it's hooked up to the namespace so that the node persists
- * if there's a crash, or before it can be accessed. On successful
- * commit of the label to disk (etc), do cache the label.
- */
-int
-vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
-{
- struct oldmac extmac;
- int error;
-
- ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
- if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(tvp, tvp->v_mount);
- } else {
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- /*
- * Stick the label in the vnode. Then try to write to
- * disk. If we fail, return a failure to abort the
- * create operation. Really, this failure shouldn't
- * happen except in fairly unusual circumstances (out
- * of disk, etc).
- */
- mac_create_vnode(cred, dvp, tvp);
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
- error = mac_stdcreatevnode_ea(tvp);
- if (error)
- return (error);
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
- /*
- * XXX: Eventually this will go away and all policies will
- * directly manage their extended attributes.
- */
- error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
- if (error)
- return (error);
-
- error = vn_extattr_set(tvp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
- if (error == 0)
- tvp->v_vflag |= VV_CACHEDLABEL;
- else {
-#if 0
- /*
- * In theory, we could have fall-back behavior here.
- * It would probably be incorrect.
- */
-#endif
- return (error);
- }
- }
-
- return (0);
+ return (error);
}
void
mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
{
- int error;
ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
- error = vn_refreshlabel(vp, old);
- if (error) {
- printf("mac_execve_transition: vn_refreshlabel returned %d\n",
- error);
- printf("mac_execve_transition: using old vnode label\n");
- }
-
MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
}
int
mac_execve_will_transition(struct ucred *old, struct vnode *vp)
{
- int error, result;
-
- error = vn_refreshlabel(vp, old);
- if (error)
- return (error);
+ int result;
result = 0;
MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
@@ -2040,10 +1860,6 @@ mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2058,10 +1874,6 @@ mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2076,10 +1888,6 @@ mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2095,10 +1903,6 @@ mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
return (error);
}
@@ -2115,13 +1919,6 @@ mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2138,10 +1935,6 @@ mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2156,9 +1949,6 @@ mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_process && !mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
return (error);
@@ -2174,10 +1964,6 @@ mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2193,10 +1979,6 @@ mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2214,14 +1996,6 @@ mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2238,10 +2012,6 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
return (error);
}
@@ -2256,10 +2026,6 @@ mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2290,10 +2056,6 @@ mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2308,10 +2070,6 @@ mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
return (error);
}
@@ -2327,10 +2085,6 @@ mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
&vp->v_label);
@@ -2348,10 +2102,6 @@ mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
&vp->v_label);
@@ -2368,10 +2118,6 @@ mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2386,10 +2132,6 @@ mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
return (error);
}
@@ -2402,10 +2144,6 @@ mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
return (error);
@@ -2423,13 +2161,6 @@ mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2447,14 +2178,6 @@ mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- if (vp != NULL) {
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
- }
MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
vp != NULL ? &vp->v_label : NULL, samedir, cnp);
return (error);
@@ -2470,10 +2193,6 @@ mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
return (error);
}
@@ -2489,10 +2208,6 @@ mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
return (error);
}
@@ -2508,10 +2223,6 @@ mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2527,10 +2238,6 @@ mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2545,10 +2252,6 @@ mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
return (error);
}
@@ -2564,10 +2267,6 @@ mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
return (error);
}
@@ -2583,10 +2282,6 @@ mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
mtime);
return (error);
@@ -2603,10 +2298,6 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
&vp->v_label);
return (error);
@@ -2622,10 +2313,6 @@ mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
@@ -2641,10 +2328,6 @@ mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
&vp->v_label);
@@ -3344,7 +3027,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3352,7 +3034,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3382,7 +3063,6 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3444,16 +3124,6 @@ mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
&de->de_label);
}
-static int
-mac_stdcreatevnode_ea(struct vnode *vp)
-{
- int error;
-
- MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
-
- return (error);
-}
-
void
mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de)
@@ -3463,29 +3133,6 @@ mac_create_devfs_directory(char *dirname, int dirnamelen,
&de->de_label);
}
-/*
- * When a new vnode is created, this call will initialize its label.
- */
-void
-mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child)
-{
- int error;
-
- ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
- ASSERT_VOP_LOCKED(child, "mac_create_vnode");
-
- error = vn_refreshlabel(parent, cred);
- if (error) {
- printf("mac_create_vnode: vn_refreshlabel returned %d\n",
- error);
- printf("mac_create_vnode: using old vnode label\n");
- }
-
- MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
- &child->v_label);
-}
-
int
mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
struct mac *mac)
@@ -3499,7 +3146,6 @@ mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
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);
@@ -3554,7 +3200,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
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);
@@ -3562,7 +3207,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_label(&so->so_label, elements,
buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3586,7 +3230,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
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);
@@ -3594,7 +3237,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_peer_label(&so->so_peerlabel,
elements, buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3616,35 +3258,19 @@ vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
{
struct vnode *vp = ap->a_vp;
struct label *intlabel = ap->a_label;
- struct oldmac extmac;
int error;
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
- /*
- * XXX: Eventually call out to EA check/set calls here.
- * Be particularly careful to avoid race conditions,
- * consistency problems, and stability problems when
- * dealing with multiple EAs. In particular, we require
- * the ability to write multiple EAs on the same file in
- * a single transaction, which the current EA interface
- * does not provide.
- */
-
- error = mac_externalize_vnode_oldmac(intlabel, &extmac);
- if (error)
- return (error);
+ if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+ return (EOPNOTSUPP);
- error = vn_extattr_set(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
+ error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
if (error)
return (error);
mac_relabel_vnode(ap->a_cred, vp, intlabel);
- vp->v_vflag |= VV_CACHEDLABEL;
-
return (0);
}
@@ -3721,7 +3347,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
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);
@@ -3730,7 +3355,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_cred_label(&tcred->cr_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3761,7 +3385,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
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);
@@ -3769,7 +3392,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
}
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, M_WAITOK);
if (error == 0)
@@ -3802,7 +3424,6 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
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);
@@ -3880,7 +3501,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
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);
@@ -3888,7 +3508,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
mtx_lock(&Giant); /* VFS */
error = fget(td, SCARG(uap, fd), &fp);
if (error)
@@ -3903,9 +3522,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
mac_init_vnode_label(&intlabel);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = vn_refreshlabel(vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&vp->v_label, &intlabel);
+ mac_copy_vnode_label(&vp->v_label, &intlabel);
VOP_UNLOCK(vp, 0, td);
break;
@@ -3974,7 +3591,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
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);
@@ -3982,7 +3598,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
}
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);
@@ -3991,12 +3606,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4034,7 +3646,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
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);
@@ -4042,7 +3653,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
}
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);
@@ -4051,12 +3661,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4096,7 +3703,6 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
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);
@@ -4183,7 +3789,6 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
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);
@@ -4240,7 +3845,6 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
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);
diff --git a/sys/security/mac/mac_pipe.c b/sys/security/mac/mac_pipe.c
index 78bc485..2ff4162 100644
--- a/sys/security/mac/mac_pipe.c
+++ b/sys/security/mac/mac_pipe.c
@@ -115,6 +115,12 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
*/
static int mac_late = 0;
+/*
+ * Warn about EA transactions only the first time they happen.
+ * Weak coherency, no locking.
+ */
+static int ea_warn_once = 0;
+
static int mac_enforce_fs = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -145,23 +151,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
-static int mac_label_size = sizeof(struct oldmac);
-SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
- &mac_label_size, 0, "Pre-compiled MAC label size");
-
static int mac_cache_fslabel_in_vnode = 1;
SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
&mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
&mac_cache_fslabel_in_vnode);
-static int mac_vnode_label_cache_hits = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
- &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
-static int mac_vnode_label_cache_misses = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
- &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
-
static int mac_mmap_revocation = 1;
SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
&mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
@@ -214,12 +209,9 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
#endif
static int error_select(int error1, int error2);
-static int mac_externalize_vnode_oldmac(struct label *label,
- struct oldmac *extmac);
static int mac_policy_register(struct mac_policy_conf *mpc);
static int mac_policy_unregister(struct mac_policy_conf *mpc);
-static int mac_stdcreatevnode_ea(struct vnode *vp);
static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
struct vnode *vp, int *prot);
static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
@@ -227,6 +219,10 @@ static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
static void mac_destroy_socket_label(struct label *label);
+static int mac_setlabel_vnode_extattr(struct ucred *cred,
+ struct vnode *vp, struct label *intlabel);
+
+
MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@@ -623,10 +619,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_externalize_vnode_label =
mpe->mpe_function;
break;
- case MAC_EXTERNALIZE_VNODE_OLDMAC:
- mpc->mpc_ops->mpo_externalize_vnode_oldmac =
- mpe->mpe_function;
- break;
case MAC_INTERNALIZE_CRED_LABEL:
mpc->mpc_ops->mpo_internalize_cred_label =
mpe->mpe_function;
@@ -663,14 +655,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_create_devfs_vnode =
mpe->mpe_function;
break;
- case MAC_STDCREATEVNODE_EA:
- mpc->mpc_ops->mpo_stdcreatevnode_ea =
- mpe->mpe_function;
- break;
- case MAC_CREATE_VNODE:
- mpc->mpc_ops->mpo_create_vnode =
- mpe->mpe_function;
- break;
case MAC_CREATE_MOUNT:
mpc->mpc_ops->mpo_create_mount =
mpe->mpe_function;
@@ -687,20 +671,24 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_update_devfsdirent =
mpe->mpe_function;
break;
- case MAC_UPDATE_PROCFSVNODE:
- mpc->mpc_ops->mpo_update_procfsvnode =
+ case MAC_ASSOCIATE_VNODE_DEVFS:
+ mpc->mpc_ops->mpo_associate_vnode_devfs =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTATTR:
- mpc->mpc_ops->mpo_update_vnode_from_extattr =
+ case MAC_ASSOCIATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_associate_vnode_extattr =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
- mpc->mpc_ops->mpo_update_vnode_from_externalized =
+ case MAC_ASSOCIATE_VNODE_SINGLELABEL:
+ mpc->mpc_ops->mpo_associate_vnode_singlelabel =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_MOUNT:
- mpc->mpc_ops->mpo_update_vnode_from_mount =
+ case MAC_CREATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_create_vnode_extattr =
+ mpe->mpe_function;
+ break;
+ case MAC_SETLABEL_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_setlabel_vnode_extattr =
mpe->mpe_function;
break;
case MAC_CREATE_MBUF_FROM_SOCKET:
@@ -1379,7 +1367,7 @@ mac_init_socket(struct socket *socket, int flag)
return (error);
}
-static void
+void
mac_init_vnode_label(struct label *label)
{
@@ -1536,7 +1524,7 @@ mac_destroy_socket(struct socket *socket)
mac_destroy_socket_peer_label(&socket->so_peerlabel);
}
-static void
+void
mac_destroy_vnode_label(struct label *label)
{
@@ -1561,7 +1549,7 @@ mac_copy_pipe_label(struct label *src, struct label *dest)
MAC_PERFORM(copy_pipe_label, src, dest);
}
-static void
+void
mac_copy_vnode_label(struct label *src, struct label *dest)
{
@@ -1645,16 +1633,6 @@ mac_externalize_vnode_label(struct label *label, char *elements,
}
static int
-mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(externalize_vnode_oldmac, label, extmac);
-
- return (error);
-}
-
-static int
mac_internalize_cred_label(struct label *label, char *string)
{
int error;
@@ -1753,276 +1731,118 @@ mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
}
void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
+ struct vnode *vp)
{
- MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+ MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
+ &de->de_label, vp, &vp->v_label);
}
-/*
- * Support callout for policies that manage their own externalization
- * using extended attributes.
- */
-static int
-mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
+int
+mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
{
int error;
- MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- return (error);
-}
+ ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+ MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
return (error);
}
-/*
- * Call out to individual policies to update the label in a vnode from
- * the mountpoint.
- */
void
-mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
+mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
{
- MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
- if (mac_cache_fslabel_in_vnode)
- vp->v_vflag |= VV_CACHEDLABEL;
+ MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
}
-/*
- * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
- * to store label data. Can be referenced by filesystems supporting
- * extended attributes.
- */
int
-vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
+mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+ struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
- struct vnode *vp = ap->a_vp;
- struct oldmac extmac;
- int buflen, error;
+ int error;
- ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+ ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
+ ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
- /*
- * Call out to external policies first. Order doesn't really
- * matter, as long as failure of one assures failure of all.
- */
- error = mac_update_vnode_from_extattr(vp, vp->v_mount);
- if (error)
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
return (error);
- buflen = sizeof(extmac);
- error = vn_extattr_get(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
- (char *)&extmac, curthread);
- switch (error) {
- case 0:
- /* Got it */
- break;
-
- case ENOATTR:
- /*
- * Use the label from the mount point.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
+ MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
+ dvp, &dvp->v_label, vp, &vp->v_label, cnp);
- case EOPNOTSUPP:
- default:
- /* Fail horribly. */
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
- if (buflen != sizeof(extmac))
- error = EPERM; /* Fail very closed. */
- if (error == 0)
- error = mac_update_vnode_from_externalized(vp, &extmac);
- if (error == 0)
- vp->v_vflag |= VV_CACHEDLABEL;
- else {
- struct vattr va;
-
- printf("Corrupted label on %s",
- vp->v_mount->mnt_stat.f_mntonname);
- if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
- printf(" inum %ld", va.va_fileid);
-#ifdef MAC_DEBUG
- if (mac_debug_label_fallback) {
- printf(", falling back.\n");
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- } else {
-#endif
- printf(".\n");
- error = EPERM;
-#ifdef MAC_DEBUG
- }
-#endif
- }
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
+
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
return (error);
}
-/*
- * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle
- * the labeling activity outselves. Filesystems should be careful not
- * to change their minds regarding whether they support vop_refreshlabel()
- * for a vnode or not. Don't cache the vnode here, allow the file
- * system code to determine if it's safe to cache. If we update from
- * the mount, don't cache since a change to the mount label should affect
- * all vnodes.
- */
static int
-vn_refreshlabel(struct vnode *vp, struct ucred *cred)
+mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *intlabel)
{
int error;
- ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
-
- if (vp->v_mount == NULL) {
-/*
- Eventually, we probably want to special-case refreshing
- of deadfs vnodes, and if there's a lock-free race somewhere,
- that case might be handled here.
+ ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
- mac_update_vnode_deadfs(vp);
- return (0);
- */
- /* printf("vn_refreshlabel: null v_mount\n"); */
- if (vp->v_type != VNON)
- printf(
- "vn_refreshlabel: null v_mount with non-VNON\n");
- return (EBADF);
- }
-
- if (vp->v_vflag & VV_CACHEDLABEL) {
- mac_vnode_label_cache_hits++;
- return (0);
- } else
- mac_vnode_label_cache_misses++;
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
+ return (error);
- if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
- }
+ MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
- error = VOP_REFRESHLABEL(vp, cred, curthread);
- switch (error) {
- case EOPNOTSUPP:
- /*
- * If labels are not supported on this vnode, fall back to
- * the label in the mount and propagate it to the vnode.
- * There should probably be some sort of policy/flag/decision
- * about doing this.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- default:
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
-}
-/*
- * Helper function for file systems using the vop_std*_ea() calls. This
- * function must be called after EA service is available for the vnode,
- * but before it's hooked up to the namespace so that the node persists
- * if there's a crash, or before it can be accessed. On successful
- * commit of the label to disk (etc), do cache the label.
- */
-int
-vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
-{
- struct oldmac extmac;
- int error;
-
- ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
- if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(tvp, tvp->v_mount);
- } else {
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- /*
- * Stick the label in the vnode. Then try to write to
- * disk. If we fail, return a failure to abort the
- * create operation. Really, this failure shouldn't
- * happen except in fairly unusual circumstances (out
- * of disk, etc).
- */
- mac_create_vnode(cred, dvp, tvp);
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
- error = mac_stdcreatevnode_ea(tvp);
- if (error)
- return (error);
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
- /*
- * XXX: Eventually this will go away and all policies will
- * directly manage their extended attributes.
- */
- error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
- if (error)
- return (error);
-
- error = vn_extattr_set(tvp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
- if (error == 0)
- tvp->v_vflag |= VV_CACHEDLABEL;
- else {
-#if 0
- /*
- * In theory, we could have fall-back behavior here.
- * It would probably be incorrect.
- */
-#endif
- return (error);
- }
- }
-
- return (0);
+ return (error);
}
void
mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
{
- int error;
ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
- error = vn_refreshlabel(vp, old);
- if (error) {
- printf("mac_execve_transition: vn_refreshlabel returned %d\n",
- error);
- printf("mac_execve_transition: using old vnode label\n");
- }
-
MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
}
int
mac_execve_will_transition(struct ucred *old, struct vnode *vp)
{
- int error, result;
-
- error = vn_refreshlabel(vp, old);
- if (error)
- return (error);
+ int result;
result = 0;
MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
@@ -2040,10 +1860,6 @@ mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2058,10 +1874,6 @@ mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2076,10 +1888,6 @@ mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2095,10 +1903,6 @@ mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
return (error);
}
@@ -2115,13 +1919,6 @@ mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2138,10 +1935,6 @@ mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2156,9 +1949,6 @@ mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_process && !mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
return (error);
@@ -2174,10 +1964,6 @@ mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2193,10 +1979,6 @@ mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2214,14 +1996,6 @@ mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2238,10 +2012,6 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
return (error);
}
@@ -2256,10 +2026,6 @@ mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2290,10 +2056,6 @@ mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2308,10 +2070,6 @@ mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
return (error);
}
@@ -2327,10 +2085,6 @@ mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
&vp->v_label);
@@ -2348,10 +2102,6 @@ mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
&vp->v_label);
@@ -2368,10 +2118,6 @@ mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2386,10 +2132,6 @@ mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
return (error);
}
@@ -2402,10 +2144,6 @@ mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
return (error);
@@ -2423,13 +2161,6 @@ mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2447,14 +2178,6 @@ mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- if (vp != NULL) {
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
- }
MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
vp != NULL ? &vp->v_label : NULL, samedir, cnp);
return (error);
@@ -2470,10 +2193,6 @@ mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
return (error);
}
@@ -2489,10 +2208,6 @@ mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
return (error);
}
@@ -2508,10 +2223,6 @@ mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2527,10 +2238,6 @@ mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2545,10 +2252,6 @@ mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
return (error);
}
@@ -2564,10 +2267,6 @@ mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
return (error);
}
@@ -2583,10 +2282,6 @@ mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
mtime);
return (error);
@@ -2603,10 +2298,6 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
&vp->v_label);
return (error);
@@ -2622,10 +2313,6 @@ mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
@@ -2641,10 +2328,6 @@ mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
&vp->v_label);
@@ -3344,7 +3027,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3352,7 +3034,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3382,7 +3063,6 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3444,16 +3124,6 @@ mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
&de->de_label);
}
-static int
-mac_stdcreatevnode_ea(struct vnode *vp)
-{
- int error;
-
- MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
-
- return (error);
-}
-
void
mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de)
@@ -3463,29 +3133,6 @@ mac_create_devfs_directory(char *dirname, int dirnamelen,
&de->de_label);
}
-/*
- * When a new vnode is created, this call will initialize its label.
- */
-void
-mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child)
-{
- int error;
-
- ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
- ASSERT_VOP_LOCKED(child, "mac_create_vnode");
-
- error = vn_refreshlabel(parent, cred);
- if (error) {
- printf("mac_create_vnode: vn_refreshlabel returned %d\n",
- error);
- printf("mac_create_vnode: using old vnode label\n");
- }
-
- MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
- &child->v_label);
-}
-
int
mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
struct mac *mac)
@@ -3499,7 +3146,6 @@ mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
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);
@@ -3554,7 +3200,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
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);
@@ -3562,7 +3207,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_label(&so->so_label, elements,
buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3586,7 +3230,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
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);
@@ -3594,7 +3237,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_peer_label(&so->so_peerlabel,
elements, buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3616,35 +3258,19 @@ vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
{
struct vnode *vp = ap->a_vp;
struct label *intlabel = ap->a_label;
- struct oldmac extmac;
int error;
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
- /*
- * XXX: Eventually call out to EA check/set calls here.
- * Be particularly careful to avoid race conditions,
- * consistency problems, and stability problems when
- * dealing with multiple EAs. In particular, we require
- * the ability to write multiple EAs on the same file in
- * a single transaction, which the current EA interface
- * does not provide.
- */
-
- error = mac_externalize_vnode_oldmac(intlabel, &extmac);
- if (error)
- return (error);
+ if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+ return (EOPNOTSUPP);
- error = vn_extattr_set(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
+ error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
if (error)
return (error);
mac_relabel_vnode(ap->a_cred, vp, intlabel);
- vp->v_vflag |= VV_CACHEDLABEL;
-
return (0);
}
@@ -3721,7 +3347,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
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);
@@ -3730,7 +3355,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_cred_label(&tcred->cr_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3761,7 +3385,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
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);
@@ -3769,7 +3392,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
}
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, M_WAITOK);
if (error == 0)
@@ -3802,7 +3424,6 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
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);
@@ -3880,7 +3501,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
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);
@@ -3888,7 +3508,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
mtx_lock(&Giant); /* VFS */
error = fget(td, SCARG(uap, fd), &fp);
if (error)
@@ -3903,9 +3522,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
mac_init_vnode_label(&intlabel);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = vn_refreshlabel(vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&vp->v_label, &intlabel);
+ mac_copy_vnode_label(&vp->v_label, &intlabel);
VOP_UNLOCK(vp, 0, td);
break;
@@ -3974,7 +3591,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
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);
@@ -3982,7 +3598,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
}
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);
@@ -3991,12 +3606,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4034,7 +3646,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
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);
@@ -4042,7 +3653,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
}
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);
@@ -4051,12 +3661,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4096,7 +3703,6 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
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);
@@ -4183,7 +3789,6 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
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);
@@ -4240,7 +3845,6 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
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);
diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h
index aabc95e..46c4c1b 100644
--- a/sys/security/mac/mac_policy.h
+++ b/sys/security/mac/mac_policy.h
@@ -118,8 +118,6 @@ struct mac_policy_ops {
int (*mpo_externalize_vnode_label)(struct label *label,
char *element_name, char *buffer, size_t buflen,
size_t *len, int *claimed);
- int (*mpo_externalize_vnode_oldmac)(struct label *label,
- struct oldmac *extmac);
int (*mpo_internalize_cred_label)(struct label *label,
char *element_name, char *element_data, int *claimed);
int (*mpo_internalize_ifnet_label)(struct label *label,
@@ -135,6 +133,16 @@ struct mac_policy_ops {
* 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)(dev_t dev, struct devfs_dirent *de,
struct label *label);
void (*mpo_create_devfs_directory)(char *dirname, int dirnamelen,
@@ -145,30 +153,23 @@ struct mac_policy_ops {
void (*mpo_create_devfs_vnode)(struct devfs_dirent *de,
struct label *direntlabel, struct vnode *vp,
struct label *vnodelabel);
- void (*mpo_create_vnode)(struct ucred *cred, struct vnode *parent,
- struct label *parentlabel, struct vnode *child,
- struct label *childlabel);
+ 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_stdcreatevnode_ea)(struct vnode *vp,
- struct label *vnodelabel);
+ int (*mpo_setlabel_vnode_extattr)(struct ucred *cred,
+ struct vnode *vp, struct label *vlabel,
+ struct label *intlabel);
void (*mpo_update_devfsdirent)(struct devfs_dirent *devfs_dirent,
struct label *direntlabel, struct vnode *vp,
struct label *vnodelabel);
- void (*mpo_update_procfsvnode)(struct vnode *vp,
- struct label *vnodelabel, struct ucred *cred);
- int (*mpo_update_vnode_from_extattr)(struct vnode *vp,
- struct label *vnodelabel, struct mount *mp,
- struct label *fslabel);
- int (*mpo_update_vnode_from_externalized)(struct vnode *vp,
- struct label *vnodelabel, struct oldmac *extmac);
- void (*mpo_update_vnode_from_mount)(struct vnode *vp,
- struct label *vnodelabel, struct mount *mp,
- struct label *fslabel);
/*
* Labeling event operations: IPC objects.
@@ -431,7 +432,6 @@ enum mac_op_constant {
MAC_EXTERNALIZE_SOCKET_LABEL,
MAC_EXTERNALIZE_SOCKET_PEER_LABEL,
MAC_EXTERNALIZE_VNODE_LABEL,
- MAC_EXTERNALIZE_VNODE_OLDMAC,
MAC_INTERNALIZE_CRED_LABEL,
MAC_INTERNALIZE_IFNET_LABEL,
MAC_INTERNALIZE_PIPE_LABEL,
@@ -441,16 +441,15 @@ enum mac_op_constant {
MAC_CREATE_DEVFS_DIRECTORY,
MAC_CREATE_DEVFS_SYMLINK,
MAC_CREATE_DEVFS_VNODE,
- MAC_CREATE_VNODE,
MAC_CREATE_MOUNT,
MAC_CREATE_ROOT_MOUNT,
MAC_RELABEL_VNODE,
- MAC_STDCREATEVNODE_EA,
MAC_UPDATE_DEVFSDIRENT,
- MAC_UPDATE_PROCFSVNODE,
- MAC_UPDATE_VNODE_FROM_EXTATTR,
- MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
- MAC_UPDATE_VNODE_FROM_MOUNT,
+ MAC_ASSOCIATE_VNODE_DEVFS,
+ MAC_ASSOCIATE_VNODE_EXTATTR,
+ MAC_ASSOCIATE_VNODE_SINGLELABEL,
+ MAC_CREATE_VNODE_EXTATTR,
+ MAC_SETLABEL_VNODE_EXTATTR,
MAC_CREATE_MBUF_FROM_SOCKET,
MAC_CREATE_PIPE,
MAC_CREATE_SOCKET,
diff --git a/sys/security/mac/mac_process.c b/sys/security/mac/mac_process.c
index 78bc485..2ff4162 100644
--- a/sys/security/mac/mac_process.c
+++ b/sys/security/mac/mac_process.c
@@ -115,6 +115,12 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
*/
static int mac_late = 0;
+/*
+ * Warn about EA transactions only the first time they happen.
+ * Weak coherency, no locking.
+ */
+static int ea_warn_once = 0;
+
static int mac_enforce_fs = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -145,23 +151,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
-static int mac_label_size = sizeof(struct oldmac);
-SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
- &mac_label_size, 0, "Pre-compiled MAC label size");
-
static int mac_cache_fslabel_in_vnode = 1;
SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
&mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
&mac_cache_fslabel_in_vnode);
-static int mac_vnode_label_cache_hits = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
- &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
-static int mac_vnode_label_cache_misses = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
- &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
-
static int mac_mmap_revocation = 1;
SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
&mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
@@ -214,12 +209,9 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
#endif
static int error_select(int error1, int error2);
-static int mac_externalize_vnode_oldmac(struct label *label,
- struct oldmac *extmac);
static int mac_policy_register(struct mac_policy_conf *mpc);
static int mac_policy_unregister(struct mac_policy_conf *mpc);
-static int mac_stdcreatevnode_ea(struct vnode *vp);
static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
struct vnode *vp, int *prot);
static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
@@ -227,6 +219,10 @@ static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
static void mac_destroy_socket_label(struct label *label);
+static int mac_setlabel_vnode_extattr(struct ucred *cred,
+ struct vnode *vp, struct label *intlabel);
+
+
MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@@ -623,10 +619,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_externalize_vnode_label =
mpe->mpe_function;
break;
- case MAC_EXTERNALIZE_VNODE_OLDMAC:
- mpc->mpc_ops->mpo_externalize_vnode_oldmac =
- mpe->mpe_function;
- break;
case MAC_INTERNALIZE_CRED_LABEL:
mpc->mpc_ops->mpo_internalize_cred_label =
mpe->mpe_function;
@@ -663,14 +655,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_create_devfs_vnode =
mpe->mpe_function;
break;
- case MAC_STDCREATEVNODE_EA:
- mpc->mpc_ops->mpo_stdcreatevnode_ea =
- mpe->mpe_function;
- break;
- case MAC_CREATE_VNODE:
- mpc->mpc_ops->mpo_create_vnode =
- mpe->mpe_function;
- break;
case MAC_CREATE_MOUNT:
mpc->mpc_ops->mpo_create_mount =
mpe->mpe_function;
@@ -687,20 +671,24 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_update_devfsdirent =
mpe->mpe_function;
break;
- case MAC_UPDATE_PROCFSVNODE:
- mpc->mpc_ops->mpo_update_procfsvnode =
+ case MAC_ASSOCIATE_VNODE_DEVFS:
+ mpc->mpc_ops->mpo_associate_vnode_devfs =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTATTR:
- mpc->mpc_ops->mpo_update_vnode_from_extattr =
+ case MAC_ASSOCIATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_associate_vnode_extattr =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
- mpc->mpc_ops->mpo_update_vnode_from_externalized =
+ case MAC_ASSOCIATE_VNODE_SINGLELABEL:
+ mpc->mpc_ops->mpo_associate_vnode_singlelabel =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_MOUNT:
- mpc->mpc_ops->mpo_update_vnode_from_mount =
+ case MAC_CREATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_create_vnode_extattr =
+ mpe->mpe_function;
+ break;
+ case MAC_SETLABEL_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_setlabel_vnode_extattr =
mpe->mpe_function;
break;
case MAC_CREATE_MBUF_FROM_SOCKET:
@@ -1379,7 +1367,7 @@ mac_init_socket(struct socket *socket, int flag)
return (error);
}
-static void
+void
mac_init_vnode_label(struct label *label)
{
@@ -1536,7 +1524,7 @@ mac_destroy_socket(struct socket *socket)
mac_destroy_socket_peer_label(&socket->so_peerlabel);
}
-static void
+void
mac_destroy_vnode_label(struct label *label)
{
@@ -1561,7 +1549,7 @@ mac_copy_pipe_label(struct label *src, struct label *dest)
MAC_PERFORM(copy_pipe_label, src, dest);
}
-static void
+void
mac_copy_vnode_label(struct label *src, struct label *dest)
{
@@ -1645,16 +1633,6 @@ mac_externalize_vnode_label(struct label *label, char *elements,
}
static int
-mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(externalize_vnode_oldmac, label, extmac);
-
- return (error);
-}
-
-static int
mac_internalize_cred_label(struct label *label, char *string)
{
int error;
@@ -1753,276 +1731,118 @@ mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
}
void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
+ struct vnode *vp)
{
- MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+ MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
+ &de->de_label, vp, &vp->v_label);
}
-/*
- * Support callout for policies that manage their own externalization
- * using extended attributes.
- */
-static int
-mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
+int
+mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
{
int error;
- MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- return (error);
-}
+ ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+ MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
return (error);
}
-/*
- * Call out to individual policies to update the label in a vnode from
- * the mountpoint.
- */
void
-mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
+mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
{
- MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
- if (mac_cache_fslabel_in_vnode)
- vp->v_vflag |= VV_CACHEDLABEL;
+ MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
}
-/*
- * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
- * to store label data. Can be referenced by filesystems supporting
- * extended attributes.
- */
int
-vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
+mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+ struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
- struct vnode *vp = ap->a_vp;
- struct oldmac extmac;
- int buflen, error;
+ int error;
- ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+ ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
+ ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
- /*
- * Call out to external policies first. Order doesn't really
- * matter, as long as failure of one assures failure of all.
- */
- error = mac_update_vnode_from_extattr(vp, vp->v_mount);
- if (error)
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
return (error);
- buflen = sizeof(extmac);
- error = vn_extattr_get(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
- (char *)&extmac, curthread);
- switch (error) {
- case 0:
- /* Got it */
- break;
-
- case ENOATTR:
- /*
- * Use the label from the mount point.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
+ MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
+ dvp, &dvp->v_label, vp, &vp->v_label, cnp);
- case EOPNOTSUPP:
- default:
- /* Fail horribly. */
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
- if (buflen != sizeof(extmac))
- error = EPERM; /* Fail very closed. */
- if (error == 0)
- error = mac_update_vnode_from_externalized(vp, &extmac);
- if (error == 0)
- vp->v_vflag |= VV_CACHEDLABEL;
- else {
- struct vattr va;
-
- printf("Corrupted label on %s",
- vp->v_mount->mnt_stat.f_mntonname);
- if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
- printf(" inum %ld", va.va_fileid);
-#ifdef MAC_DEBUG
- if (mac_debug_label_fallback) {
- printf(", falling back.\n");
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- } else {
-#endif
- printf(".\n");
- error = EPERM;
-#ifdef MAC_DEBUG
- }
-#endif
- }
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
+
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
return (error);
}
-/*
- * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle
- * the labeling activity outselves. Filesystems should be careful not
- * to change their minds regarding whether they support vop_refreshlabel()
- * for a vnode or not. Don't cache the vnode here, allow the file
- * system code to determine if it's safe to cache. If we update from
- * the mount, don't cache since a change to the mount label should affect
- * all vnodes.
- */
static int
-vn_refreshlabel(struct vnode *vp, struct ucred *cred)
+mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *intlabel)
{
int error;
- ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
-
- if (vp->v_mount == NULL) {
-/*
- Eventually, we probably want to special-case refreshing
- of deadfs vnodes, and if there's a lock-free race somewhere,
- that case might be handled here.
+ ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
- mac_update_vnode_deadfs(vp);
- return (0);
- */
- /* printf("vn_refreshlabel: null v_mount\n"); */
- if (vp->v_type != VNON)
- printf(
- "vn_refreshlabel: null v_mount with non-VNON\n");
- return (EBADF);
- }
-
- if (vp->v_vflag & VV_CACHEDLABEL) {
- mac_vnode_label_cache_hits++;
- return (0);
- } else
- mac_vnode_label_cache_misses++;
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
+ return (error);
- if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
- }
+ MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
- error = VOP_REFRESHLABEL(vp, cred, curthread);
- switch (error) {
- case EOPNOTSUPP:
- /*
- * If labels are not supported on this vnode, fall back to
- * the label in the mount and propagate it to the vnode.
- * There should probably be some sort of policy/flag/decision
- * about doing this.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- default:
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
-}
-/*
- * Helper function for file systems using the vop_std*_ea() calls. This
- * function must be called after EA service is available for the vnode,
- * but before it's hooked up to the namespace so that the node persists
- * if there's a crash, or before it can be accessed. On successful
- * commit of the label to disk (etc), do cache the label.
- */
-int
-vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
-{
- struct oldmac extmac;
- int error;
-
- ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
- if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(tvp, tvp->v_mount);
- } else {
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- /*
- * Stick the label in the vnode. Then try to write to
- * disk. If we fail, return a failure to abort the
- * create operation. Really, this failure shouldn't
- * happen except in fairly unusual circumstances (out
- * of disk, etc).
- */
- mac_create_vnode(cred, dvp, tvp);
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
- error = mac_stdcreatevnode_ea(tvp);
- if (error)
- return (error);
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
- /*
- * XXX: Eventually this will go away and all policies will
- * directly manage their extended attributes.
- */
- error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
- if (error)
- return (error);
-
- error = vn_extattr_set(tvp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
- if (error == 0)
- tvp->v_vflag |= VV_CACHEDLABEL;
- else {
-#if 0
- /*
- * In theory, we could have fall-back behavior here.
- * It would probably be incorrect.
- */
-#endif
- return (error);
- }
- }
-
- return (0);
+ return (error);
}
void
mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
{
- int error;
ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
- error = vn_refreshlabel(vp, old);
- if (error) {
- printf("mac_execve_transition: vn_refreshlabel returned %d\n",
- error);
- printf("mac_execve_transition: using old vnode label\n");
- }
-
MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
}
int
mac_execve_will_transition(struct ucred *old, struct vnode *vp)
{
- int error, result;
-
- error = vn_refreshlabel(vp, old);
- if (error)
- return (error);
+ int result;
result = 0;
MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
@@ -2040,10 +1860,6 @@ mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2058,10 +1874,6 @@ mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2076,10 +1888,6 @@ mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2095,10 +1903,6 @@ mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
return (error);
}
@@ -2115,13 +1919,6 @@ mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2138,10 +1935,6 @@ mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2156,9 +1949,6 @@ mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_process && !mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
return (error);
@@ -2174,10 +1964,6 @@ mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2193,10 +1979,6 @@ mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2214,14 +1996,6 @@ mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2238,10 +2012,6 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
return (error);
}
@@ -2256,10 +2026,6 @@ mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2290,10 +2056,6 @@ mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2308,10 +2070,6 @@ mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
return (error);
}
@@ -2327,10 +2085,6 @@ mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
&vp->v_label);
@@ -2348,10 +2102,6 @@ mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
&vp->v_label);
@@ -2368,10 +2118,6 @@ mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2386,10 +2132,6 @@ mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
return (error);
}
@@ -2402,10 +2144,6 @@ mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
return (error);
@@ -2423,13 +2161,6 @@ mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2447,14 +2178,6 @@ mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- if (vp != NULL) {
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
- }
MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
vp != NULL ? &vp->v_label : NULL, samedir, cnp);
return (error);
@@ -2470,10 +2193,6 @@ mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
return (error);
}
@@ -2489,10 +2208,6 @@ mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
return (error);
}
@@ -2508,10 +2223,6 @@ mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2527,10 +2238,6 @@ mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2545,10 +2252,6 @@ mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
return (error);
}
@@ -2564,10 +2267,6 @@ mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
return (error);
}
@@ -2583,10 +2282,6 @@ mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
mtime);
return (error);
@@ -2603,10 +2298,6 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
&vp->v_label);
return (error);
@@ -2622,10 +2313,6 @@ mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
@@ -2641,10 +2328,6 @@ mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
&vp->v_label);
@@ -3344,7 +3027,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3352,7 +3034,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3382,7 +3063,6 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3444,16 +3124,6 @@ mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
&de->de_label);
}
-static int
-mac_stdcreatevnode_ea(struct vnode *vp)
-{
- int error;
-
- MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
-
- return (error);
-}
-
void
mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de)
@@ -3463,29 +3133,6 @@ mac_create_devfs_directory(char *dirname, int dirnamelen,
&de->de_label);
}
-/*
- * When a new vnode is created, this call will initialize its label.
- */
-void
-mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child)
-{
- int error;
-
- ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
- ASSERT_VOP_LOCKED(child, "mac_create_vnode");
-
- error = vn_refreshlabel(parent, cred);
- if (error) {
- printf("mac_create_vnode: vn_refreshlabel returned %d\n",
- error);
- printf("mac_create_vnode: using old vnode label\n");
- }
-
- MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
- &child->v_label);
-}
-
int
mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
struct mac *mac)
@@ -3499,7 +3146,6 @@ mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
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);
@@ -3554,7 +3200,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
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);
@@ -3562,7 +3207,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_label(&so->so_label, elements,
buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3586,7 +3230,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
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);
@@ -3594,7 +3237,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_peer_label(&so->so_peerlabel,
elements, buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3616,35 +3258,19 @@ vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
{
struct vnode *vp = ap->a_vp;
struct label *intlabel = ap->a_label;
- struct oldmac extmac;
int error;
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
- /*
- * XXX: Eventually call out to EA check/set calls here.
- * Be particularly careful to avoid race conditions,
- * consistency problems, and stability problems when
- * dealing with multiple EAs. In particular, we require
- * the ability to write multiple EAs on the same file in
- * a single transaction, which the current EA interface
- * does not provide.
- */
-
- error = mac_externalize_vnode_oldmac(intlabel, &extmac);
- if (error)
- return (error);
+ if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+ return (EOPNOTSUPP);
- error = vn_extattr_set(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
+ error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
if (error)
return (error);
mac_relabel_vnode(ap->a_cred, vp, intlabel);
- vp->v_vflag |= VV_CACHEDLABEL;
-
return (0);
}
@@ -3721,7 +3347,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
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);
@@ -3730,7 +3355,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_cred_label(&tcred->cr_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3761,7 +3385,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
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);
@@ -3769,7 +3392,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
}
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, M_WAITOK);
if (error == 0)
@@ -3802,7 +3424,6 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
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);
@@ -3880,7 +3501,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
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);
@@ -3888,7 +3508,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
mtx_lock(&Giant); /* VFS */
error = fget(td, SCARG(uap, fd), &fp);
if (error)
@@ -3903,9 +3522,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
mac_init_vnode_label(&intlabel);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = vn_refreshlabel(vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&vp->v_label, &intlabel);
+ mac_copy_vnode_label(&vp->v_label, &intlabel);
VOP_UNLOCK(vp, 0, td);
break;
@@ -3974,7 +3591,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
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);
@@ -3982,7 +3598,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
}
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);
@@ -3991,12 +3606,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4034,7 +3646,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
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);
@@ -4042,7 +3653,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
}
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);
@@ -4051,12 +3661,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4096,7 +3703,6 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
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);
@@ -4183,7 +3789,6 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
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);
@@ -4240,7 +3845,6 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
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);
diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c
index 78bc485..2ff4162 100644
--- a/sys/security/mac/mac_syscalls.c
+++ b/sys/security/mac/mac_syscalls.c
@@ -115,6 +115,12 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
*/
static int mac_late = 0;
+/*
+ * Warn about EA transactions only the first time they happen.
+ * Weak coherency, no locking.
+ */
+static int ea_warn_once = 0;
+
static int mac_enforce_fs = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -145,23 +151,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
-static int mac_label_size = sizeof(struct oldmac);
-SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
- &mac_label_size, 0, "Pre-compiled MAC label size");
-
static int mac_cache_fslabel_in_vnode = 1;
SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
&mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
&mac_cache_fslabel_in_vnode);
-static int mac_vnode_label_cache_hits = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
- &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
-static int mac_vnode_label_cache_misses = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
- &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
-
static int mac_mmap_revocation = 1;
SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
&mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
@@ -214,12 +209,9 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
#endif
static int error_select(int error1, int error2);
-static int mac_externalize_vnode_oldmac(struct label *label,
- struct oldmac *extmac);
static int mac_policy_register(struct mac_policy_conf *mpc);
static int mac_policy_unregister(struct mac_policy_conf *mpc);
-static int mac_stdcreatevnode_ea(struct vnode *vp);
static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
struct vnode *vp, int *prot);
static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
@@ -227,6 +219,10 @@ static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
static void mac_destroy_socket_label(struct label *label);
+static int mac_setlabel_vnode_extattr(struct ucred *cred,
+ struct vnode *vp, struct label *intlabel);
+
+
MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@@ -623,10 +619,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_externalize_vnode_label =
mpe->mpe_function;
break;
- case MAC_EXTERNALIZE_VNODE_OLDMAC:
- mpc->mpc_ops->mpo_externalize_vnode_oldmac =
- mpe->mpe_function;
- break;
case MAC_INTERNALIZE_CRED_LABEL:
mpc->mpc_ops->mpo_internalize_cred_label =
mpe->mpe_function;
@@ -663,14 +655,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_create_devfs_vnode =
mpe->mpe_function;
break;
- case MAC_STDCREATEVNODE_EA:
- mpc->mpc_ops->mpo_stdcreatevnode_ea =
- mpe->mpe_function;
- break;
- case MAC_CREATE_VNODE:
- mpc->mpc_ops->mpo_create_vnode =
- mpe->mpe_function;
- break;
case MAC_CREATE_MOUNT:
mpc->mpc_ops->mpo_create_mount =
mpe->mpe_function;
@@ -687,20 +671,24 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_update_devfsdirent =
mpe->mpe_function;
break;
- case MAC_UPDATE_PROCFSVNODE:
- mpc->mpc_ops->mpo_update_procfsvnode =
+ case MAC_ASSOCIATE_VNODE_DEVFS:
+ mpc->mpc_ops->mpo_associate_vnode_devfs =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTATTR:
- mpc->mpc_ops->mpo_update_vnode_from_extattr =
+ case MAC_ASSOCIATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_associate_vnode_extattr =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
- mpc->mpc_ops->mpo_update_vnode_from_externalized =
+ case MAC_ASSOCIATE_VNODE_SINGLELABEL:
+ mpc->mpc_ops->mpo_associate_vnode_singlelabel =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_MOUNT:
- mpc->mpc_ops->mpo_update_vnode_from_mount =
+ case MAC_CREATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_create_vnode_extattr =
+ mpe->mpe_function;
+ break;
+ case MAC_SETLABEL_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_setlabel_vnode_extattr =
mpe->mpe_function;
break;
case MAC_CREATE_MBUF_FROM_SOCKET:
@@ -1379,7 +1367,7 @@ mac_init_socket(struct socket *socket, int flag)
return (error);
}
-static void
+void
mac_init_vnode_label(struct label *label)
{
@@ -1536,7 +1524,7 @@ mac_destroy_socket(struct socket *socket)
mac_destroy_socket_peer_label(&socket->so_peerlabel);
}
-static void
+void
mac_destroy_vnode_label(struct label *label)
{
@@ -1561,7 +1549,7 @@ mac_copy_pipe_label(struct label *src, struct label *dest)
MAC_PERFORM(copy_pipe_label, src, dest);
}
-static void
+void
mac_copy_vnode_label(struct label *src, struct label *dest)
{
@@ -1645,16 +1633,6 @@ mac_externalize_vnode_label(struct label *label, char *elements,
}
static int
-mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(externalize_vnode_oldmac, label, extmac);
-
- return (error);
-}
-
-static int
mac_internalize_cred_label(struct label *label, char *string)
{
int error;
@@ -1753,276 +1731,118 @@ mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
}
void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
+ struct vnode *vp)
{
- MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+ MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
+ &de->de_label, vp, &vp->v_label);
}
-/*
- * Support callout for policies that manage their own externalization
- * using extended attributes.
- */
-static int
-mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
+int
+mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
{
int error;
- MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- return (error);
-}
+ ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+ MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
return (error);
}
-/*
- * Call out to individual policies to update the label in a vnode from
- * the mountpoint.
- */
void
-mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
+mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
{
- MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
- if (mac_cache_fslabel_in_vnode)
- vp->v_vflag |= VV_CACHEDLABEL;
+ MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
}
-/*
- * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
- * to store label data. Can be referenced by filesystems supporting
- * extended attributes.
- */
int
-vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
+mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+ struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
- struct vnode *vp = ap->a_vp;
- struct oldmac extmac;
- int buflen, error;
+ int error;
- ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+ ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
+ ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
- /*
- * Call out to external policies first. Order doesn't really
- * matter, as long as failure of one assures failure of all.
- */
- error = mac_update_vnode_from_extattr(vp, vp->v_mount);
- if (error)
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
return (error);
- buflen = sizeof(extmac);
- error = vn_extattr_get(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
- (char *)&extmac, curthread);
- switch (error) {
- case 0:
- /* Got it */
- break;
-
- case ENOATTR:
- /*
- * Use the label from the mount point.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
+ MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
+ dvp, &dvp->v_label, vp, &vp->v_label, cnp);
- case EOPNOTSUPP:
- default:
- /* Fail horribly. */
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
- if (buflen != sizeof(extmac))
- error = EPERM; /* Fail very closed. */
- if (error == 0)
- error = mac_update_vnode_from_externalized(vp, &extmac);
- if (error == 0)
- vp->v_vflag |= VV_CACHEDLABEL;
- else {
- struct vattr va;
-
- printf("Corrupted label on %s",
- vp->v_mount->mnt_stat.f_mntonname);
- if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
- printf(" inum %ld", va.va_fileid);
-#ifdef MAC_DEBUG
- if (mac_debug_label_fallback) {
- printf(", falling back.\n");
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- } else {
-#endif
- printf(".\n");
- error = EPERM;
-#ifdef MAC_DEBUG
- }
-#endif
- }
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
+
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
return (error);
}
-/*
- * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle
- * the labeling activity outselves. Filesystems should be careful not
- * to change their minds regarding whether they support vop_refreshlabel()
- * for a vnode or not. Don't cache the vnode here, allow the file
- * system code to determine if it's safe to cache. If we update from
- * the mount, don't cache since a change to the mount label should affect
- * all vnodes.
- */
static int
-vn_refreshlabel(struct vnode *vp, struct ucred *cred)
+mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *intlabel)
{
int error;
- ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
-
- if (vp->v_mount == NULL) {
-/*
- Eventually, we probably want to special-case refreshing
- of deadfs vnodes, and if there's a lock-free race somewhere,
- that case might be handled here.
+ ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
- mac_update_vnode_deadfs(vp);
- return (0);
- */
- /* printf("vn_refreshlabel: null v_mount\n"); */
- if (vp->v_type != VNON)
- printf(
- "vn_refreshlabel: null v_mount with non-VNON\n");
- return (EBADF);
- }
-
- if (vp->v_vflag & VV_CACHEDLABEL) {
- mac_vnode_label_cache_hits++;
- return (0);
- } else
- mac_vnode_label_cache_misses++;
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
+ return (error);
- if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
- }
+ MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
- error = VOP_REFRESHLABEL(vp, cred, curthread);
- switch (error) {
- case EOPNOTSUPP:
- /*
- * If labels are not supported on this vnode, fall back to
- * the label in the mount and propagate it to the vnode.
- * There should probably be some sort of policy/flag/decision
- * about doing this.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- default:
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
-}
-/*
- * Helper function for file systems using the vop_std*_ea() calls. This
- * function must be called after EA service is available for the vnode,
- * but before it's hooked up to the namespace so that the node persists
- * if there's a crash, or before it can be accessed. On successful
- * commit of the label to disk (etc), do cache the label.
- */
-int
-vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
-{
- struct oldmac extmac;
- int error;
-
- ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
- if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(tvp, tvp->v_mount);
- } else {
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- /*
- * Stick the label in the vnode. Then try to write to
- * disk. If we fail, return a failure to abort the
- * create operation. Really, this failure shouldn't
- * happen except in fairly unusual circumstances (out
- * of disk, etc).
- */
- mac_create_vnode(cred, dvp, tvp);
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
- error = mac_stdcreatevnode_ea(tvp);
- if (error)
- return (error);
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
- /*
- * XXX: Eventually this will go away and all policies will
- * directly manage their extended attributes.
- */
- error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
- if (error)
- return (error);
-
- error = vn_extattr_set(tvp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
- if (error == 0)
- tvp->v_vflag |= VV_CACHEDLABEL;
- else {
-#if 0
- /*
- * In theory, we could have fall-back behavior here.
- * It would probably be incorrect.
- */
-#endif
- return (error);
- }
- }
-
- return (0);
+ return (error);
}
void
mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
{
- int error;
ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
- error = vn_refreshlabel(vp, old);
- if (error) {
- printf("mac_execve_transition: vn_refreshlabel returned %d\n",
- error);
- printf("mac_execve_transition: using old vnode label\n");
- }
-
MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
}
int
mac_execve_will_transition(struct ucred *old, struct vnode *vp)
{
- int error, result;
-
- error = vn_refreshlabel(vp, old);
- if (error)
- return (error);
+ int result;
result = 0;
MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
@@ -2040,10 +1860,6 @@ mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2058,10 +1874,6 @@ mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2076,10 +1888,6 @@ mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2095,10 +1903,6 @@ mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
return (error);
}
@@ -2115,13 +1919,6 @@ mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2138,10 +1935,6 @@ mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2156,9 +1949,6 @@ mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_process && !mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
return (error);
@@ -2174,10 +1964,6 @@ mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2193,10 +1979,6 @@ mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2214,14 +1996,6 @@ mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2238,10 +2012,6 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
return (error);
}
@@ -2256,10 +2026,6 @@ mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2290,10 +2056,6 @@ mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2308,10 +2070,6 @@ mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
return (error);
}
@@ -2327,10 +2085,6 @@ mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
&vp->v_label);
@@ -2348,10 +2102,6 @@ mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
&vp->v_label);
@@ -2368,10 +2118,6 @@ mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2386,10 +2132,6 @@ mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
return (error);
}
@@ -2402,10 +2144,6 @@ mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
return (error);
@@ -2423,13 +2161,6 @@ mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2447,14 +2178,6 @@ mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- if (vp != NULL) {
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
- }
MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
vp != NULL ? &vp->v_label : NULL, samedir, cnp);
return (error);
@@ -2470,10 +2193,6 @@ mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
return (error);
}
@@ -2489,10 +2208,6 @@ mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
return (error);
}
@@ -2508,10 +2223,6 @@ mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2527,10 +2238,6 @@ mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2545,10 +2252,6 @@ mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
return (error);
}
@@ -2564,10 +2267,6 @@ mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
return (error);
}
@@ -2583,10 +2282,6 @@ mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
mtime);
return (error);
@@ -2603,10 +2298,6 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
&vp->v_label);
return (error);
@@ -2622,10 +2313,6 @@ mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
@@ -2641,10 +2328,6 @@ mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
&vp->v_label);
@@ -3344,7 +3027,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3352,7 +3034,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3382,7 +3063,6 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3444,16 +3124,6 @@ mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
&de->de_label);
}
-static int
-mac_stdcreatevnode_ea(struct vnode *vp)
-{
- int error;
-
- MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
-
- return (error);
-}
-
void
mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de)
@@ -3463,29 +3133,6 @@ mac_create_devfs_directory(char *dirname, int dirnamelen,
&de->de_label);
}
-/*
- * When a new vnode is created, this call will initialize its label.
- */
-void
-mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child)
-{
- int error;
-
- ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
- ASSERT_VOP_LOCKED(child, "mac_create_vnode");
-
- error = vn_refreshlabel(parent, cred);
- if (error) {
- printf("mac_create_vnode: vn_refreshlabel returned %d\n",
- error);
- printf("mac_create_vnode: using old vnode label\n");
- }
-
- MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
- &child->v_label);
-}
-
int
mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
struct mac *mac)
@@ -3499,7 +3146,6 @@ mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
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);
@@ -3554,7 +3200,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
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);
@@ -3562,7 +3207,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_label(&so->so_label, elements,
buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3586,7 +3230,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
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);
@@ -3594,7 +3237,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_peer_label(&so->so_peerlabel,
elements, buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3616,35 +3258,19 @@ vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
{
struct vnode *vp = ap->a_vp;
struct label *intlabel = ap->a_label;
- struct oldmac extmac;
int error;
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
- /*
- * XXX: Eventually call out to EA check/set calls here.
- * Be particularly careful to avoid race conditions,
- * consistency problems, and stability problems when
- * dealing with multiple EAs. In particular, we require
- * the ability to write multiple EAs on the same file in
- * a single transaction, which the current EA interface
- * does not provide.
- */
-
- error = mac_externalize_vnode_oldmac(intlabel, &extmac);
- if (error)
- return (error);
+ if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+ return (EOPNOTSUPP);
- error = vn_extattr_set(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
+ error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
if (error)
return (error);
mac_relabel_vnode(ap->a_cred, vp, intlabel);
- vp->v_vflag |= VV_CACHEDLABEL;
-
return (0);
}
@@ -3721,7 +3347,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
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);
@@ -3730,7 +3355,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_cred_label(&tcred->cr_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3761,7 +3385,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
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);
@@ -3769,7 +3392,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
}
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, M_WAITOK);
if (error == 0)
@@ -3802,7 +3424,6 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
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);
@@ -3880,7 +3501,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
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);
@@ -3888,7 +3508,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
mtx_lock(&Giant); /* VFS */
error = fget(td, SCARG(uap, fd), &fp);
if (error)
@@ -3903,9 +3522,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
mac_init_vnode_label(&intlabel);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = vn_refreshlabel(vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&vp->v_label, &intlabel);
+ mac_copy_vnode_label(&vp->v_label, &intlabel);
VOP_UNLOCK(vp, 0, td);
break;
@@ -3974,7 +3591,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
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);
@@ -3982,7 +3598,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
}
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);
@@ -3991,12 +3606,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4034,7 +3646,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
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);
@@ -4042,7 +3653,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
}
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);
@@ -4051,12 +3661,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4096,7 +3703,6 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
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);
@@ -4183,7 +3789,6 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
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);
@@ -4240,7 +3845,6 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
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);
diff --git a/sys/security/mac/mac_system.c b/sys/security/mac/mac_system.c
index 78bc485..2ff4162 100644
--- a/sys/security/mac/mac_system.c
+++ b/sys/security/mac/mac_system.c
@@ -115,6 +115,12 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
*/
static int mac_late = 0;
+/*
+ * Warn about EA transactions only the first time they happen.
+ * Weak coherency, no locking.
+ */
+static int ea_warn_once = 0;
+
static int mac_enforce_fs = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -145,23 +151,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
-static int mac_label_size = sizeof(struct oldmac);
-SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
- &mac_label_size, 0, "Pre-compiled MAC label size");
-
static int mac_cache_fslabel_in_vnode = 1;
SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
&mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
&mac_cache_fslabel_in_vnode);
-static int mac_vnode_label_cache_hits = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
- &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
-static int mac_vnode_label_cache_misses = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
- &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
-
static int mac_mmap_revocation = 1;
SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
&mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
@@ -214,12 +209,9 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
#endif
static int error_select(int error1, int error2);
-static int mac_externalize_vnode_oldmac(struct label *label,
- struct oldmac *extmac);
static int mac_policy_register(struct mac_policy_conf *mpc);
static int mac_policy_unregister(struct mac_policy_conf *mpc);
-static int mac_stdcreatevnode_ea(struct vnode *vp);
static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
struct vnode *vp, int *prot);
static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
@@ -227,6 +219,10 @@ static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
static void mac_destroy_socket_label(struct label *label);
+static int mac_setlabel_vnode_extattr(struct ucred *cred,
+ struct vnode *vp, struct label *intlabel);
+
+
MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@@ -623,10 +619,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_externalize_vnode_label =
mpe->mpe_function;
break;
- case MAC_EXTERNALIZE_VNODE_OLDMAC:
- mpc->mpc_ops->mpo_externalize_vnode_oldmac =
- mpe->mpe_function;
- break;
case MAC_INTERNALIZE_CRED_LABEL:
mpc->mpc_ops->mpo_internalize_cred_label =
mpe->mpe_function;
@@ -663,14 +655,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_create_devfs_vnode =
mpe->mpe_function;
break;
- case MAC_STDCREATEVNODE_EA:
- mpc->mpc_ops->mpo_stdcreatevnode_ea =
- mpe->mpe_function;
- break;
- case MAC_CREATE_VNODE:
- mpc->mpc_ops->mpo_create_vnode =
- mpe->mpe_function;
- break;
case MAC_CREATE_MOUNT:
mpc->mpc_ops->mpo_create_mount =
mpe->mpe_function;
@@ -687,20 +671,24 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_update_devfsdirent =
mpe->mpe_function;
break;
- case MAC_UPDATE_PROCFSVNODE:
- mpc->mpc_ops->mpo_update_procfsvnode =
+ case MAC_ASSOCIATE_VNODE_DEVFS:
+ mpc->mpc_ops->mpo_associate_vnode_devfs =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTATTR:
- mpc->mpc_ops->mpo_update_vnode_from_extattr =
+ case MAC_ASSOCIATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_associate_vnode_extattr =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
- mpc->mpc_ops->mpo_update_vnode_from_externalized =
+ case MAC_ASSOCIATE_VNODE_SINGLELABEL:
+ mpc->mpc_ops->mpo_associate_vnode_singlelabel =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_MOUNT:
- mpc->mpc_ops->mpo_update_vnode_from_mount =
+ case MAC_CREATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_create_vnode_extattr =
+ mpe->mpe_function;
+ break;
+ case MAC_SETLABEL_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_setlabel_vnode_extattr =
mpe->mpe_function;
break;
case MAC_CREATE_MBUF_FROM_SOCKET:
@@ -1379,7 +1367,7 @@ mac_init_socket(struct socket *socket, int flag)
return (error);
}
-static void
+void
mac_init_vnode_label(struct label *label)
{
@@ -1536,7 +1524,7 @@ mac_destroy_socket(struct socket *socket)
mac_destroy_socket_peer_label(&socket->so_peerlabel);
}
-static void
+void
mac_destroy_vnode_label(struct label *label)
{
@@ -1561,7 +1549,7 @@ mac_copy_pipe_label(struct label *src, struct label *dest)
MAC_PERFORM(copy_pipe_label, src, dest);
}
-static void
+void
mac_copy_vnode_label(struct label *src, struct label *dest)
{
@@ -1645,16 +1633,6 @@ mac_externalize_vnode_label(struct label *label, char *elements,
}
static int
-mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(externalize_vnode_oldmac, label, extmac);
-
- return (error);
-}
-
-static int
mac_internalize_cred_label(struct label *label, char *string)
{
int error;
@@ -1753,276 +1731,118 @@ mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
}
void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
+ struct vnode *vp)
{
- MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+ MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
+ &de->de_label, vp, &vp->v_label);
}
-/*
- * Support callout for policies that manage their own externalization
- * using extended attributes.
- */
-static int
-mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
+int
+mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
{
int error;
- MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- return (error);
-}
+ ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+ MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
return (error);
}
-/*
- * Call out to individual policies to update the label in a vnode from
- * the mountpoint.
- */
void
-mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
+mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
{
- MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
- if (mac_cache_fslabel_in_vnode)
- vp->v_vflag |= VV_CACHEDLABEL;
+ MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
}
-/*
- * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
- * to store label data. Can be referenced by filesystems supporting
- * extended attributes.
- */
int
-vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
+mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+ struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
- struct vnode *vp = ap->a_vp;
- struct oldmac extmac;
- int buflen, error;
+ int error;
- ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+ ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
+ ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
- /*
- * Call out to external policies first. Order doesn't really
- * matter, as long as failure of one assures failure of all.
- */
- error = mac_update_vnode_from_extattr(vp, vp->v_mount);
- if (error)
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
return (error);
- buflen = sizeof(extmac);
- error = vn_extattr_get(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
- (char *)&extmac, curthread);
- switch (error) {
- case 0:
- /* Got it */
- break;
-
- case ENOATTR:
- /*
- * Use the label from the mount point.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
+ MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
+ dvp, &dvp->v_label, vp, &vp->v_label, cnp);
- case EOPNOTSUPP:
- default:
- /* Fail horribly. */
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
- if (buflen != sizeof(extmac))
- error = EPERM; /* Fail very closed. */
- if (error == 0)
- error = mac_update_vnode_from_externalized(vp, &extmac);
- if (error == 0)
- vp->v_vflag |= VV_CACHEDLABEL;
- else {
- struct vattr va;
-
- printf("Corrupted label on %s",
- vp->v_mount->mnt_stat.f_mntonname);
- if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
- printf(" inum %ld", va.va_fileid);
-#ifdef MAC_DEBUG
- if (mac_debug_label_fallback) {
- printf(", falling back.\n");
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- } else {
-#endif
- printf(".\n");
- error = EPERM;
-#ifdef MAC_DEBUG
- }
-#endif
- }
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
+
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
return (error);
}
-/*
- * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle
- * the labeling activity outselves. Filesystems should be careful not
- * to change their minds regarding whether they support vop_refreshlabel()
- * for a vnode or not. Don't cache the vnode here, allow the file
- * system code to determine if it's safe to cache. If we update from
- * the mount, don't cache since a change to the mount label should affect
- * all vnodes.
- */
static int
-vn_refreshlabel(struct vnode *vp, struct ucred *cred)
+mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *intlabel)
{
int error;
- ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
-
- if (vp->v_mount == NULL) {
-/*
- Eventually, we probably want to special-case refreshing
- of deadfs vnodes, and if there's a lock-free race somewhere,
- that case might be handled here.
+ ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
- mac_update_vnode_deadfs(vp);
- return (0);
- */
- /* printf("vn_refreshlabel: null v_mount\n"); */
- if (vp->v_type != VNON)
- printf(
- "vn_refreshlabel: null v_mount with non-VNON\n");
- return (EBADF);
- }
-
- if (vp->v_vflag & VV_CACHEDLABEL) {
- mac_vnode_label_cache_hits++;
- return (0);
- } else
- mac_vnode_label_cache_misses++;
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
+ return (error);
- if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
- }
+ MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
- error = VOP_REFRESHLABEL(vp, cred, curthread);
- switch (error) {
- case EOPNOTSUPP:
- /*
- * If labels are not supported on this vnode, fall back to
- * the label in the mount and propagate it to the vnode.
- * There should probably be some sort of policy/flag/decision
- * about doing this.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- default:
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
-}
-/*
- * Helper function for file systems using the vop_std*_ea() calls. This
- * function must be called after EA service is available for the vnode,
- * but before it's hooked up to the namespace so that the node persists
- * if there's a crash, or before it can be accessed. On successful
- * commit of the label to disk (etc), do cache the label.
- */
-int
-vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
-{
- struct oldmac extmac;
- int error;
-
- ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
- if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(tvp, tvp->v_mount);
- } else {
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- /*
- * Stick the label in the vnode. Then try to write to
- * disk. If we fail, return a failure to abort the
- * create operation. Really, this failure shouldn't
- * happen except in fairly unusual circumstances (out
- * of disk, etc).
- */
- mac_create_vnode(cred, dvp, tvp);
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
- error = mac_stdcreatevnode_ea(tvp);
- if (error)
- return (error);
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
- /*
- * XXX: Eventually this will go away and all policies will
- * directly manage their extended attributes.
- */
- error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
- if (error)
- return (error);
-
- error = vn_extattr_set(tvp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
- if (error == 0)
- tvp->v_vflag |= VV_CACHEDLABEL;
- else {
-#if 0
- /*
- * In theory, we could have fall-back behavior here.
- * It would probably be incorrect.
- */
-#endif
- return (error);
- }
- }
-
- return (0);
+ return (error);
}
void
mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
{
- int error;
ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
- error = vn_refreshlabel(vp, old);
- if (error) {
- printf("mac_execve_transition: vn_refreshlabel returned %d\n",
- error);
- printf("mac_execve_transition: using old vnode label\n");
- }
-
MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
}
int
mac_execve_will_transition(struct ucred *old, struct vnode *vp)
{
- int error, result;
-
- error = vn_refreshlabel(vp, old);
- if (error)
- return (error);
+ int result;
result = 0;
MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
@@ -2040,10 +1860,6 @@ mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2058,10 +1874,6 @@ mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2076,10 +1888,6 @@ mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2095,10 +1903,6 @@ mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
return (error);
}
@@ -2115,13 +1919,6 @@ mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2138,10 +1935,6 @@ mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2156,9 +1949,6 @@ mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_process && !mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
return (error);
@@ -2174,10 +1964,6 @@ mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2193,10 +1979,6 @@ mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2214,14 +1996,6 @@ mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2238,10 +2012,6 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
return (error);
}
@@ -2256,10 +2026,6 @@ mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2290,10 +2056,6 @@ mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2308,10 +2070,6 @@ mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
return (error);
}
@@ -2327,10 +2085,6 @@ mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
&vp->v_label);
@@ -2348,10 +2102,6 @@ mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
&vp->v_label);
@@ -2368,10 +2118,6 @@ mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2386,10 +2132,6 @@ mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
return (error);
}
@@ -2402,10 +2144,6 @@ mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
return (error);
@@ -2423,13 +2161,6 @@ mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2447,14 +2178,6 @@ mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- if (vp != NULL) {
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
- }
MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
vp != NULL ? &vp->v_label : NULL, samedir, cnp);
return (error);
@@ -2470,10 +2193,6 @@ mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
return (error);
}
@@ -2489,10 +2208,6 @@ mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
return (error);
}
@@ -2508,10 +2223,6 @@ mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2527,10 +2238,6 @@ mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2545,10 +2252,6 @@ mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
return (error);
}
@@ -2564,10 +2267,6 @@ mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
return (error);
}
@@ -2583,10 +2282,6 @@ mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
mtime);
return (error);
@@ -2603,10 +2298,6 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
&vp->v_label);
return (error);
@@ -2622,10 +2313,6 @@ mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
@@ -2641,10 +2328,6 @@ mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
&vp->v_label);
@@ -3344,7 +3027,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3352,7 +3034,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3382,7 +3063,6 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3444,16 +3124,6 @@ mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
&de->de_label);
}
-static int
-mac_stdcreatevnode_ea(struct vnode *vp)
-{
- int error;
-
- MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
-
- return (error);
-}
-
void
mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de)
@@ -3463,29 +3133,6 @@ mac_create_devfs_directory(char *dirname, int dirnamelen,
&de->de_label);
}
-/*
- * When a new vnode is created, this call will initialize its label.
- */
-void
-mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child)
-{
- int error;
-
- ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
- ASSERT_VOP_LOCKED(child, "mac_create_vnode");
-
- error = vn_refreshlabel(parent, cred);
- if (error) {
- printf("mac_create_vnode: vn_refreshlabel returned %d\n",
- error);
- printf("mac_create_vnode: using old vnode label\n");
- }
-
- MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
- &child->v_label);
-}
-
int
mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
struct mac *mac)
@@ -3499,7 +3146,6 @@ mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
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);
@@ -3554,7 +3200,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
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);
@@ -3562,7 +3207,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_label(&so->so_label, elements,
buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3586,7 +3230,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
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);
@@ -3594,7 +3237,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_peer_label(&so->so_peerlabel,
elements, buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3616,35 +3258,19 @@ vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
{
struct vnode *vp = ap->a_vp;
struct label *intlabel = ap->a_label;
- struct oldmac extmac;
int error;
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
- /*
- * XXX: Eventually call out to EA check/set calls here.
- * Be particularly careful to avoid race conditions,
- * consistency problems, and stability problems when
- * dealing with multiple EAs. In particular, we require
- * the ability to write multiple EAs on the same file in
- * a single transaction, which the current EA interface
- * does not provide.
- */
-
- error = mac_externalize_vnode_oldmac(intlabel, &extmac);
- if (error)
- return (error);
+ if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+ return (EOPNOTSUPP);
- error = vn_extattr_set(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
+ error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
if (error)
return (error);
mac_relabel_vnode(ap->a_cred, vp, intlabel);
- vp->v_vflag |= VV_CACHEDLABEL;
-
return (0);
}
@@ -3721,7 +3347,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
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);
@@ -3730,7 +3355,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_cred_label(&tcred->cr_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3761,7 +3385,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
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);
@@ -3769,7 +3392,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
}
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, M_WAITOK);
if (error == 0)
@@ -3802,7 +3424,6 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
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);
@@ -3880,7 +3501,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
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);
@@ -3888,7 +3508,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
mtx_lock(&Giant); /* VFS */
error = fget(td, SCARG(uap, fd), &fp);
if (error)
@@ -3903,9 +3522,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
mac_init_vnode_label(&intlabel);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = vn_refreshlabel(vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&vp->v_label, &intlabel);
+ mac_copy_vnode_label(&vp->v_label, &intlabel);
VOP_UNLOCK(vp, 0, td);
break;
@@ -3974,7 +3591,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
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);
@@ -3982,7 +3598,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
}
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);
@@ -3991,12 +3606,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4034,7 +3646,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
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);
@@ -4042,7 +3653,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
}
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);
@@ -4051,12 +3661,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4096,7 +3703,6 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
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);
@@ -4183,7 +3789,6 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
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);
@@ -4240,7 +3845,6 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
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);
diff --git a/sys/security/mac/mac_vfs.c b/sys/security/mac/mac_vfs.c
index 78bc485..2ff4162 100644
--- a/sys/security/mac/mac_vfs.c
+++ b/sys/security/mac/mac_vfs.c
@@ -115,6 +115,12 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_policies, CTLFLAG_RD,
*/
static int mac_late = 0;
+/*
+ * Warn about EA transactions only the first time they happen.
+ * Weak coherency, no locking.
+ */
+static int ea_warn_once = 0;
+
static int mac_enforce_fs = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
@@ -145,23 +151,12 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
TUNABLE_INT("security.mac.enforce_vm", &mac_enforce_vm);
-static int mac_label_size = sizeof(struct oldmac);
-SYSCTL_INT(_security_mac, OID_AUTO, label_size, CTLFLAG_RD,
- &mac_label_size, 0, "Pre-compiled MAC label size");
-
static int mac_cache_fslabel_in_vnode = 1;
SYSCTL_INT(_security_mac, OID_AUTO, cache_fslabel_in_vnode, CTLFLAG_RW,
&mac_cache_fslabel_in_vnode, 0, "Cache mount fslabel in vnode");
TUNABLE_INT("security.mac.cache_fslabel_in_vnode",
&mac_cache_fslabel_in_vnode);
-static int mac_vnode_label_cache_hits = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_hits, CTLFLAG_RD,
- &mac_vnode_label_cache_hits, 0, "Cache hits on vnode labels");
-static int mac_vnode_label_cache_misses = 0;
-SYSCTL_INT(_security_mac, OID_AUTO, vnode_label_cache_misses, CTLFLAG_RD,
- &mac_vnode_label_cache_misses, 0, "Cache misses on vnode labels");
-
static int mac_mmap_revocation = 1;
SYSCTL_INT(_security_mac, OID_AUTO, mmap_revocation, CTLFLAG_RW,
&mac_mmap_revocation, 0, "Revoke mmap access to files on subject "
@@ -214,12 +209,9 @@ SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, devfsdirents, CTLFLAG_RD,
#endif
static int error_select(int error1, int error2);
-static int mac_externalize_vnode_oldmac(struct label *label,
- struct oldmac *extmac);
static int mac_policy_register(struct mac_policy_conf *mpc);
static int mac_policy_unregister(struct mac_policy_conf *mpc);
-static int mac_stdcreatevnode_ea(struct vnode *vp);
static void mac_check_vnode_mmap_downgrade(struct ucred *cred,
struct vnode *vp, int *prot);
static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
@@ -227,6 +219,10 @@ static void mac_cred_mmapped_drop_perms_recurse(struct thread *td,
static void mac_destroy_socket_label(struct label *label);
+static int mac_setlabel_vnode_extattr(struct ucred *cred,
+ struct vnode *vp, struct label *intlabel);
+
+
MALLOC_DEFINE(M_MACOPVEC, "macopvec", "MAC policy operation vector");
MALLOC_DEFINE(M_MACPIPELABEL, "macpipelabel", "MAC labels for pipes");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@@ -623,10 +619,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_externalize_vnode_label =
mpe->mpe_function;
break;
- case MAC_EXTERNALIZE_VNODE_OLDMAC:
- mpc->mpc_ops->mpo_externalize_vnode_oldmac =
- mpe->mpe_function;
- break;
case MAC_INTERNALIZE_CRED_LABEL:
mpc->mpc_ops->mpo_internalize_cred_label =
mpe->mpe_function;
@@ -663,14 +655,6 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_create_devfs_vnode =
mpe->mpe_function;
break;
- case MAC_STDCREATEVNODE_EA:
- mpc->mpc_ops->mpo_stdcreatevnode_ea =
- mpe->mpe_function;
- break;
- case MAC_CREATE_VNODE:
- mpc->mpc_ops->mpo_create_vnode =
- mpe->mpe_function;
- break;
case MAC_CREATE_MOUNT:
mpc->mpc_ops->mpo_create_mount =
mpe->mpe_function;
@@ -687,20 +671,24 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_update_devfsdirent =
mpe->mpe_function;
break;
- case MAC_UPDATE_PROCFSVNODE:
- mpc->mpc_ops->mpo_update_procfsvnode =
+ case MAC_ASSOCIATE_VNODE_DEVFS:
+ mpc->mpc_ops->mpo_associate_vnode_devfs =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTATTR:
- mpc->mpc_ops->mpo_update_vnode_from_extattr =
+ case MAC_ASSOCIATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_associate_vnode_extattr =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_EXTERNALIZED:
- mpc->mpc_ops->mpo_update_vnode_from_externalized =
+ case MAC_ASSOCIATE_VNODE_SINGLELABEL:
+ mpc->mpc_ops->mpo_associate_vnode_singlelabel =
mpe->mpe_function;
break;
- case MAC_UPDATE_VNODE_FROM_MOUNT:
- mpc->mpc_ops->mpo_update_vnode_from_mount =
+ case MAC_CREATE_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_create_vnode_extattr =
+ mpe->mpe_function;
+ break;
+ case MAC_SETLABEL_VNODE_EXTATTR:
+ mpc->mpc_ops->mpo_setlabel_vnode_extattr =
mpe->mpe_function;
break;
case MAC_CREATE_MBUF_FROM_SOCKET:
@@ -1379,7 +1367,7 @@ mac_init_socket(struct socket *socket, int flag)
return (error);
}
-static void
+void
mac_init_vnode_label(struct label *label)
{
@@ -1536,7 +1524,7 @@ mac_destroy_socket(struct socket *socket)
mac_destroy_socket_peer_label(&socket->so_peerlabel);
}
-static void
+void
mac_destroy_vnode_label(struct label *label)
{
@@ -1561,7 +1549,7 @@ mac_copy_pipe_label(struct label *src, struct label *dest)
MAC_PERFORM(copy_pipe_label, src, dest);
}
-static void
+void
mac_copy_vnode_label(struct label *src, struct label *dest)
{
@@ -1645,16 +1633,6 @@ mac_externalize_vnode_label(struct label *label, char *elements,
}
static int
-mac_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(externalize_vnode_oldmac, label, extmac);
-
- return (error);
-}
-
-static int
mac_internalize_cred_label(struct label *label, char *string)
{
int error;
@@ -1753,276 +1731,118 @@ mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
}
void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+mac_associate_vnode_devfs(struct mount *mp, struct devfs_dirent *de,
+ struct vnode *vp)
{
- MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+ MAC_PERFORM(associate_vnode_devfs, mp, &mp->mnt_fslabel, de,
+ &de->de_label, vp, &vp->v_label);
}
-/*
- * Support callout for policies that manage their own externalization
- * using extended attributes.
- */
-static int
-mac_update_vnode_from_extattr(struct vnode *vp, struct mount *mp)
+int
+mac_associate_vnode_extattr(struct mount *mp, struct vnode *vp)
{
int error;
- MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- return (error);
-}
+ ASSERT_VOP_LOCKED(vp, "mac_associate_vnode_extattr");
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct oldmac *extmac)
-{
- int error;
-
- MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+ MAC_CHECK(associate_vnode_extattr, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
return (error);
}
-/*
- * Call out to individual policies to update the label in a vnode from
- * the mountpoint.
- */
void
-mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp)
+mac_associate_vnode_singlelabel(struct mount *mp, struct vnode *vp)
{
- MAC_PERFORM(update_vnode_from_mount, vp, &vp->v_label, mp,
- &mp->mnt_fslabel);
-
- ASSERT_VOP_LOCKED(vp, "mac_update_vnode_from_mount");
- if (mac_cache_fslabel_in_vnode)
- vp->v_vflag |= VV_CACHEDLABEL;
+ MAC_PERFORM(associate_vnode_singlelabel, mp, &mp->mnt_fslabel, vp,
+ &vp->v_label);
}
-/*
- * Implementation of VOP_REFRESHLABEL() that relies on extended attributes
- * to store label data. Can be referenced by filesystems supporting
- * extended attributes.
- */
int
-vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap)
+mac_create_vnode_extattr(struct ucred *cred, struct mount *mp,
+ struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
{
- struct vnode *vp = ap->a_vp;
- struct oldmac extmac;
- int buflen, error;
+ int error;
- ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+ ASSERT_VOP_LOCKED(dvp, "mac_create_vnode_extattr");
+ ASSERT_VOP_LOCKED(vp, "mac_create_vnode_extattr");
- /*
- * Call out to external policies first. Order doesn't really
- * matter, as long as failure of one assures failure of all.
- */
- error = mac_update_vnode_from_extattr(vp, vp->v_mount);
- if (error)
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
return (error);
- buflen = sizeof(extmac);
- error = vn_extattr_get(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME, &buflen,
- (char *)&extmac, curthread);
- switch (error) {
- case 0:
- /* Got it */
- break;
-
- case ENOATTR:
- /*
- * Use the label from the mount point.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
+ MAC_CHECK(create_vnode_extattr, cred, mp, &mp->mnt_fslabel,
+ dvp, &dvp->v_label, vp, &vp->v_label, cnp);
- case EOPNOTSUPP:
- default:
- /* Fail horribly. */
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
- if (buflen != sizeof(extmac))
- error = EPERM; /* Fail very closed. */
- if (error == 0)
- error = mac_update_vnode_from_externalized(vp, &extmac);
- if (error == 0)
- vp->v_vflag |= VV_CACHEDLABEL;
- else {
- struct vattr va;
-
- printf("Corrupted label on %s",
- vp->v_mount->mnt_stat.f_mntonname);
- if (VOP_GETATTR(vp, &va, curthread->td_ucred, curthread) == 0)
- printf(" inum %ld", va.va_fileid);
-#ifdef MAC_DEBUG
- if (mac_debug_label_fallback) {
- printf(", falling back.\n");
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- } else {
-#endif
- printf(".\n");
- error = EPERM;
-#ifdef MAC_DEBUG
- }
-#endif
- }
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
+
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
return (error);
}
-/*
- * Make sure the vnode label is up-to-date. If EOPNOTSUPP, then we handle
- * the labeling activity outselves. Filesystems should be careful not
- * to change their minds regarding whether they support vop_refreshlabel()
- * for a vnode or not. Don't cache the vnode here, allow the file
- * system code to determine if it's safe to cache. If we update from
- * the mount, don't cache since a change to the mount label should affect
- * all vnodes.
- */
static int
-vn_refreshlabel(struct vnode *vp, struct ucred *cred)
+mac_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *intlabel)
{
int error;
- ASSERT_VOP_LOCKED(vp, "vn_refreshlabel");
-
- if (vp->v_mount == NULL) {
-/*
- Eventually, we probably want to special-case refreshing
- of deadfs vnodes, and if there's a lock-free race somewhere,
- that case might be handled here.
+ ASSERT_VOP_LOCKED(vp, "mac_setlabel_vnode_extattr");
- mac_update_vnode_deadfs(vp);
- return (0);
- */
- /* printf("vn_refreshlabel: null v_mount\n"); */
- if (vp->v_type != VNON)
- printf(
- "vn_refreshlabel: null v_mount with non-VNON\n");
- return (EBADF);
- }
-
- if (vp->v_vflag & VV_CACHEDLABEL) {
- mac_vnode_label_cache_hits++;
- return (0);
- } else
- mac_vnode_label_cache_misses++;
+ error = VOP_OPENEXTATTR(vp, cred, curthread);
+ if (error == EOPNOTSUPP) {
+ /* XXX: Optionally abort if transactions not supported. */
+ if (ea_warn_once == 0) {
+ printf("Warning: transactions not supported "
+ "in EA write.\n");
+ ea_warn_once = 1;
+ }
+ } else if (error)
+ return (error);
- if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(vp, vp->v_mount);
- return (0);
- }
+ MAC_CHECK(setlabel_vnode_extattr, cred, vp, &vp->v_label, intlabel);
- error = VOP_REFRESHLABEL(vp, cred, curthread);
- switch (error) {
- case EOPNOTSUPP:
- /*
- * If labels are not supported on this vnode, fall back to
- * the label in the mount and propagate it to the vnode.
- * There should probably be some sort of policy/flag/decision
- * about doing this.
- */
- mac_update_vnode_from_mount(vp, vp->v_mount);
- error = 0;
- default:
+ if (error) {
+ VOP_CLOSEEXTATTR(vp, 0, NOCRED, curthread);
return (error);
}
-}
-/*
- * Helper function for file systems using the vop_std*_ea() calls. This
- * function must be called after EA service is available for the vnode,
- * but before it's hooked up to the namespace so that the node persists
- * if there's a crash, or before it can be accessed. On successful
- * commit of the label to disk (etc), do cache the label.
- */
-int
-vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp, struct ucred *cred)
-{
- struct oldmac extmac;
- int error;
-
- ASSERT_VOP_LOCKED(tvp, "vop_stdcreatevnode_ea");
- if ((dvp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
- mac_update_vnode_from_mount(tvp, tvp->v_mount);
- } else {
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- /*
- * Stick the label in the vnode. Then try to write to
- * disk. If we fail, return a failure to abort the
- * create operation. Really, this failure shouldn't
- * happen except in fairly unusual circumstances (out
- * of disk, etc).
- */
- mac_create_vnode(cred, dvp, tvp);
+ error = VOP_CLOSEEXTATTR(vp, 1, NOCRED, curthread);
- error = mac_stdcreatevnode_ea(tvp);
- if (error)
- return (error);
+ if (error == EOPNOTSUPP)
+ error = 0; /* XXX */
- /*
- * XXX: Eventually this will go away and all policies will
- * directly manage their extended attributes.
- */
- error = mac_externalize_vnode_oldmac(&tvp->v_label, &extmac);
- if (error)
- return (error);
-
- error = vn_extattr_set(tvp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
- if (error == 0)
- tvp->v_vflag |= VV_CACHEDLABEL;
- else {
-#if 0
- /*
- * In theory, we could have fall-back behavior here.
- * It would probably be incorrect.
- */
-#endif
- return (error);
- }
- }
-
- return (0);
+ return (error);
}
void
mac_execve_transition(struct ucred *old, struct ucred *new, struct vnode *vp)
{
- int error;
ASSERT_VOP_LOCKED(vp, "mac_execve_transition");
- error = vn_refreshlabel(vp, old);
- if (error) {
- printf("mac_execve_transition: vn_refreshlabel returned %d\n",
- error);
- printf("mac_execve_transition: using old vnode label\n");
- }
-
MAC_PERFORM(execve_transition, old, new, vp, &vp->v_label);
}
int
mac_execve_will_transition(struct ucred *old, struct vnode *vp)
{
- int error, result;
-
- error = vn_refreshlabel(vp, old);
- if (error)
- return (error);
+ int result;
result = 0;
MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
@@ -2040,10 +1860,6 @@ mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_access, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2058,10 +1874,6 @@ mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2076,10 +1888,6 @@ mac_check_vnode_chroot(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_chroot, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2095,10 +1903,6 @@ mac_check_vnode_create(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_create, cred, dvp, &dvp->v_label, cnp, vap);
return (error);
}
@@ -2115,13 +1919,6 @@ mac_check_vnode_delete(struct ucred *cred, struct vnode *dvp, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_delete, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2138,10 +1935,6 @@ mac_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_deleteacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2156,9 +1949,6 @@ mac_check_vnode_exec(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_process && !mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
MAC_CHECK(check_vnode_exec, cred, vp, &vp->v_label);
return (error);
@@ -2174,10 +1964,6 @@ mac_check_vnode_getacl(struct ucred *cred, struct vnode *vp, acl_type_t type)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getacl, cred, vp, &vp->v_label, type);
return (error);
}
@@ -2193,10 +1979,6 @@ mac_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_getextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2214,14 +1996,6 @@ mac_check_vnode_link(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_link, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2238,10 +2012,6 @@ mac_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_lookup, cred, dvp, &dvp->v_label, cnp);
return (error);
}
@@ -2256,10 +2026,6 @@ mac_check_vnode_mmap(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mmap, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2290,10 +2056,6 @@ mac_check_vnode_mprotect(struct ucred *cred, struct vnode *vp, int prot)
if (!mac_enforce_fs || !mac_enforce_vm)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_mprotect, cred, vp, &vp->v_label, prot);
return (error);
}
@@ -2308,10 +2070,6 @@ mac_check_vnode_open(struct ucred *cred, struct vnode *vp, mode_t acc_mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_open, cred, vp, &vp->v_label, acc_mode);
return (error);
}
@@ -2327,10 +2085,6 @@ mac_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_poll, active_cred, file_cred, vp,
&vp->v_label);
@@ -2348,10 +2102,6 @@ mac_check_vnode_read(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_read, active_cred, file_cred, vp,
&vp->v_label);
@@ -2368,10 +2118,6 @@ mac_check_vnode_readdir(struct ucred *cred, struct vnode *dvp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readdir, cred, dvp, &dvp->v_label);
return (error);
}
@@ -2386,10 +2132,6 @@ mac_check_vnode_readlink(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_readlink, cred, vp, &vp->v_label);
return (error);
}
@@ -2402,10 +2144,6 @@ mac_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_relabel");
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_relabel, cred, vp, &vp->v_label, newlabel);
return (error);
@@ -2423,13 +2161,6 @@ mac_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_rename_from, cred, dvp, &dvp->v_label, vp,
&vp->v_label, cnp);
return (error);
@@ -2447,14 +2178,6 @@ mac_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(dvp, cred);
- if (error)
- return (error);
- if (vp != NULL) {
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
- }
MAC_CHECK(check_vnode_rename_to, cred, dvp, &dvp->v_label, vp,
vp != NULL ? &vp->v_label : NULL, samedir, cnp);
return (error);
@@ -2470,10 +2193,6 @@ mac_check_vnode_revoke(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_revoke, cred, vp, &vp->v_label);
return (error);
}
@@ -2489,10 +2208,6 @@ mac_check_vnode_setacl(struct ucred *cred, struct vnode *vp, acl_type_t type,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setacl, cred, vp, &vp->v_label, type, acl);
return (error);
}
@@ -2508,10 +2223,6 @@ mac_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setextattr, cred, vp, &vp->v_label,
attrnamespace, name, uio);
return (error);
@@ -2527,10 +2238,6 @@ mac_check_vnode_setflags(struct ucred *cred, struct vnode *vp, u_long flags)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setflags, cred, vp, &vp->v_label, flags);
return (error);
}
@@ -2545,10 +2252,6 @@ mac_check_vnode_setmode(struct ucred *cred, struct vnode *vp, mode_t mode)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setmode, cred, vp, &vp->v_label, mode);
return (error);
}
@@ -2564,10 +2267,6 @@ mac_check_vnode_setowner(struct ucred *cred, struct vnode *vp, uid_t uid,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setowner, cred, vp, &vp->v_label, uid, gid);
return (error);
}
@@ -2583,10 +2282,6 @@ mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_setutimes, cred, vp, &vp->v_label, atime,
mtime);
return (error);
@@ -2603,10 +2298,6 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_stat, active_cred, file_cred, vp,
&vp->v_label);
return (error);
@@ -2622,10 +2313,6 @@ mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
@@ -2641,10 +2328,6 @@ mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
if (!mac_enforce_fs)
return (0);
- error = vn_refreshlabel(vp, active_cred);
- if (error)
- return (error);
-
MAC_CHECK(check_vnode_write, active_cred, file_cred, vp,
&vp->v_label);
@@ -3344,7 +3027,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3352,7 +3034,6 @@ mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3382,7 +3063,6 @@ mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
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);
@@ -3444,16 +3124,6 @@ mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
&de->de_label);
}
-static int
-mac_stdcreatevnode_ea(struct vnode *vp)
-{
- int error;
-
- MAC_CHECK(stdcreatevnode_ea, vp, &vp->v_label);
-
- return (error);
-}
-
void
mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de)
@@ -3463,29 +3133,6 @@ mac_create_devfs_directory(char *dirname, int dirnamelen,
&de->de_label);
}
-/*
- * When a new vnode is created, this call will initialize its label.
- */
-void
-mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child)
-{
- int error;
-
- ASSERT_VOP_LOCKED(parent, "mac_create_vnode");
- ASSERT_VOP_LOCKED(child, "mac_create_vnode");
-
- error = vn_refreshlabel(parent, cred);
- if (error) {
- printf("mac_create_vnode: vn_refreshlabel returned %d\n",
- error);
- printf("mac_create_vnode: using old vnode label\n");
- }
-
- MAC_PERFORM(create_vnode, cred, parent, &parent->v_label, child,
- &child->v_label);
-}
-
int
mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
struct mac *mac)
@@ -3499,7 +3146,6 @@ mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
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);
@@ -3554,7 +3200,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
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);
@@ -3562,7 +3207,6 @@ mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_label(&so->so_label, elements,
buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3586,7 +3230,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
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);
@@ -3594,7 +3237,6 @@ mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
}
buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_socket_peer_label(&so->so_peerlabel,
elements, buffer, mac->m_buflen, M_WAITOK);
if (error == 0)
@@ -3616,35 +3258,19 @@ vop_stdsetlabel_ea(struct vop_setlabel_args *ap)
{
struct vnode *vp = ap->a_vp;
struct label *intlabel = ap->a_label;
- struct oldmac extmac;
int error;
ASSERT_VOP_LOCKED(vp, "vop_stdsetlabel_ea");
- /*
- * XXX: Eventually call out to EA check/set calls here.
- * Be particularly careful to avoid race conditions,
- * consistency problems, and stability problems when
- * dealing with multiple EAs. In particular, we require
- * the ability to write multiple EAs on the same file in
- * a single transaction, which the current EA interface
- * does not provide.
- */
-
- error = mac_externalize_vnode_oldmac(intlabel, &extmac);
- if (error)
- return (error);
+ if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0)
+ return (EOPNOTSUPP);
- error = vn_extattr_set(vp, IO_NODELOCKED,
- FREEBSD_MAC_EXTATTR_NAMESPACE, FREEBSD_MAC_EXTATTR_NAME,
- sizeof(extmac), (char *)&extmac, curthread);
+ error = mac_setlabel_vnode_extattr(ap->a_cred, vp, intlabel);
if (error)
return (error);
mac_relabel_vnode(ap->a_cred, vp, intlabel);
- vp->v_vflag |= VV_CACHEDLABEL;
-
return (0);
}
@@ -3721,7 +3347,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
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);
@@ -3730,7 +3355,6 @@ __mac_get_pid(struct thread *td, struct __mac_get_pid_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
error = mac_externalize_cred_label(&tcred->cr_label, elements,
buffer, mac.m_buflen, M_WAITOK);
if (error == 0)
@@ -3761,7 +3385,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
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);
@@ -3769,7 +3392,6 @@ __mac_get_proc(struct thread *td, struct __mac_get_proc_args *uap)
}
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, M_WAITOK);
if (error == 0)
@@ -3802,7 +3424,6 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
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);
@@ -3880,7 +3501,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
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);
@@ -3888,7 +3508,6 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
}
buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
-
mtx_lock(&Giant); /* VFS */
error = fget(td, SCARG(uap, fd), &fp);
if (error)
@@ -3903,9 +3522,7 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
mac_init_vnode_label(&intlabel);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- error = vn_refreshlabel(vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&vp->v_label, &intlabel);
+ mac_copy_vnode_label(&vp->v_label, &intlabel);
VOP_UNLOCK(vp, 0, td);
break;
@@ -3974,7 +3591,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
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);
@@ -3982,7 +3598,6 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
}
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);
@@ -3991,12 +3606,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4034,7 +3646,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
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);
@@ -4042,7 +3653,6 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
}
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);
@@ -4051,12 +3661,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
goto out;
mac_init_vnode_label(&intlabel);
- error = vn_refreshlabel(nd.ni_vp, td->td_ucred);
- if (error == 0)
- mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
- if (error == 0)
- error = mac_externalize_vnode_label(&intlabel, elements,
- buffer, mac.m_buflen, M_WAITOK);
+ mac_copy_vnode_label(&nd.ni_vp->v_label, &intlabel);
+ error = mac_externalize_vnode_label(&intlabel, elements, buffer,
+ mac.m_buflen, M_WAITOK);
NDFREE(&nd, 0);
mac_destroy_vnode_label(&intlabel);
@@ -4096,7 +3703,6 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
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);
@@ -4183,7 +3789,6 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
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);
@@ -4240,7 +3845,6 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
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);
diff --git a/sys/security/mac_biba/mac_biba.c b/sys/security/mac_biba/mac_biba.c
index c30d39f..9292a73 100644
--- a/sys/security/mac_biba/mac_biba.c
+++ b/sys/security/mac_biba/mac_biba.c
@@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/acl.h>
#include <sys/conf.h>
+#include <sys/extattr.h>
#include <sys/kernel.h>
#include <sys/mac.h>
#include <sys/malloc.h>
@@ -83,6 +84,10 @@ SYSCTL_DECL(_security_mac);
SYSCTL_NODE(_security_mac, OID_AUTO, biba, CTLFLAG_RW, 0,
"TrustedBSD mac_biba policy controls");
+static int mac_biba_label_size = sizeof(struct mac_biba);
+SYSCTL_INT(_security_mac_biba, OID_AUTO, label_size, CTLFLAG_RD,
+ &mac_biba_label_size, 0, "Size of struct mac_biba");
+
static int mac_biba_enabled = 0;
SYSCTL_INT(_security_mac_biba, OID_AUTO, enabled, CTLFLAG_RW,
&mac_biba_enabled, 0, "Enforce MAC/Biba policy");
@@ -215,6 +220,19 @@ mac_biba_dominate_element(struct mac_biba_element *a,
}
static int
+mac_biba_subject_dominate_high(struct mac_biba *mac_biba)
+{
+ struct mac_biba_element *element;
+
+ KASSERT((mac_biba->mb_single->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
+ ("mac_biba_single_in_range: mac_biba not single"));
+ element = &mac_biba->mb_single;
+
+ return (element->mbe_type == MAC_BIBA_TYPE_EQUAL ||
+ element->mbe_type == MAC_BIBA_TYPE_HIGH);
+}
+
+static int
mac_biba_range_in_range(struct mac_biba *rangea, struct mac_biba *rangeb)
{
@@ -319,6 +337,15 @@ mac_biba_subject_equal_ok(struct mac_biba *mac_biba)
return (EPERM);
}
+mac_biba_high_single(struct mac_biba *mac_biba)
+{
+
+ KASSERT((mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) != 0,
+ ("mac_biba_equal_single: mac_biba not single"));
+
+ return (mac_biba->mb_single.mbe_type == MAC_BIBA_TYPE_HIGH);
+}
+
static int
mac_biba_valid(struct mac_biba *mac_biba)
{
@@ -620,23 +647,6 @@ mac_biba_externalize_label(struct label *label, char *element_name,
}
static int
-mac_biba_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- struct mac_biba *mac_biba;
-
- mac_biba = SLOT(label);
-
- if (mac_biba == NULL) {
- printf("mac_biba_externalize_vnode_oldmac: NULL pointer\n");
- return (0);
- }
-
- extmac->m_biba = *mac_biba;
-
- return (0);
-}
-
-static int
mac_biba_parse_element(struct mac_biba_element *element, char *string)
{
@@ -847,18 +857,6 @@ mac_biba_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
}
static void
-mac_biba_create_vnode(struct ucred *cred, struct vnode *parent,
- struct label *parentlabel, struct vnode *child, struct label *childlabel)
-{
- struct mac_biba *source, *dest;
-
- source = SLOT(&cred->cr_label);
- dest = SLOT(childlabel);
-
- mac_biba_copy_single(source, dest);
-}
-
-static void
mac_biba_create_mount(struct ucred *cred, struct mount *mp,
struct label *mntlabel, struct label *fslabel)
{
@@ -909,55 +907,116 @@ mac_biba_update_devfsdirent(struct devfs_dirent *devfs_dirent,
}
static void
-mac_biba_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
- struct ucred *cred)
+mac_biba_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
+ struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
+ struct label *vlabel)
{
struct mac_biba *source, *dest;
- source = SLOT(&cred->cr_label);
- dest = SLOT(vnodelabel);
+ source = SLOT(delabel);
+ dest = SLOT(vlabel);
- /*
- * Only copy the single, not the range, since vnodes only have
- * a single.
- */
mac_biba_copy_single(source, dest);
}
static int
-mac_biba_update_vnode_from_externalized(struct vnode *vp,
- struct label *vnodelabel, struct oldmac *extmac)
+mac_biba_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
+ struct vnode *vp, struct label *vlabel)
{
- struct mac_biba *source, *dest;
+ struct mac_biba temp, *source, *dest;
+ size_t buflen;
int error;
- source = &extmac->m_biba;
- dest = SLOT(vnodelabel);
+ source = SLOT(fslabel);
+ dest = SLOT(vlabel);
- error = mac_biba_valid(source);
- if (error)
- return (error);
+ buflen = sizeof(temp);
+ bzero(&temp, buflen);
- if ((source->mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE)
- return (EINVAL);
+ error = vn_extattr_get(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
+ MAC_BIBA_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
+ if (error == ENOATTR || error == EOPNOTSUPP) {
+ /* Fall back to the fslabel. */
+ mac_biba_copy_single(source, dest);
+ return (0);
+ } else if (error)
+ return (error);
- mac_biba_copy_single(source, dest);
+ if (buflen != sizeof(temp)) {
+ printf("mac_biba_associate_vnode_extattr: bad size %d\n",
+ buflen);
+ return (EPERM);
+ }
+ if (mac_biba_valid(&temp) != 0) {
+ printf("mac_biba_associate_vnode_extattr: invalid\n");
+ return (EPERM);
+ }
+ if ((temp.mb_flags & MAC_BIBA_FLAGS_BOTH) != MAC_BIBA_FLAG_SINGLE) {
+ printf("mac_biba_associate_vnode_extattr: not single\n");
+ return (EPERM);
+ }
+ mac_biba_copy_single(&temp, dest);
return (0);
}
static void
-mac_biba_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
- struct mount *mp, struct label *fslabel)
+mac_biba_associate_vnode_singlelabel(struct mount *mp,
+ struct label *fslabel, struct vnode *vp, struct label *vlabel)
{
struct mac_biba *source, *dest;
source = SLOT(fslabel);
- dest = SLOT(vnodelabel);
+ dest = SLOT(vlabel);
mac_biba_copy_single(source, dest);
}
+static int
+mac_biba_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)
+{
+ struct mac_biba *source, *dest, temp;
+ size_t buflen;
+ int error;
+
+ buflen = sizeof(temp);
+ bzero(&temp, buflen);
+
+ source = SLOT(&cred->cr_label);
+ dest = SLOT(vlabel);
+ mac_biba_copy_single(source, &temp);
+
+ error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
+ MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
+ if (error == 0)
+ mac_biba_copy_single(source, dest);
+ return (error);
+}
+
+static int
+mac_biba_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *vlabel, struct label *intlabel)
+{
+ struct mac_biba *source, temp;
+ size_t buflen;
+ int error;
+
+ buflen = sizeof(temp);
+ bzero(&temp, buflen);
+
+ source = SLOT(intlabel);
+ if ((source->mb_flags & MAC_BIBA_FLAG_SINGLE) == 0)
+ return (0);
+
+ mac_biba_copy_single(source, &temp);
+
+ error = vn_extattr_set(vp, IO_NODELOCKED, MAC_BIBA_EXTATTR_NAMESPACE,
+ MAC_BIBA_EXTATTR_NAME, buflen, (char *) &temp, curthread);
+ return (error);
+}
+
/*
* Labeling event operations: IPC object.
*/
@@ -2450,8 +2509,6 @@ static struct mac_policy_op_entry mac_biba_ops[] =
(macop_t)mac_biba_externalize_label },
{ MAC_EXTERNALIZE_VNODE_LABEL,
(macop_t)mac_biba_externalize_label },
- { MAC_EXTERNALIZE_VNODE_OLDMAC,
- (macop_t)mac_biba_externalize_vnode_oldmac },
{ MAC_INTERNALIZE_CRED_LABEL,
(macop_t)mac_biba_internalize_label },
{ MAC_INTERNALIZE_IFNET_LABEL,
@@ -2470,8 +2527,6 @@ static struct mac_policy_op_entry mac_biba_ops[] =
(macop_t)mac_biba_create_devfs_symlink },
{ MAC_CREATE_DEVFS_VNODE,
(macop_t)mac_biba_create_devfs_vnode },
- { MAC_CREATE_VNODE,
- (macop_t)mac_biba_create_vnode },
{ MAC_CREATE_MOUNT,
(macop_t)mac_biba_create_mount },
{ MAC_CREATE_ROOT_MOUNT,
@@ -2480,12 +2535,16 @@ static struct mac_policy_op_entry mac_biba_ops[] =
(macop_t)mac_biba_relabel_vnode },
{ MAC_UPDATE_DEVFSDIRENT,
(macop_t)mac_biba_update_devfsdirent },
- { MAC_UPDATE_PROCFSVNODE,
- (macop_t)mac_biba_update_procfsvnode },
- { MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
- (macop_t)mac_biba_update_vnode_from_externalized },
- { MAC_UPDATE_VNODE_FROM_MOUNT,
- (macop_t)mac_biba_update_vnode_from_mount },
+ { MAC_ASSOCIATE_VNODE_DEVFS,
+ (macop_t)mac_biba_associate_vnode_devfs },
+ { MAC_ASSOCIATE_VNODE_EXTATTR,
+ (macop_t)mac_biba_associate_vnode_extattr },
+ { MAC_ASSOCIATE_VNODE_SINGLELABEL,
+ (macop_t)mac_biba_associate_vnode_singlelabel },
+ { MAC_CREATE_VNODE_EXTATTR,
+ (macop_t)mac_biba_create_vnode_extattr },
+ { MAC_SETLABEL_VNODE_EXTATTR,
+ (macop_t)mac_biba_setlabel_vnode_extattr },
{ MAC_CREATE_MBUF_FROM_SOCKET,
(macop_t)mac_biba_create_mbuf_from_socket },
{ MAC_CREATE_PIPE,
diff --git a/sys/security/mac_mls/mac_mls.c b/sys/security/mac_mls/mac_mls.c
index 02c1f7e..744e073 100644
--- a/sys/security/mac_mls/mac_mls.c
+++ b/sys/security/mac_mls/mac_mls.c
@@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/acl.h>
#include <sys/conf.h>
+#include <sys/extattr.h>
#include <sys/kernel.h>
#include <sys/mac.h>
#include <sys/malloc.h>
@@ -83,6 +84,10 @@ SYSCTL_DECL(_security_mac);
SYSCTL_NODE(_security_mac, OID_AUTO, mls, CTLFLAG_RW, 0,
"TrustedBSD mac_mls policy controls");
+static int mac_mls_label_size = sizeof(struct mac_mls);
+SYSCTL_INT(_security_mac_mls, OID_AUTO, label_size, CTLFLAG_RD,
+ &mac_mls_label_size, 0, "Size of struct mac_mls");
+
static int mac_mls_enabled = 0;
SYSCTL_INT(_security_mac_mls, OID_AUTO, enabled, CTLFLAG_RW,
&mac_mls_enabled, 0, "Enforce MAC/MLS policy");
@@ -609,23 +614,6 @@ mac_mls_externalize_label(struct label *label, char *element_name,
}
static int
-mac_mls_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
- struct mac_mls *mac_mls;
-
- mac_mls = SLOT(label);
-
- if (mac_mls == NULL) {
- printf("mac_mls_externalize: NULL pointer\n");
- return (0);
- }
-
- extmac->m_mls = *mac_mls;
-
- return (0);
-}
-
-static int
mac_mls_parse_element(struct mac_mls_element *element, char *string)
{
@@ -839,18 +827,6 @@ mac_mls_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
}
static void
-mac_mls_create_vnode(struct ucred *cred, struct vnode *parent,
- struct label *parentlabel, struct vnode *child, struct label *childlabel)
-{
- struct mac_mls *source, *dest;
-
- source = SLOT(&cred->cr_label);
- dest = SLOT(childlabel);
-
- mac_mls_copy_single(source, dest);
-}
-
-static void
mac_mls_create_mount(struct ucred *cred, struct mount *mp,
struct label *mntlabel, struct label *fslabel)
{
@@ -901,55 +877,116 @@ mac_mls_update_devfsdirent(struct devfs_dirent *devfs_dirent,
}
static void
-mac_mls_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
- struct ucred *cred)
+mac_mls_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
+ struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
+ struct label *vlabel)
{
struct mac_mls *source, *dest;
- source = SLOT(&cred->cr_label);
- dest = SLOT(vnodelabel);
+ source = SLOT(delabel);
+ dest = SLOT(vlabel);
- /*
- * Only copy the single, not the range, since vnodes only have
- * a single.
- */
mac_mls_copy_single(source, dest);
}
static int
-mac_mls_update_vnode_from_externalized(struct vnode *vp,
- struct label *vnodelabel, struct oldmac *extmac)
+mac_mls_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
+ struct vnode *vp, struct label *vlabel)
{
- struct mac_mls *source, *dest;
+ struct mac_mls temp, *source, *dest;
+ size_t buflen;
int error;
- source = &extmac->m_mls;
- dest = SLOT(vnodelabel);
+ source = SLOT(fslabel);
+ dest = SLOT(vlabel);
- error = mac_mls_valid(source);
- if (error)
- return (error);
+ buflen = sizeof(temp);
+ bzero(&temp, buflen);
- if ((source->mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE)
- return (EINVAL);
+ error = vn_extattr_get(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
+ MAC_MLS_EXTATTR_NAME, &buflen, (char *) &temp, curthread);
+ if (error == ENOATTR || error == EOPNOTSUPP) {
+ /* Fall back to the fslabel. */
+ mac_mls_copy_single(source, dest);
+ return (0);
+ } else if (error)
+ return (error);
- mac_mls_copy_single(source, dest);
+ if (buflen != sizeof(temp)) {
+ printf("mac_mls_associate_vnode_extattr: bad size %d\n",
+ buflen);
+ return (EPERM);
+ }
+ if (mac_mls_valid(&temp) != 0) {
+ printf("mac_mls_associate_vnode_extattr: invalid\n");
+ return (EPERM);
+ }
+ if ((temp.mm_flags & MAC_MLS_FLAGS_BOTH) != MAC_MLS_FLAG_SINGLE) {
+ printf("mac_mls_associated_vnode_extattr: not single\n");
+ return (EPERM);
+ }
+ mac_mls_copy_single(&temp, dest);
return (0);
}
static void
-mac_mls_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
- struct mount *mp, struct label *fslabel)
+mac_mls_associate_vnode_singlelabel(struct mount *mp,
+ struct label *fslabel, struct vnode *vp, struct label *vlabel)
{
struct mac_mls *source, *dest;
source = SLOT(fslabel);
- dest = SLOT(vnodelabel);
+ dest = SLOT(vlabel);
mac_mls_copy_single(source, dest);
}
+static int
+mac_mls_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)
+{
+ struct mac_mls *source, *dest, temp;
+ size_t buflen;
+ int error;
+
+ buflen = sizeof(temp);
+ bzero(&temp, buflen);
+
+ source = SLOT(&cred->cr_label);
+ dest = SLOT(vlabel);
+ mac_mls_copy_single(source, &temp);
+
+ error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
+ MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread);
+ if (error == 0)
+ mac_mls_copy_single(source, dest);
+ return (error);
+}
+
+static int
+mac_mls_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *vlabel, struct label *intlabel)
+{
+ struct mac_mls *source, temp;
+ size_t buflen;
+ int error;
+
+ buflen = sizeof(temp);
+ bzero(&temp, buflen);
+
+ source = SLOT(intlabel);
+ if ((source->mm_flags & MAC_MLS_FLAG_SINGLE) == 0)
+ return (0);
+
+ mac_mls_copy_single(source, &temp);
+
+ error = vn_extattr_set(vp, IO_NODELOCKED, MAC_MLS_EXTATTR_NAMESPACE,
+ MAC_MLS_EXTATTR_NAME, buflen, (char *) &temp, curthread);
+ return (error);
+}
+
/*
* Labeling event operations: IPC object.
*/
@@ -2405,8 +2442,6 @@ static struct mac_policy_op_entry mac_mls_ops[] =
(macop_t)mac_mls_externalize_label },
{ MAC_EXTERNALIZE_VNODE_LABEL,
(macop_t)mac_mls_externalize_label },
- { MAC_EXTERNALIZE_VNODE_OLDMAC,
- (macop_t)mac_mls_externalize_vnode_oldmac },
{ MAC_INTERNALIZE_CRED_LABEL,
(macop_t)mac_mls_internalize_label },
{ MAC_INTERNALIZE_IFNET_LABEL,
@@ -2425,8 +2460,6 @@ static struct mac_policy_op_entry mac_mls_ops[] =
(macop_t)mac_mls_create_devfs_symlink },
{ MAC_CREATE_DEVFS_VNODE,
(macop_t)mac_mls_create_devfs_vnode },
- { MAC_CREATE_VNODE,
- (macop_t)mac_mls_create_vnode },
{ MAC_CREATE_MOUNT,
(macop_t)mac_mls_create_mount },
{ MAC_CREATE_ROOT_MOUNT,
@@ -2435,12 +2468,16 @@ static struct mac_policy_op_entry mac_mls_ops[] =
(macop_t)mac_mls_relabel_vnode },
{ MAC_UPDATE_DEVFSDIRENT,
(macop_t)mac_mls_update_devfsdirent },
- { MAC_UPDATE_PROCFSVNODE,
- (macop_t)mac_mls_update_procfsvnode },
- { MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
- (macop_t)mac_mls_update_vnode_from_externalized },
- { MAC_UPDATE_VNODE_FROM_MOUNT,
- (macop_t)mac_mls_update_vnode_from_mount },
+ { MAC_ASSOCIATE_VNODE_DEVFS,
+ (macop_t)mac_mls_associate_vnode_devfs },
+ { MAC_ASSOCIATE_VNODE_EXTATTR,
+ (macop_t)mac_mls_associate_vnode_extattr },
+ { MAC_ASSOCIATE_VNODE_SINGLELABEL,
+ (macop_t)mac_mls_associate_vnode_singlelabel },
+ { MAC_CREATE_VNODE_EXTATTR,
+ (macop_t)mac_mls_create_vnode_extattr },
+ { MAC_SETLABEL_VNODE_EXTATTR,
+ (macop_t)mac_mls_setlabel_vnode_extattr },
{ MAC_CREATE_MBUF_FROM_SOCKET,
(macop_t)mac_mls_create_mbuf_from_socket },
{ MAC_CREATE_PIPE,
diff --git a/sys/security/mac_none/mac_none.c b/sys/security/mac_none/mac_none.c
index 85eb896..913fba2 100644
--- a/sys/security/mac_none/mac_none.c
+++ b/sys/security/mac_none/mac_none.c
@@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/acl.h>
#include <sys/conf.h>
+#include <sys/extattr.h>
#include <sys/kernel.h>
#include <sys/mac.h>
#include <sys/mount.h>
@@ -136,13 +137,6 @@ mac_none_externalize_label(struct label *label, char *element_name,
}
static int
-mac_none_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
-
- return (0);
-}
-
-static int
mac_none_internalize_label(struct label *label, char *element_name,
char *element_data, int *claimed)
{
@@ -155,6 +149,29 @@ mac_none_internalize_label(struct label *label, char *element_name,
* a lot like file system objects.
*/
static void
+mac_none_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
+ struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
+ struct label *vlabel)
+{
+
+}
+
+static int
+mac_none_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
+ struct vnode *vp, struct label *vlabel)
+{
+
+ return (0);
+}
+
+static void
+mac_none_associate_vnode_singlelabel(struct mount *mp,
+ struct label *fslabel, struct vnode *vp, struct label *vlabel)
+{
+
+}
+
+static void
mac_none_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
struct label *label)
{
@@ -182,12 +199,13 @@ mac_none_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
}
-static void
-mac_none_create_vnode(struct ucred *cred, struct vnode *parent,
- struct label *parentlabel, struct vnode *child,
- struct label *childlabel)
+static int
+mac_none_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)
{
+ return (0);
}
static void
@@ -211,31 +229,17 @@ mac_none_relabel_vnode(struct ucred *cred, struct vnode *vp,
}
-static void
-mac_none_update_devfsdirent(struct devfs_dirent *devfs_dirent,
- struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
-{
-
-}
-
-static void
-mac_none_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
- struct ucred *cred)
-{
-
-}
-
static int
-mac_none_update_vnode_from_externalized(struct vnode *vp,
- struct label *vnodelabel, struct oldmac *extmac)
+mac_none_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *vlabel, struct label *intlabel)
{
return (0);
}
static void
-mac_none_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
- struct mount *mp, struct label *fslabel)
+mac_none_update_devfsdirent(struct devfs_dirent *devfs_dirent,
+ struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
{
}
@@ -924,8 +928,6 @@ static struct mac_policy_op_entry mac_none_ops[] =
(macop_t)mac_none_externalize_label },
{ MAC_EXTERNALIZE_VNODE_LABEL,
(macop_t)mac_none_externalize_label },
- { MAC_EXTERNALIZE_VNODE_OLDMAC,
- (macop_t)mac_none_externalize_vnode_oldmac },
{ MAC_INTERNALIZE_CRED_LABEL,
(macop_t)mac_none_internalize_label },
{ MAC_INTERNALIZE_IFNET_LABEL,
@@ -936,6 +938,12 @@ static struct mac_policy_op_entry mac_none_ops[] =
(macop_t)mac_none_internalize_label },
{ MAC_INTERNALIZE_VNODE_LABEL,
(macop_t)mac_none_internalize_label },
+ { MAC_ASSOCIATE_VNODE_DEVFS,
+ (macop_t)mac_none_associate_vnode_devfs },
+ { MAC_ASSOCIATE_VNODE_EXTATTR,
+ (macop_t)mac_none_associate_vnode_extattr },
+ { MAC_ASSOCIATE_VNODE_SINGLELABEL,
+ (macop_t)mac_none_associate_vnode_singlelabel },
{ MAC_CREATE_DEVFS_DEVICE,
(macop_t)mac_none_create_devfs_device },
{ MAC_CREATE_DEVFS_DIRECTORY,
@@ -944,22 +952,18 @@ static struct mac_policy_op_entry mac_none_ops[] =
(macop_t)mac_none_create_devfs_symlink },
{ MAC_CREATE_DEVFS_VNODE,
(macop_t)mac_none_create_devfs_vnode },
- { MAC_CREATE_VNODE,
- (macop_t)mac_none_create_vnode },
+ { MAC_CREATE_VNODE_EXTATTR,
+ (macop_t)mac_none_create_vnode_extattr },
{ MAC_CREATE_MOUNT,
(macop_t)mac_none_create_mount },
{ MAC_CREATE_ROOT_MOUNT,
(macop_t)mac_none_create_root_mount },
{ MAC_RELABEL_VNODE,
(macop_t)mac_none_relabel_vnode },
+ { MAC_SETLABEL_VNODE_EXTATTR,
+ (macop_t)mac_none_setlabel_vnode_extattr },
{ MAC_UPDATE_DEVFSDIRENT,
(macop_t)mac_none_update_devfsdirent },
- { MAC_UPDATE_PROCFSVNODE,
- (macop_t)mac_none_update_procfsvnode },
- { MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
- (macop_t)mac_none_update_vnode_from_externalized },
- { MAC_UPDATE_VNODE_FROM_MOUNT,
- (macop_t)mac_none_update_vnode_from_mount },
{ MAC_CREATE_MBUF_FROM_SOCKET,
(macop_t)mac_none_create_mbuf_from_socket },
{ MAC_CREATE_PIPE,
diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c
index 85eb896..913fba2 100644
--- a/sys/security/mac_stub/mac_stub.c
+++ b/sys/security/mac_stub/mac_stub.c
@@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/acl.h>
#include <sys/conf.h>
+#include <sys/extattr.h>
#include <sys/kernel.h>
#include <sys/mac.h>
#include <sys/mount.h>
@@ -136,13 +137,6 @@ mac_none_externalize_label(struct label *label, char *element_name,
}
static int
-mac_none_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
-
- return (0);
-}
-
-static int
mac_none_internalize_label(struct label *label, char *element_name,
char *element_data, int *claimed)
{
@@ -155,6 +149,29 @@ mac_none_internalize_label(struct label *label, char *element_name,
* a lot like file system objects.
*/
static void
+mac_none_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
+ struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
+ struct label *vlabel)
+{
+
+}
+
+static int
+mac_none_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
+ struct vnode *vp, struct label *vlabel)
+{
+
+ return (0);
+}
+
+static void
+mac_none_associate_vnode_singlelabel(struct mount *mp,
+ struct label *fslabel, struct vnode *vp, struct label *vlabel)
+{
+
+}
+
+static void
mac_none_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
struct label *label)
{
@@ -182,12 +199,13 @@ mac_none_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
}
-static void
-mac_none_create_vnode(struct ucred *cred, struct vnode *parent,
- struct label *parentlabel, struct vnode *child,
- struct label *childlabel)
+static int
+mac_none_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)
{
+ return (0);
}
static void
@@ -211,31 +229,17 @@ mac_none_relabel_vnode(struct ucred *cred, struct vnode *vp,
}
-static void
-mac_none_update_devfsdirent(struct devfs_dirent *devfs_dirent,
- struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
-{
-
-}
-
-static void
-mac_none_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
- struct ucred *cred)
-{
-
-}
-
static int
-mac_none_update_vnode_from_externalized(struct vnode *vp,
- struct label *vnodelabel, struct oldmac *extmac)
+mac_none_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *vlabel, struct label *intlabel)
{
return (0);
}
static void
-mac_none_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
- struct mount *mp, struct label *fslabel)
+mac_none_update_devfsdirent(struct devfs_dirent *devfs_dirent,
+ struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
{
}
@@ -924,8 +928,6 @@ static struct mac_policy_op_entry mac_none_ops[] =
(macop_t)mac_none_externalize_label },
{ MAC_EXTERNALIZE_VNODE_LABEL,
(macop_t)mac_none_externalize_label },
- { MAC_EXTERNALIZE_VNODE_OLDMAC,
- (macop_t)mac_none_externalize_vnode_oldmac },
{ MAC_INTERNALIZE_CRED_LABEL,
(macop_t)mac_none_internalize_label },
{ MAC_INTERNALIZE_IFNET_LABEL,
@@ -936,6 +938,12 @@ static struct mac_policy_op_entry mac_none_ops[] =
(macop_t)mac_none_internalize_label },
{ MAC_INTERNALIZE_VNODE_LABEL,
(macop_t)mac_none_internalize_label },
+ { MAC_ASSOCIATE_VNODE_DEVFS,
+ (macop_t)mac_none_associate_vnode_devfs },
+ { MAC_ASSOCIATE_VNODE_EXTATTR,
+ (macop_t)mac_none_associate_vnode_extattr },
+ { MAC_ASSOCIATE_VNODE_SINGLELABEL,
+ (macop_t)mac_none_associate_vnode_singlelabel },
{ MAC_CREATE_DEVFS_DEVICE,
(macop_t)mac_none_create_devfs_device },
{ MAC_CREATE_DEVFS_DIRECTORY,
@@ -944,22 +952,18 @@ static struct mac_policy_op_entry mac_none_ops[] =
(macop_t)mac_none_create_devfs_symlink },
{ MAC_CREATE_DEVFS_VNODE,
(macop_t)mac_none_create_devfs_vnode },
- { MAC_CREATE_VNODE,
- (macop_t)mac_none_create_vnode },
+ { MAC_CREATE_VNODE_EXTATTR,
+ (macop_t)mac_none_create_vnode_extattr },
{ MAC_CREATE_MOUNT,
(macop_t)mac_none_create_mount },
{ MAC_CREATE_ROOT_MOUNT,
(macop_t)mac_none_create_root_mount },
{ MAC_RELABEL_VNODE,
(macop_t)mac_none_relabel_vnode },
+ { MAC_SETLABEL_VNODE_EXTATTR,
+ (macop_t)mac_none_setlabel_vnode_extattr },
{ MAC_UPDATE_DEVFSDIRENT,
(macop_t)mac_none_update_devfsdirent },
- { MAC_UPDATE_PROCFSVNODE,
- (macop_t)mac_none_update_procfsvnode },
- { MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
- (macop_t)mac_none_update_vnode_from_externalized },
- { MAC_UPDATE_VNODE_FROM_MOUNT,
- (macop_t)mac_none_update_vnode_from_mount },
{ MAC_CREATE_MBUF_FROM_SOCKET,
(macop_t)mac_none_create_mbuf_from_socket },
{ MAC_CREATE_PIPE,
diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c
index b4b18a3..6a2cf76 100644
--- a/sys/security/mac_test/mac_test.c
+++ b/sys/security/mac_test/mac_test.c
@@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/acl.h>
#include <sys/conf.h>
+#include <sys/extattr.h>
#include <sys/kernel.h>
#include <sys/mac.h>
#include <sys/mount.h>
@@ -483,15 +484,6 @@ mac_test_externalize_label(struct label *label, char *element_name,
}
static int
-mac_test_externalize_vnode_oldmac(struct label *label, struct oldmac *extmac)
-{
-
- atomic_add_int(&externalize_count, 1);
-
- return (0);
-}
-
-static int
mac_test_internalize_label(struct label *label, struct mac *mac,
char *element_name, char *element_data, int *claimed)
{
@@ -506,6 +498,29 @@ mac_test_internalize_label(struct label *label, struct mac *mac,
* a lot like file system objects.
*/
static void
+mac_test_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
+ struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
+ struct label *vlabel)
+{
+
+}
+
+static int
+mac_test_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
+ struct vnode *vp, struct label *vlabel)
+{
+
+ return (0);
+}
+
+static void
+mac_test_associate_vnode_singlelabel(struct mount *mp,
+ struct label *fslabel, struct vnode *vp, struct label *vlabel)
+{
+
+}
+
+static void
mac_test_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
struct label *label)
{
@@ -533,11 +548,13 @@ mac_test_create_devfs_vnode(struct devfs_dirent *devfs_dirent,
}
-static void
-mac_test_create_vnode(struct ucred *cred, struct vnode *parent,
- struct label *parentlabel, struct vnode *child, struct label *childlabel)
+static int
+mac_test_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)
{
+ return (0);
}
static void
@@ -561,31 +578,17 @@ mac_test_relabel_vnode(struct ucred *cred, struct vnode *vp,
}
-static void
-mac_test_update_devfsdirent(struct devfs_dirent *devfs_dirent,
- struct vnode *vp)
-{
-
-}
-
-static void
-mac_test_update_procfsvnode(struct vnode *vp, struct label *vnodelabel,
- struct ucred *cred)
-{
-
-}
-
static int
-mac_test_update_vnode_from_externalized(struct vnode *vp,
- struct label *vnodelabel, struct mac *extmac)
+mac_test_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
+ struct label *vlabel, struct label *intlabel)
{
return (0);
}
static void
-mac_test_update_vnode_from_mount(struct vnode *vp, struct label *vnodelabel,
- struct mount *mp, struct label *fslabel)
+mac_test_update_devfsdirent(struct devfs_dirent *devfs_dirent,
+ struct label *direntlabel, struct vnode *vp, struct label *vnodelabel)
{
}
@@ -1275,8 +1278,6 @@ static struct mac_policy_op_entry mac_test_ops[] =
(macop_t)mac_test_externalize_label },
{ MAC_EXTERNALIZE_VNODE_LABEL,
(macop_t)mac_test_externalize_label },
- { MAC_EXTERNALIZE_VNODE_OLDMAC,
- (macop_t)mac_test_externalize_vnode_oldmac },
{ MAC_INTERNALIZE_CRED_LABEL,
(macop_t)mac_test_internalize_label },
{ MAC_INTERNALIZE_IFNET_LABEL,
@@ -1287,6 +1288,12 @@ static struct mac_policy_op_entry mac_test_ops[] =
(macop_t)mac_test_internalize_label },
{ MAC_INTERNALIZE_VNODE_LABEL,
(macop_t)mac_test_internalize_label },
+ { MAC_ASSOCIATE_VNODE_DEVFS,
+ (macop_t)mac_test_associate_vnode_devfs },
+ { MAC_ASSOCIATE_VNODE_EXTATTR,
+ (macop_t)mac_test_associate_vnode_extattr },
+ { MAC_ASSOCIATE_VNODE_SINGLELABEL,
+ (macop_t)mac_test_associate_vnode_singlelabel },
{ MAC_CREATE_DEVFS_DEVICE,
(macop_t)mac_test_create_devfs_device },
{ MAC_CREATE_DEVFS_DIRECTORY,
@@ -1295,22 +1302,18 @@ static struct mac_policy_op_entry mac_test_ops[] =
(macop_t)mac_test_create_devfs_symlink },
{ MAC_CREATE_DEVFS_VNODE,
(macop_t)mac_test_create_devfs_vnode },
- { MAC_CREATE_VNODE,
- (macop_t)mac_test_create_vnode },
+ { MAC_CREATE_VNODE_EXTATTR,
+ (macop_t)mac_test_create_vnode_extattr },
{ MAC_CREATE_MOUNT,
(macop_t)mac_test_create_mount },
{ MAC_CREATE_ROOT_MOUNT,
(macop_t)mac_test_create_root_mount },
{ MAC_RELABEL_VNODE,
(macop_t)mac_test_relabel_vnode },
+ { MAC_SETLABEL_VNODE_EXTATTR,
+ (macop_t)mac_test_setlabel_vnode_extattr },
{ MAC_UPDATE_DEVFSDIRENT,
(macop_t)mac_test_update_devfsdirent },
- { MAC_UPDATE_PROCFSVNODE,
- (macop_t)mac_test_update_procfsvnode },
- { MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
- (macop_t)mac_test_update_vnode_from_externalized },
- { MAC_UPDATE_VNODE_FROM_MOUNT,
- (macop_t)mac_test_update_vnode_from_mount },
{ MAC_CREATE_MBUF_FROM_SOCKET,
(macop_t)mac_test_create_mbuf_from_socket },
{ MAC_CREATE_PIPE,
diff --git a/sys/sys/mac.h b/sys/sys/mac.h
index bcf36e0..cc9552b 100644
--- a/sys/sys/mac.h
+++ b/sys/sys/mac.h
@@ -195,6 +195,8 @@ void mac_init_pipe(struct pipe *);
int mac_init_mbuf(struct mbuf *m, int flag);
void mac_init_mount(struct mount *);
void mac_init_vnode(struct vnode *);
+void mac_init_vnode_label(struct label *);
+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 *);
@@ -205,26 +207,29 @@ void mac_destroy_pipe(struct pipe *);
void mac_destroy_mbuf(struct mbuf *);
void mac_destroy_mount(struct mount *);
void mac_destroy_vnode(struct vnode *);
+void mac_destroy_vnode_label(struct 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(dev_t dev, struct devfs_dirent *de);
void mac_create_devfs_directory(char *dirname, int dirnamelen,
struct devfs_dirent *de);
void mac_create_devfs_symlink(struct ucred *cred, struct devfs_dirent *dd,
struct devfs_dirent *de);
void mac_create_devfs_vnode(struct devfs_dirent *de, struct vnode *vp);
-void mac_create_vnode(struct ucred *cred, struct vnode *parent,
- struct vnode *child);
+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 devfs_dirent *de, struct vnode *vp);
-void mac_update_procfsvnode(struct vnode *vp, struct ucred *cred);
-void mac_update_vnode_from_mount(struct vnode *vp, struct mount *mp);
/*
* Labeling event operations: IPC objects.
@@ -362,9 +367,6 @@ int mac_pipe_label_set(struct ucred *cred, struct pipe *pipe,
* Calls to help various file systems implement labeling functionality
* using their existing EA implementation.
*/
-int vop_stdcreatevnode_ea(struct vnode *dvp, struct vnode *tvp,
- struct ucred *cred);
-int vop_stdrefreshlabel_ea(struct vop_refreshlabel_args *ap);
int vop_stdsetlabel_ea(struct vop_setlabel_args *ap);
#endif /* _KERNEL */
diff --git a/sys/sys/mac_policy.h b/sys/sys/mac_policy.h
index aabc95e..46c4c1b 100644
--- a/sys/sys/mac_policy.h
+++ b/sys/sys/mac_policy.h
@@ -118,8 +118,6 @@ struct mac_policy_ops {
int (*mpo_externalize_vnode_label)(struct label *label,
char *element_name, char *buffer, size_t buflen,
size_t *len, int *claimed);
- int (*mpo_externalize_vnode_oldmac)(struct label *label,
- struct oldmac *extmac);
int (*mpo_internalize_cred_label)(struct label *label,
char *element_name, char *element_data, int *claimed);
int (*mpo_internalize_ifnet_label)(struct label *label,
@@ -135,6 +133,16 @@ struct mac_policy_ops {
* 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)(dev_t dev, struct devfs_dirent *de,
struct label *label);
void (*mpo_create_devfs_directory)(char *dirname, int dirnamelen,
@@ -145,30 +153,23 @@ struct mac_policy_ops {
void (*mpo_create_devfs_vnode)(struct devfs_dirent *de,
struct label *direntlabel, struct vnode *vp,
struct label *vnodelabel);
- void (*mpo_create_vnode)(struct ucred *cred, struct vnode *parent,
- struct label *parentlabel, struct vnode *child,
- struct label *childlabel);
+ 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_stdcreatevnode_ea)(struct vnode *vp,
- struct label *vnodelabel);
+ int (*mpo_setlabel_vnode_extattr)(struct ucred *cred,
+ struct vnode *vp, struct label *vlabel,
+ struct label *intlabel);
void (*mpo_update_devfsdirent)(struct devfs_dirent *devfs_dirent,
struct label *direntlabel, struct vnode *vp,
struct label *vnodelabel);
- void (*mpo_update_procfsvnode)(struct vnode *vp,
- struct label *vnodelabel, struct ucred *cred);
- int (*mpo_update_vnode_from_extattr)(struct vnode *vp,
- struct label *vnodelabel, struct mount *mp,
- struct label *fslabel);
- int (*mpo_update_vnode_from_externalized)(struct vnode *vp,
- struct label *vnodelabel, struct oldmac *extmac);
- void (*mpo_update_vnode_from_mount)(struct vnode *vp,
- struct label *vnodelabel, struct mount *mp,
- struct label *fslabel);
/*
* Labeling event operations: IPC objects.
@@ -431,7 +432,6 @@ enum mac_op_constant {
MAC_EXTERNALIZE_SOCKET_LABEL,
MAC_EXTERNALIZE_SOCKET_PEER_LABEL,
MAC_EXTERNALIZE_VNODE_LABEL,
- MAC_EXTERNALIZE_VNODE_OLDMAC,
MAC_INTERNALIZE_CRED_LABEL,
MAC_INTERNALIZE_IFNET_LABEL,
MAC_INTERNALIZE_PIPE_LABEL,
@@ -441,16 +441,15 @@ enum mac_op_constant {
MAC_CREATE_DEVFS_DIRECTORY,
MAC_CREATE_DEVFS_SYMLINK,
MAC_CREATE_DEVFS_VNODE,
- MAC_CREATE_VNODE,
MAC_CREATE_MOUNT,
MAC_CREATE_ROOT_MOUNT,
MAC_RELABEL_VNODE,
- MAC_STDCREATEVNODE_EA,
MAC_UPDATE_DEVFSDIRENT,
- MAC_UPDATE_PROCFSVNODE,
- MAC_UPDATE_VNODE_FROM_EXTATTR,
- MAC_UPDATE_VNODE_FROM_EXTERNALIZED,
- MAC_UPDATE_VNODE_FROM_MOUNT,
+ MAC_ASSOCIATE_VNODE_DEVFS,
+ MAC_ASSOCIATE_VNODE_EXTATTR,
+ MAC_ASSOCIATE_VNODE_SINGLELABEL,
+ MAC_CREATE_VNODE_EXTATTR,
+ MAC_SETLABEL_VNODE_EXTATTR,
MAC_CREATE_MBUF_FROM_SOCKET,
MAC_CREATE_PIPE,
MAC_CREATE_SOCKET,
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index b80cd1c..91d396b 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -44,6 +44,7 @@
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/kernel.h>
+#include <sys/mac.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/bio.h>
@@ -1337,6 +1338,23 @@ ffs_vget(mp, ino, flags, vpp)
ip->i_gid = ip->i_din1->di_ogid; /* XXX */
} /* XXX */
+#ifdef MAC
+ if ((mp->mnt_flag & MNT_MULTILABEL) && ip->i_mode) {
+ /*
+ * If this vnode is already allocated, and we're running
+ * multi-label, attempt to perform a label association
+ * from the extended attributes on the inode.
+ */
+ error = mac_associate_vnode_extattr(mp, vp);
+ if (error) {
+ /* ufs_inactive will release ip->i_devvp ref. */
+ vput(vp);
+ *vpp = NULL;
+ return (error);
+ }
+ }
+#endif
+
*vpp = vp;
return (0);
}
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index ba6edd2..f8867e1 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1523,9 +1523,12 @@ ufs_mkdir(ap)
if (error)
goto bad;
#ifdef MAC
- error = vop_stdcreatevnode_ea(dvp, tvp, cnp->cn_cred);
- if (error)
- goto bad;
+ if (dvp->v_mount->mnt_flag & MNT_MULTILABEL) {
+ error = mac_create_vnode_extattr(cnp->cn_cred, dvp->v_mount,
+ dvp, tvp, cnp);
+ if (error)
+ goto bad;
+ }
#endif
#ifdef UFS_ACL
if (acl != NULL) {
@@ -2459,9 +2462,12 @@ ufs_makeinode(mode, dvp, vpp, cnp)
if (error)
goto bad;
#ifdef MAC
- error = vop_stdcreatevnode_ea(dvp, tvp, cnp->cn_cred);
- if (error)
- goto bad;
+ if (dvp->v_mount->mnt_flag & MNT_MULTILABEL) {
+ error = mac_create_vnode_extattr(cnp->cn_cred, dvp->v_mount,
+ dvp, tvp, cnp);
+ if (error)
+ goto bad;
+ }
#endif
#ifdef UFS_ACL
if (acl != NULL) {
@@ -2649,9 +2655,6 @@ static struct vnodeopv_entry_desc ufs_vnodeop_entries[] = {
{ &vop_readdir_desc, (vop_t *) ufs_readdir },
{ &vop_readlink_desc, (vop_t *) ufs_readlink },
{ &vop_reclaim_desc, (vop_t *) ufs_reclaim },
-#ifdef MAC
- { &vop_refreshlabel_desc, (vop_t *) vop_stdrefreshlabel_ea },
-#endif
{ &vop_remove_desc, (vop_t *) ufs_remove },
{ &vop_rename_desc, (vop_t *) ufs_rename },
{ &vop_rmdir_desc, (vop_t *) ufs_rmdir },
@@ -2690,9 +2693,6 @@ static struct vnodeopv_entry_desc ufs_specop_entries[] = {
{ &vop_print_desc, (vop_t *) ufs_print },
{ &vop_read_desc, (vop_t *) ufsspec_read },
{ &vop_reclaim_desc, (vop_t *) ufs_reclaim },
-#ifdef MAC
- { &vop_refreshlabel_desc, (vop_t *) vop_stdrefreshlabel_ea },
-#endif
{ &vop_setattr_desc, (vop_t *) ufs_setattr },
#ifdef MAC
{ &vop_setlabel_desc, (vop_t *) vop_stdsetlabel_ea },
@@ -2727,9 +2727,6 @@ static struct vnodeopv_entry_desc ufs_fifoop_entries[] = {
{ &vop_print_desc, (vop_t *) ufs_print },
{ &vop_read_desc, (vop_t *) ufsfifo_read },
{ &vop_reclaim_desc, (vop_t *) ufs_reclaim },
-#ifdef MAC
- { &vop_refreshlabel_desc, (vop_t *) vop_stdrefreshlabel_ea },
-#endif
{ &vop_setattr_desc, (vop_t *) ufs_setattr },
#ifdef MAC
{ &vop_setlabel_desc, (vop_t *) vop_stdsetlabel_ea },
OpenPOWER on IntegriCloud