Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+19 −4
Original line number Original line Diff line number Diff line
@@ -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)
		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,
	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,
	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)


	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,
	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 = {
	.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,
};
};
+32 −0
Original line number Original line Diff line number Diff line
@@ -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)
		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;
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -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__ */