summaryrefslogtreecommitdiffstats
path: root/sys/security/mac/mac_syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/security/mac/mac_syscalls.c')
-rw-r--r--sys/security/mac/mac_syscalls.c576
1 files changed, 90 insertions, 486 deletions
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);
OpenPOWER on IntegriCloud