]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/5.0.18/ext4-fix-use-after-free-race-with-debug_want_extra_isize.patch
Linux 5.0.18
[thirdparty/kernel/stable-queue.git] / releases / 5.0.18 / ext4-fix-use-after-free-race-with-debug_want_extra_isize.patch
CommitLineData
21f93658
GKH
1From 7bc04c5c2cc467c5b40f2b03ba08da174a0d5fa7 Mon Sep 17 00:00:00 2001
2From: Barret Rhoden <brho@google.com>
3Date: Thu, 25 Apr 2019 11:55:50 -0400
4Subject: ext4: fix use-after-free race with debug_want_extra_isize
5
6From: Barret Rhoden <brho@google.com>
7
8commit 7bc04c5c2cc467c5b40f2b03ba08da174a0d5fa7 upstream.
9
10When remounting with debug_want_extra_isize, we were not performing the
11same checks that we do during a normal mount. That allowed us to set a
12value for s_want_extra_isize that reached outside the s_inode_size.
13
14Fixes: e2b911c53584 ("ext4: clean up feature test macros with predicate functions")
15Reported-by: syzbot+f584efa0ac7213c226b7@syzkaller.appspotmail.com
16Reviewed-by: Jan Kara <jack@suse.cz>
17Signed-off-by: Barret Rhoden <brho@google.com>
18Signed-off-by: Theodore Ts'o <tytso@mit.edu>
19Cc: stable@vger.kernel.org
20Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
21
22---
23 fs/ext4/super.c | 58 ++++++++++++++++++++++++++++++++------------------------
24 1 file changed, 34 insertions(+), 24 deletions(-)
25
26--- a/fs/ext4/super.c
27+++ b/fs/ext4/super.c
28@@ -3514,6 +3514,37 @@ int ext4_calculate_overhead(struct super
29 return 0;
30 }
31
32+static void ext4_clamp_want_extra_isize(struct super_block *sb)
33+{
34+ struct ext4_sb_info *sbi = EXT4_SB(sb);
35+ struct ext4_super_block *es = sbi->s_es;
36+
37+ /* determine the minimum size of new large inodes, if present */
38+ if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE &&
39+ sbi->s_want_extra_isize == 0) {
40+ sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
41+ EXT4_GOOD_OLD_INODE_SIZE;
42+ if (ext4_has_feature_extra_isize(sb)) {
43+ if (sbi->s_want_extra_isize <
44+ le16_to_cpu(es->s_want_extra_isize))
45+ sbi->s_want_extra_isize =
46+ le16_to_cpu(es->s_want_extra_isize);
47+ if (sbi->s_want_extra_isize <
48+ le16_to_cpu(es->s_min_extra_isize))
49+ sbi->s_want_extra_isize =
50+ le16_to_cpu(es->s_min_extra_isize);
51+ }
52+ }
53+ /* Check if enough inode space is available */
54+ if (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize >
55+ sbi->s_inode_size) {
56+ sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
57+ EXT4_GOOD_OLD_INODE_SIZE;
58+ ext4_msg(sb, KERN_INFO,
59+ "required extra inode space not available");
60+ }
61+}
62+
63 static void ext4_set_resv_clusters(struct super_block *sb)
64 {
65 ext4_fsblk_t resv_clusters;
66@@ -4388,30 +4419,7 @@ no_journal:
67 } else if (ret)
68 goto failed_mount4a;
69
70- /* determine the minimum size of new large inodes, if present */
71- if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE &&
72- sbi->s_want_extra_isize == 0) {
73- sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
74- EXT4_GOOD_OLD_INODE_SIZE;
75- if (ext4_has_feature_extra_isize(sb)) {
76- if (sbi->s_want_extra_isize <
77- le16_to_cpu(es->s_want_extra_isize))
78- sbi->s_want_extra_isize =
79- le16_to_cpu(es->s_want_extra_isize);
80- if (sbi->s_want_extra_isize <
81- le16_to_cpu(es->s_min_extra_isize))
82- sbi->s_want_extra_isize =
83- le16_to_cpu(es->s_min_extra_isize);
84- }
85- }
86- /* Check if enough inode space is available */
87- if (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize >
88- sbi->s_inode_size) {
89- sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
90- EXT4_GOOD_OLD_INODE_SIZE;
91- ext4_msg(sb, KERN_INFO, "required extra inode space not"
92- "available");
93- }
94+ ext4_clamp_want_extra_isize(sb);
95
96 ext4_set_resv_clusters(sb);
97
98@@ -5195,6 +5203,8 @@ static int ext4_remount(struct super_blo
99 goto restore_opts;
100 }
101
102+ ext4_clamp_want_extra_isize(sb);
103+
104 if ((old_opts.s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) ^
105 test_opt(sb, JOURNAL_CHECKSUM)) {
106 ext4_msg(sb, KERN_ERR, "changing journal_checksum "