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

Commit 2a7dba39 authored by Eric Paris's avatar Eric Paris
Browse files

fs/vfs/security: pass last path component to LSM on inode creation



SELinux would like to implement a new labeling behavior of newly created
inodes.  We currently label new inodes based on the parent and the creating
process.  This new behavior would also take into account the name of the
new object when deciding the new label.  This is not the (supposed) full path,
just the last component of the path.

This is very useful because creating /etc/shadow is different than creating
/etc/passwd but the kernel hooks are unable to differentiate these
operations.  We currently require that userspace realize it is doing some
difficult operation like that and than userspace jumps through SELinux hoops
to get things set up correctly.  This patch does not implement new
behavior, that is obviously contained in a seperate SELinux patch, but it
does pass the needed name down to the correct LSM hook.  If no such name
exists it is fine to pass NULL.

Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent 82140443
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -90,13 +90,14 @@ static noinline int cow_file_range(struct inode *inode,
				   unsigned long *nr_written, int unlock);

static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
				     struct inode *inode,  struct inode *dir)
				     struct inode *inode,  struct inode *dir,
				     const struct qstr *qstr)
{
	int err;

	err = btrfs_init_acl(trans, inode, dir);
	if (!err)
		err = btrfs_xattr_security_init(trans, inode, dir);
		err = btrfs_xattr_security_init(trans, inode, dir, qstr);
	return err;
}

@@ -4675,7 +4676,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
	if (IS_ERR(inode))
		goto out_unlock;

	err = btrfs_init_inode_security(trans, inode, dir);
	err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
	if (err) {
		drop_inode = 1;
		goto out_unlock;
@@ -4736,7 +4737,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
	if (IS_ERR(inode))
		goto out_unlock;

	err = btrfs_init_inode_security(trans, inode, dir);
	err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
	if (err) {
		drop_inode = 1;
		goto out_unlock;
@@ -4864,7 +4865,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)

	drop_on_err = 1;

	err = btrfs_init_inode_security(trans, inode, dir);
	err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
	if (err)
		goto out_fail;

@@ -6946,7 +6947,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
	if (IS_ERR(inode))
		goto out_unlock;

	err = btrfs_init_inode_security(trans, inode, dir);
	err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name);
	if (err) {
		drop_inode = 1;
		goto out_unlock;
+4 −2
Original line number Diff line number Diff line
@@ -352,7 +352,8 @@ int btrfs_removexattr(struct dentry *dentry, const char *name)
}

int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
			      struct inode *inode, struct inode *dir)
			      struct inode *inode, struct inode *dir,
			      const struct qstr *qstr)
{
	int err;
	size_t len;
@@ -360,7 +361,8 @@ int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
	char *suffix;
	char *name;

	err = security_inode_init_security(inode, dir, &suffix, &value, &len);
	err = security_inode_init_security(inode, dir, qstr, &suffix, &value,
					   &len);
	if (err) {
		if (err == -EOPNOTSUPP)
			return 0;
+2 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ extern int btrfs_setxattr(struct dentry *dentry, const char *name,
extern int btrfs_removexattr(struct dentry *dentry, const char *name);

extern int btrfs_xattr_security_init(struct btrfs_trans_handle *trans,
				     struct inode *inode, struct inode *dir);
				     struct inode *inode, struct inode *dir,
				     const struct qstr *qstr);

#endif /* __XATTR__ */
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ extern struct ext2_dir_entry_2 * ext2_dotdot (struct inode *, struct page **);
extern void ext2_set_link(struct inode *, struct ext2_dir_entry_2 *, struct page *, struct inode *, int);

/* ialloc.c */
extern struct inode * ext2_new_inode (struct inode *, int);
extern struct inode * ext2_new_inode (struct inode *, int, const struct qstr *);
extern void ext2_free_inode (struct inode *);
extern unsigned long ext2_count_free_inodes (struct super_block *);
extern void ext2_check_inodes_bitmap (struct super_block *);
+3 −2
Original line number Diff line number Diff line
@@ -429,7 +429,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent)
	return group;
}

struct inode *ext2_new_inode(struct inode *dir, int mode)
struct inode *ext2_new_inode(struct inode *dir, int mode,
			     const struct qstr *qstr)
{
	struct super_block *sb;
	struct buffer_head *bitmap_bh = NULL;
@@ -585,7 +586,7 @@ struct inode *ext2_new_inode(struct inode *dir, int mode)
	if (err)
		goto fail_free_drop;

	err = ext2_init_security(inode,dir);
	err = ext2_init_security(inode, dir, qstr);
	if (err)
		goto fail_free_drop;

Loading