From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out3-smtp.messagingengine.com ([66.111.4.27]:49499 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755347AbeDTPIm (ORCPT ); Fri, 20 Apr 2018 11:08:42 -0400 Subject: FAILED: patch "[PATCH] ext4: add bounds checking to ext4_xattr_find_entry()" failed to apply to 4.4-stable tree To: tytso@mit.edu Cc: From: Date: Fri, 20 Apr 2018 17:08:36 +0200 Message-ID: <15242369163126@kroah.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org List-ID: The patch below does not apply to the 4.4-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to . thanks, greg k-h ------------------ original commit in Linus's tree ------------------ >>From 9496005d6ca4cf8f5ee8f828165a8956872dc59d Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 30 Mar 2018 20:00:56 -0400 Subject: [PATCH] ext4: add bounds checking to ext4_xattr_find_entry() Add some paranoia checks to make sure we don't stray beyond the end of the valid memory region containing ext4 xattr entries while we are scanning for a match. Also rename the function to xattr_find_entry() since it is static and thus only used in fs/ext4/xattr.c Signed-off-by: Theodore Ts'o Cc: stable@kernel.org diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index c030e41818ab..6304e81bfe6a 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -276,18 +276,22 @@ __xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header, __xattr_check_inode((inode), (header), (end), __func__, __LINE__) static int -ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index, - const char *name, int sorted) +xattr_find_entry(struct inode *inode, struct ext4_xattr_entry **pentry, + void *end, int name_index, const char *name, int sorted) { - struct ext4_xattr_entry *entry; + struct ext4_xattr_entry *entry, *next; size_t name_len; int cmp = 1; if (name == NULL) return -EINVAL; name_len = strlen(name); - entry = *pentry; - for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { + for (entry = *pentry; !IS_LAST_ENTRY(entry); entry = next) { + next = EXT4_XATTR_NEXT(entry); + if ((void *) next >= end) { + EXT4_ERROR_INODE(inode, "corrupted xattr entries"); + return -EFSCORRUPTED; + } cmp = name_index - entry->e_name_index; if (!cmp) cmp = name_len - entry->e_name_len; @@ -509,6 +513,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name, struct buffer_head *bh = NULL; struct ext4_xattr_entry *entry; size_t size; + void *end; int error; struct mb_cache *ea_block_cache = EA_BLOCK_CACHE(inode); @@ -530,7 +535,8 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name, goto cleanup; ext4_xattr_block_cache_insert(ea_block_cache, bh); entry = BFIRST(bh); - error = ext4_xattr_find_entry(&entry, name_index, name, 1); + end = bh->b_data + bh->b_size; + error = xattr_find_entry(inode, &entry, end, name_index, name, 1); if (error) goto cleanup; size = le32_to_cpu(entry->e_value_size); @@ -579,7 +585,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name, if (error) goto cleanup; entry = IFIRST(header); - error = ext4_xattr_find_entry(&entry, name_index, name, 0); + error = xattr_find_entry(inode, &entry, end, name_index, name, 0); if (error) goto cleanup; size = le32_to_cpu(entry->e_value_size); @@ -1808,8 +1814,8 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i, bs->s.first = BFIRST(bs->bh); bs->s.end = bs->bh->b_data + bs->bh->b_size; bs->s.here = bs->s.first; - error = ext4_xattr_find_entry(&bs->s.here, i->name_index, - i->name, 1); + error = xattr_find_entry(inode, &bs->s.here, bs->s.end, + i->name_index, i->name, 1); if (error && error != -ENODATA) goto cleanup; bs->s.not_found = error; @@ -2168,8 +2174,8 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i, if (error) return error; /* Find the named attribute. */ - error = ext4_xattr_find_entry(&is->s.here, i->name_index, - i->name, 0); + error = xattr_find_entry(inode, &is->s.here, is->s.end, + i->name_index, i->name, 0); if (error && error != -ENODATA) return error; is->s.not_found = error;