1 ext4: fix hang when processing corrupted orphaned inode list
3 If the orphaned inode list contains inode #5, ext4_iget() returns a
4 bad inode (since the bootloader inode should never be referenced
5 directly). Because of the bad inode, we end up processing the inode
6 repeatedly and this hangs the machine.
8 This can be reproduced via:
10 mke2fs -t ext4 /tmp/foo.img 100
11 debugfs -w -R "ssv last_orphan 5" /tmp/foo.img
12 mount -o loop /tmp/foo.img /mnt
14 (But don't do this if you are using an unpatched kernel if you care
15 about the system staying functional. :-)
17 This bug was found by the port of American Fuzzy Lop into the kernel
18 to find file system problems[1]. (Since it *only* happens if inode #5
19 shows up on the orphan list --- 3, 7, 8, etc. won't do it, it's not
20 surprising that AFL needed two hours before it found it.)
22 [1] http://events.linuxfoundation.org/sites/events/files/slides/AFL%20filesystem%20fuzzing%2C%20Vault%202016_0.pdf
24 Cc: stable@vger.kernel.org
25 Reported by: Vegard Nossum <vegard.nossum@oracle.com>
26 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
28 fs/ext4/ialloc.c | 10 ++++++----
29 1 file changed, 6 insertions(+), 4 deletions(-)
31 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
32 index 237b877..c2caf2d 100644
33 --- a/fs/ext4/ialloc.c
34 +++ b/fs/ext4/ialloc.c
35 @@ -1183,11 +1183,13 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
39 - * If the orphans has i_nlinks > 0 then it should be able to be
40 - * truncated, otherwise it won't be removed from the orphan list
41 - * during processing and an infinite loop will result.
42 + * If the orphans has i_nlinks > 0 then it should be able to
43 + * be truncated, otherwise it won't be removed from the orphan
44 + * list during processing and an infinite loop will result.
45 + * Similarly, it must not be a bad inode.
47 - if (inode->i_nlink && !ext4_can_truncate(inode))
48 + if ((inode->i_nlink && !ext4_can_truncate(inode)) ||
49 + is_bad_inode(inode))
52 if (NEXT_ORPHAN(inode) > max_ino)