aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2012-12-27 01:42:50 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-13 14:51:08 -0700
commit6ac3a550f14a5b4a24417097cd6abcb8c79a0d5a (patch)
tree2f61bae1855b77f99763bda455ce494827536861
parent3609e1162ce723d3269924e95f2663d8bd72a537 (diff)
downloadkernel_samsung_tuna-6ac3a550f14a5b4a24417097cd6abcb8c79a0d5a.zip
kernel_samsung_tuna-6ac3a550f14a5b4a24417097cd6abcb8c79a0d5a.tar.gz
kernel_samsung_tuna-6ac3a550f14a5b4a24417097cd6abcb8c79a0d5a.tar.bz2
ext4: avoid hang when mounting non-journal filesystems with orphan list
commit 0e9a9a1ad619e7e987815d20262d36a2f95717ca upstream. When trying to mount a file system which does not contain a journal, but which does have a orphan list containing an inode which needs to be truncated, the mount call with hang forever in ext4_orphan_cleanup() because ext4_orphan_del() will return immediately without removing the inode from the orphan list, leading to an uninterruptible loop in kernel code which will busy out one of the CPU's on the system. This can be trivially reproduced by trying to mount the file system found in tests/f_orphan_extents_inode/image.gz from the e2fsprogs source tree. If a malicious user were to put this on a USB stick, and mount it on a Linux desktop which has automatic mounts enabled, this could be considered a potential denial of service attack. (Not a big deal in practice, but professional paranoids worry about such things, and have even been known to allocate CVE numbers for such problems.) -js: This is a fix for CVE-2013-2015. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Reviewed-by: Zheng Liu <wenqing.lz@taobao.com> Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/ext4/namei.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 8d3716f..595d087 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2059,7 +2059,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
int err = 0;
/* ext4_handle_valid() assumes a valid handle_t pointer */
- if (handle && !ext4_handle_valid(handle))
+ if (handle && !ext4_handle_valid(handle) &&
+ !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS))
return 0;
mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock);