]> git.saurik.com Git - apple/xnu.git/blobdiff - security/mac_vfs.c
xnu-2050.24.15.tar.gz
[apple/xnu.git] / security / mac_vfs.c
index 4316e2d3ba690d119bdb68f0fc07e87dda6b3f15..7bf550622ad8488f2f85052bbb805d75f40807d2 100644 (file)
@@ -79,7 +79,7 @@
 #include <sys/vnode_internal.h>
 
 #include <miscfs/devfs/devfsdefs.h>
-#include <miscfs/fdesc/fdesc.h>
+#include <miscfs/devfs/fdesc.h>
 
 #include <security/mac_internal.h>
 
@@ -139,10 +139,15 @@ mac_vnode_label_alloc(void)
 void
 mac_vnode_label_init(vnode_t vp)
 {
-
        vp->v_label = mac_vnode_label_alloc();
 }
 
+int
+mac_vnode_label_init_needed(vnode_t vp)
+{
+       return (mac_label_vnodes != 0 && vp->v_label == NULL);
+}
+
 /* 
  * vnode labels are allocated at the same time as vnodes, but vnodes are never
  * freed.  Instead, we want to remove any sensitive information before putting
@@ -182,8 +187,6 @@ mac_mount_label_free(struct label *label)
 void
 mac_mount_label_destroy(struct mount *mp)
 {
-
-
        if (mp->mnt_mntlabel != NULL) {
                mac_mount_label_free(mp->mnt_mntlabel);
                mp->mnt_mntlabel = NULL;
@@ -193,7 +196,6 @@ mac_mount_label_destroy(struct mount *mp)
 void
 mac_vnode_label_free(struct label *label)
 {
-
        MAC_PERFORM(vnode_label_destroy, label);
        mac_labelzone_free(label);
 }
@@ -202,17 +204,21 @@ mac_vnode_label_free(struct label *label)
 void
 mac_vnode_label_destroy(struct vnode *vp)
 {
-
-       mac_vnode_label_free(vp->v_label);
-       vp->v_label = NULL;
+       if (vp->v_label != NULL) {
+               mac_vnode_label_free(vp->v_label);
+               vp->v_label = NULL;
+       }
 }
 #endif
 
 void
 mac_vnode_label_copy(struct label *src, struct label *dest)
 {
-
-       MAC_PERFORM(vnode_label_copy, src, dest);
+       if (src == NULL) {
+               MAC_PERFORM(vnode_label_init, dest);
+       } else {
+               MAC_PERFORM(vnode_label_copy, src, dest);
+       }
 }
 
 int
@@ -346,7 +352,7 @@ void
 mac_vnode_label_associate_singlelabel(struct mount *mp, struct vnode *vp)
 {
 
-       if (!mac_vnode_enforce)
+       if (!mac_vnode_enforce || !mac_label_vnodes)
                return;
 
        MAC_PERFORM(vnode_label_associate_singlelabel, mp,
@@ -371,6 +377,34 @@ mac_vnode_notify_create(vfs_context_t ctx, struct mount *mp,
        return (error);
 }
 
+void
+mac_vnode_notify_rename(vfs_context_t ctx, struct vnode *vp,
+    struct vnode *dvp, struct componentname *cnp)
+{
+       kauth_cred_t cred;
+
+       if (!mac_vnode_enforce ||
+               !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
+               return;
+
+       cred = vfs_context_ucred(ctx);
+       MAC_PERFORM(vnode_notify_rename, cred, vp, vp->v_label,
+           dvp, dvp->v_label, cnp);
+}
+
+void
+mac_vnode_notify_open(vfs_context_t ctx, struct vnode *vp, int acc_flags)
+{
+       kauth_cred_t cred;
+
+       if (!mac_vnode_enforce || 
+               !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
+               return;
+
+       cred = vfs_context_ucred(ctx);
+       MAC_PERFORM(vnode_notify_open, cred, vp, vp->v_label, acc_flags);
+}
+
 /*
  * Extended attribute 'name' was updated via
  * vn_setxattr() or vn_removexattr().  Allow the
@@ -382,7 +416,7 @@ mac_vnode_label_update_extattr(struct mount *mp, struct vnode *vp,
 {
        int error = 0;
 
-       if (!mac_vnode_enforce)
+       if (!mac_vnode_enforce || !mac_label_vnodes)
                return;
 
        MAC_PERFORM(vnode_label_update_extattr, mp, mp->mnt_mntlabel, vp,
@@ -403,7 +437,7 @@ mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
        kauth_cred_t cred;
        int error;
 
-       if (!mac_vnode_enforce &&
+       if (!mac_vnode_enforce || !mac_label_vnodes ||
            !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
                return 0;
 
@@ -413,21 +447,25 @@ mac_vnode_label_store(vfs_context_t ctx, struct vnode *vp,
        return (error);
 }
 
-void
+int
 mac_cred_label_update_execve(vfs_context_t ctx, kauth_cred_t new, struct vnode *vp,
     struct label *scriptvnodelabel, struct label *execl)
 {
        kauth_cred_t cred;
+       int disjoint = 0;
+       posix_cred_t pcred = posix_cred_get(new);
 
        if (!mac_proc_enforce && !mac_vnode_enforce)
-               return
+               return disjoint;
 
        /* mark the new cred to indicate "matching" includes the label */
-       new->cr_flags |= CRF_MAC_ENFORCE;
+       pcred->cr_flags |= CRF_MAC_ENFORCE;
 
        cred = vfs_context_ucred(ctx);
        MAC_PERFORM(cred_label_update_execve, cred, new, vp, vp->v_label,
-           scriptvnodelabel, execl);
+           scriptvnodelabel, execl, &disjoint);
+
+       return (disjoint);
 }
 
 int
@@ -633,6 +671,34 @@ mac_vnode_check_exec(vfs_context_t ctx, struct vnode *vp,
        return (error);
 }
 
+int
+mac_vnode_check_fsgetpath(vfs_context_t ctx, struct vnode *vp)
+{
+       kauth_cred_t cred;
+       int error;
+
+       if (!mac_vnode_enforce ||
+               !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
+               return (0);
+
+       cred = vfs_context_ucred(ctx);
+       MAC_CHECK(vnode_check_fsgetpath, cred, vp, vp->v_label);
+       return (error);
+}
+
+int
+mac_vnode_check_signature(struct vnode *vp, unsigned char *sha1,
+                         void * signature, size_t size)
+{
+       int error;
+       
+       if (!mac_vnode_enforce || !mac_proc_enforce)
+               return (0);
+       
+       MAC_CHECK(vnode_check_signature, vp, vp->v_label, sha1, signature, size);
+       return (error);
+}
+
 #if 0
 int
 mac_vnode_check_getacl(vfs_context_t ctx, struct vnode *vp, acl_type_t type)
@@ -877,6 +943,21 @@ mac_vnode_check_revoke(vfs_context_t ctx, struct vnode *vp)
        return (error);
 }
 
+int
+mac_vnode_check_searchfs(vfs_context_t ctx, struct vnode *vp, struct attrlist *alist)
+{
+       kauth_cred_t cred;
+       int error;
+
+       if (!mac_vnode_enforce || 
+               !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
+               return (0);
+
+       cred = vfs_context_ucred(ctx);
+       MAC_CHECK(vnode_check_searchfs, cred, vp, vp->v_label, alist);
+       return (error);
+}
+
 int
 mac_vnode_check_select(vfs_context_t ctx, struct vnode *vp, int which)
 {
@@ -1058,14 +1139,59 @@ mac_vnode_check_write(vfs_context_t ctx, struct ucred *file_cred,
        return (error);
 }
 
+int
+mac_vnode_check_uipc_bind(vfs_context_t ctx, struct vnode *dvp,
+    struct componentname *cnp, struct vnode_attr *vap)
+{
+       kauth_cred_t cred;
+       int error;
+
+       if (!mac_vnode_enforce || 
+               !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
+               return (0);
+
+       cred = vfs_context_ucred(ctx);
+       MAC_CHECK(vnode_check_uipc_bind, cred, dvp, dvp->v_label, cnp, vap);
+       return (error);
+}
+
+int
+mac_vnode_check_uipc_connect(vfs_context_t ctx, struct vnode *vp)
+{
+       kauth_cred_t cred;
+       int error;
+
+       if (!mac_vnode_enforce || 
+               !mac_context_check_enforce(ctx, MAC_VNODE_ENFORCE))
+               return (0);
+
+       cred = vfs_context_ucred(ctx);
+       MAC_CHECK(vnode_check_uipc_connect, cred, vp, vp->v_label);
+       return (error);
+}
+
 void
 mac_vnode_label_update(vfs_context_t ctx, struct vnode *vp, struct label *newlabel)
 {
        kauth_cred_t cred = vfs_context_ucred(ctx);
+       struct label *tmpl = NULL;
+
+       if (vp->v_label == NULL)
+               tmpl = mac_vnode_label_alloc();
 
        vnode_lock(vp);
+
+       /* recheck after lock */
+       if (vp->v_label == NULL) {
+               vp->v_label = tmpl;
+               tmpl = NULL;
+       }
+
        MAC_PERFORM(vnode_label_update, cred, vp, vp->v_label, newlabel);
        vnode_unlock(vp);
+
+       if (tmpl != NULL)
+               mac_vnode_label_free(tmpl);
 }
 
 void
@@ -1108,7 +1234,7 @@ mac_mount_label_associate(vfs_context_t ctx, struct mount *mp)
        }
 
        MAC_PERFORM(mount_label_associate, cred, mp, mp->mnt_mntlabel);
-#if MAC_DEBUG
+#if DEBUG
        printf("MAC Framework enabling %s support: %s -> %s (%s)\n",
                mp->mnt_flag & MNT_MULTILABEL ? "multilabel" : "singlelabel", 
                mp->mnt_vfsstat.f_mntfromname,
@@ -1273,7 +1399,7 @@ vn_setlabel(struct vnode *vp, struct label *intlabel, vfs_context_t context)
 {
        int error;
 
-       if (!mac_vnode_enforce)
+       if (!mac_vnode_enforce || !mac_label_vnodes)
                return (0);
 
        if (vp->v_mount == NULL) {