aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2016-11-18 13:00:24 -0500
committerTheodore Ts'o <tytso@mit.edu>2016-11-19 20:58:15 -0500
commit8cdf3372fe8368f56315e66bea9f35053c418093 (patch)
treece03e6d1c641f2eac33bb811c1ac260c8b2d2c23 /fs
parent0f0909e242f73c1154272cf04f07fc9afe13e5b8 (diff)
ext4: sanity check the block and cluster size at mount time
If the block size or cluster size is insane, reject the mount. This is important for security reasons (although we shouldn't be just depending on this check). Ref: http://www.securityfocus.com/archive/1/539661 Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1332506 Reported-by: Borislav Petkov <bp@alien8.de> Reported-by: Nikolay Borisov <kernel@kyup.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Cc: stable@vger.kernel.org
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/ext4.h1
-rw-r--r--fs/ext4/super.c17
2 files changed, 17 insertions, 1 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 282a51b07c57..a8a750f59621 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -235,6 +235,7 @@ struct ext4_io_submit {
235#define EXT4_MAX_BLOCK_SIZE 65536 235#define EXT4_MAX_BLOCK_SIZE 65536
236#define EXT4_MIN_BLOCK_LOG_SIZE 10 236#define EXT4_MIN_BLOCK_LOG_SIZE 10
237#define EXT4_MAX_BLOCK_LOG_SIZE 16 237#define EXT4_MAX_BLOCK_LOG_SIZE 16
238#define EXT4_MAX_CLUSTER_LOG_SIZE 30
238#ifdef __KERNEL__ 239#ifdef __KERNEL__
239# define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize) 240# define EXT4_BLOCK_SIZE(s) ((s)->s_blocksize)
240#else 241#else
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 20da99da0a34..52b0530c5d65 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3565,7 +3565,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3565 if (blocksize < EXT4_MIN_BLOCK_SIZE || 3565 if (blocksize < EXT4_MIN_BLOCK_SIZE ||
3566 blocksize > EXT4_MAX_BLOCK_SIZE) { 3566 blocksize > EXT4_MAX_BLOCK_SIZE) {
3567 ext4_msg(sb, KERN_ERR, 3567 ext4_msg(sb, KERN_ERR,
3568 "Unsupported filesystem blocksize %d", blocksize); 3568 "Unsupported filesystem blocksize %d (%d log_block_size)",
3569 blocksize, le32_to_cpu(es->s_log_block_size));
3570 goto failed_mount;
3571 }
3572 if (le32_to_cpu(es->s_log_block_size) >
3573 (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
3574 ext4_msg(sb, KERN_ERR,
3575 "Invalid log block size: %u",
3576 le32_to_cpu(es->s_log_block_size));
3569 goto failed_mount; 3577 goto failed_mount;
3570 } 3578 }
3571 3579
@@ -3697,6 +3705,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3697 "block size (%d)", clustersize, blocksize); 3705 "block size (%d)", clustersize, blocksize);
3698 goto failed_mount; 3706 goto failed_mount;
3699 } 3707 }
3708 if (le32_to_cpu(es->s_log_cluster_size) >
3709 (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
3710 ext4_msg(sb, KERN_ERR,
3711 "Invalid log cluster size: %u",
3712 le32_to_cpu(es->s_log_cluster_size));
3713 goto failed_mount;
3714 }
3700 sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) - 3715 sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) -
3701 le32_to_cpu(es->s_log_block_size); 3716 le32_to_cpu(es->s_log_block_size);
3702 sbi->s_clusters_per_group = 3717 sbi->s_clusters_per_group =