Btrfs: selinux support
Add call to LSM security initialization and save resulting security xattr for new inodes. Add xattr support to symlink inode ops. Set inode->i_op for existing special files. Signed-off-by: jim owens <jowens@hp.com>
This commit is contained in:
parent
bef62ef339
commit
0279b4cd86
|
@ -90,6 +90,16 @@ static noinline int cow_file_range(struct inode *inode,
|
|||
u64 start, u64 end, int *page_started,
|
||||
unsigned long *nr_written, int unlock);
|
||||
|
||||
static int btrfs_init_inode_security(struct inode *inode, struct inode *dir)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = btrfs_init_acl(inode, dir);
|
||||
if (!err)
|
||||
err = btrfs_xattr_security_init(inode, dir);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* a very lame attempt at stopping writes when the FS is 85% full. There
|
||||
* are countless ways this is incorrect, but it is better than nothing.
|
||||
|
@ -2037,6 +2047,7 @@ void btrfs_read_locked_inode(struct inode *inode)
|
|||
inode->i_mapping->backing_dev_info = &root->fs_info->bdi;
|
||||
break;
|
||||
default:
|
||||
inode->i_op = &btrfs_special_inode_operations;
|
||||
init_special_inode(inode, inode->i_mode, rdev);
|
||||
break;
|
||||
}
|
||||
|
@ -3584,7 +3595,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
|
|||
if (IS_ERR(inode))
|
||||
goto out_unlock;
|
||||
|
||||
err = btrfs_init_acl(inode, dir);
|
||||
err = btrfs_init_inode_security(inode, dir);
|
||||
if (err) {
|
||||
drop_inode = 1;
|
||||
goto out_unlock;
|
||||
|
@ -3647,7 +3658,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
|
|||
if (IS_ERR(inode))
|
||||
goto out_unlock;
|
||||
|
||||
err = btrfs_init_acl(inode, dir);
|
||||
err = btrfs_init_inode_security(inode, dir);
|
||||
if (err) {
|
||||
drop_inode = 1;
|
||||
goto out_unlock;
|
||||
|
@ -3770,7 +3781,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
|||
|
||||
drop_on_err = 1;
|
||||
|
||||
err = btrfs_init_acl(inode, dir);
|
||||
err = btrfs_init_inode_security(inode, dir);
|
||||
if (err)
|
||||
goto out_fail;
|
||||
|
||||
|
@ -4732,7 +4743,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|||
if (IS_ERR(inode))
|
||||
goto out_unlock;
|
||||
|
||||
err = btrfs_init_acl(inode, dir);
|
||||
err = btrfs_init_inode_security(inode, dir);
|
||||
if (err) {
|
||||
drop_inode = 1;
|
||||
goto out_unlock;
|
||||
|
@ -5043,4 +5054,8 @@ static struct inode_operations btrfs_symlink_inode_operations = {
|
|||
.follow_link = page_follow_link_light,
|
||||
.put_link = page_put_link,
|
||||
.permission = btrfs_permission,
|
||||
.setxattr = btrfs_setxattr,
|
||||
.getxattr = btrfs_getxattr,
|
||||
.listxattr = btrfs_listxattr,
|
||||
.removexattr = btrfs_removexattr,
|
||||
};
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/xattr.h>
|
||||
#include <linux/security.h>
|
||||
#include "ctree.h"
|
||||
#include "btrfs_inode.h"
|
||||
#include "transaction.h"
|
||||
|
@ -330,3 +331,34 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
|
|||
return -EOPNOTSUPP;
|
||||
return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
|
||||
}
|
||||
|
||||
int btrfs_xattr_security_init(struct inode *inode, struct inode *dir)
|
||||
{
|
||||
int err;
|
||||
size_t len;
|
||||
void *value;
|
||||
char *suffix;
|
||||
char *name;
|
||||
|
||||
err = security_inode_init_security(inode, dir, &suffix, &value, &len);
|
||||
if (err) {
|
||||
if (err == -EOPNOTSUPP)
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
name = kmalloc(XATTR_SECURITY_PREFIX_LEN + strlen(suffix) + 1,
|
||||
GFP_NOFS);
|
||||
if (!name) {
|
||||
err = -ENOMEM;
|
||||
} else {
|
||||
strcpy(name, XATTR_SECURITY_PREFIX);
|
||||
strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
|
||||
err = __btrfs_setxattr(inode, name, value, len, 0);
|
||||
kfree(name);
|
||||
}
|
||||
|
||||
kfree(suffix);
|
||||
kfree(value);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -36,4 +36,6 @@ extern int btrfs_setxattr(struct dentry *dentry, const char *name,
|
|||
const void *value, size_t size, int flags);
|
||||
extern int btrfs_removexattr(struct dentry *dentry, const char *name);
|
||||
|
||||
extern int btrfs_xattr_security_init(struct inode *inode, struct inode *dir);
|
||||
|
||||
#endif /* __XATTR__ */
|
||||
|
|
Loading…
Reference in New Issue