Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1208

kernel-2.6.18-238.el5.src.rpm

From: Eric Paris <eparis@redhat.com>
Date: Thu, 16 Sep 2010 18:27:12 -0400
Subject: [fs] xattr: refactor vfs_setxattr for SELinux hook use
Message-id: <20100916182712.3360.24374.stgit@paris.rdu.redhat.com>
Patchwork-id: 28267
O-Subject: [RHEL5 PATCH -v2 1/3] VFS: Factor out part of vfs_setxattr so it can
	be called from the SELinux hook for inode_setsecctx.
Bugzilla: 582374
RH-Acked-by: Alexander Viro <aviro@redhat.com>

RHBZ 582374
upstream commit b1ab7e4b2a88d3ac13771463be8f302ce1616cfc

version 2: address kabi concerns by not converting char * into const char *
like upstream.

This factors out the part of the vfs_setxattr function that performs the
setting of the xattr and its notification. This is needed so the SELinux
implementation of inode_setsecctx can handle the setting of the xattr while
maintaining the proper separation of layers.

Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>

diff --git a/fs/xattr.c b/fs/xattr.c
index 0e5447f..7060d78 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -62,22 +62,28 @@ xattr_permission(struct inode *inode, const char *name, int mask)
 	return permission(inode, mask, NULL);
 }
 
-int
-vfs_setxattr(struct dentry *dentry, char *name, void *value,
-		size_t size, int flags)
+/**
+ *  __vfs_setxattr_noperm - perform setxattr operation without performing
+ *  permission checks.
+ *
+ *  @dentry - object to perform setxattr on
+ *  @name - xattr name to set
+ *  @value - value to set @name to
+ *  @size - size of @value
+ *  @flags - flags to pass into filesystem operations
+ *
+ *  returns the result of the internal setxattr or setsecurity operations.
+ *
+ *  This function requires the caller to lock the inode's i_mutex before it
+ *  is executed. It also assumes that the caller will make the appropriate
+ *  permission checks.
+ */
+int __vfs_setxattr_noperm(struct dentry *dentry, char *name,
+		void *value, size_t size, int flags)
 {
 	struct inode *inode = dentry->d_inode;
-	int error;
-
-	error = xattr_permission(inode, name, MAY_WRITE);
-	if (error)
-		return error;
+	int error = -EOPNOTSUPP;
 
-	mutex_lock(&inode->i_mutex);
-	error = security_inode_setxattr(dentry, name, value, size, flags);
-	if (error)
-		goto out;
-	error = -EOPNOTSUPP;
 	if (inode->i_op->setxattr) {
 		error = inode->i_op->setxattr(dentry, name, value, size, flags);
 		if (!error) {
@@ -87,12 +93,35 @@ vfs_setxattr(struct dentry *dentry, char *name, void *value,
 		}
 	} else if (!strncmp(name, XATTR_SECURITY_PREFIX,
 				XATTR_SECURITY_PREFIX_LEN)) {
-		const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
+		char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
 		error = security_inode_setsecurity(inode, suffix, value,
 						   size, flags);
 		if (!error)
 			fsnotify_xattr(dentry);
 	}
+
+	return error;
+}
+
+
+int
+vfs_setxattr(struct dentry *dentry, char *name, void *value,
+		size_t size, int flags)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+
+	error = xattr_permission(inode, name, MAY_WRITE);
+	if (error)
+		return error;
+
+	mutex_lock(&inode->i_mutex);
+	error = security_inode_setxattr(dentry, name, value, size, flags);
+	if (error)
+		goto out;
+
+	error = __vfs_setxattr_noperm(dentry, name, value, size, flags);
+
 out:
 	mutex_unlock(&inode->i_mutex);
 	return error;
diff --git a/include/linux/security.h b/include/linux/security.h
index ba252dc..a899161 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1776,7 +1776,7 @@ static inline int security_inode_setxattr (struct dentry *dentry, char *name,
 }
 
 static inline void security_inode_post_setxattr (struct dentry *dentry, char *name,
-						void *value, size_t size, int flags)
+						 void *value, size_t size, int flags)
 {
 	if (unlikely (IS_PRIVATE (dentry->d_inode)))
 		return;
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index cda8a96..d29e9b4 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -41,6 +41,7 @@ struct xattr_handler {
 };
 
 ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
+int __vfs_setxattr_noperm(struct dentry *, char *, void *, size_t, int);
 int vfs_setxattr(struct dentry *, char *, void *, size_t, int);
 int vfs_removexattr(struct dentry *, char *);