[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180327033800.3081-1-ebiggers3@gmail.com>
Date: Mon, 26 Mar 2018 20:38:00 -0700
From: Eric Biggers <ebiggers3@...il.com>
To: linux-ext4@...r.kernel.org, Theodore Ts'o <tytso@....edu>
Cc: Andreas Dilger <adilger.kernel@...ger.ca>,
Wen Xu <wen.xu@...ech.edu>, Eric Biggers <ebiggers@...gle.com>
Subject: [PATCH] ext4: limit external inode xattrs to XATTR_SIZE_MAX
From: Eric Biggers <ebiggers@...gle.com>
This is a replacement for the broken patch "ext4: add better range
checking for e_value_size in xattrs" currently in ext4/dev.
-----8<-----
ext4 isn't validating the sizes of xattrs that are stored in external
inodes. This is problematic because ->e_value_size is a u32, but
ext4_xattr_get() returns an int. A very large size is misinterpreted as
an error code, which ext4_get_acl() translates into a bogus ERR_PTR()
for which IS_ERR() returns false, causing a crash.
Fix this by validating that all xattrs are <= XATTR_SIZE_MAX bytes.
(It's not strictly needed for non-EA-inode xattrs, but it doesn't hurt.)
https://bugzilla.kernel.org/show_bug.cgi?id=199185
Reported-by: Wen Xu <wen.xu@...ech.edu>
Fixes: e50e5129f384 ("ext4: xattr-in-inode support")
Cc: <stable@...r.kernel.org> # v4.13+
Signed-off-by: Eric Biggers <ebiggers@...gle.com>
---
fs/ext4/xattr.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 63656dbafdc45..8c9ade64aea2a 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -195,10 +195,13 @@ ext4_xattr_check_entries(struct ext4_xattr_entry *entry, void *end,
/* Check the values */
while (!IS_LAST_ENTRY(entry)) {
- if (entry->e_value_size != 0 &&
- entry->e_value_inum == 0) {
+ u32 size = le32_to_cpu(entry->e_value_size);
+
+ if (size > XATTR_SIZE_MAX)
+ return -EFSCORRUPTED;
+
+ if (size != 0 && entry->e_value_inum == 0) {
u16 offs = le16_to_cpu(entry->e_value_offs);
- u32 size = le32_to_cpu(entry->e_value_size);
void *value;
/*
--
2.16.2
Powered by blists - more mailing lists