summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2002-10-26 14:38:24 +0000
committerrwatson <rwatson@FreeBSD.org>2002-10-26 14:38:24 +0000
commit312cab0dee67b902f2b3c5b4d8873b978e5f0191 (patch)
treec8fd3cabfa2bfa5d30b618f0bd199b68acdff307 /sys
parent5de667a68d9bb17cb2a9a6df00a724b91d053f12 (diff)
downloadFreeBSD-src-312cab0dee67b902f2b3c5b4d8873b978e5f0191.zip
FreeBSD-src-312cab0dee67b902f2b3c5b4d8873b978e5f0191.tar.gz
Slightly change the semantics of vnode labels for MAC: rather than
"refreshing" the label on the vnode before use, just get the label right from inception. For single-label file systems, set the label in the generic VFS getnewvnode() code; for multi-label file systems, leave the labeling up to the file system. With UFS1/2, this means reading the extended attribute during vfs_vget() as the inode is pulled off disk, rather than hitting the extended attributes frequently during operations later, improving performance. This also corrects sematics for shared vnode locks, which were not previously present in the system. This chances the cache coherrency properties WRT out-of-band access to label data, but in an acceptable form. With UFS1, there is a small race condition during automatic extended attribute start -- this is not present with UFS2, and occurs because EAs aren't available at vnode inception. We'll introduce a work around for this shortly. Approved by: re Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories
Diffstat (limited to 'sys')
-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