add patch fix-inode-checksum-calculation-if-i_extra_size-is-too-small
[ext4-patch-queue.git] / sanity-check-block-and-cluster-size
blobf9f64ac2ff2933512878396a76e2af76202db6ec
1 ext4: sanity check the block and cluster size at mount time
3 If the block size or cluster size is insane, reject the mount.  This
4 is important for security reasons (although we shouldn't be just
5 depending on this check).
7 Ref: http://www.securityfocus.com/archive/1/539661
8 Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1332506
9 Reported-by: Borislav Petkov <bp@alien8.de>
10 Reported-by: Nikolay Borisov <kernel@kyup.com>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
12 Cc: stable@vger.kernel.org
13 ---
14  fs/ext4/ext4.h  |  1 +
15  fs/ext4/super.c | 17 ++++++++++++++++-
16  2 files changed, 17 insertions(+), 1 deletion(-)
18 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
19 index 53d6d463ac4d..bdf1e5ee8642 100644
20 --- a/fs/ext4/ext4.h
21 +++ b/fs/ext4/ext4.h
22 @@ -235,6 +235,7 @@ struct ext4_io_submit {
23  #define        EXT4_MAX_BLOCK_SIZE             65536
24  #define EXT4_MIN_BLOCK_LOG_SIZE                10
25  #define EXT4_MAX_BLOCK_LOG_SIZE                16
26 +#define EXT4_MAX_CLUSTER_LOG_SIZE      30
27  #ifdef __KERNEL__
28  # define EXT4_BLOCK_SIZE(s)            ((s)->s_blocksize)
29  #else
30 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
31 index 35ccbdc2d64e..0f9ae4ce33d6 100644
32 --- a/fs/ext4/super.c
33 +++ b/fs/ext4/super.c
34 @@ -3567,7 +3567,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
35         if (blocksize < EXT4_MIN_BLOCK_SIZE ||
36             blocksize > EXT4_MAX_BLOCK_SIZE) {
37                 ext4_msg(sb, KERN_ERR,
38 -                      "Unsupported filesystem blocksize %d", blocksize);
39 +                      "Unsupported filesystem blocksize %d (%d log_block_size)",
40 +                        blocksize, le32_to_cpu(es->s_log_block_size));
41 +               goto failed_mount;
42 +       }
43 +       if (le32_to_cpu(es->s_log_block_size) >
44 +           (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
45 +               ext4_msg(sb, KERN_ERR,
46 +                        "Invalid log block size: %u",
47 +                        le32_to_cpu(es->s_log_block_size));
48                 goto failed_mount;
49         }
51 @@ -3699,6 +3707,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
52                                  "block size (%d)", clustersize, blocksize);
53                         goto failed_mount;
54                 }
55 +               if (le32_to_cpu(es->s_log_cluster_size) >
56 +                   (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
57 +                       ext4_msg(sb, KERN_ERR,
58 +                                "Invalid log cluster size: %u",
59 +                                le32_to_cpu(es->s_log_cluster_size));
60 +                       goto failed_mount;
61 +               }
62                 sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) -
63                         le32_to_cpu(es->s_log_block_size);
64                 sbi->s_clusters_per_group =