Commit 667b93eb authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Change LSM hooks in setxattr

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.
parent 16685211
...@@ -79,15 +79,16 @@ setxattr(struct dentry *d, char *name, void *value, size_t size, int flags) ...@@ -79,15 +79,16 @@ setxattr(struct dentry *d, char *name, void *value, size_t size, int flags)
error = -EOPNOTSUPP; error = -EOPNOTSUPP;
if (d->d_inode->i_op && d->d_inode->i_op->setxattr) { 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); error = security_inode_setxattr(d, kname, kvalue, size, flags);
if (error) if (error)
goto out; goto out;
down(&d->d_inode->i_sem);
error = d->d_inode->i_op->setxattr(d, kname, kvalue, size, flags); 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); up(&d->d_inode->i_sem);
} }
out:
xattr_free(kvalue, size); xattr_free(kvalue, size);
return error; return error;
} }
......
...@@ -361,6 +361,9 @@ struct swap_info_struct; ...@@ -361,6 +361,9 @@ struct swap_info_struct;
* Check permission before setting the extended attributes * Check permission before setting the extended attributes
* @value identified by @name for @dentry. * @value identified by @name for @dentry.
* Return 0 if permission is granted. * 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: * @inode_getxattr:
* Check permission before obtaining the extended attributes * Check permission before obtaining the extended attributes
* identified by @name for @dentry. * identified by @name for @dentry.
...@@ -1036,6 +1039,8 @@ struct security_operations { ...@@ -1036,6 +1039,8 @@ struct security_operations {
void (*inode_delete) (struct inode *inode); void (*inode_delete) (struct inode *inode);
int (*inode_setxattr) (struct dentry *dentry, char *name, void *value, int (*inode_setxattr) (struct dentry *dentry, char *name, void *value,
size_t size, int flags); 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_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry); int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name); int (*inode_removexattr) (struct dentry *dentry, char *name);
...@@ -1464,6 +1469,12 @@ static inline int security_inode_setxattr (struct dentry *dentry, char *name, ...@@ -1464,6 +1469,12 @@ static inline int security_inode_setxattr (struct dentry *dentry, char *name,
return security_ops->inode_setxattr (dentry, name, value, size, flags); 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) static inline int security_inode_getxattr (struct dentry *dentry, char *name)
{ {
return security_ops->inode_getxattr (dentry, name); return security_ops->inode_getxattr (dentry, name);
...@@ -2063,6 +2074,10 @@ static inline int security_inode_setxattr (struct dentry *dentry, char *name, ...@@ -2063,6 +2074,10 @@ static inline int security_inode_setxattr (struct dentry *dentry, char *name,
return 0; 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) static inline int security_inode_getxattr (struct dentry *dentry, char *name)
{ {
return 0; return 0;
......
...@@ -334,6 +334,11 @@ static int dummy_inode_setxattr (struct dentry *dentry, char *name, void *value, ...@@ -334,6 +334,11 @@ static int dummy_inode_setxattr (struct dentry *dentry, char *name, void *value,
return 0; 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) static int dummy_inode_getxattr (struct dentry *dentry, char *name)
{ {
return 0; return 0;
...@@ -803,6 +808,7 @@ void security_fixup_ops (struct security_operations *ops) ...@@ -803,6 +808,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, inode_getattr); set_to_dummy_if_null(ops, inode_getattr);
set_to_dummy_if_null(ops, inode_delete); set_to_dummy_if_null(ops, inode_delete);
set_to_dummy_if_null(ops, inode_setxattr); 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_getxattr);
set_to_dummy_if_null(ops, inode_listxattr); set_to_dummy_if_null(ops, inode_listxattr);
set_to_dummy_if_null(ops, inode_removexattr); set_to_dummy_if_null(ops, inode_removexattr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment