Add patches to fix kernel crashes on corrupted file systems
[ext4-patch-queue.git] / dont-truncate-or-orphan-boot-inode
blob82452432dce599e675fc8f027591cc5eda89fc7d
1 ext4: don't orphan or truncate the boot loader inode
3 The boot loader inode (inode #5) should never be visible in the
4 directory hierarchy, but it's possible if the file system is corrupted
5 that there will be a directory entry that points at inode #5.  In
6 order to avoid accidentally trashing it, when such a directory inode
7 is opened, the inode will be marked as a bad inode, so that it's not
8 possible to modify (or read) the inode from userspace.
10 Unfortunately, when we unlink this (invalid/illegal) directory entry,
11 we will put the bad inode on the ophan list, and then when try to
12 unlink the directory, we don't actually remove the bad inode from the
13 orphan list before freeing in-memory inode structure.  This means the
14 in-memory orphan list is corrupted, leading to a kernel oops.
16 In addition, avoid truncating a bad inode in ext4_destroy_inode(),
17 since truncating the boot loader inode is not a smart thing to do.
19 Reported-by: Sami Liedes <sami.liedes@iki.fi>
20 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
21 Cc: stable@vger.kernel.org
22 ---
23  fs/ext4/inode.c | 7 +++----
24  fs/ext4/namei.c | 2 +-
25  2 files changed, 4 insertions(+), 5 deletions(-)
27 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
28 index 41c4f97..59983b2 100644
29 --- a/fs/ext4/inode.c
30 +++ b/fs/ext4/inode.c
31 @@ -224,16 +224,15 @@ void ext4_evict_inode(struct inode *inode)
32                 goto no_delete;
33         }
35 -       if (!is_bad_inode(inode))
36 -               dquot_initialize(inode);
37 +       if (is_bad_inode(inode))
38 +               goto no_delete;
39 +       dquot_initialize(inode);
41         if (ext4_should_order_data(inode))
42                 ext4_begin_ordered_truncate(inode, 0);
43         truncate_inode_pages_final(&inode->i_data);
45         WARN_ON(atomic_read(&EXT4_I(inode)->i_ioend_count));
46 -       if (is_bad_inode(inode))
47 -               goto no_delete;
49         /*
50          * Protect us against freezing - iput() caller didn't have to have any
51 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
52 index 51705f8..a2a9d40 100644
53 --- a/fs/ext4/namei.c
54 +++ b/fs/ext4/namei.c
55 @@ -2544,7 +2544,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
56         int err = 0, rc;
57         bool dirty = false;
59 -       if (!sbi->s_journal)
60 +       if (!sbi->s_journal || is_bad_inode(inode))
61                 return 0;
63         WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) &&