summaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorGoldwyn Rodrigues <rgoldwyn@suse.de>2022-08-16 16:42:56 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-09-05 10:26:31 +0200
commit41d5e986e7553b7ec2c80f0d356d74a60f2c9d57 (patch)
tree60a6e1f3e6acd53eaff7c4c432a0c957934a8c5c /fs/btrfs
parent38a66dc9be858400477ae80fcad1ae950a105e8b (diff)
downloadlinux-stable-41d5e986e7553b7ec2c80f0d356d74a60f2c9d57.tar.gz
linux-stable-41d5e986e7553b7ec2c80f0d356d74a60f2c9d57.tar.bz2
linux-stable-41d5e986e7553b7ec2c80f0d356d74a60f2c9d57.zip
btrfs: check if root is readonly while setting security xattr
commit b51111271b0352aa596c5ae8faf06939e91b3b68 upstream. For a filesystem which has btrfs read-only property set to true, all write operations including xattr should be denied. However, security xattr can still be changed even if btrfs ro property is true. This happens because xattr_permission() does not have any restrictions on security.*, system.* and in some cases trusted.* from VFS and the decision is left to the underlying filesystem. See comments in xattr_permission() for more details. This patch checks if the root is read-only before performing the set xattr operation. Testcase: DEV=/dev/vdb MNT=/mnt mkfs.btrfs -f $DEV mount $DEV $MNT echo "file one" > $MNT/f1 setfattr -n "security.one" -v 2 $MNT/f1 btrfs property set /mnt ro true setfattr -n "security.one" -v 1 $MNT/f1 umount $MNT CC: stable@vger.kernel.org # 4.9+ Reviewed-by: Qu Wenruo <wqu@suse.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/xattr.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index f141b45ce349..6adee94637a9 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -369,6 +369,9 @@ static int btrfs_xattr_handler_set(const struct xattr_handler *handler,
const char *name, const void *buffer,
size_t size, int flags)
{
+ if (btrfs_root_readonly(BTRFS_I(inode)->root))
+ return -EROFS;
+
name = xattr_full_name(handler, name);
return btrfs_setxattr(NULL, inode, name, buffer, size, flags);
}