
From: Stephen Smalley <sds@epoch.ncsc.mil>

This patch against 2.5.69 adds a security_inode_post_setxattr hook so that
security modules can update the inode security structure after a successful
setxattr, and it moves the existing security_inode_setxattr hook call after
the taking the inode semaphore so that atomicity is provided for the
security check and the update to the inode security structure.



 25-akpm/fs/xattr.c               |    7 ++++---
 25-akpm/include/linux/security.h |   15 +++++++++++++++
 25-akpm/security/dummy.c         |    6 ++++++
 3 files changed, 25 insertions(+), 3 deletions(-)

diff -puN fs/xattr.c~lsm-setxattr-changes fs/xattr.c
--- 25/fs/xattr.c~lsm-setxattr-changes	Tue May  6 14:02:55 2003
+++ 25-akpm/fs/xattr.c	Tue May  6 14:02:55 2003
@@ -79,15 +79,16 @@ setxattr(struct dentry *d, char *name, v
 
 	error = -EOPNOTSUPP;
 	if (d->d_inode->i_op && d->d_inode->i_op->setxattr) {
+		down(&d->d_inode->i_sem);
 		error = security_inode_setxattr(d, kname, kvalue, size, flags);
 		if (error)
 			goto out;
-		down(&d->d_inode->i_sem);
 		error = d->d_inode->i_op->setxattr(d, kname, kvalue, size, flags);
+		if (!error)
+			security_inode_post_setxattr(d, kname, kvalue, size, flags);
+out:
 		up(&d->d_inode->i_sem);
 	}
-
-out:
 	xattr_free(kvalue, size);
 	return error;
 }
diff -puN include/linux/security.h~lsm-setxattr-changes include/linux/security.h
--- 25/include/linux/security.h~lsm-setxattr-changes	Tue May  6 14:02:55 2003
+++ 25-akpm/include/linux/security.h	Tue May  6 14:02:55 2003
@@ -361,6 +361,9 @@ struct swap_info_struct;
  * 	Check permission before setting the extended attributes
  * 	@value identified by @name for @dentry.
  * 	Return 0 if permission is granted.
+ * @inode_post_setxattr:
+ * 	Update inode security field after successful setxattr operation.
+ * 	@value identified by @name for @dentry.
  * @inode_getxattr:
  * 	Check permission before obtaining the extended attributes
  * 	identified by @name for @dentry.
@@ -1036,6 +1039,8 @@ struct security_operations {
         void (*inode_delete) (struct inode *inode);
 	int (*inode_setxattr) (struct dentry *dentry, char *name, void *value,
 			       size_t size, int flags);
+	void (*inode_post_setxattr) (struct dentry *dentry, char *name, void *value,
+				     size_t size, int flags);
 	int (*inode_getxattr) (struct dentry *dentry, char *name);
 	int (*inode_listxattr) (struct dentry *dentry);
 	int (*inode_removexattr) (struct dentry *dentry, char *name);
@@ -1464,6 +1469,12 @@ static inline int security_inode_setxatt
 	return security_ops->inode_setxattr (dentry, name, value, size, flags);
 }
 
+static inline void security_inode_post_setxattr (struct dentry *dentry, char *name,
+						void *value, size_t size, int flags)
+{
+	security_ops->inode_post_setxattr (dentry, name, value, size, flags);
+}
+
 static inline int security_inode_getxattr (struct dentry *dentry, char *name)
 {
 	return security_ops->inode_getxattr (dentry, name);
@@ -2063,6 +2074,10 @@ static inline int security_inode_setxatt
 	return 0;
 }
 
+static inline void security_inode_post_setxattr (struct dentry *dentry, char *name,
+						 void *value, size_t size, int flags)
+{ }
+
 static inline int security_inode_getxattr (struct dentry *dentry, char *name)
 {
 	return 0;
diff -puN security/dummy.c~lsm-setxattr-changes security/dummy.c
--- 25/security/dummy.c~lsm-setxattr-changes	Tue May  6 14:02:55 2003
+++ 25-akpm/security/dummy.c	Tue May  6 14:02:55 2003
@@ -334,6 +334,11 @@ static int dummy_inode_setxattr (struct 
 	return 0;
 }
 
+static void dummy_inode_post_setxattr (struct dentry *dentry, char *name, void *value,
+				       size_t size, int flags)
+{
+}
+
 static int dummy_inode_getxattr (struct dentry *dentry, char *name)
 {
 	return 0;
@@ -803,6 +808,7 @@ void security_fixup_ops (struct security
 	set_to_dummy_if_null(ops, inode_getattr);
 	set_to_dummy_if_null(ops, inode_delete);
 	set_to_dummy_if_null(ops, inode_setxattr);
+	set_to_dummy_if_null(ops, inode_post_setxattr);
 	set_to_dummy_if_null(ops, inode_getxattr);
 	set_to_dummy_if_null(ops, inode_listxattr);
 	set_to_dummy_if_null(ops, inode_removexattr);

_
