Forbid user to change file flags on quota files
Forbid user from changing file flags on quota files. User has no bussiness
in playing with these flags when quota is on. Furthermore there is a
remote possibility of deadlock due to a lock inversion between quota file's
i_mutex and transaction's start (i_mutex for quota file is locked only when
trasaction is started in quota operations) in ext3 and ext4.
Signed-off-by: Jan Kara <jack@suse.cz>
Cc: LIOU Payphone <lioupayphone@gmail.com>
Cc: <linux-ext4@vger.kernel.org>
Acked-by: Dave Kleikamp <shaggy@austin.ibm.com>
Cc: <reiserfs-dev@namesys.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index c2324d5..320b2cb 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -47,6 +47,11 @@
flags &= ~EXT2_DIRSYNC_FL;
mutex_lock(&inode->i_mutex);
+ /* Is it quota file? Do not allow user to mess with it */
+ if (IS_NOQUOTA(inode)) {
+ mutex_unlock(&inode->i_mutex);
+ return -EPERM;
+ }
oldflags = ei->i_flags;
/*
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 4a2a02c..023a070 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -51,6 +51,11 @@
flags &= ~EXT3_DIRSYNC_FL;
mutex_lock(&inode->i_mutex);
+ /* Is it quota file? Do not allow user to mess with it */
+ if (IS_NOQUOTA(inode)) {
+ mutex_unlock(&inode->i_mutex);
+ return -EPERM;
+ }
oldflags = ei->i_flags;
/* The JOURNAL_DATA flag is modifiable only by root */
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index c04c7cc..e7f894b 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -51,6 +51,11 @@
flags &= ~EXT4_DIRSYNC_FL;
mutex_lock(&inode->i_mutex);
+ /* Is it quota file? Do not allow user to mess with it */
+ if (IS_NOQUOTA(inode)) {
+ mutex_unlock(&inode->i_mutex);
+ return -EPERM;
+ }
oldflags = ei->i_flags;
/* The JOURNAL_DATA flag is modifiable only by root */
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c
index 3c8663b..dfda12a 100644
--- a/fs/jfs/ioctl.c
+++ b/fs/jfs/ioctl.c
@@ -79,6 +79,9 @@
if (!S_ISDIR(inode->i_mode))
flags &= ~JFS_DIRSYNC_FL;
+ /* Is it quota file? Do not allow user to mess with it */
+ if (IS_NOQUOTA(inode))
+ return -EPERM;
jfs_get_inode_flags(jfs_inode);
oldflags = jfs_inode->mode2;
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index c438a8f..e0f0f09 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -57,6 +57,9 @@
if (get_user(flags, (int __user *)arg))
return -EFAULT;
+ /* Is it quota file? Do not allow user to mess with it. */
+ if (IS_NOQUOTA(inode))
+ return -EPERM;
if (((flags ^ REISERFS_I(inode)->
i_attrs) & (REISERFS_IMMUTABLE_FL |
REISERFS_APPEND_FL))