ext4: do not allow external inodes for inline data (CVE-2018-11412)

Plus the related fix "ext4: bubble errors from
ext4_find_inline_data_nolock() up to ext4_iget()".
This commit is contained in:
Ben Hutchings 2018-06-25 23:59:59 +01:00
parent 5e4f042d2f
commit 8d25e929ea
4 changed files with 108 additions and 0 deletions

2
debian/changelog vendored
View File

@ -14,6 +14,8 @@ linux (4.17.2-1) UNRELEASED; urgency=medium
* vhost: fix info leak due to uninitialized memory (CVE-2018-1118)
* ext4: correctly handle a zero-length xattr with a non-zero e_value_offs
(CVE-2018-10840)
* ext4: do not allow external inodes for inline data (CVE-2018-11412)
* ext4: bubble errors from ext4_find_inline_data_nolock() up to ext4_iget()
[ Romain Perier ]
* [x86] Enable DCN 1.0 Raven family (Closes #901349)

View File

@ -0,0 +1,61 @@
From: Theodore Ts'o <tytso@mit.edu>
Date: Tue, 22 May 2018 17:14:07 -0400
Subject: ext4: bubble errors from ext4_find_inline_data_nolock() up to
ext4_iget()
Origin: https://git.kernel.org/linus/eb9b5f01c33adebc31cbc236c02695f605b0e417
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-11412
If ext4_find_inline_data_nolock() returns an error it needs to get
reflected up to ext4_iget(). In order to fix this,
ext4_iget_extra_inode() needs to return an error (and not return
void).
This is related to "ext4: do not allow external inodes for inline
data" (which fixes CVE-2018-11412) in that in the errors=continue
case, it would be useful to for userspace to receive an error
indicating that file system is corrupted.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Cc: stable@kernel.org
---
fs/ext4/inode.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4701,19 +4701,21 @@ static blkcnt_t ext4_inode_blocks(struct
}
}
-static inline void ext4_iget_extra_inode(struct inode *inode,
+static inline int ext4_iget_extra_inode(struct inode *inode,
struct ext4_inode *raw_inode,
struct ext4_inode_info *ei)
{
__le32 *magic = (void *)raw_inode +
EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize;
+
if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize + sizeof(__le32) <=
EXT4_INODE_SIZE(inode->i_sb) &&
*magic == cpu_to_le32(EXT4_XATTR_MAGIC)) {
ext4_set_inode_state(inode, EXT4_STATE_XATTR);
- ext4_find_inline_data_nolock(inode);
+ return ext4_find_inline_data_nolock(inode);
} else
EXT4_I(inode)->i_inline_off = 0;
+ return 0;
}
int ext4_get_projid(struct inode *inode, kprojid_t *projid)
@@ -4893,7 +4895,9 @@ struct inode *ext4_iget(struct super_blo
ei->i_extra_isize = sizeof(struct ext4_inode) -
EXT4_GOOD_OLD_INODE_SIZE;
} else {
- ext4_iget_extra_inode(inode, raw_inode, ei);
+ ret = ext4_iget_extra_inode(inode, raw_inode, ei);
+ if (ret)
+ goto bad_inode;
}
}

View File

@ -0,0 +1,43 @@
From: Theodore Ts'o <tytso@mit.edu>
Date: Tue, 22 May 2018 16:15:24 -0400
Subject: ext4: do not allow external inodes for inline data
Origin: https://git.kernel.org/linus/117166efb1ee8f13c38f9e96b258f16d4923f888
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2018-11412
The inline data feature was implemented before we added support for
external inodes for xattrs. It makes no sense to support that
combination, but the problem is that there are a number of extended
attribute checks that are skipped if e_value_inum is non-zero.
Unfortunately, the inline data code is completely e_value_inum
unaware, and attempts to interpret the xattr fields as if it were an
inline xattr --- at which point, Hilarty Ensues.
This addresses CVE-2018-11412.
https://bugzilla.kernel.org/show_bug.cgi?id=199803
Reported-by: Jann Horn <jannh@google.com>
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Fixes: e50e5129f384 ("ext4: xattr-in-inode support")
Cc: stable@kernel.org
---
fs/ext4/inline.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -144,6 +144,12 @@ int ext4_find_inline_data_nolock(struct
goto out;
if (!is.s.not_found) {
+ if (is.s.here->e_value_inum) {
+ EXT4_ERROR_INODE(inode, "inline data xattr refers "
+ "to an external xattr inode");
+ error = -EFSCORRUPTED;
+ goto out;
+ }
EXT4_I(inode)->i_inline_off = (u16)((void *)is.s.here -
(void *)ext4_raw_inode(&is.iloc));
EXT4_I(inode)->i_inline_size = EXT4_MIN_INLINE_DATA_SIZE +

View File

@ -127,6 +127,8 @@ features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch
debian/i386-686-pae-pci-set-pci-nobios-by-default.patch
bugfix/all/vhost-fix-info-leak-due-to-uninitialized-memory.patch
bugfix/all/ext4-correctly-handle-a-zero-length-xattr-with-a-non.patch
bugfix/all/ext4-do-not-allow-external-inodes-for-inline-data.patch
bugfix/all/ext4-bubble-errors-from-ext4_find_inline_data_nolock.patch
# Fix exported symbol versions
bugfix/all/module-disable-matching-missing-version-crc.patch