]>
Commit | Line | Data |
---|---|---|
d033d661 GKH |
1 | From 5b9554dc5bf008ae7f68a52e3d7e76c0920938a2 Mon Sep 17 00:00:00 2001 |
2 | From: Theodore Ts'o <tytso@mit.edu> | |
3 | Date: Tue, 5 Jul 2016 20:01:52 -0400 | |
4 | Subject: ext4: validate s_reserved_gdt_blocks on mount | |
5 | ||
6 | From: Theodore Ts'o <tytso@mit.edu> | |
7 | ||
8 | commit 5b9554dc5bf008ae7f68a52e3d7e76c0920938a2 upstream. | |
9 | ||
10 | If s_reserved_gdt_blocks is extremely large, it's possible for | |
11 | ext4_init_block_bitmap(), which is called when ext4 sets up an | |
12 | uninitialized block bitmap, to corrupt random kernel memory. Add the | |
13 | same checks which e2fsck has --- it must never be larger than | |
14 | blocksize / sizeof(__u32) --- and then add a backup check in | |
15 | ext4_init_block_bitmap() in case the superblock gets modified after | |
16 | the file system is mounted. | |
17 | ||
18 | Reported-by: Vegard Nossum <vegard.nossum@oracle.com> | |
19 | Signed-off-by: Theodore Ts'o <tytso@mit.edu> | |
20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
21 | ||
22 | --- | |
23 | fs/ext4/balloc.c | 3 +++ | |
24 | fs/ext4/super.c | 7 +++++++ | |
25 | 2 files changed, 10 insertions(+) | |
26 | ||
27 | --- a/fs/ext4/balloc.c | |
28 | +++ b/fs/ext4/balloc.c | |
29 | @@ -208,6 +208,9 @@ static int ext4_init_block_bitmap(struct | |
30 | memset(bh->b_data, 0, sb->s_blocksize); | |
31 | ||
32 | bit_max = ext4_num_base_meta_clusters(sb, block_group); | |
33 | + if ((bit_max >> 3) >= bh->b_size) | |
34 | + return -EFSCORRUPTED; | |
35 | + | |
36 | for (bit = 0; bit < bit_max; bit++) | |
37 | ext4_set_bit(bit, bh->b_data); | |
38 | ||
39 | --- a/fs/ext4/super.c | |
40 | +++ b/fs/ext4/super.c | |
41 | @@ -3416,6 +3416,13 @@ static int ext4_fill_super(struct super_ | |
42 | goto failed_mount; | |
43 | } | |
44 | ||
45 | + if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) { | |
46 | + ext4_msg(sb, KERN_ERR, | |
47 | + "Number of reserved GDT blocks insanely large: %d", | |
48 | + le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks)); | |
49 | + goto failed_mount; | |
50 | + } | |
51 | + | |
52 | if (sbi->s_mount_opt & EXT4_MOUNT_DAX) { | |
53 | err = bdev_dax_supported(sb, blocksize); | |
54 | if (err) |