[PATCH] ext4: limit external inode xattrs to XATTR_SIZE_MAX

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Eric Biggers <ebiggers@xxxxxxxxxx>

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@xxxxxxxxxx>
Fixes: e50e5129f384 ("ext4: xattr-in-inode support")
Cc: <stable@xxxxxxxxxxxxxxx> # v4.13+
Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx>
---
 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




[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux