Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Aug 2002 10:28:15 -0700 (PDT)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 16342 for review
Message-ID:  <200208201728.g7KHSEFD078892@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=16342

Change 16342 by rwatson@rwatson_tislabs on 2002/08/20 10:27:18

	Move a chunk of vnode-related label management code to a more
	logical location away from label initialization/destruction/...

Affected files ...

.. //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#255 edit

Differences ...

==== //depot/projects/trustedbsd/mac/sys/kern/kern_mac.c#255 (text+ko) ====

@@ -196,7 +196,6 @@
 #endif
 
 static int	error_select(int error1, int error2);
-static int	mac_externalize(struct label *label, struct mac *mac);
 static int	mac_policy_register(struct mac_policy_conf *mpc);
 static int	mac_policy_unregister(struct mac_policy_conf *mpc);
 
@@ -962,287 +961,6 @@
 	return (error2);
 }
 
-void
-mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
-{
-
-	MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label);
-}
-
-void
-mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
-{
-
-	MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
-}
-
-/*
- * 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 error;
-
-	MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
-	    &mp->mnt_fslabel);
-
-	return (error);
-}
-
-/*
- * Given an externalized mac label, internalize it and stamp it on a
- * vnode.
- */
-static int
-mac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac)
-{
-	int error;
-
-	MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
-
-	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_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;
-}
-
-/*
- * 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)
-{
-	struct vnode *vp = ap->a_vp;
-	struct mac extmac;
-	int buflen, error;
-
-	ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
-
-	/*
-	 * 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)
-		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);
-
-	case EOPNOTSUPP:
-	default:
-		/* Fail horribly. */
-		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);
-		if (mac_debug_label_fallback) {
-			printf(", falling back.\n");
-			mac_update_vnode_from_mount(vp, vp->v_mount);
-			error = 0;
-		} else {
-			printf(".\n");
-			error = EPERM;
-		}
-	}
-
-	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)
-{
-	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.
-
-		mac_update_vnode_deadfs(vp);
-		return (0);
- */
-		/* printf("vn_refreshlabel: null v_mount\n"); */
-		if (vp->v_tag != VT_NON)
-			printf(
-			    "vn_refreshlabel: null v_mount with non-VT_NON\n");
-		return (EBADF);
-	}
-
-	if (vp->v_vflag & VV_CACHEDLABEL) {
-		mac_vnode_label_cache_hits++;
-		return (0);
-	} else
-		mac_vnode_label_cache_misses++;
-
-	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
-		mac_update_vnode_from_mount(vp, vp->v_mount);
-		return (0);
-	}
-
-	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:
-		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 mac 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 = mac_stdcreatevnode_ea(tvp);
-		if (error)
-			return (error);
-
-		/*
-		 * XXX: Eventually this will go away and all policies will
-		 * directly manage their extended attributes.
-		 */
-		error = mac_externalize(&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);
-}
-
-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);
-
-	result = 0;
-	MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
-
-	return (result);
-}
-
 static void
 mac_init_label(struct label *label)
 {
@@ -1584,6 +1302,287 @@
 	MAC_PERFORM(create_cred, parent_cred, child_cred);
 }
 
+void
+mac_update_devfsdirent(struct devfs_dirent *de, struct vnode *vp)
+{
+
+	MAC_PERFORM(update_devfsdirent, de, &de->de_label, vp, &vp->v_label);
+}
+
+void
+mac_update_procfsvnode(struct vnode *vp, struct ucred *cred)
+{
+
+	MAC_PERFORM(update_procfsvnode, vp, &vp->v_label, cred);
+}
+
+/*
+ * 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 error;
+
+	MAC_CHECK(update_vnode_from_extattr, vp, &vp->v_label, mp,
+	    &mp->mnt_fslabel);
+
+	return (error);
+}
+
+/*
+ * Given an externalized mac label, internalize it and stamp it on a
+ * vnode.
+ */
+static int
+mac_update_vnode_from_externalized(struct vnode *vp, struct mac *extmac)
+{
+	int error;
+
+	MAC_CHECK(update_vnode_from_externalized, vp, &vp->v_label, extmac);
+
+	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_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;
+}
+
+/*
+ * 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)
+{
+	struct vnode *vp = ap->a_vp;
+	struct mac extmac;
+	int buflen, error;
+
+	ASSERT_VOP_LOCKED(vp, "vop_stdrefreshlabel_ea");
+
+	/*
+	 * 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)
+		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);
+
+	case EOPNOTSUPP:
+	default:
+		/* Fail horribly. */
+		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);
+		if (mac_debug_label_fallback) {
+			printf(", falling back.\n");
+			mac_update_vnode_from_mount(vp, vp->v_mount);
+			error = 0;
+		} else {
+			printf(".\n");
+			error = EPERM;
+		}
+	}
+
+	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)
+{
+	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.
+
+		mac_update_vnode_deadfs(vp);
+		return (0);
+ */
+		/* printf("vn_refreshlabel: null v_mount\n"); */
+		if (vp->v_tag != VT_NON)
+			printf(
+			    "vn_refreshlabel: null v_mount with non-VT_NON\n");
+		return (EBADF);
+	}
+
+	if (vp->v_vflag & VV_CACHEDLABEL) {
+		mac_vnode_label_cache_hits++;
+		return (0);
+	} else
+		mac_vnode_label_cache_misses++;
+
+	if ((vp->v_mount->mnt_flag & MNT_MULTILABEL) == 0) {
+		mac_update_vnode_from_mount(vp, vp->v_mount);
+		return (0);
+	}
+
+	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:
+		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 mac 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 = mac_stdcreatevnode_ea(tvp);
+		if (error)
+			return (error);
+
+		/*
+		 * XXX: Eventually this will go away and all policies will
+		 * directly manage their extended attributes.
+		 */
+		error = mac_externalize(&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);
+}
+
+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);
+
+	result = 0;
+	MAC_BOOLEAN(execve_will_transition, ||, old, vp, &vp->v_label);
+
+	return (result);
+}
+
 int
 mac_check_vnode_access(struct ucred *cred, struct vnode *vp, int flags)
 {

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208201728.g7KHSEFD078892>