Commit 0279b4cd authored by Jim Owens's avatar Jim Owens Committed by Chris Mason

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: default avatarjim owens <jowens@hp.com>
parent bef62ef3
...@@ -90,6 +90,16 @@ static noinline int cow_file_range(struct inode *inode, ...@@ -90,6 +90,16 @@ static noinline int cow_file_range(struct inode *inode,
u64 start, u64 end, int *page_started, u64 start, u64 end, int *page_started,
unsigned long *nr_written, int unlock); 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 * 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. * are countless ways this is incorrect, but it is better than nothing.
...@@ -2037,6 +2047,7 @@ void btrfs_read_locked_inode(struct inode *inode) ...@@ -2037,6 +2047,7 @@ void btrfs_read_locked_inode(struct inode *inode)
inode->i_mapping->backing_dev_info = &root->fs_info->bdi; inode->i_mapping->backing_dev_info = &root->fs_info->bdi;
break; break;
default: default:
inode->i_op = &btrfs_special_inode_operations;
init_special_inode(inode, inode->i_mode, rdev); init_special_inode(inode, inode->i_mode, rdev);
break; break;
} }
...@@ -3584,7 +3595,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, ...@@ -3584,7 +3595,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
if (IS_ERR(inode)) if (IS_ERR(inode))
goto out_unlock; goto out_unlock;
err = btrfs_init_acl(inode, dir); err = btrfs_init_inode_security(inode, dir);
if (err) { if (err) {
drop_inode = 1; drop_inode = 1;
goto out_unlock; goto out_unlock;
...@@ -3647,7 +3658,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, ...@@ -3647,7 +3658,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
if (IS_ERR(inode)) if (IS_ERR(inode))
goto out_unlock; goto out_unlock;
err = btrfs_init_acl(inode, dir); err = btrfs_init_inode_security(inode, dir);
if (err) { if (err) {
drop_inode = 1; drop_inode = 1;
goto out_unlock; goto out_unlock;
...@@ -3770,7 +3781,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -3770,7 +3781,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
drop_on_err = 1; drop_on_err = 1;
err = btrfs_init_acl(inode, dir); err = btrfs_init_inode_security(inode, dir);
if (err) if (err)
goto out_fail; goto out_fail;
...@@ -4732,7 +4743,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, ...@@ -4732,7 +4743,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
if (IS_ERR(inode)) if (IS_ERR(inode))
goto out_unlock; goto out_unlock;
err = btrfs_init_acl(inode, dir); err = btrfs_init_inode_security(inode, dir);
if (err) { if (err) {
drop_inode = 1; drop_inode = 1;
goto out_unlock; goto out_unlock;
...@@ -5043,4 +5054,8 @@ static struct inode_operations btrfs_symlink_inode_operations = { ...@@ -5043,4 +5054,8 @@ static struct inode_operations btrfs_symlink_inode_operations = {
.follow_link = page_follow_link_light, .follow_link = page_follow_link_light,
.put_link = page_put_link, .put_link = page_put_link,
.permission = btrfs_permission, .permission = btrfs_permission,
.setxattr = btrfs_setxattr,
.getxattr = btrfs_getxattr,
.listxattr = btrfs_listxattr,
.removexattr = btrfs_removexattr,
}; };
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/xattr.h> #include <linux/xattr.h>
#include <linux/security.h>
#include "ctree.h" #include "ctree.h"
#include "btrfs_inode.h" #include "btrfs_inode.h"
#include "transaction.h" #include "transaction.h"
...@@ -330,3 +331,34 @@ int btrfs_removexattr(struct dentry *dentry, const char *name) ...@@ -330,3 +331,34 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return __btrfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); 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, ...@@ -36,4 +36,6 @@ extern int btrfs_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags); const void *value, size_t size, int flags);
extern int btrfs_removexattr(struct dentry *dentry, const char *name); extern int btrfs_removexattr(struct dentry *dentry, const char *name);
extern int btrfs_xattr_security_init(struct inode *inode, struct inode *dir);
#endif /* __XATTR__ */ #endif /* __XATTR__ */
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