]> git.hungrycats.org Git - linux/commitdiff
ext4: add more inode number paranoia checks
authorTheodore Ts'o <tytso@mit.edu>
Sun, 17 Jun 2018 04:41:14 +0000 (00:41 -0400)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 25 Sep 2018 22:47:29 +0000 (23:47 +0100)
commit c37e9e013469521d9adb932d17a1795c139b36db upstream.

If there is a directory entry pointing to a system inode (such as a
journal inode), complain and declare the file system to be corrupted.

Also, if the superblock's first inode number field is too small,
refuse to mount the file system.

This addresses CVE-2018-10882.

https://bugzilla.kernel.org/show_bug.cgi?id=200069

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
fs/ext4/ext4.h
fs/ext4/inode.c
fs/ext4/super.c

index 7075d70b73af86e698e78766cedab2a172d4545d..f058d5cd81f755a1f7cf73db654da8ff8074b211 100644 (file)
@@ -1422,11 +1422,6 @@ static inline struct timespec ext4_current_time(struct inode *inode)
 static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
 {
        return ino == EXT4_ROOT_INO ||
-               ino == EXT4_USR_QUOTA_INO ||
-               ino == EXT4_GRP_QUOTA_INO ||
-               ino == EXT4_BOOT_LOADER_INO ||
-               ino == EXT4_JOURNAL_INO ||
-               ino == EXT4_RESIZE_INO ||
                (ino >= EXT4_FIRST_INO(sb) &&
                 ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count));
 }
index e90fa513c14cbfd2e3f4fc06e8cc837ae18b137c..72213cfa8aae4caa40d9fd9f00fa40f4fa3e9745 100644 (file)
@@ -3957,7 +3957,8 @@ static int __ext4_get_inode_loc(struct inode *inode,
        int                     inodes_per_block, inode_offset;
 
        iloc->bh = NULL;
-       if (!ext4_valid_inum(sb, inode->i_ino))
+       if (inode->i_ino < EXT4_ROOT_INO ||
+           inode->i_ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))
                return -EIO;
 
        iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
index a5da8120deb7ede31d9c4f019da5536f8c5dac5f..92b47444728b7f231c8965e67081249cdcf6bb43 100644 (file)
@@ -3771,6 +3771,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        } else {
                sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
                sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
+               if (sbi->s_first_ino < EXT4_GOOD_OLD_FIRST_INO) {
+                       ext4_msg(sb, KERN_ERR, "invalid first ino: %u",
+                                sbi->s_first_ino);
+                       goto failed_mount;
+               }
                if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) ||
                    (!is_power_of_2(sbi->s_inode_size)) ||
                    (sbi->s_inode_size > blocksize)) {