summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Wellving <andreas.wellving@enea.com>2018-10-12 14:03:30 +0200
committerAdrian Dudau <Adrian.Dudau@enea.com>2018-10-16 17:38:50 +0200
commit71432d8efa1925bc5d239848cd8810eb8dc1f80a (patch)
treec9af906d5f0affda8b07c84b3b9f905e4f059930
parent84546865e1800e1cd60af0427b45481bc794a7f3 (diff)
downloadenea-kernel-cache-71432d8efa1925bc5d239848cd8810eb8dc1f80a.tar.gz
ext4: CVE-2018-10876
ext4: only look at the bg_flags field if it is valid References: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8844618d8aa7a9973e7b527d038a2a589665002c Change-Id: If6d5ecfd74acafe75c6e6f4919f44127cfc7baa7 Signed-off-by: Andreas Wellving <andreas.wellving@enea.com>
-rw-r--r--patches/cve/4.9.x.scc3
-rw-r--r--patches/cve/CVE-2018-10876-ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch135
2 files changed, 138 insertions, 0 deletions
diff --git a/patches/cve/4.9.x.scc b/patches/cve/4.9.x.scc
index f7429aa..959c87b 100644
--- a/patches/cve/4.9.x.scc
+++ b/patches/cve/4.9.x.scc
@@ -25,3 +25,6 @@ patch CVE-2017-18255-perf-core-Fix-the-perf_cpu_time_max_percent-check.patch
25 25
26#CVEs fixed in 4.9.104: 26#CVEs fixed in 4.9.104:
27patch CVE-2018-9518-NFC-llcp-Limit-size-of-SDP-URI.patch 27patch CVE-2018-9518-NFC-llcp-Limit-size-of-SDP-URI.patch
28
29#CVEs fixed in 4.9.112:
30patch CVE-2018-10876-ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
diff --git a/patches/cve/CVE-2018-10876-ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch b/patches/cve/CVE-2018-10876-ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
new file mode 100644
index 0000000..fe172e6
--- /dev/null
+++ b/patches/cve/CVE-2018-10876-ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
@@ -0,0 +1,135 @@
1Date: Fri, 12 Oct 2018 13:56:16 +0200
2Subject: [PATCH] ext4: only look at the bg_flags field if it is valid The
3 bg_flags field in the block group descripts is only valid if the uninit_bg or
4 metadata_csum feature is enabled. We were not consistently looking at this
5 field; fix this.
6
7Also block group #0 must never have uninitialized allocation bitmaps,
8or need to be zeroed, since that's where the root inode, and other
9special inodes are set up. Check for these conditions and mark the
10file system as corrupted if they are detected.
11
12This addresses CVE-2018-10876.
13Upstream-Status: Backport
14
15https://bugzilla.kernel.org/show_bug.cgi?id=199403
16
17Signed-off-by: Theodore Ts'o <tytso@mit.edu>
18Cc: stable@kernel.org
19Signed-off-by: Andreas Wellving <andreas.wellving@enea.com>
20---
21 fs/ext4/balloc.c | 11 ++++++++++-
22 fs/ext4/ialloc.c | 14 ++++++++++++--
23 fs/ext4/mballoc.c | 6 ++++--
24 fs/ext4/super.c | 11 ++++++++++-
25 4 files changed, 36 insertions(+), 6 deletions(-)
26
27diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
28index e04ec86..10e18f7 100644
29--- a/fs/ext4/balloc.c
30+++ b/fs/ext4/balloc.c
31@@ -443,7 +443,16 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
32 goto verify;
33 }
34 ext4_lock_group(sb, block_group);
35- if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
36+ if (ext4_has_group_desc_csum(sb) &&
37+ (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
38+ if (block_group == 0) {
39+ ext4_unlock_group(sb, block_group);
40+ unlock_buffer(bh);
41+ ext4_error(sb, "Block bitmap for bg 0 marked "
42+ "uninitialized");
43+ err = -EFSCORRUPTED;
44+ goto out;
45+ }
46 err = ext4_init_block_bitmap(sb, bh, block_group, desc);
47 set_bitmap_uptodate(bh);
48 set_buffer_uptodate(bh);
49diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
50index 2d94e85..e937aad 100644
51--- a/fs/ext4/ialloc.c
52+++ b/fs/ext4/ialloc.c
53@@ -183,7 +183,16 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
54 }
55
56 ext4_lock_group(sb, block_group);
57- if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
58+ if (ext4_has_group_desc_csum(sb) &&
59+ (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) {
60+ if (block_group == 0) {
61+ ext4_unlock_group(sb, block_group);
62+ unlock_buffer(bh);
63+ ext4_error(sb, "Inode bitmap for bg 0 marked "
64+ "uninitialized");
65+ err = -EFSCORRUPTED;
66+ goto out;
67+ }
68 err = ext4_init_inode_bitmap(sb, bh, block_group, desc);
69 set_bitmap_uptodate(bh);
70 set_buffer_uptodate(bh);
71@@ -960,7 +969,8 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
72
73 /* recheck and clear flag under lock if we still need to */
74 ext4_lock_group(sb, group);
75- if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
76+ if (ext4_has_group_desc_csum(sb) &&
77+ (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
78 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
79 ext4_free_group_clusters_set(sb, gdp,
80 ext4_free_clusters_after_init(sb, group, gdp));
81diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
82index 64056c6..4869946 100644
83--- a/fs/ext4/mballoc.c
84+++ b/fs/ext4/mballoc.c
85@@ -2444,7 +2444,8 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
86 * initialize bb_free to be able to skip
87 * empty groups without initialization
88 */
89- if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
90+ if (ext4_has_group_desc_csum(sb) &&
91+ (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
92 meta_group_info[i]->bb_free =
93 ext4_free_clusters_after_init(sb, group, desc);
94 } else {
95@@ -2969,7 +2970,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
96 #endif
97 ext4_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,
98 ac->ac_b_ex.fe_len);
99- if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
100+ if (ext4_has_group_desc_csum(sb) &&
101+ (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
102 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
103 ext4_free_group_clusters_set(sb, gdp,
104 ext4_free_clusters_after_init(sb,
105diff --git a/fs/ext4/super.c b/fs/ext4/super.c
106index 1f58179..97d322b 100644
107--- a/fs/ext4/super.c
108+++ b/fs/ext4/super.c
109@@ -2991,13 +2991,22 @@ static ext4_group_t ext4_has_uninit_itable(struct super_block *sb)
110 ext4_group_t group, ngroups = EXT4_SB(sb)->s_groups_count;
111 struct ext4_group_desc *gdp = NULL;
112
113+ if (!ext4_has_group_desc_csum(sb))
114+ return ngroups;
115+
116 for (group = 0; group < ngroups; group++) {
117 gdp = ext4_get_group_desc(sb, group, NULL);
118 if (!gdp)
119 continue;
120
121- if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)))
122+ if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))
123+ continue;
124+ if (group != 0)
125 break;
126+ ext4_error(sb, "Inode table for bg 0 marked as "
127+ "needing zeroing");
128+ if (sb_rdonly(sb))
129+ return ngroups;
130 }
131
132 return group;
133--
134
135