diff options
author | Andreas Wellving <andreas.wellving@enea.com> | 2018-10-12 14:03:30 +0200 |
---|---|---|
committer | Adrian Dudau <Adrian.Dudau@enea.com> | 2018-10-16 17:38:50 +0200 |
commit | 71432d8efa1925bc5d239848cd8810eb8dc1f80a (patch) | |
tree | c9af906d5f0affda8b07c84b3b9f905e4f059930 | |
parent | 84546865e1800e1cd60af0427b45481bc794a7f3 (diff) | |
download | enea-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.scc | 3 | ||||
-rw-r--r-- | patches/cve/CVE-2018-10876-ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch | 135 |
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: |
27 | patch CVE-2018-9518-NFC-llcp-Limit-size-of-SDP-URI.patch | 27 | patch CVE-2018-9518-NFC-llcp-Limit-size-of-SDP-URI.patch |
28 | |||
29 | #CVEs fixed in 4.9.112: | ||
30 | patch 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 @@ | |||
1 | Date: Fri, 12 Oct 2018 13:56:16 +0200 | ||
2 | Subject: [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 | |||
7 | Also block group #0 must never have uninitialized allocation bitmaps, | ||
8 | or need to be zeroed, since that's where the root inode, and other | ||
9 | special inodes are set up. Check for these conditions and mark the | ||
10 | file system as corrupted if they are detected. | ||
11 | |||
12 | This addresses CVE-2018-10876. | ||
13 | Upstream-Status: Backport | ||
14 | |||
15 | https://bugzilla.kernel.org/show_bug.cgi?id=199403 | ||
16 | |||
17 | Signed-off-by: Theodore Ts'o <tytso@mit.edu> | ||
18 | Cc: stable@kernel.org | ||
19 | Signed-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 | |||
27 | diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c | ||
28 | index 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); | ||
49 | diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c | ||
50 | index 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)); | ||
81 | diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c | ||
82 | index 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, | ||
105 | diff --git a/fs/ext4/super.c b/fs/ext4/super.c | ||
106 | index 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 | |||