]>
Commit | Line | Data |
---|---|---|
adb53c40 GKH |
1 | From c9eb13a9105e2e418f72e46a2b6da3f49e696902 Mon Sep 17 00:00:00 2001 |
2 | From: Theodore Ts'o <tytso@mit.edu> | |
3 | Date: Sat, 30 Apr 2016 00:48:54 -0400 | |
4 | Subject: ext4: fix hang when processing corrupted orphaned inode list | |
5 | ||
6 | From: Theodore Ts'o <tytso@mit.edu> | |
7 | ||
8 | commit c9eb13a9105e2e418f72e46a2b6da3f49e696902 upstream. | |
9 | ||
10 | If the orphaned inode list contains inode #5, ext4_iget() returns a | |
11 | bad inode (since the bootloader inode should never be referenced | |
12 | directly). Because of the bad inode, we end up processing the inode | |
13 | repeatedly and this hangs the machine. | |
14 | ||
15 | This can be reproduced via: | |
16 | ||
17 | mke2fs -t ext4 /tmp/foo.img 100 | |
18 | debugfs -w -R "ssv last_orphan 5" /tmp/foo.img | |
19 | mount -o loop /tmp/foo.img /mnt | |
20 | ||
21 | (But don't do this if you are using an unpatched kernel if you care | |
22 | about the system staying functional. :-) | |
23 | ||
24 | This bug was found by the port of American Fuzzy Lop into the kernel | |
25 | to find file system problems[1]. (Since it *only* happens if inode #5 | |
26 | shows up on the orphan list --- 3, 7, 8, etc. won't do it, it's not | |
27 | surprising that AFL needed two hours before it found it.) | |
28 | ||
29 | [1] http://events.linuxfoundation.org/sites/events/files/slides/AFL%20filesystem%20fuzzing%2C%20Vault%202016_0.pdf | |
30 | ||
31 | Reported by: Vegard Nossum <vegard.nossum@oracle.com> | |
32 | Signed-off-by: Theodore Ts'o <tytso@mit.edu> | |
33 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
34 | ||
35 | --- | |
36 | fs/ext4/ialloc.c | 10 ++++++---- | |
37 | 1 file changed, 6 insertions(+), 4 deletions(-) | |
38 | ||
39 | --- a/fs/ext4/ialloc.c | |
40 | +++ b/fs/ext4/ialloc.c | |
41 | @@ -1176,11 +1176,13 @@ struct inode *ext4_orphan_get(struct sup | |
42 | goto iget_failed; | |
43 | ||
44 | /* | |
45 | - * If the orphans has i_nlinks > 0 then it should be able to be | |
46 | - * truncated, otherwise it won't be removed from the orphan list | |
47 | - * during processing and an infinite loop will result. | |
48 | + * If the orphans has i_nlinks > 0 then it should be able to | |
49 | + * be truncated, otherwise it won't be removed from the orphan | |
50 | + * list during processing and an infinite loop will result. | |
51 | + * Similarly, it must not be a bad inode. | |
52 | */ | |
53 | - if (inode->i_nlink && !ext4_can_truncate(inode)) | |
54 | + if ((inode->i_nlink && !ext4_can_truncate(inode)) || | |
55 | + is_bad_inode(inode)) | |
56 | goto bad_orphan; | |
57 | ||
58 | if (NEXT_ORPHAN(inode) > max_ino) |